Published on

와이어가드 VPN 구축 오픈VPN보다 빠르고 가벼운 VPN 서버 만들기

Authors

VPN을 처음 구축할 때 많은 사람이 OpenVPN부터 떠올립니다. 기능은 풍부하지만 설정 파일이 길고, TLS/인증서 체인 관리가 번거롭고, 성능 튜닝 포인트도 많습니다. 반면 WireGuard는 “필요한 것만” 남긴 설계 덕분에 설정이 짧고, 커널 레벨에서 동작해 빠르고 가볍게 운영할 수 있습니다.

이 글에서는 Ubuntu 서버(예: VPS, EC2, 베어메탈)에서 WireGuard VPN을 구축해 외부에서 집/사내 네트워크로 안전하게 접속하거나, 클라이언트 트래픽을 서버를 통해 라우팅(Full tunnel) 하는 방법을 다룹니다. 중간중간 실제로 자주 터지는 문제(핸드셰이크는 되는데 인터넷이 안 됨, DNS가 안 됨, 모바일에서만 안 됨 등)도 함께 해결합니다.

인프라를 코드로 만들고 싶다면 VPC/보안그룹/EC2를 자동화하는 글도 함께 보면 좋습니다: 테라폼으로 AWS 인프라 자동화 VPC와 EC2를 클릭 없이 만드는 실전 가이드


WireGuard가 OpenVPN보다 실전에서 편한 이유

1) 설정이 단순하다

WireGuard는 기본적으로 키 기반(공개키/개인키) 이고, “피어(peer) 목록”만 선언하면 됩니다.

  • 서버: 어떤 포트로 듣고(UDP), 어떤 IP 대역을 줄지
  • 클라이언트: 서버의 공개키/엔드포인트, 내가 사용할 터널 IP, 어떤 트래픽을 터널로 보낼지

2) 성능이 좋다

  • UDP 기반 + 간결한 프로토콜
  • Linux에서는 커널 모듈로 동작(대부분 배포판에서 기본 제공)

3) 운영이 쉽다

  • wg show 한 방으로 현재 피어 상태/트래픽/핸드셰이크 시간을 확인 가능
  • 설정 파일이 짧아 실수 지점이 줄어듦

목표 아키텍처

  • 서버 OS: Ubuntu 22.04/24.04 LTS 가정
  • WireGuard 인터페이스: wg0
  • VPN 대역: 10.8.0.0/24
    • 서버: 10.8.0.1
    • 클라이언트1: 10.8.0.2
  • 서버 WireGuard 포트: 51820/udp

두 가지 사용 시나리오를 모두 커버합니다.

  1. Split tunnel: 사내/집 내부망(예: 192.168.0.0/24)만 VPN으로
  2. Full tunnel: 모든 인터넷 트래픽을 VPN 서버로

서버 구축 (Ubuntu)

1) 설치

sudo apt update
sudo apt install -y wireguard

커널 모듈/툴이 설치되며, wg, wg-quick 명령을 사용할 수 있습니다.

2) 키 생성

sudo -i
umask 077
wg genkey | tee /etc/wireguard/server.key | wg pubkey > /etc/wireguard/server.pub
cat /etc/wireguard/server.pub
  • server.key: 서버 개인키(절대 외부 유출 금지)
  • server.pub: 클라이언트에 배포할 서버 공개키

3) IP 포워딩 활성화

VPN 서버를 라우터처럼 쓰려면 포워딩이 필요합니다.

echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl --system

IPv6도 쓸 경우:

echo 'net.ipv6.conf.all.forwarding=1' | sudo tee -a /etc/sysctl.d/99-wireguard.conf
sudo sysctl --system

4) 서버 설정 파일 작성

/etc/wireguard/wg0.conf:

