두 개의 LAN, 하나의 WireGuard 허브, 그리고 어떤 프리픽스를 쓸지, 각 라우터에 어떤 주소가 속하는지, 어느 피어가 어느 서브넷을 소유하는지라는 세 가지 별개의 질문에 답해야 하는 IPv6 주소 계획이 있습니다. 이 중 하나만 틀려도 핸드셰이크는 되지만 아무것도 라우팅하지 않는 터널이 됩니다. 아래 계획은 그 순서대로 프라이빗 두 사이트 설계를 다룹니다. 의도적으로 IPv6 인터넷 액세스는 제공하지 않습니다.

프리픽스의 용도를 정하세요

사이트 간 프라이빗 연결이 목표라면 fd00::/8에서 가져온 고유 로컬 프리픽스가 자연스러운 선택입니다. 각 사이트를 어느 ISP가 제공하든 안정적으로 유지되고 글로벌 라우팅 테이블에 광고되지 않으므로 내부 번호 체계가 인터넷으로 유출될 수 없습니다.

같은 성질이 한계이기도 합니다. ULA는 어떤 상위 제공자도 그것을 여러분의 게이트웨이로 라우팅해야 한다는 것을 알지 못하기 때문에 공용 반환 경로를 제공하지 않습니다. 요구 사항에 IPv6 인터넷 이그레스가 포함된다면 필요한 것은 그것을 여러분에게 라우팅해 주는 제공자의 할당이며, 이는 자체 프리픽스 크기를 가진 별도의 설계 결정입니다.

모든 배포에 /48이 필요하다고 가정하지 마세요. RFC 6177은 엔드 사이트의 단일 의무 크기에서 벗어났고, 올바른 크기는 운영할 네트워크 수를 따릅니다. 다른 조직도 사용할 수 있는 프리픽스를 만들어 내는 대신 RFC 4193 절차로 ULA를 생성하세요. 아무도 기록하지 않은 프리픽스는 누군가 재사용할 것이므로 어떤 장비도 구성하기 전에 결과를 주소 계획에 기록하세요.

프리픽스를 역할로 나누세요

아래 예제는 fd7c:2e91:4a00::/48을 사용하며, 표는 사이트가 아니라 각 블록을 어디에 기록하는지에 따라 구성했습니다. 값은 예시로 취급하고 무엇이든 배포하기 전에 직접 생성하세요.

Where it is writtenWhat appears thereBlock usedWhat it establishes
Hub wg0.conf, interface addressA single host address on the tunnelfd7c:2e91:4a00:ff00::1/128The hub's own tunnel identity
Hub wg0.conf, Site A peerTwo ranges in one AllowedIPs line::2/128 and :10::/64That A owns its tunnel address and its LAN
Hub wg0.conf, Site B peerTwo ranges in one AllowedIPs line::3/128 and :20::/64That B owns its tunnel address and its LAN
Site A wg0.conf, interface addressA single host address on the tunnelfd7c:2e91:4a00:ff00::2/128A's identity as the hub sees it
Site B wg0.conf, interface addressA single host address on the tunnelfd7c:2e91:4a00:ff00::3/128B's identity as the hub sees it

LAN 블록이 /64인 이유는 일반적인 SLAAC가 64비트 인터페이스 식별자를 기대하기 때문입니다. LAN을 더 작은 블록으로 쪼개면 대부분의 호스트에서 그 가정이 깨지고, 프라이빗 계획에서는 주소 절약만큼 운영 비용이 정당화되지 않습니다. 두 LAN 블록 모두 /48의 중앙에서 가져오므로 낮은 범위는 이후 사이트를 위해 비워 둡니다.

터널 주소는 링크상의 네트워크가 아니라 관리용 풀입니다. 각 인터페이스는 여기서 /128을 하나만 받으므로 터널에서 공유 서브넷을 가정하는 호스트가 없고 필요 없는 곳에서 이웃 탐색이 돌지 않습니다. 역할은 중복되지 않게 유지하고 조직의 주소 계획에 기록하여 나중 사이트가 블록을 재사용하지 않게 하세요.

각 라우터에 터널 주소 하나를 주세요

라우터마다 /128을 하나 할당하고 작동 중인 허브의 기존 키와 엔드포인트는 그대로 유지하세요. 아래 세 값은 호스트 부분만 다릅니다.

Hub:    Address = fd7c:2e91:4a00:ff00::1/128
Site A: Address = fd7c:2e91:4a00:ff00::2/128
Site B: Address = fd7c:2e91:4a00:ff00::3/128

