보드는 공통 이미지에서 부팅하고 DHCP 임대를 받으며, 누군가 기기를 만지기 전에 프로비저닝 스크립트가 실행된다. 그 스크립트 어딘가에서 이 보드에만 속하고 다른 어떤 보드에도 속하지 않는 WireGuard 정체성을 얻고, 그 정체성을 승인받고, 게이트웨이가 받아들일 프로파일을 작성해야 한다. 이미지는 클라이언트 소프트웨어, 검토된 템플릿, 게이트웨이의 공개 키를 담을 수 있다. 절대 담아서는 안 되는 것은 플리트 전체가 공유하는 하나의 개인 키이며, 그러면 훔친 보드 하나가 플리트 전체의 사고가 된다. 아래 순서는 정체성을 로컬에 두고 승인을 명시적으로 만든다.

이미지가 담는 것과 담지 않는 것

패키지, 자리 표시자가 있는 템플릿, 게이트웨이의 공개 키, 등록 클라이언트를 함께 보낸다. 템플릿은 형태이지 비밀이 아니며, 프로비저닝 사용자가 읽을 수 있어야 하고 키 자료를 포함해서는 안 된다.

개인 키는 첫 부팅 시 기기에서 생성되어 결코 기기를 떠나지 않는다. 공개 절반만 이동하며, 기기가 자신이 누구인지에 대한 자기 주장이 아닌 다른 무언가로 승인되는 등록 요청 안에 들어간다. 이 구분이 훔친 보드를 플리트 전체의 문제로 만들지 않는다. 그리고 이것이 대부분의 첫 부팅 스크립트가 틀리는 부분이기도 하다.

1단계: 키를 로컬에서 생성한다

기저 네트워크 연결이 승인되어 동작한 후 보호된 디렉터리에서 생성을 실행한다. 서브셸은 umask 변경을 이 작업에 한정하고, set -C는 기존 파일 덮어쓰기를 거부한다:

(
    umask 077
    set -C
    wg genkey > /etc/wireguard/device.key &&
        wg pubkey < /etc/wireguard/device.key > /etc/wireguard/device.pub
)

WireGuard 빠른 시작 문서는 이 두 명령이 의존하는 키 생성 관계를 설명한다. 생성이 중단되면 기기를 미등록 상태로 두고 워크플로가 파일을 정합하도록 둔다. 스크립트가 처음부터 깔끔하게 돌도록 하기 위해 기존 정체성을 삭제하지 않는다.

재시도 사이에 대기 중인 키를 유지한다. 일시적인 네트워크 장애마다 정체성을 다시 생성하는 것이 플리트가 아무도 기기와 짝지을 수 없는 고아 peer를 남기는 방식이다.

2단계: 기기 레코드를 승인한다

인벤터리가 이 보드를 device-042라고 부르고 10.90.0.42/32를 할당한다고 하자. 등록 서비스는 이 요청자가 그 레코드에 대한 권리가 있는지 검증해야 한다. 양식에 입력한 시리얼 번호는 상자 바깥에 인쇄되어 있으므로 증거가 아니다.

기기별 부트스트랩 자격 증명, 운영자 승인 또는 하드웨어 기반 증명이 주장을 성립시킬 수 있다. 요청의 무결성과 응답의 진정성을 보호하고, 하나의 공유 VPN 비밀을 하나의 공유 공장 자격 증명으로 대체하지 않는다.

등록된 레코드는 기기, 공개 키, 할당된 주소, 허용된 관리 역할을 묶는다. WireGuard 자체는 등록 API를 정의하지 않으므로 그 서비스는 의도적으로 구축하고 운영하는 것이다.

3단계: 서로 맞는 두 개의 구성을 작성한다

기기에는 관리 프리픽스를 터널로 라우팅하는 프로파일이 필요하고, 게이트웨이에는 이 기기 자체의 출발지 주소만 허용하는 peer 항목이 필요하다. 게이트웨이가 10.90.0.1에 있고 관리 네트워크가 10.60.0.0/16일 때 기기 쪽은 이렇게 생겼다:

[Interface]
PrivateKey = <device-042 private key>
Address = 10.90.0.42/32

[Peer]
PublicKey = <trusted gateway public key>
Endpoint = vpn.example.com:51820
AllowedIPs = 10.90.0.1/32, 10.60.0.0/16
PersistentKeepalive = 25

대괄호 안의 값은 자리 표시자이지 키가 아니다. keepalive는 보드가 NAT 뒤에 있어 도달 가능하게 유지되어야 할 때 중요하지만, 어디서나 필요한 것은 아니며, 습관적으로 추가하면 이유 없이 무선을 깨워 둔다.

게이트웨이에서 peer 항목은 의도적으로 좁다:

[Peer]
PublicKey = <device-042 public key>
AllowedIPs = 10.90.0.42/32

기기의 목적지 목록을 게이트웨이 peer에 복사하지 않는다. 기기에서 그 목록은 무엇을 터널로 라우팅할지를 말하고, 게이트웨이에서는 이 peer가 어떤 출발지 주소를 쓸 수 있는지를 말하는, 다른 진술이기 때문이다.

포워딩, 방화벽 규칙, 관리 네트워크로의 귀환 경로는 여전히 승인된 접근을 허용해야 한다. 등록된 peer는 그 뒤의 모든 애플리케이션에 대한 허가가 아니다.

4단계: 등록을 수명 주기 상태로 확정한다

각 구성의 소유자를 통해 게이트웨이 레코드와 기기 프로파일을 적용하고, 의도한 정체성과 주소가 수용될 때에만 등록을 완료로 표시한다. 재시도는 두 번째 peer나 두 번째 주소를 할당하는 대신 같은 레코드를 정합해야 한다.

중단된 프로비저닝을 위한 복구 경로를, 게이트웨이가 키를 받아들였는데 기기가 프로파일을 쓰지 않은 경우까지 포함해 유지한다.

보드가 교체되거나 퇴역하면 공개 키와 승인을 함께 제거한다. 새 키는 의도적인 재등록 이벤트이지 재이미지의 부작용이 아니다. 작업 순서: 로컬에서 생성하고, 인벤터리에 대해 승인하고, 양쪽을 작성하고, 상태를 확정한 다음, 터널을 통해 관리 요청 하나를 시험한다.

관련 글