[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = <SERVER_PRIVATE_KEY>

# NAT(Full tunnel용): wg0로 들어온 트래픽을 서버의 공인망 인터페이스로 마스커레이드
# 아래 eth0는 환경에 따라 ens3, ens5, enp0s1 등으로 바뀔 수 있습니다.
PostUp = iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

# (선택) 포워딩 허용 규칙을 wg-quick에 묶어서 관리하고 싶다면
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT

eth0는 반드시 실제 외부 인터페이스로 바꾸세요.

ip route | grep default

예: default via ... dev ens3 라면 -o ens3.

nftables/ufw를 쓰는 경우

  • Ubuntu에서 UFW 사용 시, 기본적으로 iptables 백엔드(nft)로 동작하므로 위 규칙이 대부분 잘 먹습니다.
  • 다만 UFW에서 포워딩 정책이 DROP이면 트래픽이 막힙니다. 아래 “트러블슈팅” 참고.

5) 서버 기동

sudo systemctl enable --now wg-quick@wg0
sudo wg show
sudo ip a show wg0

6) 방화벽/보안그룹 열기

서버에 UDP 51820 인바운드를 열어야 합니다.

  • 클라우드(예: AWS): Security Group 인바운드 UDP 51820 허용
  • 서버 방화벽(UFW):
sudo ufw allow 51820/udp
sudo ufw status

클라이언트 추가 (PC/모바일 공통)

1) 클라이언트 키 생성

클라이언트 장치에서 생성하는 것이 가장 안전합니다.

Linux/macOS:

umask 077
wg genkey | tee client1.key | wg pubkey > client1.pub
cat client1.pub

Windows/모바일은 WireGuard 앱에서 “Add tunnel” 시 자동 생성 가능.

2) 서버에 피어 등록

서버의 /etc/wireguard/wg0.conf에 아래를 추가합니다.

[Peer]
PublicKey = <CLIENT1_PUBLIC_KEY>
AllowedIPs = 10.8.0.2/32

적용:

sudo wg syncconf wg0 <(wg-quick strip wg0)
sudo wg show

wg-quick down/up으로 재기동해도 되지만, 운영 중에는 syncconf가 깔끔합니다.

3) 클라이언트 설정 파일

(A) Split tunnel 예시 (내부망만 VPN)

예를 들어 서버 뒤쪽 사설망이 192.168.0.0/24이고, 그쪽 자원(NAS, DB, 내부 서비스)만 접근하고 싶다면:

[Interface]
PrivateKey = <CLIENT1_PRIVATE_KEY>
Address = 10.8.0.2/32
DNS = 1.1.1.1

[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
Endpoint = <SERVER_PUBLIC_IP_OR_DNS>:51820
AllowedIPs = 10.8.0.0/24, 192.168.0.0/24
PersistentKeepalive = 25
  • AllowedIPs가 “어떤 목적지로 가는 트래픽을 이 터널로 보낼지”를 결정합니다.
  • NAT 환경(모바일/공유기 뒤)에서는 PersistentKeepalive=25가 연결 안정성에 도움이 됩니다.

(B) Full tunnel 예시 (모든 트래픽 VPN)

[Interface]
PrivateKey = <CLIENT1_PRIVATE_KEY>
Address = 10.8.0.2/32
DNS = 1.1.1.1

[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
Endpoint = <SERVER_PUBLIC_IP_OR_DNS>:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
  • 이 경우 서버에서 NAT(MASQUERADE) + 포워딩이 제대로 되어야 인터넷이 됩니다.

동작 확인 체크리스트

서버에서

sudo wg show

확인 포인트:

  • latest handshake: 최근 시간이 찍히는지
  • transfer: RX/TX가 증가하는지

클라이언트에서

  • 10.8.0.1 ping
  • 내부망 접근(Split tunnel일 때): ping 192.168.0.10 같은 대상
  • Full tunnel일 때: curl ifconfig.me로 공인 IP가 서버로 바뀌는지

트러블슈팅: “연결은 되는데 인터넷/내부망이 안 된다”

WireGuard는 “터널 자체”는 쉽게 붙지만, 라우팅/포워딩/NAT/DNS 중 하나만 어긋나도 체감상 “안 됨”이 됩니다.

1) 핸드셰이크가 안 잡힘

증상:

  • wg showlatest handshake: (none)

원인/해결:

  • 서버 인바운드 UDP 51820 미오픈 (클라우드 보안그룹 포함)
  • Endpoint IP/DNS 오타
  • 서버가 NAT 뒤에 있고 포트포워딩이 안 됨
  • 시간 동기 문제는 드물지만, 서버/클라 시간 오차가 심하면 문제될 수 있음(NTP 확인)

2) 핸드셰이크는 되는데 Full tunnel에서 인터넷이 안 됨

