家庭用VPNボックスをWi-FiからEthernetに移したら、その「固定」アドレスが同じ夜に変わった。ルーターに壊れたところは何もなかった。予約は無線アダプターに一致していて、そのアダプターはもう経路にいなかった。

同じ誤解にはもう半分がある。LANアドレスを直しても、友人が接続してくるアドレスには何の効果もなく、VPNがクライアントに渡すプライベートプールとも関係がない。三つのアドレス、三つの別々の故障モードがあり、そのうち予約の仕事は一つだけだ。

予約が一致するのはクライアントであり、デバイスではない

DHCPv4では予約はクライアントのハードウェアアドレスに紐づく。DHCPv6ではクライアントが保持することが期待されるDUIDに紐づく。hostnameフィールドは人間のためのラベルだ。ルーターが実際に比較するのは、リクエストに入ってくる識別子である。

その項目は条件として読む。この識別子が要求したら、このアドレスを渡す。一致が続く限り更新は同じリースを保ち、再起動はただもう一度要求する。識別子が変わると、リクエストは予約を外れ、クライアントは動的プールが差し出すものを取る。エラーも警告もなく、ただ別のアドレスになる。

OpenWrtはその形をはっきり示す。/etc/config/dhcp内のconfig hostブロックが名前、MAC、アドレスを結びつけ、静的リースのドキュメントがその項目とプールの関わりを説明している。他のルーターも同じ三つのフィールドを別のラベルの下に隠している。

一致が静かに外れる場所

ハードウェアの入れ替えはよくある。NICを変える、あるいはマシンをEthernetとWi-Fiの間で動かすと、ルーターが見るアドレスも一緒に変わる。古い予約は一覧に残り、今も正しく見える。

再インストールは二つ目のケースで、IPv6で最も強く噛みつく。新しいインストールが新しいDUIDを生成しても古いIPv4リースはまだ有効なので、v4アドレスはしばらく生き残り、v6の項目は目に見える編集もなく適用されなくなる。

三つ目は固定されたクライアント識別子だ。多くのDHCPクライアントはMACの代わりに識別子文字列を設定できる。アップグレードや設定の書き直しでその設定が落ちると、マシンが動いていなくても一致は消える。

四つ目は重複だ。同じホストに対して古いブロックと新しいブロックがある。サーバーは一致した規則で応答し、たいていは避けたかったプールのアドレスになる。二つ目を足すのではなく、古い項目を削除する。

ホスト側の設定とその代償

ホスト側でアドレスを設定すれば、一致の問題は完全になくなる。DHCPが応答してもしなくてもインターフェースはそのアドレスで上がり、ルーターの再起動後も到達できる必要があるマシンに求めるのはまさにそれだ。

代償は所有権だ。プレフィックス、ゲートウェイ、リゾルバーを自分で用意し、アドレスを動的プールの外に自分で保つ必要がある。netplanを使うUbuntuでは/etc/netplan/01-vpn.yamlがそれを担う。

network:
  version: 2
  ethernets:
    eth0:
      dhcp4: false
      addresses: [192.168.50.10/24]
      routes:
        - to: default
          via: 192.168.50.1
      nameservers:
        addresses: [192.168.50.1]

NetworkManagerの利用者はnmcli con mod "Wired connection 1" ipv4.method manual ipv4.addresses 192.168.50.10/24 ipv4.gateway 192.168.50.1、続いてnmcli con up "Wired connection 1"で同じ状態に到達する。最初の試行ではnetplan applyではなくnetplan tryでnetplanを適用する。ゲートウェイを打ち間違えるとマシンがネットワークから外れ、コンソールを探すことになる。

それでも一致する予約は残しておく。無駄ではない。項目はルーター側にアドレスを記録し、後で誰かがプールを広げたときにDHCPサーバーがそのアドレスをゲスト機器に渡すのを防ぐ。

安定したLANアドレスは公開エンドポイントではない

ポートフォワードを192.168.50.10に向ければ、その規則はLAN側のあらゆる変更に耐える。しかし安定したインターネットアドレスは与えない。公開IPはISPのものであり、再接続やモデム交換で動く。動的DNSはそのためにある。

キャリアグレードNATの背後には転送できる公開IPv4がそもそもなく、どんな予約もそれを作らない。まずルーターのWANページを確認する。アドレスが共有範囲にあれば、予約がどれほどきれいでも受信転送は動かない。

三つ目のアドレスはトンネルプールで、しばしば10.8.0.0/24のようなものだ。そのアドレスはトンネルの中にしか存在せず、LANには決して現れない。サーバーのLANアドレスと混同すると、接続中だけオンラインのクライアントへポートが転送されることになる。

壊れる順番で経路を確認する

ルーターから始める。リース表の項目を予約の対象と比べる。サーバーがプールのアドレスを取っていれば識別子が間違っており、ホストでのip link showが比較する値を与えてくれる。

次にホスト。ip -4 addr show eth0は期待どおりのアドレスとプレフィックスを報告するはずだ。同じインターフェースに二つ目のアドレスがあるなら、通常は静的設定の隣でDHCPがまだ動いている。

次に転送。宛先が先ほど確認したアドレスのままだということ、そして何かがss -lntpで待ち受けていることを確認する。閉じたポートへ向けた転送は、外から見ると壊れた転送とまったく同じに見える。

外から仕上げる。Wi-Fiを切った電話で試す。この一つのテストが「ローカルアドレスが違う」と「公的な到達性が壊れている」を切り分け、この設定が混同し続ける二つの問題を分ける。

三つのアドレス、LAN、公開、トンネルプールを書き留め、それぞれをどのシステムが持つかも記す。来月接続が失敗したとき、三つを一度に変えるのではなく、どれを見るべきか分かる。

関連記事