WireGuard 핸드셰이크는 되지만 사무실 서브넷이 응답하지 않는다
WireGuard는 켜져 있고 서버에 핑이 가지만, 그 LAN에서는 아무것도 응답하지 않습니다. 클라이언트 프리픽스, 서버 포워딩, 응답 경로를 확인하세요.
핸드셰이크가 완료되고, wg show 최근 전송을 보고하며 서버의 터널 주소가 핑에 응답합니다. 하지만 서버 LAN의 호스트는 응답하지 않습니다. 세 가지 조건이 동시에 성립해야 합니다. 클라이언트가 LAN 프리픽스를 터널로 라우팅해야 하고, 서버가 패킷을 포워딩해야 하며, 응답에는 되돌아갈 경로가 필요합니다. 셋 중 하나가 빠지면 증상은 같습니다.
AllowedIPs는 접근 목록이자 라우팅 테이블이다
클라이언트에서 AllowedIPs 목록은 그 피어로 무엇을 보낼 수 있는지와 WireGuard가 어떤 경로를 설치하는지를 모두 결정합니다. 서버의 터널 주소만 나열한 피어 항목은 호스트 경로 하나만 설치하므로 LAN 목적지는 터널로 들어가지 않습니다. LAN 프리픽스를 추가하는 것이 가장 먼저 확인할 일이며, 복사한 설정에서 가장 자주 빠지는 변경이기도 합니다. 기본 경로까지 넓힌 피어는 다른 설계이며, 클라이언트의 인터넷 트래픽도 옮깁니다.
호스트 경로와 LAN 프리픽스를 별도 항목으로 유지하세요. 사무실에 서브넷이 둘이라면 둘 다 목록에 들어가야 하며, 두 번째 프리픽스가 빠지면 전체가 아니라 선택적으로 보이는 장애가 생깁니다.
[Peer] PublicKey = <server public key> Endpoint = vpn.example.net:51820 AllowedIPs = 10.66.0.1/32, 192.168.50.0/24
포워딩과 변환은 서버의 몫
서버에는 IP 포워딩 활성화, 터널에서 오는 트래픽을 받아들이는 포워딩 규칙, 그리고 LAN 인터페이스 쪽으로 향하는 변환 규칙이 필요합니다. 바로 이 변환이 사무실 네트워크의 모든 호스트를 건드리지 않고 설계를 동작하게 합니다. 그러면 응답은 LAN이 들어본 적 없는 주소가 아니라 서버로 돌아옵니다. 이것이 없으면 모든 호스트에 터널 서브넷 경로와 이를 허용하는 방화벽 규칙이 필요하며, 남이 관리하는 네트워크에서는 좀처럼 받아들여지지 않습니다.
sysctl -w net.ipv4.ip_forward=1 iptables -A FORWARD -i wg0 -j ACCEPT iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
손으로 추가한 규칙은 재부팅 시 사라지므로 서버 설정의 hook 명령으로 인터페이스에 묶어 두세요. 인터페이스보다 오래 사는 규칙 집합은 더 이상 존재하지 않는 터널을 위해 기계가 트래픽을 변환하게 되는 이유입니다.
LAN은 옮겨졌는데 규칙은 그대로일 때
사무실 서브넷의 번호를 다시 매기는 라우터 교체는 이 장애의 전형적인 형태입니다. 터널은 켜져 있고 핸드셰이크도 신선하며, 서버 뒤에서는 아무것도 응답하지 않습니다. 변환 규칙이 아직 옛 주소를 가리키기 때문입니다. 설치 스크립트는 서버의 LAN 주소를 POSTROUTING 규칙에 박아 넣는 경우가 많고, 번호를 다시 매긴 뒤에는 그 주소가 어느 인터페이스에도 없습니다. 그러면 패킷은 응답할 수 없는 목적지로 다시 쓰입니다.
iptables -t nat -n -L POSTROUTING ip -br addr show
두 출력을 비교하세요. 인터페이스 목록에 없는 변환 대상이 바로 버그이며, 한 번 보면 고치는 일은 한 줄 수정입니다. 규칙은 WireGuard 설정이 아니라 생성된 unit에 있을 수 있으므로 편집 후 그 unit을 다시 불러오고, 다음 부팅에서 변경이 덮어써지지 않는지 확인하세요.
NAT 뒤의 두 사이트에는 만날 지점이 필요하다
어느 쪽도 인바운드 연결을 받지 않을 때 현실적인 답은 공인 주소와 WireGuard 인터페이스 두 개를 가진 작은 호스트입니다. 각 사이트는 바깥으로 연결하고, 중간 호스트는 각 피어의 LAN을 자신의 AllowedIPs에 나열하며, 포워딩이 두 터널 사이로 패킷을 나릅니다. 어느 사이트의 방화벽에서도 바꿀 것이 없으며, 그래서 이 설계는 쉽게 퍼집니다.
사이트 사이의 라우팅은 원래 출발지 주소를 유지하므로 호스트별 로깅이 의미를 갖습니다. 두 LAN이 겹칠 때는 중간 호스트에서 변환하는 편이 간단하지만, 로그에서 출처 정체성을 잃는 대가가 따릅니다. 고르기 전에 어떤 속성이 중요한지 정하세요.
네 가지 확인으로 계층을 분리한다
세 가지를 바꾸고 기대하는 대신 계층마다 확인을 하나씩 하세요. 첫째는 피어별 핸드셰이크 나이와 카운터를 보여 줍니다. 둘째는 클라이언트가 그 목적지를 실제로 터널로 라우팅하는지 보여 줍니다. 셋째와 넷째는 요청이 도착했는지, 도착 후 정책이 버렸는지를 알려 줍니다.
wg show ip route get 192.168.50.20 tcpdump -ni wg0 icmp iptables -vnL FORWARD --line-numbers
도착했지만 응답을 얻지 못한 요청은 응답 경로나 LAN 호스트를 가리킵니다. 전혀 도착하지 않은 요청은 AllowedIPs 또는 클라이언트의 경로를 가리킵니다. 이 두 결과는 서로 다른 수정을 필요로 하며, 캡처가 그것을 구분합니다.