사이트 간 VPN을 넘는 IPv6 프리픽스 위임: 점검 목록
위임된 IPv6 프리픽스를 사이트 간 VPN 너머로 라우팅하기 위한 점검 사항: 프리픽스 맵, 트래픽 셀렉터, 포워딩, MTU, 반환 경로, 재번호 부여.
터널을 올리는 것은 쉬운 절반이다. 사이트 간 링크가 며칠씩 연결된 채로 있는데도 반대편 LAN의 모든 호스트가 침묵만 돌려받는 모습을 본 적이 있는데, 그 게이트웨이 뒤의 위임된 프리픽스가 인터페이스에는 설정되었지만 터널로 라우팅되지 않았기 때문이다. 터널 주소는 그동안 계속 ping에 응답했고, 바로 그래서 아무도 프리픽스를 보지 않았다. 위임된 IPv6 프리픽스가 사이트 VPN을 통과해야 할 때 내가 확인하는 순서는 프리픽스 맵, 트래픽 셀렉터, 포워딩과 방화벽, 그리고 반환 경로다.
터널을 건드리기 전에 프리픽스 맵을 작성한다
프리픽스 위임은 요청한 라우터에 블록을 넘겨줄 뿐이다. 피어에 경로를 설치하지 않고, 그 블록을 on-link로 확장하지 않으며, 요청 라우터 뒤에 무엇이 있는지 원격 게이트웨이에 알려주지도 않는다. 이 세 가지는 직접 설정해야 하며, 어떤 설정 파일을 바꾸기 전에 주소 계획에 들어가야 한다.
사이트마다 위임된 프리픽스, LAN에서 실제로 쓰는 /64, 터널 주소, 모든 경로의 소유자를 기록한다. 공급자는 사이트 A에 2001:db8:a1::/56을 위임하여 자기 LAN에서 2001:db8:a1:10::/64를 제공하게 하고, 사이트 B는 2001:db8:b2::/64를 유지한다. 사이트 A가 그 /64 하나만 제공한다면 양쪽 끝은 전체 /56이 아니라 2001:db8:a1:10::/64를 지정해야 한다.
거의 항상 두 가지 실수가 나타난다. 하나는 원격 프리픽스를 on-link로 취급하여 브리지하거나 터널 인터페이스에 올려, 게이트웨이가 도달할 수 없는 호스트의 이웃 요청에 응답하게 만드는 것이다. 다른 하나는 /64 하나만 설정했는데 /56 전체를 광고하는 것이며, 경로 테이블은 그 블록이 도달 가능하다고 주장하고 대부분의 주소는 블랙홀로 빠진다.
양쪽 끝의 트래픽 셀렉터를 경로에 맞춘다
IKEv2와 WireGuard 모두 일치하지 않는 트래픽을 거부하며, 그 거부는 터널이 여전히 정상으로 보일 만큼 조용하다.
strongSwan에서는 셀렉터를 명시하며, 사이트 A에서는 다음과 같다.
conn a-to-b
left=2001:db8:ff::1
leftsubnet=2001:db8:a1:10::/64
right=2001:db8:ff::2
rightsubnet=2001:db8:b2::/64
auto=start사이트 B의 conn은 두 서브넷을 그대로 비춘다. 둘이 어긋나면 응답자는 TS_UNACCEPTABLE로 CHILD_SA를 거부하므로, IKE_SA가 올라갔어도 child SA는 올라오지 않는다. 양쪽 모두에서 설정된 서브넷은 로컬 커널이 터널 쪽으로 라우팅하는 것과 같아야 한다.
WireGuard는 같은 정보를 AllowedIPs에 담는데, AllowedIPs는 송신 시의 경로이자 수신 시의 소스 필터라는 변형이 있다. 사이트 B의 사이트 A 피어 항목이 2001:db8:a1:10::/64를 빠뜨리면, 사이트 A에서 온 패킷은 유효한 핸드셰이크로 도착하고 허용되지 않음으로 폐기된다. 그래서 핸드셰이크만 계속 갱신되고 응답은 결코 나가지 않는 익숙한 패턴이 생긴다. 양쪽 끝을 wg show wg0 allowed-ips로 비교하고, 위임이 바뀔 때마다 그 목록을 다시 확인한다. 오래된 /64는 세션을 살려 두고 새 프리픽스를 도달 불가능하게 만든다.
포워딩, 방화벽, MTU를 먼저 배제한다
다음 로그 줄을 읽기 전에 게이트웨이가 애초에 포워딩하는지 확인한다. sysctl net.ipv6.conf.all.forwarding는 양쪽에서 1을 반환해야 하며 터널과 LAN 인터페이스에도 적용된다. 함정이 하나 따라오는데, 포워딩을 켜면 accept_ra=1인 인터페이스는 공급자의 라우터 광고를 받지 않게 되어, 터널 안에서는 완벽하게 라우팅하면서도 업스트림 기본 경로를 잃을 수 있다. 공급자 RA가 여전히 필요한 곳에서는 accept_ra=2를 설정한다.
그다음 방화벽 규칙이 프리픽스를 양방향으로 허용해야 하고, ICMPv6도 살아남아야 한다. 이웃 탐색, packet-too-big, destination-unreachable은 선택 사항이 아니어서 이것들을 버리면 경로 MTU 탐색이 깨져 연결이 열린 뒤 첫 큰 응답에서 멈추므로, 최소한의 규칙 한 쌍은 다음과 같다.
nft add rule inet filter forward ip6 saddr 2001:db8:a1:10::/64 ip6 daddr 2001:db8:b2::/64 accept
nft add rule inet filter forward ip6 saddr 2001:db8:b2::/64 ip6 daddr 2001:db8:a1:10::/64 accept
nft add rule inet filter forward icmpv6 type { packet-too-big, nd-neighbor-solicit, nd-neighbor-advert } acceptMTU는 그 뒤에 있다. 터널은 쓸 수 있는 MTU를 1500 아래로 줄이고, IPv6는 모든 링크가 최소 1280을 전달할 것을 요구한다. 작은 ping은 통과하지만 SSH 세션은 큰 버스트에서 멈추고, /proc/net/snmp6에는 돌아오지 않는 packet-too-big 메시지가 나타난다. 터널 MTU를 명시적으로 설정하거나 mangle 테이블에서 TCP MSS를 클램프하고, 더 작은 MTU를 알리는 ICMPv6가 돌아오게 한다.
터널 주소가 아니라 반환 경로를 시험한다
가장 많은 시간을 잡아먹는 장애는 단방향 라우팅이다. 각 게이트웨이는 원격 프리픽스를 터널로 라우팅하지만, 호스트는 자기 /64가 있는 곳이라며 자기 기본 게이트웨이로 응답한다. 패킷을 목적지까지 보내는 것은 경로의 절반일 뿐이다.
| What you see | Likely cause | First check |
|---|---|---|
| Tunnel up, every host silent | remote prefix not routed into the tunnel | ip -6 route get on both gateways |
| Handshake renews, no replies | source prefix missing from selectors or AllowedIPs | ipsec statusall, wg show allowed-ips |
| Small pings pass, transfers stall | MTU or ICMPv6 packet-too-big filtered | /proc/net/snmp6 counters |
| Old prefix still works | stale /64 left in routes or selectors | delegation lease and route table |
두 명령이 대부분을 정리한다. 사이트 A에서 ip -6 route get 2001:db8:b2::53 from 2001:db8:a1:10::5는 그 소스의 응답이 어느 인터페이스를 쓸지 보여 주므로 사이트 B에서 거울처럼 같은 점검을 한다. 그다음 게이트웨이가 아니라 호스트에서 트래픽을 만들어 양쪽 끝의 카운터를 비교한다.
원격 프리픽스에 대한 이웃 요청이 터널에 나타난다면, 그 프리픽스는 있어서는 안 될 곳에서 on-link가 된 것이므로 경로를 조정하기 전에 그것을 고친다. 프록시 NDP는 브리지가 정말로 필요한 경우를 다루는 것이지 경로의 대체물이 아니다.
프리픽스가 아래에서 바뀔 것을 계획한다
프리픽스 위임은 위임하는 라우터와 요청하는 라우터 사이의 임대이며, 갱신은 다른 블록을 돌려줄 수 있다. 공급자 이전 후의 다른 /56이거나 터널이 올라와 있던 기간보다 짧은 임대이며, 옛 프리픽스를 언급하는 모든 곳이 경로, 셀렉터, AllowedIPs, 방화벽 규칙, DNS 레코드, 그리고 리터럴 주소를 하드코딩한 모든 모니터링과 함께 한꺼번에 낡는다. 메시지 흐름은 RFC 8415에 있다.
프리픽스가 움직일 것으로 예상되면 그것에 의존하지 않는 내부 주소 계획을 유지하고 경계에서 변환한다. NPTv6는 무상태 선택지이며 내부 정책을 읽을 수 있게 유지하지만, 이는 프리픽스 변환이지 마법의 계층이 아니므로 /64 경계가 맞아야 하고, 체크섬이 조정되며, 리터럴 주소를 포함하는 애플리케이션은 여전히 깨진다. 공급자 주소를 끝에서 끝까지 유지한다면 임대 동작과 변경 절차를 주소 계획에 기록한다.
시간을 견디는 시험으로 마무리한다. 각 LAN의 허용된 호스트가 다른 LAN의 서비스에 도달하고, 응답이 터널을 통해 돌아오며, 터널 재시작과 위임 갱신 후에도 같은 쌍이 여전히 동작해야 하며, 마지막 부분이 실패하면 그 설계는 일주일도 버티지 못할 상태에 의존하고 있다.