터널은 모바일 데이터에서 올라오지만 집에서는 같은 프로필, 같은 피어 키, 중간의 설정 변경도 없이 연결 중에 머뭅니다. 차이는 여정에 있는데, LAN 내부에서 라우터의 공인 주소로 보내는 요청은 인터넷에서 도착하는 요청과 같은 여정이 아닙니다. 대부분의 가정용 게이트웨이는 반환 경로를 구현하지 않거나 특정 프로토콜에 대해서만 구현합니다. 그래서 키에 대해서는 아무것도 바뀌지 않았는데도 증상은 키가 깨진 것처럼 보입니다. 키, 포트 포워드, 클라이언트 프로필을 건드리기 전에 어느 경로가 실패했는지 먼저 확정하세요.

하나의 주소, 두 개의 다른 경로

바깥에서는 패킷이 라우터의 공인 주소에 도달하고 포트 포워드 규칙이 그것을 내부 호스트의 WireGuard 리스너에 넘깁니다. 안쪽에서는 클라이언트가 같은 공인 주소로 연결을 시도하므로, 패킷은 클라이언트를 떠나 라우터에 도착하고 다시 LAN 쪽으로 되돌려져야 합니다. 두 경로가 갈라지는 곳이 바로 이 되돌림 지점인데, 라우터는 같은 인터페이스에서 나갔다가 다시 그 인터페이스로 들어오는 흐름을 변환해야 하기 때문입니다. 많은 구현이 변환하지 않고 그 흐름을 버리며, 그러면 클라이언트는한 번도 보내지지 않은 핸드셰이크를 기다립니다.

이 동작은 보통 NAT 루프백 또는 헤어피닝이라 불리며 WireGuard가 아니라 라우터에 속하는 성질이고, RFC 4787은 게이트웨이가 이를 지원할 수도 있고 아닐 수도 있는 변환 사례를 규정합니다. WireGuard 자체는 자신의 인터페이스에 도달한 패킷만 보기 때문에 경로에 대해 아무 의견이 없습니다. 라우터가 흐름을 버리면 데몬은 아무것도 받지 못하고, 클라이언트는 핸드셰이크 시간 초과를 보고하며 서버 로그는 비어 있습니다. 그러므로 빈 로그는 패킷이 어디서 멈췄는지 알려주는 단서이지 서버가 죽었다는 증거가 아닙니다. 재설치로 아무것도 달라지지 않는 이유도 여기에 있습니다.

반대 방향도 중요한데, LAN 주소에서 온 핸드셰이크 시도를 보여 주는 서버 로그는 패킷이 도착했고 경로가 정상임을 증명하며, 그러면 조사는 키와 허용 주소로 옮겨 갑니다. 로그는 보고 싶었던 것이 아니라 그것이 증명하는 것을 기준으로 읽으세요.

무언가를 바꾸기 전에 먼저 재현하세요

같은 기기와 같은 프로필로 허가된 외부 네트워크에서 시험한 뒤, 아무것도 바꾸지 않은 채 LAN 안에서 같은 시험을 반복하세요. 바깥에서 완료된 핸드셰이크와 안쪽에서 기기를 벗어나지 않는 클라이언트는 추측이 아니라 그 상태를 재현합니다. 두 시도가 같은 프로필을 쓰지 않으면 비교는 아무것도 증명하지 못합니다.

그다음 이 기기에서 엔드포인트 이름이 무엇으로 확인되는지 보세요. 다음 세 명령은 클라이언트가 실제로 어느 주소로 접속했는지도 보여 줍니다:

wg show wg0 endpoints
dig +short vpn.example.net A
resolvectl query vpn.example.net

첫 번째 명령은 인터페이스가 지금 어떤 엔드포인트를 쓰는지 알려 주고, 나머지 둘은 이 머신에서 이름이 무엇으로 확인되는지 보여 줍니다. 서버와 같은 네트워크에 앉아 공인 주소로 접속하는 클라이언트는 헤어핀 경로를 쓰는 것입니다. LAN 주소로 접속하는 클라이언트는 그렇지 않으며, 그곳의 실패는 다른 조사에 속합니다. 이 구분이 다음 절이 여기에 해당하는지를 결정합니다.

가까운 서버에 도달하는 지원되는 방법

가장 깔끔한 구성은 스플릿 호라이즌 응답으로, 공인 이름이 인터넷에는 공인 주소로, 내부 클라이언트에는 서버의 LAN 주소로 확인됩니다. 프로필은 엔드포인트 이름 하나를 유지하고 리졸버가 경로를 고릅니다. 이에는 내부 DNS 응답에 대한 통제가 필요하며, 가정용 라우터는 보통 이를 제공하고 조직은 의도적으로 마련할 수 있습니다. 그 통제가 없으면 남는 선택은 라우터 기능이나 두 번째 프로필입니다.

라우터 기능은 리플렉션이며, 게이트웨이가 내부에서 공인으로 나가는 흐름을 변환해 다시 안쪽으로 보냅니다. 되는 곳에서는 클라이언트 변경이 필요 없고, 되지 않는 곳에서는 어떤 클라이언트 설정도 구제하지 못합니다. 라우터의 기능 목록을 읽는 대신 내부 시도 중에 서버 로그를 보며 시험하세요.

프로필을 사설 주소로 바꾸는 것은 진단이지 설계가 아닙니다. 서버가 LAN에서 응답한다는 것을 증명하지만, 노트북이 집을 나서는 순간 같은 프로필은 깨집니다.

ApproachWhat it depends onWhere it fails
Split-horizon nameControl of the internal DNS answerClients that resolve through a server outside the zone
Router reflectionGateway support for hairpin translationRouters that drop the flow silently
Private address in the profileNothing beyond the LANEvery network except the one at home

집 밖에서도 쓸 수 있는 프로필로 남겨 두세요

어느 경로를 고르든 신원 확인은 건드리지 마세요. 엔드포인트 주소는 피어 신원이 아니며, 주소가 바뀌었다고 해서 마침 응답하는 무관한 공개 키를 받아들일 이유가 되지는 않습니다. WireGuard는 키로 인증하므로 잘못된 호스트는 핸드셰이크에 실패할 뿐 예상치 못한 무언가로의 접근을 허용하지 않습니다.

공인 주소가 옮겨 가면 이름을 쓸모 있게 유지하는 것은 동적 DNS이고, 변경이 얼마나 빨리 반영되는지는 클라이언트의 갱신 동작이 결정합니다. 주소가 바뀐 뒤에는, LAN 경우로는 검증할 수 없으므로 바깥에서 시험하세요. 레코드 수명이 지난 뒤에도 옛 응답을 캐시에 남기는 리졸버를 주의하세요. 이전 주소를 가리키는 이름은 죽은 서버와 똑같이 보입니다.

프로필이 어느 이름을 쓰는지, 그리고 경계의 양쪽에서 그 이름이 무엇으로 확인되는지 적어 두세요. 아무도 기록하지 않은 라우터 기능에 의존하는 프로필은 다음 펌웨어 업데이트를 기다리는 지원 요청입니다. 그 메모는 내부 실패가 알려진 헤어핀 사례인지 새로운 것인지를 다음 사람에게 알려 주는 것이기도 합니다.

관련 글