🌍 네트워크

WireGuard

WireGuard

현대적 VPN 프로토콜. 간단하고 빠름.

📖 상세 설명

WireGuard는 Jason A. Donenfeld가 2016년에 개발한 차세대 VPN 프로토콜입니다. 기존 VPN 솔루션인 OpenVPN(~600,000줄)이나 IPsec(~400,000줄)과 달리, WireGuard는 단 4,000줄 미만의 코드로 구성되어 보안 감사가 용이하고 버그 발생 가능성이 현저히 낮습니다.

WireGuard의 핵심 철학은 "단순함이 보안"입니다. 복잡한 암호화 옵션 협상 없이, ChaCha20(대칭 암호화), Poly1305(인증), Curve25519(키 교환), BLAKE2s(해싱), HKDF(키 파생) 등 검증된 최신 암호화 알고리즘만 사용합니다. 이로 인해 구성이 간단하고 공격 표면이 최소화됩니다.

성능 면에서 WireGuard는 커널 레벨에서 동작하여 OpenVPN 대비 3-4배 빠른 처리량을 제공합니다. 2020년 Linux 커널 5.6에 공식 통합되어 별도 드라이버 설치 없이 사용 가능합니다. 핸드셰이크가 1-RTT로 완료되어 연결 수립 시간이 밀리초 단위입니다.

현재 WireGuard는 Linux, Windows, macOS, iOS, Android 모든 주요 플랫폼을 지원합니다. Cloudflare WARP, Tailscale, Mullvad VPN 등 많은 상용 VPN 서비스가 WireGuard를 기반으로 구축되었으며, AWS, Azure, GCP의 Site-to-Site VPN에서도 활용됩니다.

💻 코드 예제

# WireGuard 설치 (Ubuntu/Debian)
sudo apt update && sudo apt install wireguard

# 키 쌍 생성 (서버 & 클라이언트 각각)
wg genkey | tee privatekey | wg pubkey > publickey
chmod 600 privatekey

# WireGuard 인터페이스 생성 및 시작
sudo wg-quick up wg0

# 연결 상태 확인
sudo wg show
# 출력 예시:
# interface: wg0
#   public key: abc123...
#   listening port: 51820
#   peer: xyz789...
#     endpoint: 203.0.113.1:51820
#     latest handshake: 5 seconds ago
#     transfer: 1.5 GiB received, 500 MiB sent

# 실시간 트래픽 모니터링
watch -n 1 sudo wg show

# WireGuard 중지
sudo wg-quick down wg0

# 부팅 시 자동 시작
sudo systemctl enable wg-quick@wg0
# /etc/wireguard/wg0.conf (서버)
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY
# NAT 설정 (인터넷 공유 시)
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
# 클라이언트 1
PublicKey = CLIENT1_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32

[Peer]
# 클라이언트 2
PublicKey = CLIENT2_PUBLIC_KEY
AllowedIPs = 10.0.0.3/32

# ------------------------------------------
# /etc/wireguard/wg0.conf (클라이언트)
[Interface]
Address = 10.0.0.2/24
PrivateKey = CLIENT_PRIVATE_KEY
DNS = 1.1.1.1, 8.8.8.8

[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0  # 모든 트래픽 VPN 경유
PersistentKeepalive = 25  # NAT 뒤에서 연결 유지
# docker-compose.yml - WireGuard 서버
version: "3.8"
services:
  wireguard:
    image: linuxserver/wireguard
    container_name: wireguard
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Seoul
      - SERVERURL=vpn.example.com
      - SERVERPORT=51820
      - PEERS=3  # 클라이언트 수
      - PEERDNS=auto
      - INTERNAL_SUBNET=10.13.13.0
    volumes:
      - ./config:/config
      - /lib/modules:/lib/modules
    ports:
      - 51820:51820/udp
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
    restart: unless-stopped

# 실행
# docker-compose up -d
# 클라이언트 설정 확인: docker exec wireguard cat /config/peer1/peer1.conf
# QR 코드 생성: docker exec wireguard /app/show-peer 1

🗣️ 실무에서 이렇게 말하세요

💬 VPN 솔루션 선정 회의에서
"기존 OpenVPN 대비 WireGuard는 코드가 4,000줄 미만이라 보안 감사가 쉽고, 커널 레벨 동작으로 처리량이 3배 이상 빠릅니다. Linux 5.6부터 기본 탑재되어 별도 모듈 설치도 필요 없습니다. 모바일 환경에서 네트워크 전환 시에도 세션이 유지되는 로밍 기능도 큰 장점입니다."
💬 인프라 팀 미팅에서
"WireGuard는 UDP 51820 포트만 열어주면 됩니다. 설정 파일이 20줄 내외로 간단해서 Ansible이나 Terraform으로 자동화하기 좋습니다. Tailscale처럼 WireGuard 기반 메시 VPN을 도입하면 복잡한 허브-스포크 구성 없이도 P2P 연결이 가능합니다."
💬 보안 검토 미팅에서
"WireGuard는 ChaCha20-Poly1305와 Curve25519만 사용해서 암호화 스위트 협상이 없습니다. 공격자가 약한 암호화로 다운그레이드할 수 없어서 오히려 보안상 유리합니다. 다만 PFS(Perfect Forward Secrecy)는 기본 지원하니 키 노출 시에도 과거 트래픽은 안전합니다."

⚠️ 흔한 실수 & 주의사항

Private Key를 설정 파일에 직접 커밋

wg0.conf 파일을 Git에 그대로 커밋하면 Private Key가 노출됩니다. 환경 변수나 Vault를 사용하고, .gitignore에 *.conf를 추가하세요.

AllowedIPs 설정 오류

AllowedIPs는 "이 피어에서 올 수 있는 IP"와 "이 피어로 라우팅할 IP"를 동시에 지정합니다. 0.0.0.0/0은 모든 트래픽을 VPN으로 보내고, 특정 서브넷만 지정하면 Split Tunneling이 됩니다.

NAT 뒤에서 PersistentKeepalive 미설정

클라이언트가 NAT 뒤에 있으면 서버에서 먼저 패킷을 보낼 수 없습니다. PersistentKeepalive = 25를 설정해 25초마다 킵얼라이브 패킷을 보내 NAT 매핑을 유지하세요.

올바른 WireGuard 운영 방법

키는 각 디바이스마다 고유하게 생성하고, 정기적으로 로테이션하세요. PostUp/PostDown 스크립트로 방화벽 규칙을 자동화하고, wg show로 핸드셰이크 시간을 모니터링해 연결 상태를 확인하세요.

🔗 관련 용어

📚 더 배우기