OpenVPN のプロセスが二つ、ローミング ユーザーを受け入れながら上流プロバイダーにも到達する Pi 上で動いており、ハードウェア以外はほとんど何も共有していません。一方は受信トンネルを待ち受け、もう一方は外向きに発信します。それぞれが自分のディレクトリを読み、それぞれに独自の障害の仕方があります。間違ったほうを再起動することが、クライアントの修正が代わりにリスナーを揺さぶってしまう最も一般的な原因です。

ユニット名と、それが読み込むディレクトリを対応させる

Upstream 2.6 は二つのテンプレート ユニット、[email protected] と [email protected] を提供します。サーバーのテンプレートは /etc/openvpn/server で起動し、そこから %i.conf を読み込みます。クライアントのテンプレートは /etc/openvpn/client で起動します。roaming という名前のインスタンスは、サーバーとしてもクライアントとしても、両方の場所に同時に存在でき、二つの無関係な設定を持ち、文字列以外に両者をつなぐものはありません。

ファイルシステムではなく systemd に尋ねてください。パッケージ作成者が、作業ディレクトリやバイナリが受け取る引数を変えうる追加ファイルを入れるからです。

systemctl list-units --type=service 'openvpn-*@*'
systemctl cat [email protected]
systemctl show -p WorkingDirectory -p ExecStart [email protected]

最初のコマンドは、失敗して読み込まれたまま残ったものも含め、生成されたすべてのユニットを一覧します。二番目はユニット ファイルを上書き設定とともに出力します。三番目は、この問いを決める二つの事実、つまりプロセスが起動するディレクトリと、渡された設定パスを最短で見る方法です。

パケットの方向で判断し、インターフェース名では判断しない

サーバー インスタンスは待ち受けソケットを持ち、接続を受け入れます。その暗号化トランスポートは Pi 上ではローカルの入力と出力ですが、ユーザーのために転送するトラフィックは転送経路を通り、別の規則群に従います。クライアント インスタンスにはその意味でのリスナーがありません。相手に発信するので、暗号化トランスポートは下位層へ向かうローカルの出力です。

その違いが、ある規則がどこに属するかを教えてくれます。転送チェーン内のインターフェースに一致する規則は、ルーティングがすでに選んだトラフィックを許可するだけで、経路を選ぶことは決してありません。ローミング ユーザーのパケットが誤った道から出ていくとき、調べるべきチェーンは forward であり、output ではありません。

理論を語る前にソケットを見てください。udp/1194 に束縛されたサーバーは待ち受けソケットを示します。クライアントはプロバイダーのアドレスへの関連を示し、待ち受けているものは何もありません。

ss -lunp | grep openvpn
ss -unp state established '( dport = :1194 or sport = :1194 )'

一方のインスタンスの既定ルートが他方の応答を奪うことがある

上流クライアントが押し込む redirect-gateway は、マシン上の他のすべてと競合する既定ルートを設定します。その中には サーバーがローミング ユーザーへ送る応答も含まれます。OpenVPN はトンネルが到達可能であり続けるよう、自分のピア アドレスに例外を設けますが、その例外はホテルのネットワーク上にある携帯電話については何も語りません。

症状はたいてい非対称です。ハンドシェイクが完了し、クライアントは接続済みと報告し、最初の応答パケットの後にトラフィックが死にます。送信元ベースのポリシー ルーティング、またはサーバー インスタンスに --mark で付けたパケット マークが、二つの流れを切り離します。どちらも単独では完全な規則群ではなく、どちらも選択したテーブルに有効な経路を必要とします。

トンネルの状態ではなくローカルの判断を試してください。カーネルは OpenVPN がパケットを見る前に送信元とインターフェースを選ぶからです。

ip route get 203.0.113.44
ip rule show

一方の役割を再起動し、もう一方が生き残ったことを証明する

両方の役割が同じ下位層に依存するときは順序が重要です。ユーザーのトラフィックを転送できるようになる前に上流経路が必要ならクライアントを先に再起動し、リスナーやプールだけを変えるならサーバーを先に再起動します。いずれにせよ後で両方のユニットを確認してください。失敗した再起動は、もう一方の役割を古い状態のまま動かし続けることがあるからです。

変更の前に停止条件を書き留めてください。上流トンネルを失うとローミング ユーザーは遮断されるのか、それとも Pi 自身の上りリンクに戻るのか。DNS と IPv6 にも明示的な答えが要ります。押し込まれたリゾルバーは、それを役立てた経路より長く生き残ることが多いからです。

systemctl restart [email protected]
systemctl is-active [email protected]
journalctl -u [email protected] -n 20 --no-pager

次の三つが同時に成り立つときだけ変更を受け入れてください。新しい受信接続が完了し、転送されたアプリケーションが意図した出口から宛先に届き、両方のプロセスが今も期待どおりのピアを報告していることです。三つのうち一つが失敗したら、間違ったインスタンスか間違った経路を変えたのであり、次の手順はほかを再起動することではなくユニットを読み直すことです。

関連記事