증상:

  • latest handshake는 갱신됨
  • ping 10.8.0.1은 됨
  • 그런데 웹이 안 열림

점검 순서:

  1. 서버 IP 포워딩:
sysctl net.ipv4.ip_forward

= 1이어야 합니다.

  1. NAT 규칙 확인:
sudo iptables -t nat -S POSTROUTING | grep MASQUERADE

규칙이 없거나, -o eth0 인터페이스명이 틀린 경우가 많습니다.

  1. FORWARD 정책/방화벽:
  • UFW 사용 시 /etc/default/ufw에서 DEFAULT_FORWARD_POLICY="ACCEPT" 필요할 수 있습니다.
  • 또는 UFW에 라우팅 허용 규칙 추가:
sudo ufw route allow in on wg0 out on eth0
sudo ufw route allow in on eth0 out on wg0
  1. 클라이언트 AllowedIPs:
  • Full tunnel은 0.0.0.0/0
  • Split tunnel은 필요한 대역만 포함

3) DNS만 안 됨

증상:

  • IP로는 접속되는데 도메인은 실패

해결:

  • 클라이언트 설정에 DNS = 1.1.1.1 또는 사내 DNS 지정
  • 사내 DNS를 쓰려면 Split tunnel에서 해당 DNS 서버 IP가 AllowedIPs에 포함되어야 함

4) 특정 클라이언트만 접속이 불안정(특히 모바일)

해결:

  • PersistentKeepalive = 25 추가
  • 모바일 데이터/공유기 NAT가 세션을 빨리 끊는 환경에서 효과적

5) 여러 클라이언트가 같은 터널 IP를 씀

증상:

  • 한쪽이 붙으면 다른 쪽이 끊기거나, 트래픽이 엉킴

해결:

  • 각 피어는 반드시 고유한 Address(예: 10.8.0.2/32, 10.8.0.3/32)
  • 서버의 각 [Peer] AllowedIPs도 각각 /32로 분리

Best Practice: 운영 관점에서 꼭 챙길 것

1) 키/설정 파일 권한

sudo chmod 600 /etc/wireguard/*.key
sudo chmod 600 /etc/wireguard/wg0.conf

2) 피어 추가/삭제 자동화

피어가 많아지면 수작업이 실수로 이어집니다.

  • 간단히는 “클라이언트별 템플릿 + IP 할당 규칙”을 문서화
  • 더 나아가면 Ansible/Terraform(인스턴스/보안그룹) + 스크립트로 프로비저닝

3) 라우팅 정책을 명확히

  • Split tunnel은 필요한 대역만 AllowedIPs에 넣어 “업무/개발용 접근”에 적합
  • Full tunnel은 공용 와이파이/해외망에서 보안 강화에 적합하지만, 서버 트래픽 비용/대역폭 고려 필요

4) 모니터링

  • wg show로 마지막 핸드셰이크 시간, 전송량 확인
  • 시스템 레벨에서는 journalctl -u wg-quick@wg0로 장애 분석

결론: WireGuard는 “작게 시작해서 안정적으로 키우기” 좋은 VPN

WireGuard는 OpenVPN에 비해 설정이 훨씬 짧고, 성능과 운영 편의성이 뛰어나 개인/팀 단위 VPN에 특히 잘 맞습니다.

핵심만 요약하면:

  • 서버는 wg0.conf + IP 포워딩 + (Full tunnel이면) NAT(MASQUERADE) 가 필수
  • 클라이언트는 AllowedIPs로 Split/Full을 결정
  • 핸드셰이크는 되는데 통신이 안 되면 대부분 인터페이스명, 포워딩, 방화벽(UFW), DNS 문제

이 구성으로 먼저 1~2명의 클라이언트를 붙여 안정화한 뒤, 피어 추가 자동화와 모니터링을 붙이면 “가볍지만 강한” VPN을 운영할 수 있습니다.