Piゲートウェイのホスト名は静的ルートを自動で更新するのか?
PiゲートウェイのDNS名が、インストール済みのネクストホップを書き換えることはありません。カーネルが保持するものと、誰がルートを更新すべきかを見ていきます。
静的ルートをゲートウェイ名に向けると、アドレスが変わっても大丈夫なように感じますが、実際はそうなりません。名前はDNSにあり、ルートはクライアントのルーティングテーブルに数値のネクストホップとして座っています。Piが別のアドレスに移ると、古いホップをすでにインストールした利用者は全員、同じ番号へトラフィックを送り続けます。フォワーディングテーブルにリゾルバは接続されていないので、そのエントリを勝手に書き換えてくれるものはありません。
DNSの答えとルートは別のオブジェクト
Piがvpn-gw.lanに応答し、10.44.0.0/16をトンネルへ転送しているとします。192.168.30.0/24のクライアントは静的ルート経由でそこへ到達します。Piのアドレスが192.168.30.4から192.168.30.11へ移ったとき、レコードはTTLの範囲内で追随しましたが、ルートは追随しませんでした。
この二つの見え方は、別々に問い合わせるとどちらももっともらしく見えるため、見落としやすい形で食い違います。
$ ip route get 10.44.0.1
10.44.0.1 via 192.168.30.4 dev eth0 src 192.168.30.20
$ dig +short vpn-gw.lan
192.168.30.11
パケットの行き先を決めるのは最初の行だけです。二番目の行は、カーネルが一度も尋ねなかった問いに答えています。Aレコードが複数あるレコードも、フェイルオーバーのポリシーにはなりません。どのアドレスも、そのセグメントで使えるネクストホップでなければならないからです。
コマンドが終わったあとテーブルに残るもの
Linuxのルートは、ここで重要な二つを記録します。プロトコルアドレスとしてのネクストホップと、インデックス番号としての出力インターフェースです。rtnetlinkのルート属性がその最初のフィールドをRTA_GATEWAYと呼び、そこにはバイト値が入ります。エントリが置かれた時点で、TTLは結び付かず、バックグラウンドの検索もそれを更新しません。
だからip route add 10.44.0.0/16 via vpn-gw.lanは動いているように見えるのです。ツールはコマンドの実行中に名前を解決し、得られたアドレスを書き込み、名前のことは完全に忘れます。その後でip route show 10.44.0.0/16を実行すると、文字どおりのアドレスが返ってきます。
トンネルを疑う前に、この挙動を知っておく価値があります。
名前を代わりに解決してくれるツールと、そのタイミング
ルーターやファイアウォールの中には、ルートやゲートウェイのフィールドでホスト名を受け付けるものもあります。重要なのは、解決がいつ起きるかです。設定を適用するときだけ名前を解決する機器なら、保存されるエントリは手入力したアドレスと同じくらい静的で、あとでアドレスが変わったらもう一度適用する必要があります。フィールドが名前を受け付けることは、更新について何も教えてくれません。
管理された構成では、仕事を分けるのが普通です。DHCPの予約や静的リースでPiを一つのアドレスに留め、DNSレコードはそのリースに従うだけです。目標が動かないので、動く目標を追う必要はありません。
監視付きのアップデータはもう一つの正当なパターンで、これには所有者が必要です。
アドレスを固定するか、アップデータを自分で動かす
小さなLANなら、DHCPサーバーでの予約が最も安い解決策です。動的プールの外のアドレスを選び、PiのMACアドレスに結び付け、次のリース更新後にip -4 addr show dev eth0で確認します。そしてクライアントのネクストホップをそのアドレスに向けるのは一度だけ。これで安定したゲートウェイと、それを記述するレコードが手に入ります。関係が実際に成り立つ順序はこうです。
Piを本当に移す必要があるなら、各クライアントを手で編集するのではなく、ルートの修復を一か所にまとめます。解決し、比較し、置き換える短いスクリプトで、その手順は繰り返せるものになります。
new=$(dig +short vpn-gw.lan | head -n1)
cur=$(ip route get 10.44.0.1 | awk '{print $3}')
if [ "$new" != "$cur" ]; then
ip route replace 10.44.0.0/16 via "$new"
fi
ip route get 10.44.0.1
最後のコマンドが受け入れテストです。カーネルが実際に使うゲートウェイを表示するからです。表示されたアドレスがまだ古いなら、スクリプトは誤ったネットワーク名前空間で動いたか権限が足りなかったのであり、DNS側は無関係です。
戻りの経路も確認してください。Piはクライアントのサブネットへどう到達するかを知っている必要があり、ファイアウォールがトンネルのトラフィックを許可する必要があります。食い違いを覆い隠すために足したデフォルトルートは、たいてい本当の隙間を隠し、一週間後に別の何かを壊します。