VPN과 터널링 (1) - 터널링의 원리 - soo:bak
작성일 :
터널링은 어떻게 네트워크를 확장하는가
물리적으로 떨어진 두 네트워크를 하나처럼 연결하려면 어떻게 해야 할까요?
대부분의 조직은 내부 네트워크에 사설 IP를 사용합니다. IPv4 주소는 약 43억 개뿐이라 전 세계 모든 장치에 공인 IP를 할당할 수 없기 때문입니다. 내부에서는 사설 IP(10.x.x.x, 172.16.x.x, 192.168.x.x)를 쓰고, 인터넷에 나갈 때만 NAT를 통해 공인 IP로 변환합니다. NAT와 방화벽에서 이 구조를 자세히 다뤘습니다.
서울 본사를 예로 들어봅시다. 본사 내부 네트워크는 10.1.0.0/16 대역을 사용합니다. 직원이 사내 파일 서버에 접속하면, 패킷은 건물 내부의 스위치와 라우터만 거쳐 서버에 도달합니다. 인터넷을 거치지 않으니 빠르고, 외부에 노출되지 않으니 안전합니다. 부산 지사(10.2.0.0/16)도 마찬가지입니다.
그런데 본사 직원이 지사의 서버에 접근해야 한다면 어떻게 해야 할까요?
가장 확실한 방법은 전용선입니다. 통신사가 두 지점 사이에 물리적 회선을 깔아주면, 마치 같은 건물에 있는 것처럼 통신할 수 있습니다. 그러나 거리에 비례해 비용이 올라가므로, 서울-부산 구간이라면 비용이 만만치 않습니다.
이미 깔려 있는 인터넷을 활용하면 비용을 줄일 수 있습니다. 그러나 문제가 있습니다. 사설 IP 주소로는 인터넷을 통해 직접 통신할 수 없기 때문입니다.
인터넷 라우터는 “10.2.0.5로 가려면 어디로 보내야 하는가?”를 알지 못합니다. 10.0.0.0/8 대역은 전 세계 수백만 개의 조직이 동시에 사용하고 있어서, 특정 조직의 10.2.0.5를 가리키는 경로를 인터넷에 등록할 수 없습니다. ISP들은 애초에 사설 IP 대역을 라우팅하지 않습니다.
터널링(Tunneling)은 이 문제를 해결합니다.
캡슐화의 원리
터널링은 어떻게 사설 IP 패킷을 인터넷으로 전달할까요?
핵심은 캡슐화(Encapsulation)입니다. 원본 패킷 전체를 새로운 패킷 안에 넣고, 바깥쪽에 공인 IP 주소를 붙이는 것입니다. 편지를 다른 봉투에 넣어 보내는 것과 비슷합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
원본 패킷:
┌──────────────────────────────────────────┐
│ IP 헤더 │ TCP 헤더 │ 데이터 │
│ 출발:10.1.0.5│ │ │
│ 도착:10.2.0.5│ │ │
└──────────────────────────────────────────┘
캡슐화 후:
┌─────────────────────────────────────────────────────────────┐
│ 새 IP 헤더 │ 터널 헤더 │ 원본 IP 헤더 │ TCP 헤더 │ 데이터 │
│ 출발:203.0.113.1│ │ 출발:10.1.0.5│ │ │
│ 도착:198.51.100.1│ │ 도착:10.2.0.5│ │ │
└─────────────────────────────────────────────────────────────┘
원본 패킷의 목적지는 10.2.0.5(사설 IP)입니다. 이 패킷은 인터넷으로 직접 전송할 수 없습니다. 그러나 캡슐화하면 바깥쪽 IP 헤더의 목적지가 198.51.100.1(공인 IP)이 됩니다. 인터넷 라우터는 이 공인 IP만 보고 패킷을 전달합니다. 안쪽에 사설 IP 패킷이 들어있다는 사실은 알지 못합니다.
목적지(198.51.100.1)에 도착하면 터널 종료점이 바깥쪽 헤더를 벗겨냅니다. 안에서 원본 패킷(10.1.0.5 → 10.2.0.5)이 나오고, 이 패킷은 내부 네트워크로 전달됩니다.
프로토콜 위의 프로토콜
앞서 사설 IP 패킷을 공인 IP 패킷 안에 넣어 전송하는 방법을 살펴봤습니다. 그런데 터널링이 할 수 있는 일은 이것만이 아닙니다.
터널링은 본질적으로 어떤 프로토콜이든 다른 프로토콜 안에 넣어 전송하는 구조입니다. 안에 들어가는 것을 승객(Passenger), 바깥에서 운반하는 것을 전송(Carrier)이라고 부릅니다.
1
2
3
4
5
6
7
8
9
10
┌─────────────────────────────────────────┐
│ 전송 프로토콜 (Carrier) │
│ ┌───────────────────────────────────┐ │
│ │ 캡슐화 프로토콜 (Encapsulating)│ │
│ │ ┌─────────────────────────────┐ │ │
│ │ │ 승객 프로토콜 (Passenger) │ │ │
│ │ │ (원본 패킷) │ │ │
│ │ └─────────────────────────────┘ │ │
│ └───────────────────────────────────┘ │
└─────────────────────────────────────────┘
앞서 본 예시에서는 사설 IPv4 패킷(승객)을 GRE 헤더로 감싸고, 공인 IPv4 패킷(전송)으로 운반했습니다. 이 구조를 “IPv4 over GRE over IPv4”라고 표현합니다.
승객과 전송의 조합은 자유롭게 바꿀 수 있습니다. 몇 가지 예를 들면:
- IPv4 over IPv4: 사설 IP 네트워크를 공인 인터넷 위에서 연결 (앞서 본 예시)
- IPv6 over IPv4: IPv6를 사용하고 싶지만 중간 네트워크가 IPv4만 지원할 때
- Ethernet over IP: 이더넷 프레임 전체를 IP 네트워크로 전송해야 할 때
터널링의 활용
캡슐화의 원리는 알았습니다. 그렇다면 실제로 터널링은 어디에 쓰일까요?
1. 사설 네트워크 연결
도입부에서 다룬 서울 본사와 부산 지사 사례로 돌아가봅시다.
1
2
3
4
5
6
7
8
9
서울 본사 (10.1.0.0/16)
│
│ 터널
│
──── 인터넷 ────
│
│ 터널
│
부산 지사 (10.2.0.0/16)
터널이 설정되면 두 네트워크가 하나처럼 동작합니다. 본사 직원이 10.2.0.5(지사 서버)에 접속하면, 패킷은 터널을 통해 자동으로 캡슐화되어 인터넷을 건너갑니다. 직원 입장에서는 같은 건물에 있는 서버에 접속하는 것과 차이가 없습니다.
2. 프로토콜 호환성
회사 내부는 이미 IPv6로 전환했는데, 인터넷 구간이 아직 IPv4만 지원한다면 어떻게 해야 할까요?
1
2
IPv6 네트워크 ──► IPv6-over-IPv4 터널 ──► IPv6 네트워크
(IPv4 인터넷)
IPv6 패킷을 IPv4 패킷 안에 캡슐화하면 됩니다. IPv4 라우터들은 바깥쪽 IPv4 헤더만 보고 패킷을 전달합니다. 안에 IPv6 패킷이 들어있다는 사실은 알지 못합니다. 앞서 본 사설 IP 캡슐화와 같은 원리입니다.
3. 보안
여기까지 설명한 터널링에는 한 가지 문제가 있습니다. 패킷을 감싸서 전달할 뿐, 내용 자체는 보호하지 않습니다. 터널을 지나는 패킷을 누군가 가로채면 원본 데이터를 그대로 읽을 수 있습니다.
카페 Wi-Fi에서 회사 서버에 접속하는 상황을 생각해봅시다. 같은 네트워크에 있는 누군가가 패킷을 엿볼 수 있습니다. 터널링만으로는 이 문제를 해결할 수 없습니다.
터널에 암호화를 추가하면 상황이 달라집니다. 암호화된 터널은 세 가지 보안 속성을 제공합니다.
- 기밀성: 제3자가 내용을 읽을 수 없음
- 무결성: 데이터가 변조되면 탐지 가능
- 인증: 통신 상대방이 실제로 회사 서버인지 확인
이렇게 암호화와 인증이 결합된 터널을 VPN(Virtual Private Network)이라고 부릅니다.
터널링 계층
지금까지 IP 패킷을 캡슐화하는 예시를 살펴봤습니다. 그런데 캡슐화할 수 있는 것이 IP 패킷만은 아닙니다.
네트워크는 계층 구조로 되어 있습니다. 데이터 링크 계층(L2)에는 이더넷 프레임이, 네트워크 계층(L3)에는 IP 패킷이, 그 위에는 TCP나 HTTP 같은 애플리케이션 데이터가 있습니다. 터널링은 이 중 어느 계층에서든 구현할 수 있고, 어떤 계층을 선택하느냐에 따라 특성이 달라집니다.
| 구분 | L2 터널링 | L3 터널링 | 애플리케이션 터널링 |
|---|---|---|---|
| 캡슐화 단위 | 이더넷 프레임 | IP 패킷 | TCP/HTTP 등 |
| 오버헤드 | 큼 | 중간 | 큼 |
| 브로드캐스트 | 통과 | 차단 | 차단 |
| 대표 프로토콜 | L2TP, PPTP | GRE, IPsec | SSH, SSL VPN |
| 주요 용도 | 동일 서브넷 확장 | 기업 VPN | 방화벽 우회 |
각 계층의 특성을 자세히 살펴봅니다.
L2 터널링
두 사이트를 마치 같은 스위치에 연결된 것처럼 만들고 싶다면 어떻게 해야 할까요?
L2 터널링은 이더넷 프레임 전체를 캡슐화합니다. IP 패킷뿐 아니라 MAC 주소 정보까지 포함해서 전송합니다.
이렇게 하면 ARP(IP에서 MAC 주소를 찾는 프로토콜)나 DHCP(IP 주소 자동 할당) 같은 브로드캐스트 트래픽도 터널을 통과합니다. 서울 본사에서 보낸 브로드캐스트가 부산 지사까지 도달하는 것입니다. 덕분에 기존 LAN 환경의 소프트웨어를 수정 없이 그대로 사용할 수 있습니다.
대표적인 프로토콜로는 L2TP(Layer 2 Tunneling Protocol)가 있습니다. 과거에는 PPTP도 널리 쓰였으나, 심각한 보안 취약점이 발견되어 현재는 권장되지 않습니다.
다만 단점도 있습니다. 이더넷 프레임 전체를 감싸므로 오버헤드가 큽니다. 또한 브로드캐스트가 터널을 넘어 확장되면서, 불필요한 트래픽까지 터널을 통과하는 부작용이 생길 수 있습니다.
L3 터널링
L2 터널링은 브로드캐스트까지 전달하므로 오버헤드가 큽니다. 브로드캐스트가 필요한 경우는 ARP나 DHCP처럼 “같은 LAN에 있는 장치를 찾아야 할 때”입니다.
하지만 서울 본사와 부산 지사는 각각 자체 DHCP 서버와 라우터를 가지고 있습니다. 본사 직원이 지사의 파일 서버(10.2.0.5)에 접근할 때는 IP 주소로 직접 통신하면 됩니다. 브로드캐스트를 터널로 전달할 필요가 없습니다.
L3 터널링은 IP 패킷 단위로 캡슐화합니다. 이더넷 헤더(14바이트)를 포함하지 않으므로 L2보다 오버헤드가 적습니다. 또한 터널이 하나의 네트워크 인터페이스처럼 동작하므로 기존 라우팅 인프라와 자연스럽게 통합됩니다. 이 구조는 터널 내부의 라우팅 섹션에서 자세히 설명합니다.
현재 기업 VPN의 대부분은 L3 터널링을 기반으로 구축됩니다. 앞서 살펴본 서울-부산 사례도 L3 터널링으로 충분히 해결할 수 있습니다.
대표적인 프로토콜로는 GRE와 IPsec이 있습니다. GRE는 단순한 캡슐화만 제공하고, IPsec은 암호화와 인증까지 포함합니다. GRE는 아래에서, IPsec은 Part 2에서 자세히 다룹니다.
애플리케이션 터널링
회사나 호텔 네트워크에서는 GRE(프로토콜 47)나 IPsec(프로토콜 50, UDP 500/4500)이 방화벽에서 차단되어 있는 경우가 많습니다. 보안 정책상 허용된 트래픽만 통과시키기 때문입니다.
애플리케이션 터널링은 이 문제를 우회합니다. HTTPS(443)나 SSH(22)처럼 대부분의 방화벽이 허용하는 포트를 사용합니다. 방화벽 입장에서는 일반 웹 트래픽이나 SSH 접속처럼 보이므로 차단하지 않습니다.
대표적인 예로 SSH 터널링이 있습니다. SSH 연결을 먼저 맺고, 그 안에 다른 트래픽을 실어 보냅니다. 예를 들어 회사 내부의 MySQL 데이터베이스(3306 포트)에 접근하고 싶지만 방화벽이 막고 있다면, SSH 터널을 통해 우회할 수 있습니다.
1
2
로컬 PC ──[SSH 터널 (22)]──► 회사 서버 ──► DB 서버 (3306)
(방화벽 통과)
SSL/TLS VPN은 HTTPS와 같은 포트(443)를 사용합니다. 웹 브라우저만 있으면 접속할 수 있어서 클라이언트 설치가 필요 없는 경우도 많습니다.
다만 단점도 있습니다.
사용자 공간 처리의 오버헤드
L3 터널링(GRE, IPsec)은 커널에서 패킷을 처리합니다. 패킷이 도착하면 커널이 직접 캡슐화를 벗기고 라우팅합니다.
반면 SSH 터널이나 SSL VPN은 사용자 공간(User Space)의 애플리케이션이 처리합니다.
1
2
3
4
5
6
L3 터널링 (커널 처리):
패킷 도착 → 커널에서 처리 → 전달
애플리케이션 터널링:
패킷 도착 → 커널 → 사용자 공간(SSH/VPN 앱)
→ 복호화 → 커널 → 전달
사용자 공간에서 처리하면 컨텍스트 스위칭이 발생합니다. CPU가 커널 모드와 사용자 모드를 오가며 데이터를 복사해야 합니다. 패킷 하나를 처리할 때마다 이 전환이 일어나므로, 대량의 트래픽을 처리할 때 성능 저하가 눈에 띕니다.
TCP 위의 TCP 문제 (TCP Meltdown)
SSH 터널은 TCP 연결입니다. 그런데 이 터널 안에 또 다른 TCP 연결(예: HTTP, 데이터베이스)을 실으면 문제가 생깁니다.
네트워크가 혼잡해서 패킷이 손실되었다고 가정해봅시다.
1
2
3
4
정상적인 TCP (터널 없음):
클라이언트 ──► 패킷 손실 ──► 서버
◄── 재전송 요청 ───
──► 재전송 ────────►
TCP는 패킷 손실을 감지하면 재전송합니다. 한 번의 재전송으로 문제가 해결됩니다.
그런데 TCP 터널 안에 TCP가 들어 있으면 어떻게 될까요?
1
2
3
4
5
6
7
8
TCP over TCP (SSH 터널):
[내부 TCP] ──► [SSH 터널(외부 TCP)] ──► 인터넷 ──► ...
│
패킷 손실!
외부 TCP: "패킷 손실! 재전송하자"
내부 TCP: "응답이 늦네... 나도 재전송하자"
두 TCP가 모두 재전송을 시도합니다. 외부 TCP가 손실된 패킷을 재전송하는 동안, 내부 TCP도 타임아웃을 감지하고 재전송을 시작합니다.
결과적으로 같은 데이터가 여러 번 재전송됩니다. 네트워크가 혼잡할 때 트래픽이 더 증가하고, 이것이 다시 혼잡을 악화시키는 악순환이 발생합니다. 이를 TCP Meltdown이라고 부릅니다.
이런 이유로 애플리케이션 터널링은 대역폭이 중요한 환경보다는 개인 사용자나 임시 우회 용도에 적합합니다.
GRE: 가장 단순한 터널링
L3 터널링을 구현하려면 캡슐화 프로토콜이 필요합니다. 여러 프로토콜이 있지만, 가장 단순한 것은 GRE(Generic Routing Encapsulation)입니다.
시스코가 1990년대 초에 개발했고, 1994년 RFC 1701로 표준화되었습니다. “Generic”이라는 이름처럼, 특정 프로토콜에 종속되지 않고 다양한 프로토콜을 캡슐화할 수 있도록 설계되었습니다.
GRE의 구조
GRE 헤더는 4바이트에 불과합니다. 앞서 살펴본 서울-부산 예시를 GRE로 구현하면 이렇게 됩니다.
1
2
3
4
5
6
7
8
9
10
서울 본사(10.1.0.5) → 부산 지사(10.2.0.5) 패킷을 GRE로 캡슐화:
┌────────────────────────────────────────────────────────────┐
│ 외부 IP 헤더 │ GRE 헤더 │ 내부 IP 헤더 │ 페이로드 │
│ (20바이트) │ (4바이트) │ (20바이트) │ │
│ │ │ │ │
│ 출발:203.0.113.1 │ 출발:10.1.0.5 │ │
│ 도착:198.51.100.1 │ 도착:10.2.0.5 │ │
│ 프로토콜: 47(GRE) │ 프로토콜: TCP │ │
└────────────────────────────────────────────────────────────┘
인터넷 라우터는 외부 IP 헤더만 봅니다. 프로토콜 번호 47은 “이 패킷 안에 GRE로 캡슐화된 다른 패킷이 있다”는 의미입니다. 부산 지사의 터널 종료점(198.51.100.1)이 이 패킷을 받으면, GRE 헤더와 외부 IP 헤더를 벗기고 내부 패킷을 꺼냅니다.
장점
GRE가 오랫동안 사용되는 이유가 있습니다.
단순해서 디버깅이 쉽습니다. 헤더가 4바이트뿐이라 패킷 캡처로 분석하기 쉽고, 동작이 직관적이라 장애 진단이 간단합니다.
다양한 프로토콜을 지원합니다. IPv4뿐 아니라 IPv6, IPX 등 어떤 네트워크 프로토콜이든 캡슐화할 수 있습니다. OSPF 같은 라우팅 프로토콜의 멀티캐스트 트래픽도 터널을 통해 전달할 수 있습니다.
단점
그러나 GRE를 단독으로 사용하기는 어렵습니다.
첫째, 암호화나 인증이 없습니다. GRE는 캡슐화만 합니다. 터널을 지나는 패킷은 평문 그대로 노출됩니다. 중간에서 패킷을 가로채면 내용을 그대로 읽을 수 있고, 조작된 패킷을 주입할 수도 있습니다.
둘째, NAT 환경에서 문제가 생깁니다. GRE는 TCP나 UDP가 아닙니다. IP 프로토콜 번호 47을 사용하는 별도의 프로토콜입니다.
NAT 장비는 포트 번호로 내부 호스트를 구분합니다. 예를 들어 TCP 연결에서는 이렇게 동작합니다.
1
2
3
4
5
6
7
8
9
TCP 연결 (NAT가 구분 가능):
내부 호스트 A (10.0.0.1:50001) ─┐
├─► NAT ─► 인터넷 ─► 서버
내부 호스트 B (10.0.0.2:50002) ─┘
돌아오는 패킷:
서버 → NAT (도착 포트 50001) → 호스트 A
서버 → NAT (도착 포트 50002) → 호스트 B
그런데 GRE에는 포트 번호가 없습니다.
1
2
3
4
5
6
7
8
9
GRE 연결 (NAT가 구분 불가):
내부 호스트 A (10.0.0.1) ─┐
├─► NAT ─► 인터넷 ─► 터널 종료점
내부 호스트 B (10.0.0.2) ─┘
돌아오는 패킷:
터널 종료점 → NAT (프로토콜 47, 포트 없음) → ???
어느 호스트에게 전달해야 하는가?
NAT 뒤에 호스트가 하나만 GRE를 사용하면 동작할 수 있습니다. 돌아오는 GRE 패킷을 그 호스트에게 보내면 되기 때문입니다. 그러나 여러 호스트가 각각 GRE 터널을 만들면, NAT 장비는 돌아오는 패킷을 어느 호스트에게 전달해야 할지 구분하지 못합니다.
실무에서는 공유기(가정용 NAT) 뒤에서 VPN을 사용하는 경우가 많으므로, 이 제약은 GRE를 선택하기 어렵게 만듭니다.
이런 이유로 GRE를 단독으로 쓰는 경우는 드뭅니다. 실무에서는 암호화를 추가한 GRE over IPsec 구성을 주로 사용합니다. IPsec은 Part 2에서 자세히 다룹니다.
VPN의 분류
지금까지 터널링의 원리와 GRE를 살펴봤습니다. 그런데 GRE만으로는 보안이 없습니다. 실제로 사용하려면 암호화와 인증이 필요합니다.
VPN(Virtual Private Network)은 터널링에 암호화와 인증을 결합한 것입니다. 공용 네트워크(인터넷)를 통과하지만, 암호화 덕분에 마치 전용선처럼 안전하게 통신할 수 있습니다.
VPN은 “누가 터널을 만드는가”에 따라 두 가지로 나뉩니다.
Site-to-Site VPN
서울 본사와 부산 지사를 연결하는 시나리오를 다시 떠올려봅시다. 이 경우 네트워크 전체를 연결해야 합니다. 본사의 모든 직원이 지사의 서버에 접근할 수 있어야 하고, 반대도 마찬가지입니다.
1
2
3
4
5
6
7
8
9
10
서울 본사 부산 지사
┌─────────────────┐ ┌─────────────────┐
│ 내부 네트워크 │ │ 내부 네트워크 │
│ 10.1.0.0/16 │ │ 10.2.0.0/16 │
│ │ │ │
│ ┌───────────┐ │ VPN 터널 │ ┌───────────┐ │
│ │ VPN │◄─┼────────────────────┼─►│ VPN │ │
│ │ Gateway │ │ (인터넷) │ │ Gateway │ │
│ └───────────┘ │ │ └───────────┘ │
└─────────────────┘ └─────────────────┘
Site-to-Site VPN에서는 각 네트워크의 출입구에 VPN 게이트웨이를 설치합니다. 내부 네트워크와 인터넷이 연결되는 지점, 즉 방화벽이나 라우터가 있는 위치입니다. 이 게이트웨이가 터널을 만들고 유지합니다.
본사 직원이 지사 서버(10.2.0.5)에 접근하면, 패킷은 본사 게이트웨이에서 암호화되어 터널을 통과하고, 지사 게이트웨이에서 복호화됩니다. 직원의 PC에는 VPN 소프트웨어가 필요 없습니다. 게이트웨이가 모든 처리를 대신하기 때문입니다.
터널은 한 번 설정되면 항상 활성 상태를 유지합니다. 직원이 지사 서버에 접근할 때마다 연결을 새로 맺을 필요가 없으므로 추가 지연이 발생하지 않습니다.
본사-지사 연결 외에도 다양한 곳에서 사용됩니다. AWS VPC와 회사 데이터센터를 연결하는 하이브리드 클라우드, 여러 데이터센터 간 백본 연결 등이 대표적입니다.
Remote Access VPN
Site-to-Site VPN은 본사와 지사처럼 고정된 두 네트워크를 연결합니다. 양쪽에 VPN 게이트웨이를 설치하고, 터널을 상시 유지합니다.
그런데 재택 근무자는 상황이 다릅니다. 집에서 일하다가, 카페로 이동하고, 출장지 호텔에서도 접속해야 합니다. 위치가 계속 바뀌고, 사용하는 네트워크도 달라집니다.
1
2
3
4
5
6
7
8
9
10
11
회사 네트워크
┌─────────────────┐
재택 근무자 (집) VPN 터널 │ │
┌─────────┐ ◄─────────────────────────►│ │
│ PC │ (인터넷) │ VPN 서버 │
└─────────┘ │ │
│ 내부 서버 │
출장 중 (호텔) VPN 터널 │ 데이터베이스 │
┌─────────┐ ◄─────────────────────────►│ │
│ 노트북 │ (인터넷) │ │
└─────────┘ └─────────────────┘
Remote Access VPN은 개별 사용자의 장치에서 직접 터널을 만듭니다. 노트북이나 스마트폰에 VPN 클라이언트를 설치하고, 필요할 때 회사 VPN 서버에 연결합니다.
Site-to-Site VPN과 달리 터널이 상시 유지되지 않습니다. 사용자가 VPN 앱에서 “연결” 버튼을 누르면 터널이 생기고, “연결 해제”를 누르면 사라집니다. 아침에 업무를 시작할 때 연결하고 퇴근할 때 끊거나, 필요한 순간에만 잠깐 연결할 수 있습니다.
개인 장치에서 접속하므로 사용자 인증이 중요합니다. Site-to-Site VPN은 게이트웨이 간 인증이지만, Remote Access VPN은 사람을 인증합니다. 회사 계정으로 로그인하고, OTP 같은 2단계 인증을 거칩니다.
이 방식의 장점은 계정 단위로 접근을 제어할 수 있다는 것입니다. 직원이 노트북을 분실하면 그 계정만 비활성화하면 됩니다. 새 노트북에서 같은 계정으로 로그인하면 바로 업무를 재개할 수 있습니다.
코로나 이후 재택근무가 보편화되면서 Remote Access VPN 수요가 급증했습니다.
터널 내부의 라우팅
VPN 터널이 설정되었습니다. 이제 본사 직원이 부산 지사 서버(10.2.0.5)에 접속하려고 합니다. 패킷은 어떻게 터널을 찾아 들어갈까요?
터널 인터페이스
컴퓨터 뒷면에는 랜선을 꽂는 포트가 있습니다. 운영체제는 이 포트를 네트워크 인터페이스라고 부르고, 이름을 붙입니다. Linux에서는 eth0, eth1처럼 번호를 매깁니다.
일반 PC에는 포트가 하나지만, 서버나 라우터는 여러 개입니다. 각 포트를 서로 다른 네트워크에 연결하고, 각각 별도의 IP 주소를 할당합니다.
1
2
3
4
서울 본사 VPN 게이트웨이의 물리 인터페이스:
eth0 - 10.1.0.1 → 본사 내부 네트워크로 연결된 포트
eth1 - 203.0.113.5 → 인터넷으로 연결된 포트
VPN 터널을 설정하면 터널 인터페이스가 추가됩니다. 물리적인 포트는 없지만, 운영체제는 이것을 또 하나의 네트워크 인터페이스로 취급합니다.
1
2
3
4
5
터널 인터페이스 추가 후:
eth0 - 10.1.0.1 → 본사 내부 네트워크
eth1 - 203.0.113.5 → 인터넷
tunnel0 - 10.255.0.1 → 부산 지사로 가는 터널 (가상)
eth0으로 패킷을 보내면 물리 케이블을 통해 본사 내부 네트워크로 나갑니다. tunnel0으로 패킷을 보내면 어떻게 될까요? 캡슐화되어 eth1(인터넷)을 통해 부산 지사로 전송됩니다. 물리적으로는 eth1을 사용하지만, 운영체제 입장에서는 “tunnel0이라는 별도의 경로”로 보냅니다.
라우팅 테이블
터널 인터페이스가 있어도, 패킷이 자동으로 터널로 들어가지는 않습니다. “10.2.0.0/16으로 가는 패킷은 tunnel0으로 보내라”는 규칙이 필요합니다. 이것이 라우팅 테이블입니다.
1
2
3
4
5
6
7
VPN 설정 후 서울 본사 게이트웨이의 라우팅 테이블:
목적지 다음 홉 인터페이스 설명
─────────────────────────────────────────────────────────────
10.1.0.0/16 직접 연결 eth0 본사 내부
10.2.0.0/16 터널 tunnel0 부산 지사 (터널 경유)
0.0.0.0/0 203.0.113.1 eth1 그 외 모든 곳 (인터넷)
본사 직원(10.1.0.5)이 부산 지사 서버(10.2.0.5)에 패킷을 보내면 어떻게 될까요?
- 게이트웨이가 라우팅 테이블을 확인합니다
- 10.2.0.5는 10.2.0.0/16에 해당하므로 tunnel0으로 보냅니다
- tunnel0에서 패킷이 캡슐화됩니다
- 캡슐화된 패킷은 eth1을 통해 인터넷으로 나갑니다
1
2
3
4
5
6
7
8
9
10
11
12
13
본사 직원 PC 본사 게이트웨이 인터넷 부산 게이트웨이 부산 서버
(10.1.0.5) (203.0.113.5) (198.51.100.5) (10.2.0.5)
│ │ │ │
│ 10.1.0.5 → │ │ │
│ 10.2.0.5 │ │ │
│──────────────────►│ │ │
│ 캡슐화 │ │
│ 203.0.113.5 → 198.51.100.5 │ │
│───────────────────────────────────────►│ │
│ 역캡슐화 │
│ 10.1.0.5 → │
│ 10.2.0.5 │
│─────────────────►│
그렇다면 본사 직원이 Google(8.8.8.8)에 접속하면 어떻게 될까요?
라우팅 테이블을 다시 봅시다. 8.8.8.8은 부산 지사 대역(10.2.0.0/16)이 아닙니다. 그러면 마지막 줄의 “그 외 모든 곳”(0.0.0.0/0) 규칙이 적용됩니다. 패킷은 터널을 거치지 않고 eth1을 통해 인터넷으로 직접 나갑니다.
즉, 부산 지사로 가는 트래픽만 터널을 통과하고, 나머지 인터넷 트래픽은 평소처럼 직접 나갑니다.
터널링의 오버헤드
터널링에는 대가가 있습니다. 원본 패킷을 다른 패킷 안에 넣으므로, 추가 헤더만큼 공간을 더 차지합니다.
헤더 오버헤드
일반적인 TCP/IP 패킷과 GRE 터널을 통과하는 패킷을 비교해봅시다.
1
2
3
4
5
6
7
8
9
10
11
일반 IP 패킷 (터널 없음):
┌──────────────┬──────────────┬─────────────────────────────┐
│ IP 헤더(20) │ TCP 헤더(20) │ 데이터(1460) │
└──────────────┴──────────────┴─────────────────────────────┘
총 1500바이트
GRE 터널 통과 패킷:
┌────────────┬──────────┬──────────────┬──────────────┬────────────────────┐
│ 외부 IP(20)│ GRE(4) │ 내부 IP(20) │ TCP(20) │ 데이터(?) │
└────────────┴──────────┴──────────────┴──────────────┴────────────────────┘
총 1500바이트
GRE 터널을 사용하면 외부 IP 헤더(20바이트)와 GRE 헤더(4바이트)가 추가됩니다. 총 24바이트가 늘어납니다.
그런데 네트워크에는 한 번에 보낼 수 있는 패킷 크기 제한이 있습니다. 이더넷의 경우 1500바이트입니다. 이것을 MTU(Maximum Transmission Unit)라고 합니다.
패킷 크기가 1500바이트로 같다면, 터널 헤더가 추가된 만큼 실제 데이터 공간이 줄어듭니다. GRE의 경우 1460바이트에서 1436바이트로, 24바이트가 감소합니다.
MTU 초과 문제
더 큰 문제는 MTU를 초과하는 경우입니다.
본사 직원이 1500바이트짜리 패킷을 부산 지사로 보낸다고 가정합시다. 이 패킷이 터널을 통과하면 어떻게 될까요?
1
2
3
4
5
원본 패킷: 1500바이트
│
▼ 캡슐화 (GRE 헤더 24바이트 추가)
│
캡슐화된 패킷: 1524바이트 → MTU 초과!
1524바이트는 이더넷 MTU(1500바이트)를 초과합니다. 이 패킷은 그대로 전송할 수 없습니다.
이때 두 가지 일이 일어날 수 있습니다.
단편화(Fragmentation): 라우터가 패킷을 여러 조각으로 나눠서 보내고, 최종 목적지에서 다시 합칩니다. 하지만 단편화는 목적지에서의 재조립 부담, 지연, 그리고 조각 하나라도 유실되면 전체 패킷을 재전송해야 하는 문제가 있습니다.
패킷 폐기: 대부분의 TCP 구현은 IP 헤더에 “단편화 금지(DF, Don’t Fragment)” 플래그를 설정합니다. 이 플래그가 있으면 라우터는 단편화 대신 패킷을 버리고, 송신자에게 ICMP “Fragmentation Needed” 메시지를 보냅니다. 송신자는 이 메시지를 받으면 패킷 크기를 줄여서 다시 보냅니다.
해결 방법
가장 간단한 방법은 터널 인터페이스의 MTU를 미리 낮추는 것입니다.
앞서 본 문제를 다시 봅시다. 1500바이트 패킷이 터널에 들어가면 캡슐화 후 1524바이트가 되어 MTU를 초과했습니다.
그렇다면 처음부터 1476바이트 이하의 패킷만 터널에 들어가게 하면 어떨까요?
1
2
3
4
5
6
7
터널 인터페이스 MTU = 1476으로 설정
원본 패킷: 1476바이트 (MTU 제한에 맞춤)
│
▼ 캡슐화 (GRE 헤더 24바이트 추가)
│
캡슐화된 패킷: 1500바이트 → MTU 초과 안 함!
터널 인터페이스의 MTU를 1476으로 설정하면, 이 인터페이스로 나가는 패킷은 최대 1476바이트로 제한됩니다.
TCP 연결을 맺을 때, 양쪽은 MSS(Maximum Segment Size)를 교환합니다. MSS는 “한 번에 보낼 수 있는 TCP 데이터의 최대 크기”입니다. 이 값은 인터페이스의 MTU에서 IP 헤더(20바이트)와 TCP 헤더(20바이트)를 뺀 값입니다.
1
2
MTU 1476인 터널 인터페이스의 MSS:
1476 - 20(IP) - 20(TCP) = 1436바이트
TCP는 데이터를 이 MSS에 맞춰 나눠서 보냅니다. 결과적으로 터널에 들어가는 패킷은 1476바이트를 넘지 않고, 캡슐화 후에도 1500바이트 이내가 됩니다.
결과적으로 단편화나 패킷 폐기 문제가 발생하지 않습니다. 대신 한 패킷에 담을 수 있는 데이터가 24바이트 줄어듭니다. 대부분의 경우 이 정도 감소는 체감하기 어렵지만, 대용량 파일 전송처럼 효율이 중요한 환경에서는 고려해야 할 요소입니다.
마무리
이 글에서 살펴본 내용을 정리합니다.
- 터널링은 원본 패킷을 다른 패킷 안에 넣어(캡슐화) 공용 인터넷을 통해 사설 네트워크를 연결합니다.
- L2 터널링은 이더넷 프레임까지, L3 터널링은 IP 패킷만, 애플리케이션 터널링은 TCP/UDP 위에서 동작합니다.
- GRE는 단순하지만 암호화가 없고, NAT 환경에서 제약이 있습니다.
- Site-to-Site VPN은 네트워크 전체를 연결하고, Remote Access VPN은 개별 사용자가 접속합니다.
- 터널 인터페이스와 라우팅 테이블이 패킷을 터널로 보내는 역할을 합니다.
- 캡슐화로 인한 MTU 오버헤드는 터널 MTU를 미리 낮춰서 해결합니다.
터널링 덕분에 서울 본사와 부산 지사가 마치 같은 네트워크에 있는 것처럼 통신할 수 있습니다. 전용선 없이 인터넷만으로 가능합니다.
그런데 GRE로 만든 터널은 암호화가 없습니다. 인터넷을 지나는 패킷을 누군가 가로채면 내용을 그대로 읽을 수 있습니다. 안전한 터널을 만들려면 암호화가 필요합니다.
Part 2에서는 IPsec을 살펴봅니다. IPsec이 어떻게 패킷을 암호화하고, 상대방이 진짜인지 인증하는지, AH와 ESP의 차이, 전송 모드와 터널 모드, IKE 키 교환의 원리를 다룹니다.
Part 3에서는 OpenVPN, WireGuard 등 현대 VPN 기술을 살펴봅니다. IPsec보다 설정이 간편하고 성능이 뛰어난 이유를 알아봅니다.
관련 글
시리즈
- VPN과 터널링 (1) - 터널링의 원리 (현재 글)
- VPN과 터널링 (2) - IPsec의 구조
- VPN과 터널링 (3) - 현대 VPN 기술