VPN クライアントとしての Pi:マネージャーか自前スクリプトか
Raspberry Pi 上で NetworkManager のプロファイルと手作りのクライアントスクリプトを比較し、フルトンネル、DNS、IPv6、トンネル切断時の挙動まで扱います。
自分の外向きトラフィックだけを守ればよい Raspberry Pi には、現実的な設計が二つあります。ネットワークマネージャーにトンネルを持たせるか、トンネルを持つスクリプトを自分で維持するかです。どちらもトラフィックを運べます。失敗する場所が異なり、深夜二時に遠隔から診断できる失敗のほうを選ぶ価値があります。所有権、IPv6 と DNS が関与したときのフルトンネルの意味、そしてトンネルが落ちた瞬間に何が起きるかで両者を比較してください。
一つのトンネルに二人の所有者
設計 A はシステムのネットワークマネージャー内のプロファイルです。インポートした OpenVPN プロファイル、またはネイティブの WireGuard 接続で、起動時に Ethernet と Wi-Fi を立ち上げるのと同じサービスが有効化します。設計 B は自分自身のユニットで、クライアントを直接実行し、リゾルバの設定を編集し、独自のルートとファイアウォール規則をインストールします。どちらも正当な設計ですが、ルーティングテーブルを変更してよいのが誰かという点で異なります。
所有者が違うので失敗も違います。A では、有効化に失敗したプロファイルはインターフェースを上げたままトンネルを下げ、マネージャーのログが理由を語ります。B では、半分だけ成功したスクリプトは、それを作ったプロセスの終了後も残るルートを残します。両方を動かすのが最悪の結果です。二つのプロセスが既定ルートを書き、起動時に二つのリゾルバ編集が競合し、ローテーションすべき秘密が二組になります。
トンネルごとに所有者を一人選び、何かをテストする前に他方を無効にしてください。所有者が二人ということは、トンネルが上がっているのに何も解決しないときに見る場所も二つあるということです。この一つの規則が、Pi VPN のスレッドで語られる混乱した状態の大半を防ぎます。
インポートが作るもの、作らないもの
Raspberry Pi OS Bookworm 以降では既定のネットワーク設定ツールが NetworkManager なので、プロファイルはクライアントトンネルの自然な住まいです。インポートには対応するプラグインのインストールが必要で、なければ未対応の接続種別に関するメッセージで失敗します。これは止まってプラグインを入れるべきという正直な合図です。
nmcli connection import type openvpn file ./provider.ovpn
nmcli connection show
nmcli --ask connection up id provider-name
インポートはプロファイルを保存します。相手側に到達できることを証明するものではなく、ファイル内のすべての指示が変換を生き延びたことを保証するものでもありません。結果の接続を読み返し、身元と信頼を担う部分、すなわち証明書、リモートホストとポート、パスワードを尋ねるのか保存するのかを確認してください。
--ask を付けた有効化は、共有マシンのシェル履歴にパスフレーズを残しません。無人運用の Pi では、いずれプロファイルを起動時に上げたくなりますが、これは手で一度上げることとは別の判断です。
両設計で比較するフルトンネル
フルトンネルは意図ではなくルートに関する主張であり、二つの設計はそれを異なる形で表現します。プロファイル方式はマネージャーに既定ルートとリゾルバ設定のインストールを求め、スクリプト方式はスクリプトが言うとおりに動き、何もしないことも含みます。どちらの設計も指示されない限り IPv6 を覆わず、手を付けていない IPv6 の既定ルートは、IPv4 が完璧に見える間にトンネルの外へ喜んでトラフィックを運びます。
ip -4 route get 198.51.100.23
ip -6 route show default
resolvectl query example.org
ルート検索にはドキュメント用アドレスを使い、調べてよいホストに置き換えてください。最初のコマンドは Pi が通常の宛先に使うインターフェースを示し、二番目は IPv6 の既定ルートがまだ存在するかを示し、三番目はどのリゾルバが答えたかを証明します。フルトンネルについてのどんな主張も信じる前に三つとも読んでください。
プロバイダーの指示がフルトンネルを約束しているのに IPv6 の既定ルートが残っているなら、Pi は漏れています。上流リンクで IPv6 を無効にするか、プロファイルにそれを要求させ、後で発見するのではなく意図的に決めてください。
フェイルオープンとフェイルクローズド
トンネルが落ちると、既定ルートを失ったルーティングテーブルは単に物理的な上流リンクへ戻り、トラフィックは平文のまま続きます。これがフェイルオープンであり、何かが止めない限り両設計の既定の挙動です。ほとんどの人は数週間後にファイアウォールのログを読んで気づきます。
フェイルクローズドはトンネルが落ちている間の遠隔アクセスを奪うので、管理経路には意図的な例外が必要です。一つの方法は、トンネルの外では VPN ピアのアドレスだけを許可する規則です。
sudo nft add table inet vpnkill
sudo nft 'add chain inet vpnkill out { type filter hook output priority 0; policy accept; }'
sudo nft add rule inet vpnkill out oifname != "tun0" ip daddr != 203.0.113.24 reject
運用コストを正直に比較してください。プロファイルは通常この規則を表現できないため、フェイルクローズドはスクリプト方式か、トンネルとは独立に規則を入れる小さなユニットへと押しやります。いずれにせよ、一週間は拒否を記録してください。静かな拒否は壊れたサービスと見分けがつかず、利用者が一つのサイトが読み込まれなくなったと報告したときにカウンターが必要になります。
画面のない Pi での選択
イメージがすでに NetworkManager を動かしていて、トンネルに特別なものが要らず、上流リンクに自動で従わせたいならプロファイルを選んでください。ポリシールーティング、宛先ごとに選ぶ複数のトンネル、またはトンネルが上がる前に存在しなければならないフェイルクローズド規則が必要なら、スクリプトを選び、起動順序と後片付けを含むすべての部分を自分で所有してください。二つの設計を混ぜると、どちらか一方より高くつきます。
両者間の移行は主に順序の問題です。古い所有者を無効にし、古いルートやリゾルバの項目が残っていないことを確認してから、新しい方を有効にして二回再起動してください。一回の再起動では、二回目が露呈する競合を隠せます。トンネルではなく Pi をテストして終えてください。名前を解決し、IPv4 で何かを取得し、残したなら IPv6 でも取得し、それからトンネルを落として、選んだ挙動が実際に起きることを確認します。ip link のインターフェースはテストの始まりであり、終わりではありません。