OpenVPN 원격 접속 VPN — 세우고, 길을 놓고, 잠그고, 고친다
OpenVPN 과 WireGuard 를 같은 자리에서 재기
목표
같은 두 VM(노트북 → 게이트웨이) 사이에서 터널 없음·OpenVPN(AES-256-GCM)·OpenVPN(CHACHA20-POLY1305)·WireGuard 의 처리량과 지연을 같은 조건으로 재고 표 하나로 정리합니다.
왜 중요한가
「WireGuard 가 몇 배 빠르다」 같은 말은 어느 CPU·어느 망·어느 설정에서 잰 것인지가 빠지면 아무것도 말하지 않습니다. 같은 자리에서 조건을 하나씩만 바꿔 재야 무엇이 숫자를 정하는지(사용자 공간을 오가는 비용, 암호, CPU)가 보입니다. VPN 을 고르거나 「VPN 이 느리다」 는 신고를 받았을 때 이 기준선이 출발점입니다.
단계
- gateway 에서
iperf3 -s를 뒤로 띄우고(바깥 방화벽/etc/corp-edge.nft에tcp dport 5201 accept를 drop 앞에), laptop 에서iperf3 -c 172.30.1.2 -t 10 -J의 JSON 을/root/vpn/bench/plain.json(gateway)에 저장하세요. - 같은 조건으로 터널 너머의
10.8.0.1를 재어/root/vpn/bench/ovpn.json에 저장하세요. - gateway 와 laptop 각자
wg genkey로 개인 키를 만들고(권한 600, 개인 키는 자기 VM 밖으로 내보내지 않음) 공개 키만 바꿔 적어/etc/wireguard/wg0.conf를 쓰세요. gateway10.9.0.1/24·ListenPort = 51820, laptop10.9.0.2/24·Endpoint = 172.30.1.2:51820. 바깥 방화벽에udp dport 51820 accept(drop 앞), 양쪽wg-quick@wg0를 켜고(enable --now) laptop 에서10.9.0.1가 응답해야 합니다. - 같은 조건으로
10.9.0.1를 재어/root/vpn/bench/wg.json에 저장하세요. - laptop 에서 세 목적지(
172.30.1.2기준선,10.8.0.1OpenVPN,10.9.0.1WireGuard)로ping -c 30 -i 0.2 -q를 돌려 평균(ms)을/root/vpn/bench/latency.txt에plain <ms>,openvpn <ms>,wireguard <ms>세 줄로 적으세요. - 서버 설정에
data-ciphers CHACHA20-POLY1305:AES-256-GCM을 더해 다시 켜고, 클라이언트 기록에Data Channel: cipher 'CHACHA20-POLY1305'가 찍힌 것을 확인한 뒤 같은 조건으로10.8.0.1를 재어/root/vpn/bench/ovpn-chacha.json에 저장하세요. /root/vpn/bench/summary.txt에 네 줄을<이름> <Mbit/s> <지연 ms>로 적으세요. 이름은plain,openvpn-aes,openvpn-chacha,wireguard, 처리량은 각 JSON 의sum_received(소수 첫째 자리까지), 지연은latency.txt의 값(OpenVPN 둘은 openvpn 값)입니다.
참고
- 이 터미널은 gateway 입니다. 조리법이 1모듈 끝 상태의 OpenVPN 터널(alice)을 세워 두었습니다. 결과는 gateway 의
/root/vpn/bench에 모읍니다. - iperf3 는 laptop 에서
ssh laptop "iperf3 -c <대상> -t 10 -J" > /root/vpn/bench/<파일>처럼 부르면 JSON 이 gateway 에 바로 남습니다. - 다른 실습 VM 과 같은 호스트를 나눠 쓰므로 숫자가 몇 % 흔들립니다. 의심스러우면 한 번 더 재세요.
기준선 — 터널 없이 세션망 그대로
gateway 에서 iperf3 -s 를 뒤로 띄우고(바깥 방화벽 /etc/corp-edge.nft 에 tcp dport 5201 accept 를 drop 앞에), laptop 에서 iperf3 -c 172.30.1.2 -t 10 -J 의 JSON 을 /root/vpn/bench/plain.json(gateway)에 저장하세요.
기준선이 없으면 터널의 숫자가 빠른지 느린지 말할 수 없습니다. -J 는 결과를 JSON 으로 냅니다 — 받은 쪽 처리량은 .end.sum_received.bits_per_second, 양쪽 CPU 는 .end.cpu_utilization_percent. iperf3 서버는 한 번에 한 측정만 받습니다. 뒤로 띄우려면 systemd-run --unit iperf3-lab iperf3 -s.
OpenVPN(AES-256-GCM) 터널 너머
같은 조건으로 터널 너머의 10.8.0.1 를 재어 /root/vpn/bench/ovpn.json 에 저장하세요.
OpenVPN 2.6 은 커널 가속(DCO) 모듈이 있으면 데이터 채널을 커널에서 처리하지만, 이 VM 에는 그 모듈이 없어 사용자 공간에서 돕니다(서버 접속 목록의 dco_enabled 0). 그래서 패킷마다 커널과 openvpn 프로세스 사이를 오가는 비용이 듭니다 — CPU 숫자를 함께 보세요.
같은 두 VM 사이에 WireGuard 를 세운다
gateway 와 laptop 각자 wg genkey 로 개인 키를 만들고(권한 600, 개인 키는 자기 VM 밖으로 내보내지 않음) 공개 키만 바꿔 적어 /etc/wireguard/wg0.conf 를 쓰세요. gateway 10.9.0.1/24·ListenPort = 51820, laptop 10.9.0.2/24·Endpoint = 172.30.1.2:51820. 바깥 방화벽에 udp dport 51820 accept(drop 앞), 양쪽 wg-quick@wg0 를 켜고(enable --now) laptop 에서 10.9.0.1 가 응답해야 합니다.
WireGuard 에는 CA·인증서·TLS 가 없습니다. 상대의 공개 키가 곧 신원이고, AllowedIPs 가 「이 키에서 온 패킷이 쓸 수 있는 출발지」 이자 「이 대역으로 가는 패킷을 보낼 상대」 입니다. wg show wg0 의 latest handshake 가 찍히면 붙은 것입니다. 설정에 개인 키를 직접 적는 대신 PostUp = wg set %i private-key <파일> 로 따로 둘 수 있습니다.
WireGuard 너머
같은 조건으로 10.9.0.1 를 재어 /root/vpn/bench/wg.json 에 저장하세요.
WireGuard 는 리눅스 커널 안에서 암호화합니다(ChaCha20-Poly1305 고정). 사용자 공간을 오가지 않는 것이 OpenVPN(DCO 없음)과의 가장 큰 차이입니다.
지연 — ping 30번의 평균
laptop 에서 세 목적지(172.30.1.2 기준선, 10.8.0.1 OpenVPN, 10.9.0.1 WireGuard)로 ping -c 30 -i 0.2 -q 를 돌려 평균(ms)을 /root/vpn/bench/latency.txt 에 plain <ms>, openvpn <ms>, wireguard <ms> 세 줄로 적으세요.
rtt min/avg/max/mdev = … 의 두 번째 값이 평균입니다. 처리량과 지연은 다른 것을 말합니다 — 지연은 패킷 하나가 암호화·복호화·사용자 공간을 몇 번 지나는지를 보여 줍니다.
OpenVPN 의 암호를 바꿔 다시 — CHACHA20-POLY1305
서버 설정에 data-ciphers CHACHA20-POLY1305:AES-256-GCM 을 더해 다시 켜고, 클라이언트 기록에 Data Channel: cipher 'CHACHA20-POLY1305' 가 찍힌 것을 확인한 뒤 같은 조건으로 10.8.0.1 를 재어 /root/vpn/bench/ovpn-chacha.json 에 저장하세요.
OpenVPN 2.6 의 서버는 자기 data-ciphers 목록에서 클라이언트도 지원하는 첫 암호를 고릅니다. AES-GCM 은 CPU 의 AES-NI 가 있으면 빠르고, ChaCha20 은 그것이 없는 기기에서 강합니다. 어느 쪽이 빠른지는 이 VM 의 CPU 가 정합니다 — 짐작하지 말고 재세요.
한 장으로 — 처리량과 지연 표
/root/vpn/bench/summary.txt 에 네 줄을 <이름> <Mbit/s> <지연 ms> 로 적으세요. 이름은 plain, openvpn-aes, openvpn-chacha, wireguard, 처리량은 각 JSON 의 sum_received(소수 첫째 자리까지), 지연은 latency.txt 의 값(OpenVPN 둘은 openvpn 값)입니다.
숫자를 손으로 옮기지 말고 JSON 에서 계산하세요 — 옮겨 적은 숫자는 반드시 한 번은 틀립니다. python3 -c 'import json; …' 또는 jq '.end.sum_received.bits_per_second/1e6'.