OpenVPN 원격 접속 VPN — 세우고, 길을 놓고, 잠그고, 고친다
VPN 의 숫자는 무엇이 정하나 — OpenVPN 과 WireGuard
한 줄 요약
VPN 의 처리량과 지연은 프로토콜 이름이 아니라 「패킷 하나가 몇 번 커널 밖으로 나갔다 오는가」, 「어떤 암호를 이 CPU 가 얼마나 빨리 하는가」, 「바깥 경로의 MTU」 가 정합니다. 그래서 같은 자리에서 조건을 하나씩만 바꿔 재야 합니다.
왜 이게 필요했나
「WireGuard 가 OpenVPN 보다 몇 배 빠르다」 는 말은 맞을 때도 틀릴 때도 있습니다. OpenVPN 2.6 은 커널 가속 모듈(DCO)이 있으면 데이터 채널을 커널에서 처리하고, 암호를 바꾸면 같은 프로그램이라도 숫자가 달라지고, CPU 에 AES 가속이 있는지에 따라 순위가 뒤집히기도 합니다. VPN 을 고를 때나 「VPN 이 느려요」 라는 신고를 받았을 때 필요한 것은 남의 벤치마크가 아니라 내 자리에서 잰 기준선입니다.
어떻게 동작하나
OpenVPN(DCO 없음)의 길. 노트북의 앱이 보낸 패킷은 커널의 tun 장치로 들어가고, openvpn 프로세스가 그것을 사용자 공간으로 읽어 암호화한 뒤 UDP 소켓으로 다시 커널에 넘깁니다. 받는 쪽은 거꾸로 합니다. 패킷마다 커널과 사용자 공간 사이를 두 번씩 오가는 것이 비용의 큰 몫이고, openvpn 프로세스 하나가 한 CPU 코어에서 돕니다. 이 실습 VM 에는 DCO 모듈이 없어(서버 접속 목록의 dco_enabled 0) 이 길로 돕니다.
WireGuard 의 길. 암호화가 리눅스 커널 안에서 일어납니다. 사용자 공간을 오가지 않고, 암호는 ChaCha20-Poly1305 하나로 고정입니다. 신원은 CA 가 찍은 인증서가 아니라 상대의 공개 키 자체이고, AllowedIPs 한 칸이 「이 대역을 이 피어로 보낸다」 와 「이 피어의 키로 온 패킷은 이 출발지만 쓸 수 있다」 를 함께 정합니다. 대신 CA·폐기 목록·사용자별 정책 같은 것이 없어, 사람 수백 명을 관리하려면 키 배포와 회수를 따로 만들어야 합니다(Tailscale 같은 도구가 그 자리를 채웁니다).
암호. OpenVPN 2.6 의 서버는 자기 data-ciphers 목록에서 클라이언트도 지원하는 첫 암호를 고릅니다. AES-GCM 은 CPU 의 AES 명령(AES-NI 등)이 있으면 빠르고, ChaCha20-Poly1305 는 그것이 없는 기기(오래된 휴대폰·작은 ARM 보드)에서 강합니다.
UDP 인가 TCP 인가. OpenVPN 은 TCP 443 위에서도 돕니다(방화벽이 UDP 를 막는 호텔·사내망에서 쓰는 길이고, AWS Client VPN 도 기본 포트가 443 입니다). 그런데 터널 안의 TCP 를 바깥 TCP 로 다시 싸면, 바깥 연결에서 패킷 하나가 사라졌을 때 바깥 TCP 가 재전송하는 동안 안쪽 TCP 도 제 타이머로 재전송을 쌓아 서로를 늦춥니다(흔히 TCP 위의 TCP 문제라고 부릅니다). 손실이 없는 실습 망에서는 잘 드러나지 않고 손실이 있는 와이파이·모바일 회선에서 드러나므로, 기본은 UDP 로 두고 TCP 는 UDP 가 막힌 곳의 대안으로 둡니다. WireGuard 는 UDP 만 씁니다.
DCO. OpenVPN 2.6 은 리눅스의 ovpn-dco 커널 모듈(또는 윈도의 드라이버)이 있으면 데이터 채널의 암호화·복호화를 커널로 내립니다. 그러면 사용자 공간을 오가는 비용이 사라져 WireGuard 와 같은 구조가 되고, 제어 채널(TLS·인증서·CRL)만 openvpn 프로세스에 남습니다. 지원하는 암호는 AEAD(AES-GCM·ChaCha20-Poly1305)뿐이라 옛 CBC 설정은 DCO 를 쓰지 못합니다. 이 실습은 모듈 없이 재므로, DCO 를 쓰는 운영 환경의 OpenVPN 숫자는 여기와 다릅니다(미실측).
재는 법. 기준선(터널 없음) → 바꾼 조건 하나 → 같은 시간·같은 흐름 수. iperf3 의 JSON 은 받은 쪽 처리량(end.sum_received)과 양쪽 CPU 사용률을 함께 줍니다. 지연은 ping 수십 번의 평균으로 봅니다. 숫자를 표로 옮길 때는 손으로 옮기지 말고 JSON 에서 계산합니다.
이 실습 환경에서 잰 값(2026-11-01). 같은 두 VM(노트북 → 게이트웨이, 2 vCPU, Intel Xeon SierraForest·AES-NI 있음, 다른 실습 VM 과 호스트를 나눠 씀) 사이에서 iperf3 10초·한 흐름을 네 번씩 잰 중앙값입니다. 터널 없음 약 780 Mbit/s(777–784), OpenVPN AES-256-GCM 약 546(533–555), OpenVPN CHACHA20-POLY1305 약 538(487–543), WireGuard 약 728(713–745). 기준선 대비 OpenVPN 은 약 70%, WireGuard 는 약 93% 를 냈고, AES-NI 가 있는 이 CPU 에서는 두 암호의 차이가 측정의 흔들림 안이었습니다. OpenVPN 으로 받는 동안 게이트웨이의 openvpn 프로세스는 한 코어의 44–51% 를 썼습니다. ping 30번 평균 지연은 터널 없음 1.19ms, OpenVPN 1.50ms, WireGuard 1.41ms 였습니다. 이 숫자는 이 자리의 것입니다 — 다른 CPU·회선·DCO 를 쓰는 서버에서는 순위까지 바뀔 수 있습니다.
현장에서 만나는 모습
「VPN 이 느리다」 는 신고의 상당수는 VPN 프로토콜이 아니라 MTU(조각과 재전송), 게이트웨이의 CPU 한 코어 포화, 전체 터널로 몰린 화상회의 트래픽입니다. 그래서 프로토콜을 바꾸기 전에 기준선과 VPN 너머의 숫자, 게이트웨이의 코어별 CPU 를 먼저 봅니다. 프로토콜을 고를 때도 처리량 숫자만큼 「사람 수백 명의 키를 어떻게 나눠 주고 회수하나」 가 중요합니다.
다음 실습에서 할 것
같은 두 VM 사이에서 터널 없음·OpenVPN(AES-256-GCM)·WireGuard·OpenVPN(CHACHA20-POLY1305)을 iperf3 로, 지연을 ping 으로 재고 표 하나로 정리합니다.