WireGuard 핸드셰이크는 되는데 인터넷이 안 된다: 패킷을 추적하라
핸드셰이크는 키와 도달 가능성만 증명합니다. AllowedIPs에서 포워딩, NAT, 반환 경로를 거쳐 패킷 하나를 추적해 어디서 멈추는지 확인하세요.
터널은 올라와 있고, wg show는 최근 핸드셰이크를 보고하며, 서버의 터널 주소로 핑은 통하는데 그 너머에서는 아무것도 응답하지 않습니다. 첫 반응은 키를 다시 만들거나 설정을 다시 공유하는 것입니다. 그것은 이미 동작이 증명된 경로의 일부를 바꾸는 일입니다.
완료된 핸드셰이크는 두 피어가 키에 합의했고, UDP가 엔드포인트에 도달하며, 암호화 라우팅이 패킷을 받아들인다는 것만 말합니다. 패킷이 그 뒤에 서버를 떠날 수 있는지는 말하지 않습니다.
그래서 추측 대신 패킷 하나를 따라가세요. 패킷이 죽는 지점은 네 곳이며, 각각 다른 흔적을 남깁니다.
핸드셰이크가 실제로 증명하는 것
WireGuard는 Noise 핸드셰이크로 세션을 맺은 뒤 피어를 위해 패킷을 암호화하는 UDP 프로토콜입니다. wg show가 몇 초 전 핸드셰이크와 증가하는 전송 카운터를 보여 준다면 엔드포인트, 키, 피어의 공개 키는 모두 올바릅니다.
증명하지 않는 것은 클라이언트가 인터넷으로 가는 트래픽을 인터페이스에 넣는지, 서버가 그것을 포워딩할 의사가 있는지, 응답이 돌아올 길을 찾을 수 있는지입니다. 이는 커널 라우팅과 방화벽의 결정이며 터널 밖에서 내려집니다.
서버의 터널 주소로 핑을 보내는 것이 그렇게 오해를 부르는 시험인 이유입니다. 그 패킷은 서버 자신에게 보내진 것, 따라서 로컬에서 끝납니다. 포워딩도, 변환도, 인터넷으로부터의 반환 경로도 전혀 필요하지 않습니다.
AllowedIPs는 라우팅 결정입니다
클라이언트에서 AllowedIPs는 두 가지 일을 합니다. 어떤 목적지 주소가 이 피어의 터널로 들어가는지 결정하는 암호화 키 라우팅 테이블이며, 피어가 여러분에게서 받아들일 소스 주소 목록이기도 합니다. 클라이언트 설정에 10.8.0.0/24만 적혀 있으면 공용 목적지는 인터페이스에 들어오지 않고 평소의 기본 경로가 그것들을 터널 밖으로 실어 나릅니다. 그러면 터널은 완벽하게 동작하고 원한 일은 아무것도 하지 않습니다.
설정 파일이 말하는 것이 아니라 클라이언트가 실제로 설치한 것을 보세요:
wg show wg0 allowed-ipsip route get 1.1.1.1
결정적인 것은 두 번째 명령입니다. 응답이 물리 인터페이스와 평소의 게이트웨이를 가리키면 패킷은 터널을 지나지 않으며 서버 쪽 변경으로는 고칠 수 없습니다. IPv4용 0.0.0.0/0와 IPv6용 ::/0를 따로 추가하세요. 한 주소 체계만 전부 잡는 규칙은 다른 쪽을 원래 경로에 남기며, 이것이 IPv4 터널은 되고 IPv6 조회가 멈추는 흔한 원인입니다.
게이트웨이에서 패킷이 죽는 곳
경로가 맞는데도 패킷이 아무 데도 가지 않는다면 서버에 도착해 거기서 멈춥니다. 네 가지 확인으로 대부분의 게이트웨이를 덮습니다.
포워딩. sysctl net.ipv4.ip_forward가 0을 반환하는 것이 전형적인 답이며 많은 배포판이 여전히 기본값이 0입니다. 1이어야 하고, 재부팅 시 사라지는 명령이 아니라 sysctl 파일에 영구히 설정해야 합니다. IPv6 포워딩은 별도 스위치입니다.
필터 정책. 기본이 drop인 FORWARD 체인은 터널 트래픽을 버리면서 호스트 자체로 가는 트래픽은 허용하며, 이는 증상과 정확히 일치합니다. 저장된 파일이 아니라 살아 있는 규칙 집합을 읽으세요: nft list ruleset 또는 iptables -S.
변환 또는 라우팅. 사설 터널 주소를 쓰는 클라이언트에는 서버의 출구 인터페이스에서 소스 NAT가 필요하거나, 상위 네트워크가 되돌리는 방법을 아는 라우팅된 프리픽스가 필요합니다. 둘 중 선택은 주소 계획을 따릅니다. 이미 프리픽스를 되돌리는 네트워크에 MASQUERADE를 더하는 것은 무해하지만 무의미하고, 경로가 없는 곳에서 이를 빼면 응답이 라우팅되지 않는 사설 범위로 향한 채 남습니다.
반환 경로. 라우팅 설계에서는 상위 라우터에 서버를 가리키는 경로가 필요합니다. 공급자 네트워크도 이를 막을 수 있습니다. 여러 클라우드는 인스턴스에서 소스 및 목적지 검사를 켜며, 그 검사를 끄기 전까지 소스가 인스턴스 자체 주소가 아닌 패킷을 조용히 버립니다.
DNS는 라우팅과 다른 방식으로 실패합니다
알려진 주소로 가는 패킷과 이름 조회는 별개의 실패이며, 오류 메시지는 서로 반대 방향으로 오도합니다. ping 1.1.1.1가 통하는데 브라우저가 아무것도 못 불러온다면 경로는 정상이고 이름 해석이 아닙니다. 핑 자체가 실패하면 DNS는 무관하고 앞 절로 돌아갑니다.
wg-quick은 설정의 DNS = 줄에서 리졸버를 지정할 수 있고, systemd-resolved는 링크마다 고유한 동작을 합니다. 터널 안에서만 닿는 주소로 리졸버를 덮어쓰는 VPN은 터널이 끊기는 순간 모든 조회를 실패하게 만들고, 이는 터널이 인터넷을 망가뜨린 것처럼 보입니다.
| Symptom | Layer to inspect |
|---|---|
| Tunnel address pings, nothing else does | Client route, then gateway forwarding |
| Public IP pings, hostnames fail | Resolver selection and reachability |
| Handshake completes, no reply ever | FORWARD policy or missing NAT on the server |
| Small requests work, large transfers stall | MTU and TCP MSS clamping |
증거를 만드는 순서
명령 하나로 가능성의 절반이 사라지므로 먼저 클라이언트 쪽 점검을 실행하세요. 다음으로 서버가 애초에 인터넷 출구인지 확인하세요. 사설 접근을 위해 만든 게이트웨이는 공용 목적지가 실패해도 고장 난 것이 아닙니다.
서버에서는 클라이언트에서 핑을 보내면서 인터페이스를 지켜보세요. tcpdump -ni wg0 icmp는 요청을 보여 주고, tcpdump -ni eth0 icmp는 변환 여부와 관계없이 그것이 나가는 것을 보여 주어야 합니다. 앞쪽에 나타나고 뒤쪽에는 끝까지 나타나지 않으면 멈춤은 서버 안에서 일어납니다. 나가는데 응답이 돌아오지 않으면 문제는 상류에 있고, 그것은 다른 이야기입니다.
마지막으로 수정이 재부팅 후에도 살아남게 하세요. 포워딩은 sysctl 파일에, 방화벽 규칙은 그것을 불러오는 서비스에, 클라이언트 경로는 인터페이스를 올리는 설정에 속하며 여러분이 잊어버릴 셸에 두면 안 됩니다. 다시 연결하고 같은 두 시험을 반복해 카운터가 움직이는지 확인하세요.