핸드셰이크는 살아 있는데 주소는 사라졌다: WireGuard의 세 가지 상태
최근 핸드셰이크는 피어가 응답했다는 증거일 뿐, 인터페이스가 주소를 유지한다거나 다음 패킷이 의도한 상향 링크로 나간다는 뜻은 아니다.
WireGuard는 최근 핸드셰이크와 주소 없음을 동시에 가질 수 있고, 그 상태는 모순이 아니라 일관된다. 핸드셰이크는 피어의 사건이고, 주소는 인터페이스에 속하며, 라우트가 패킷이 어느 상향 링크로 나갈지를 결정한다. 세 개의 계층, 세 명의 소유자, 그리고 나머지 둘이 건강해 보여도 각각은 실패할 수 있다.
이들을 하나의 상태로 읽는 것이 두 분짜리 진단을 서비스를 다시 시작하는 반나절로 바꾸는 이유다.
핸드셰이크는 피어의 사건이지 주소 지정의 사건이 아니다
WireGuard의 핸드셰이크는 설정된 피어가 유효한 키로 응답했고 세션 키가 최신임을 증명한다. 인터페이스의 로컬 주소에 대해서는 아무것도 말하지 않고, 어떤 라우트가 그쪽을 가리키는지도 말하지 않는다. 주소는 도우미나 네트워크 관리자가 할당하고, 프로토콜 설정은 피어와 키의 이름만 나열한다. 이 둘을 혼동하는 것이 건강한 핸드셰이크를 작동하는 터널로 잘못 읽는 이유다.
그래서 wg show는 애플리케이션에서 패킷 하나도 받을 수 없는 인터페이스에서도 몇 초 전의 핸드셰이크를 보고할 수 있다.
인터페이스를 다시 만드는 관리자는 피어 설정을 건드리지 않고 주소를 떨어뜨릴 수 있고, 키가 바뀐 적이 없으므로 다음 핸드셰이크는 즉시 성공한다. 성공한 핸드셰이크에 관한 로그 줄은 정확하며 장애와 무관하다.
| Observation | Which layer it belongs to | Wrong conclusion it invites |
|---|---|---|
| Handshake a few seconds old | Peer and keys | The tunnel is usable for application traffic |
Address present on wg0 | Interface configuration | Traffic actually egresses through it |
Route points at wg0 | Forwarding table | The outer packet uses the intended uplink |
인터페이스 주소에는 자기 주인이 따로 있다
터널 장치의 주소는 도우미의 Address 줄에서 올 수도 있고, 인터페이스에서 실행되는 DHCP 클라이언트에서 올 수도 있고, 연결 시점에 그것을 만드는 관리 데몬에서 올 수도 있다. 무엇이든 그 구성 요소가 주소를 소유하며 자기 논리에 따라 복원하거나 하지 않는다. 주인을 밝히지 않고 주소를 읽으면 그것이 왜 사라졌는지 설명할 수 없게 된다.
한 인터페이스에 주인이 둘이면 전형적인 장애다. 같은 장치 위에서 도우미와 데스크톱 네트워크 관리자를 함께 시작하면 한쪽이 다른 쪽이 방금 설정한 것을 지우는 경쟁이 생기고, 그 동안에도 엔드포인트는 계속 응답한다.
주인을 하나로 정하고 다른 도구는 관리하지 말고 관찰하게 하라. 증상이 몇 주 뒤에 나타나 무작위 주소 손실처럼 보이므로 그 결정은 기록해 둘 가치가 있다.
상향 링크를 고르는 것은 라우트이지 인터페이스가 아니다
wg0를 가리키는 내부 라우트는 트래픽이 터널로 들어가는 것을 결정한다. 별도의 결정이 암호화된 외부 패킷을 피어 쪽으로 보내며, 상향 링크가 여러 개인 호스트에서는 그 결정이 포워딩 테이블과 정책 규칙에서 나온다. Wi-Fi 로밍은 내부 주소를 건드리지 않고 외부 경로를 바꿀 수 있다.
따라서 작동하는 터널과 도달할 수 없는 피어는 양립하는 상태이고, 올바른 피어와 끊어진 내부 라우트도 마찬가지다. 세 가지 관측은 같은 순간에 함께 취해야 하며, 그렇지 않으면 비교는 무의미하다.
세 상태를 한 번에 비교하라
읽기 전용 명령 세 개가 장애를 가장 빨리 분리하는 순서로 세 질문에 답한다. 그 사이에 아무것도 바꾸지 말고 실행하라.
ip address show dev wg0
ip route get 10.80.0.1
wg show wg0 latest-handshakes transfer
첫 번째는 인터페이스에 주소가 있는지 보여 주고, 두 번째는 특정 목적지가 지금 어느 장치를 쓸지 보여 준다. 세 번째는 마지막 핸드셰이크 시각과 바이트 카운터를 보고하며, 셋 중 피어를 설명하는 유일한 것이다.
타임스탬프뿐 아니라 카운터도 읽어라. 전송이 평평한데 핸드셰이크만 계속 갱신되면 피어는 응답하지만 유용한 것이 지나가지 않는다는 뜻이며, 이는 키가 아니라 라우팅이나 ACL을 가리킨다. 주소가 있는데 타임스탬프가 전진을 멈추면 반대로 상류를 가리킨다. 두 판독은 같은 출력 줄에서 나오며, 핸드셰이크의 존재만 확인하면 어느 것도 보이지 않는다.
잘못된 특정 상태를 고친 다음 터널이 아니라 애플리케이션을 다시 시험하라. 최근 핸드셰이크는 피어에 대한 증거이고, 피어에 대한 증거는 브라우저의 다음 요청이 주소와 라우트와 작동하는 상향 링크를 찾을 것이라는 증거가 아니다. wg-quick 설명서는 그중 무엇을 도우미가 설정하고 무엇이 프로토콜에 속하는지 분명히 밝힌다.