이 /128은 해당 인터페이스에 할당된 단일 주소를 나타냅니다. 연결 가능성이 인터페이스 프리픽스가 아니라 AllowedIPs에 표현되므로, 피어가 몇 개의 목적지로 라우팅할 수 있는지는 말하지 않습니다.

각 사이트 라우터에는 자기 LAN 블록 안의 주소와 그것을 배포할 수단도 필요하며, 보통 SLAAC를 위한 라우터 광고입니다. WireGuard는 그 광고를 대신 보내지 않고 두 LAN을 브리지하지도 않습니다. 사이트 라우터는 양방향의 라우터입니다.

서브넷 소유권을 AllowedIPs에 두세요

사이트 A에 대한 허브의 피어 항목은 A의 터널 주소와 A의 LAN을 소유하며, 그 짝이 소유권 진술의 전부입니다. 그 피어 섹션에서 사이트를 설명할 다른 것은 없습니다.

AllowedIPs = fd7c:2e91:4a00:ff00::2/128, fd7c:2e91:4a00:10::/64

사이트 B의 피어 항목은 대응하는 짝을 소유하며, 여기서는 간결함보다 대칭성이 중요합니다. 두 줄을 나란히 읽으면 소유 분담이 한눈에 보입니다.

AllowedIPs = fd7c:2e91:4a00:ff00::3/128, fd7c:2e91:4a00:20::/64

이것은 하나의 피어를 두고 경쟁하는 두 목록이 아니라 별개의 피어 섹션 두 개입니다. WireGuard는 AllowedIPs를 양방향으로 사용하여 송신 목적지에 대해 피어를 고르고, 복호화한 피어에 할당된 범위와 출발지가 맞지 않는 수신 패킷을 거부합니다. 두 피어 모두에 /48 전체를 주면 그 두 번째 검사가 꺼지고 어느 사이트가 어느 블록을 소유하는지 흐려집니다. 이 구분 덕분에 잘못된 출발지 주소가 조용히 받아들여지지 않고 드러납니다.

각 사이트에는 허브 피어를 통해 도달할 수 있는 목적지만 필요하며, 사이트 A는 허브 주소, 사이트 B의 터널 주소와 B의 LAN을 나열하고, 사이트 B는 그 반대 집합을 나열합니다. 목록이 비대칭인 것은 의도된 것으로, 각 라우터가 토폴로지의 다른 쪽을 보기 때문입니다. 다른 사이트의 구성이 아니라 주소 계획에서 둘 다 작성해야 오래된 범위가 재번호 지정을 견디지 못합니다.

wg-quick에서는 이 범위가 경로도 만듭니다. systemd-networkd나 수동 설정에서는 그렇지 않으면 커널이 결코 보내지 않는 패킷을 터널이 나르므로 동등한 경로를 직접 추가하세요.

포워딩을 완료하고 양방향을 테스트하세요

허브와 두 사이트 라우터에서 IPv6 포워딩을 활성화하고, 포워드 정책에서 필요한 사이트 간 서비스를 허용하세요. ICMPv6 Packet Too Big 메시지는 버리면 경로 MTU 탐색이 깨지고 애플리케이션 장애처럼 보이는 대용량 전송 정지가 생기므로 사용 가능하게 유지하세요. 방화벽 허용 없이 포워딩하는 허브는 라우팅과 터널 사이에서 패킷을 버립니다. 터널은 살아 있고 일부 흐름만 죽기 때문에 이 장애 모드는 알아 둘 가치가 있습니다.

sysctl net.ipv6.conf.all.forwarding
ip -6 route
ping -6 -c 3 fd7c:2e91:4a00:20::1

사이트 A의 호스트에서 사이트 B의 호스트로, 그리고 반대 방향으로 테스트하세요. 허브의 터널 주소로 보내는 ping은 첫 홉만 시험하므로 LAN 경로가 틀려도 통과합니다. 계획을 증명하는 것은 호스트 간 흐름입니다.

바깥쪽 WireGuard 연결은 IPv4 위에서 돌면서 안쪽 트래픽은 IPv6일 수 있고, 이 독립성은 마이그레이션 중에 유용합니다. 나중에 글로벌 IPv6 이그레스를 추가한다면 제공자 할당, 출발지 주소 선택, 반환 라우팅을 새로운 설계 단계로 다시 검토하되, 위의 프라이빗 계획은 사이트 간 트래픽에 대해서는 여전히 유효합니다.

관련 글