Tan Kim

wireguard

WireGuard

WireGuard는 현대적인 VPN 터널링 프로토콜이다. 기존 OpenVPN, IPsec에 비해 코드베이스가 작고(~4,000 LOC), 빠르며, 설정이 간단한 것이 특징이다.

특징

  • 속도: UDP 기반, 커널 레벨에서 동작 → 낮은 지연·높은 처리량
  • 보안: 최신 암호화 기법만 사용 (Noise Protocol Framework 기반)
  • 간결함: OpenVPN 대비 코드량 100배 이상 적음 → 공격 표면 최소화
  • Stateless: 연결 상태를 유지하지 않음 — 피어가 패킷 보낼 때 자동 연결

기존 VPN과 비교

항목 WireGuard OpenVPN IPsec
코드 크기 ~4,000 LOC ~600,000 LOC 복잡
포트 UDP 51820 TCP/UDP 1194 UDP 500/4500
암호화 협상 고정 (선택 불필요) 협상 가능 협상 가능
속도 빠름 보통 보통~빠름
설정 복잡도 낮음 높음 높음
커널 통합 Linux 5.6+ 내장 userspace 커널 모듈

암호화 스택

WireGuard는 암호화 알고리즘을 협상하지 않고 고정 사용한다.

역할 알고리즘
키 교환 Curve25519 (ECDH)
암호화 ChaCha20-Poly1305
해시 BLAKE2s
핸드셰이크 Noise Protocol Framework

동작 원리

WireGuard는 각 피어를 공개키로 식별한다. IP 패킷이 들어오면 출발지 IP를 기반으로 피어를 찾아 암호화 후 UDP로 전송한다.

[App] → [wg0 인터페이스] → [암호화] → [UDP/51820] → 인터넷 → [상대 피어]
                                ↑
                       공개키 기반 피어 식별

핸드셰이크

  • 연결 시작 시 1-RTT 핸드셰이크
  • 180초마다 재키잉(rekeying)으로 Forward Secrecy 보장
  • 응답이 없으면 조용히 대기 (포트 스캐닝에 비노출)

설정 파일 구조

서버 (/etc/wireguard/wg0.conf)

[Interface]
PrivateKey = <서버_개인키>
Address = 10.0.0.1/24
ListenPort = 51820
 
# 패킷 포워딩 (선택적, 클라이언트 인터넷 라우팅 시)
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]
PublicKey = <클라이언트_공개키>
AllowedIPs = 10.0.0.2/32

클라이언트 (/etc/wireguard/wg0.conf)

[Interface]
PrivateKey = <클라이언트_개인키>
Address = 10.0.0.2/24
DNS = 1.1.1.1
 
[Peer]
PublicKey = <서버_공개키>
Endpoint = <서버_IP>:51820
AllowedIPs = 0.0.0.0/0   # 전체 트래픽 터널링
# AllowedIPs = 10.0.0.0/24  # 특정 대역만 터널링 (Split Tunneling)
PersistentKeepalive = 25

주요 명령어

# 키 쌍 생성
wg genkey | tee privatekey | wg pubkey > publickey
 
# 인터페이스 시작 / 중지
wg-quick up wg0
wg-quick down wg0
 
# 상태 확인 (연결된 피어, 최근 핸드셰이크 시간, 트래픽)
wg show
 
# 부팅 시 자동 시작
systemctl enable wg-quick@wg0

AllowedIPs와 라우팅

AllowedIPs는 두 가지 역할을 한다.

  1. 송신: 해당 IP 대역으로 나가는 패킷을 이 피어에게 전송
  2. 수신: 이 피어에서 오는 패킷의 출발지 IP가 이 범위여야 허용
AllowedIPs 효과
0.0.0.0/0 모든 트래픽을 터널로 (Full Tunnel)
10.0.0.0/24 특정 대역만 터널로 (Split Tunnel)
10.0.0.2/32 단일 피어 IP만 허용

메모

이 글에 대해 물어보기