network / knowledge

WireGuard 클라이언트 트래픽이 인터넷으로 나가게 하기

paul 2025.01.03 219words (1m)

conf를 맞추고 터널이 붙어도 클라이언트에서 인터넷이 안 되는 경우가 있다. 핸드셰이크는 되는데 웹은 안 열린다. 터널까지는 왔고 그 다음이 막힌 것이다.

두 가지가 필요하다.

ip_forward

console
$ echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/99-wireguard-forward.conf
$ sysctl -p /etc/sysctl.d/99-wireguard-forward.conf

이 값이 0이면 목적지가 자기 자신이 아닌 패킷을 전부 버린다. 커널이 INPUT으로 갈 것만 처리하고 FORWARD로 갈 것은 그냥 떨어뜨린다. VPN 서버는 남의 패킷을 대신 전달하는 게 일이므로 이게 켜져 있어야 한다.

/etc/sysctl.d/ 아래에 파일로 두면 재부팅해도 유지된다. sysctl -w 로 하면 그 자리에서만 켜진다.

MASQUERADE

console
$ iptables -t nat -A POSTROUTING -s 10.7.0.0/24 ! -d 10.7.0.0/24 -j MASQUERADE

클라이언트가 보낸 패킷의 출발지는 10.7.0.2 같은 터널 안 주소다. 이걸 그대로 인터넷으로 내보내면 응답이 돌아올 길이 없다. 사설 주소라 어디로 보내야 할지 아무도 모른다.

MASQUERADE가 나가는 패킷의 출발지를 서버의 공인 IP로 바꾼다. 응답은 서버로 오고, 서버가 기억해뒀다가 원래 클라이언트에게 돌려준다.

! -d 10.7.0.0/24 조건이 붙은 이유가 있다. 터널 안에서 peer끼리 주고받는 트래픽까지 주소를 바꾸면 안 되기 때문이다. 목적지가 터널 대역이 아닐 때, 즉 밖으로 나갈 때만 적용한다.

FORWARD 허용

console
$ iptables -A FORWARD -i wg0 -j ACCEPT
$ iptables -A FORWARD -o wg0 -j ACCEPT

FORWARD 체인의 기본 정책을 DROP으로 두고 있다면 wg0을 드나드는 것을 열어줘야 한다. 들어오는 쪽과 나가는 쪽 둘 다 필요하다. 한쪽만 열면 요청은 가는데 응답이 막힌다.

올리기

console
$ wg-quick up wg0
$ systemctl enable wg-quick@wg0
console
$ wg show

wg show 에서 마지막 핸드셰이크 시각과 주고받은 양이 보인다. 핸드셰이크만 있고 전송량이 안 늘면 위의 셋 중 하나가 빠진 것이다.