技術記事[25] UnifiのWireguard peerでIPv6を使用する方法

はじめに

この記事は中国語からの翻訳です。不自然な点がありましたらご容赦ください。

原記事(中国語)

最近担当したプロジェクトで、お客様のネットワークがまだ プロバイダー 契約をしていないため、NGN網内しか使えないという状況に遭遇しました。

そこで、VPNトンネルを使用して一時的にインターネットにアクセスできる環境を構築することにしました。

具体的な構成は非常に簡単です:

┌───────────────────────────────────────────────────────────────┐
│                           NGN網内                            │
│                                                               │
│  ┌──────────────┐                              ┌──────────────┐ │
│  │   UniFiデバイス │◄─────────── IPv6 ────────────►│   VPNサーバー    │ │
│  │              │                               │ (自宅)        │ │
│  └──────────────┘                               └───────┬────────┘ │
│                                                         │          │
│          お客様ネットワーク                                │          │
│          (プロバイダー契約なし)                           │          │
└─────────────────────────────────────────────────────────┼──────────┘
                                                          │
                                                          ▼
                                              ┌──────────────────────┐
                                              │       Provider       │
                                              │ (v6plus/transix/     │
                                              │  xpass/OCN等)        │
                                              └──────────────────────┘

NGN網内で相互通信できる裏仕組みを利用して、プロバイダー契約がない状況でもインターネットにアクセスできるようにしています。

少し話がそれてしまいましたが、こんな裏技もあるということで(草

補足情報
NTT東日本のNGN網では、DS-Liteを利用してインターネットに接続できる無料の実験向けプロジェクトがあります。詳しくは
https://wiki.s.sdconw.com/68adeceb59b31226a3736ddb をご参照ください。 プロバイダー契約がない場合の一時的な解決策として完璧かな

本文

自宅に既存のWireguard VPNがあったので、それを使うことにしました。
少し試してみたところ、IPv6アドレスを入力できない問題を発見しました:
not a valid IPv4

実際のテストでは、UnifiレイヤーでまずAレコードを事前に解析してから、IPアドレスをwgに渡すようです。
そのため、ドメイン名を入力してもAAAAレコードは解析されません(NGN網内の場合、aoi.flets-east.jp だけが解析でき、パブリックインターネットはありません)

そこでもう少し考えて、GPTに聞いてみたところ、この記事がまとめました。

ご存知の通り、現在のUnifi OSはDebianなので、SSHを有効にしましょう: enable ssh

そしてwgで直接Endpointを変更します:

# wg
interface: wgclt1
  public key: XXXXXXXX
  private key: (hidden)
  listening port: 42757

peer: YYYYYY
  endpoint: [xxxxx]:37094 # Unifiがドメイン名を解析できない場合(Aレコードのみ)、endpointの列が表示されませんが、問題ありません
  allowed ips: 0.0.0.0/0, ::/0
  latest handshake: 1 minute, 6 seconds ago
  transfer: 698.13 MiB received, 296.23 MiB sent

ここで変更したいinterfaceとpeer pubkeyを控えて、endpointを設定します:

wg set wgclt1 peer YYYYYY endpoint "[xxxxx]:12345"

もちろん手動設定だけでは不足なので、設定を固定化する(再起動も同じ状態になる)ことが必要です。
ここでは30秒の定期タスクを作成します:

基本的にGPT先生が書いたものですが、必要に応じて変更してください:

/usr/local/bin/wg-check.sh

#!/bin/bash
EXPECTED_ENDPOINT="[期待するアドレス]:9981"
PEER_KEY="YYYYYY"
ENDPOINT=$(wg show wgclt1 endpoints | grep "$PEER_KEY" | awk '{print $2}')

if [ "$EXPECTED_ENDPOINT" != "$ENDPOINT" ]; then
    wg set wgclt1 peer "$PEER_KEY" endpoint "$EXPECTED_ENDPOINT"
    # MTUと静的ルートはオプションです。前述の通り一時的にインターネットに接続したいだけなので、静的ルートを追加しました(UnifiはトンネルデバイスをWANとして指定できません)
    # ip link set dev wgclt1 mtu 1280
    # ip r add default dev wgclt1
fi

chmod +x /usr/local/bin/wg-check.sh

systemctl edit --full --force wg-check.service

[Unit]
Description=Check WireGuard peer endpoint

[Service]
Type=oneshot
ExecStart=/usr/local/bin/wg-check.sh

systemctl edit --full --force wg-check.timer


[Unit]
Description=Run WireGuard peer check every minute

[Timer]
OnBootSec=30
OnUnitActiveSec=60
Unit=wg-check.service

[Install]
WantedBy=timers.target
systemctl enable --now wg-check.timer
systemctl status wg-check

まとめ

普段知っていた知識がこんな時に役立つとは思いませんでした。やはり勉強は大切ですね。
さらに問題があったらGPTに聞きましょう(

もし私と同じようにWireguardをWANとして使いたい場合は、デフォルトルートなどを追加し、ファイアウォールにMASQを追加することを忘れないでください。
(ただし、この方法だとUnifiは自分がインターネットに接続していないと認識するため、リモート管理などは使えません)

最後に、Unifiの奇妙なバグはまだ多く、UIも頻繁に変わり、IPv6関連の機能はまだ少し弱い感じがします。でも少なくともシステムSSHを開放して自分で修正できるのは良いですね = =





以上。






制作・著作
━━━━━
ⒽⓊⒼⒼⓎ