誰かが tun1 を事前に作り、プロファイルには dev tun1 と書かれているのに、接続は依然として接続されません。ホスト上に名前があるという事実だけではほとんど何も分かりません。接続は名前空間、デバイスの種類、リンクの所有者、そしてデーモンに何が許されているかによって決まるからです。デバイスの再利用は、既定の設定が隠している判断も強います。どのコンポーネントがアドレスとルートを書き込むのかという判断です。二つの構成の障害の仕方は設定行よりもはるかに大きく異なるので、プロファイルを編集する前に決めてください。

名前は接続ではない

dev tun1 は OpenVPN にその名前のインターフェースを要求し、従来のユーザースペース版はそれを開こうとします。名前が通常の tun や tap のパターンに従わない場合、種類が文字列から推測されることは決してないため、プロファイルには対応する dev-type も必要です。TAP デバイスはラベルが違うだけの TUN デバイスではありません。誤った方を接続すれば、単純に失敗するか、誰も想定しないフレームを運ぶリンクができます。何よりも先に種類を確認してください。以降のどの確認も、両者がそれに合意していることを前提とするからです。そのうえで、プロセスがデバイスを実際に開けることを、単に見えるだけではなく確かめてください。

dev tun1
dev-type tun

ネットワークインターフェースと /dev/net/tun は別のオブジェクトです。一方は名前空間内のリンクで、もう一方はユーザースペースのプログラムが接続に使うキャラクターデバイスです。Linux TUN/TAP の文書 は、その接続経路と永続デバイスの所有規則を説明しています。ip link を実行できる root シェルは、シェルに権限があることだけを示し、デーモンにあることは示しません。デバイスノードの所有、サービスの機能集合、実行しているユーザーのすべてが揃って初めて、開くことに成功します。

存在していて開けないデバイスは、ルーティングの問題ではなく所有の問題です。デバッグ中もそのように扱ってください。そうしないと午後は、決して問題ではなかったルートテーブルを読むことに費やされます。

誰がリンクを設定するか:二つの所有モデル

第一のモデルでは、OpenVPN が接続を立ち上げる一環としてアドレスとルートを設定します。これは既定の動作で、最も筋道を立てやすい方法です。単一のコンポーネントが状態を作り、また取り除くからです。第二のモデルでは外部のマネージャーがインターフェースを所有し、ifconfig-noexec が OpenVPN にアドレス設定コマンドの実行を止めさせ、パラメータをスクリプトに渡します。するとマネージャー自身が正しいローカル側とピア側の設定を適用しなければならず、オプション名から想像されるより手間がかかります。二つのどちらを選ぶかは、リンクが上がっている間に誰がそれを変更できるかという問いです。

ifconfig-noexec が扱うのはアドレスだけです。ルーティングテーブルはそのまま残り、ルートの設定は route-noexec に属します。二つのディレクティブは別々の所有者を持つ別々の制御として扱ってください。片方を設定してもう片方を前提にするのは、半端に設定されたリンクのよくある原因です。階層ごとに所有者を正確に一つ選び、アドレスは一箇所、ルートも一箇所にまとめます。ネットワークマネージャーと VPN ヘルパーの両方がアドレスを書くと、切断時に相手側がまだ依存している状態が消えます。

重要な名前空間からデバイスを調べる

VPN プロセスが動作している名前空間からデバイスを調べてください。たまたま自分のシェルがいる名前空間からではありません。次の二つのコマンドは別の問いに答えるもので、ホストがあるインターフェースを見えてもコンテナには見えないとき、その違いが現れます。示された順に実行してください。リンクがそもそも存在するかどうかを知って初めて、二つ目が意味を持ちます。

ip -details link show dev tun1
ip tuntap show

最初のコマンドは、カーネルが見ているとおりにリンクを表示します。フラグやインターフェース種別も含まれるので、これが意図したデバイスだと確認できます。二つ目は、どのプロセスも保持していなくても存在する永続的な tun/tap の登録を一覧します。本来の所有者を待っているインターフェースは、別の VPN に接続された生きたトンネルとは異なる状況であり、二つ目だけが自分の接続が失敗する理由を説明します。何かを変更する前に、デバイスを保持しているプロセスを見つけてください。永続的な登録と使用中のインターフェースでは対処が異なります。

マルチキュー対応は固有の要件を持つ特定のドライバー構成であり、無関係なプロセスが一つのインターフェースを共有する許可ではありません。別の所有者の生きたセッションは調整の問題で、プロファイルの編集では解決しません。

二種類の永続性

カーネルの永続性と persist-tun は、混同しやすく取り違えると高くつく寿命を表しています。永続デバイスはどのプロセスからも独立して存在するため、停止を越えて残り、次の起動で再利用できます。persist-tun は一つの OpenVPN プロセス内でサポートされるソフトリセットをまたいでリソースを保持するもので、はるかに短い範囲です。どちらも、サービスを停止してもルートとアドレスがその場に残ることを約束しません。見え続けるインターフェースは、動作する暗号化セッションの証拠ではありません。

バックエンドも確認してください。事前に作成したインターフェースは、どの実装がそれを開くかについて何も語らないからです。直接データパスを備えたコミュニティ版は、設計が別段の定めをしない限りそれを使おうとします。バージョンがこの切り替えに対応している場合、disable-dco は代わりにユーザースペースの経路を選びます。古いエンジンや他のクライアントにはそのようなディレクティブがないので、適用されると決めつけず、バージョンの条件をオプションのそばに置いてください。

起動だけを試すと何が壊れるか

所有の取り決めは最初の試験に通り、最後の試験で失敗することがあります。だからこそ起動だけでは弱い確認になります。代わりに二つの遷移を見てください。ソフトリセットと、完全な停止に続く起動です。

systemctl status openvpn-client@lab
ip -details link show dev tun1

起動は簡単な場合です。ユニットが立ち上がり、リンクが現れ、状態の出力が読み込まれたプロファイルを示します。接続とはデーモンがデバイスを開く瞬間なので、リンクの確認はユニットが稼働中と報告された後に、その前ではなく実行してください。状態がまだ起動処理中ののにリンクが存在するなら、あなたが見ているのはまだ誰も接続していない永続デバイスであり、動作するトンネルではありません。先に進む前に実際のトラフィックをリンクに流してください。使えるルートのない接続済みのインターフェースも、やはり失敗です。

kill -SIGHUP $(pidof openvpn)
journalctl -u openvpn-client@lab -n 40
systemctl stop openvpn-client@lab
ip -details link show dev tun1

ソフトリセットはセッションを使える状態に保ち、リソースを損なわないようにすべきで、それが persist-tun の役割です。完全な停止は、外部のマネージャーが正体を現す場面です。リンクやそのアドレスが停止を越えて残るなら、所有者は別の誰かであり、それは文書化した状態か、たった今見つけた不具合のどちらかです。両方の観察をプロファイルのそばに記録し、次の変更が図ではなく証拠から始まるようにしてください。

関連記事