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@wg0AllowedIPs와 라우팅
AllowedIPs는 두 가지 역할을 한다.
- 송신: 해당 IP 대역으로 나가는 패킷을 이 피어에게 전송
- 수신: 이 피어에서 오는 패킷의 출발지 IP가 이 범위여야 허용
| AllowedIPs | 효과 |
|---|---|
0.0.0.0/0 |
모든 트래픽을 터널로 (Full Tunnel) |
10.0.0.0/24 |
특정 대역만 터널로 (Split Tunnel) |
10.0.0.2/32 |
단일 피어 IP만 허용 |