OpenVPN 원격 접속 VPN — 세우고, 길을 놓고, 잠그고, 고친다
원격 접속 VPN 은 세 가지 일이다 — 신원, 가상 NIC, 길
한 줄 요약
원격 접속 VPN 은 세 가지 일을 합니다. 인증서로 서로의 신원을 확인하고, 노트북에 가상 NIC(tun)를 하나 만들어 사내 주소를 주고, 그 주소로 가는 길과 돌아오는 길을 놓습니다. 장애는 거의 언제나 셋째에서 납니다.
왜 이게 필요했나
사내 위키·사내 Git·DB 관리 화면은 인터넷에 내놓으면 안 되는 것들입니다. 그래서 사설 대역(이 실습에서는 10.10.0.0/24)에만 둡니다. 그런데 집에서 일하는 직원도 그것을 열어야 합니다. 방법은 둘입니다. 서비스마다 인증을 붙여 인터넷에 내놓거나, 직원의 노트북을 잠깐 「사내망 안에 있는 기계」 로 만들거나. VPN 은 뒤의 것입니다. 노트북 입장에서는 사내망 쪽으로 NIC 가 하나 더 생긴 것처럼 보이고, 회사 입장에서는 그 NIC 뒤에 누가 있는지를 인증서로 확인합니다.
어떻게 동작하나
신원 — PKI. CA 하나가 서버와 직원 모두에게 인증서를 찍어 줍니다. 노트북은 서버 인증서가 이 CA 에서 나왔는지, 「서버용(EKU serverAuth)」 인지, 이름이 기대한 것(vpn.corp.example)인지를 확인합니다(remote-cert-tls server, verify-x509-name). 둘째와 셋째 확인을 빼면 같은 CA 에서 인증서를 받은 다른 직원이 가짜 서버를 세울 수 있습니다. 서버는 반대로 직원 인증서가 이 CA 에서 나왔는지 확인합니다. 직원의 개인 키는 노트북에서 만들고 요청서(CSR)만 CA 로 보냅니다. 키가 만들어진 기계를 떠나지 않아야 「누가 그 키를 손에 쥐었었나」 라는 질문이 생기지 않습니다.
가상 NIC — tun. OpenVPN 은 커널에 tun 장치를 하나 만들어 달라고 합니다. 커널은 그 장치로 나가는 IP 패킷을 OpenVPN 프로세스에 읽기로 넘기고, OpenVPN 은 그것을 암호화해 UDP 1194 로 서버에 보냅니다. 서버의 OpenVPN 은 풀어서 자기 tun 에 씁니다 — 커널이 보기에는 tun 으로 패킷이 「들어온」 것입니다. tun 은 IP 패킷(L3)만 오가는 점대점 장치이고, tap 은 이더넷 프레임(L2)을 오가게 해 브리지로 붙입니다. 원격 접속에는 거의 언제나 tun 을 씁니다 — 방송(ARP 등)을 노트북까지 실어 나를 이유가 없습니다.
참고 — 맥의
ifconfig에 보이는 utun 은 무엇인가. macOS 의utun0·utun1… 은 리눅스의 tun 과 같은 일을 하는 사용자 공간 L3 점대점 터널 장치입니다. 앱이 커널 제어 소켓(utun 제어)으로 만들고, 만든 앱이 끝나면 함께 사라집니다. 번호는 만들어진 순서라 재부팅이나 앱을 켜는 순서에 따라 바뀝니다. VPN 을 켜지 않아도 utun 이 여러 개 보이는 것은 정상입니다 — 연속성·iCloud 관련 같은 시스템 기능이 IPv6 링크 로컬 주소(fe80::)만 가진 utun 을 평소에 만들어 둡니다. OpenVPN 클라이언트·WireGuard·Tailscale 같은 VPN 앱이 만든 utun 에는 IPv4 주소가 붙고 그 장치로 가는 경로가 생깁니다. 어느 것이 VPN 인지는 VPN 을 켜기 전과 후에ifconfig | grep utun과netstat -rn | grep utun을 비교하면 보입니다. (어느 utun 이 어느 기능의 것인지를 MTU 값으로 가르는 공식 문서는 없으니 그런 표는 믿지 마세요.)
길 — 가는 길과 돌아오는 길. 서버의 push "route 10.10.0.0 255.255.255.0" 이 노트북에 「사내망은 tun 으로」 라는 경로를 꽂아 줍니다. 패킷은 게이트웨이의 tun0 으로 나오는데, 게이트웨이가 그것을 사내망 NIC 로 넘기려면 IP 포워딩이 켜져 있어야 합니다(리눅스는 기본으로 라우터가 아닙니다). 그리고 사내 서버가 10.8.0.x 로 답할 길을 알아야 합니다. 사내 서버의 기본 경로가 VPN 게이트웨이가 아니면 — 실무에서는 VPN 장비가 사내망의 기본 게이트웨이가 아닌 경우가 흔합니다 — 답은 기본 경로로 나가 버리고 노트북에는 영영 오지 않습니다. 이 실습 환경에서 포워딩만 켜고 사내 서버에서 tcpdump -ni any port 80 을 걸면 corp0 In IP 10.8.0.2 > 10.10.0.10.80 다음 줄이 enp1s0 Out IP 10.10.0.10.80 > 10.8.0.2 로 찍힙니다. 들어온 NIC 와 나가는 NIC 가 다릅니다. 고치는 길은 둘입니다 — 사내 서버(또는 사내 라우터)에 10.8.0.0/24 를 게이트웨이로 돌려보내는 경로를 넣거나, 게이트웨이가 NAT 로 출발지를 자기 주소로 바꿔 보내거나. 첫째는 사내 서버의 기록에 직원마다 다른 주소가 남고, 둘째는 설정이 쉽지만 모두가 게이트웨이 한 주소로 보입니다.
AWS Client VPN 과의 관계. AWS 문서는 Client VPN 을 관리형 원격 접속 서비스로 소개하고, 사용자는 OpenVPN 기반 클라이언트로 붙는다고 적습니다(포트는 UDP·TCP 443 과 1194, 기본 443). 엔드포인트를 만들 때 넣는 서버 인증서, 클라이언트 CIDR(노트북이 받을 주소 대역, 이 실습의 10.8.0.0/24), 경로 표와 인가 규칙(어느 대역으로 갈 수 있나)이 이 실습의 server·push route·방화벽에 그대로 대응합니다. 인증서 기반 인증을 쓰면 직원 인증서를 오늘처럼 같은 CA 에서 찍습니다. 돌아오는 길은 AWS 가 NAT 쪽을 골랐습니다 — 문서에 따르면 IPv4 트래픽은 출발지가 클라이언트 CIDR 주소에서 VPC 서브넷에 만든 Client VPN 네트워크 인터페이스 주소로 바뀌고(SNAT), IPv6 는 바꾸지 않습니다. 그래서 VPC 안의 서버 기록에는 IPv4 로 붙은 직원이 모두 그 인터페이스 주소로 남고, 누가 붙었는지는 Client VPN 의 연결 기록으로 따로 봐야 합니다. 사무실과 VPC 를 잇는 사이트 간 VPN(Site-to-Site)은 IPsec 이고, 그것은 사람 한 명이 아니라 망 둘을 잇는 일입니다.
이 실습 환경에서 잰 값(2026-11-01). 세션망 MTU 1450, 사내망 1400 위에서 VM 세 대가 준비되기까지 58초, CA 부터 노트북 연결까지 정답지 다섯 단계가 합쳐 10초 안에 끝났고, 터널이 선 뒤 노트북에서 사내 서버의 4MiB 응답을 받는 데 0.07초가 걸렸습니다. 노트북의 SYN 에는 OpenVPN 이 MSS 를 1400 으로 깎아 넣었습니다.
현장에서 만나는 모습
「VPN 은 연결됐는데 사내 시스템이 안 열립니다」 라는 문의의 대부분은 돌아오는 경로입니다. VPN 장비를 새로 들이면서 사내 라우터에 클라이언트 대역을 알려 주지 않은 경우, 클라이언트 대역을 사내에서 이미 쓰는 대역과 겹치게 잡은 경우가 흔합니다. 반대로 「NAT 로 일단 붙였더니 보안 감사에서 누가 접속했는지 모른다는 지적을 받았다」 는 이야기도 흔합니다. 어느 쪽을 고를지는 사내 서버의 기록을 누가 어떻게 쓰느냐로 정합니다.
다음 실습에서 할 것
CA·서버 인증서·노트북에서 태어난 직원 키를 만들고, tun 서버를 세워 바깥 방화벽에 1194/udp 를 열고, 노트북을 붙입니다. 터널이 선 뒤에도 사내 서버가 안 열리는 것을 직접 보고 포워딩과 돌아오는 경로로 풉니다.