クライアントは接続済みと言い、トンネルのアドレスはpingに応答し、オフィスのLANでは何も応答しない。これはほぼすべてのクライアント更新後に見かけるもので、最初の衝動はファイアウォールを開けることだが、それはたいてい間違った一手だ。トンネルは正常で、断絶はパケットが越えるべき三つのホップのどこかにあり、パケットが通る順に経路をたどれば、クライアントルート、次にサーバーの転送、最後に戻りの経路の順で、数分で原因の持ち主が見つかる。

第一段階:クライアントのルーティング判断を見る

サーバーに触れる前に、クライアントがパケットをトンネルへ送っていることを証明する。テーブル全体を読む代わりに、特定のLANホストに対してカーネルがどのインターフェースを使うかを尋ねる:

ip route get 192.168.50.10

答えが物理アダプターとオフィスのゲートウェイを挙げるなら、サーバー側の変更では何も解決しない。OpenVPNがルートを配るのはサーバーがプッシュしたときだけなので、サーバー設定のpush "route 192.168.50.0 255.255.255.0"を探し、その後でクライアントを再接続する。ほとんどのクライアントはプッシュされたルートを接続時に適用し、プロファイルを読み直したときには適用しない。

Windowsでは同じ問いにも別のコマンドがある。Find-NetRoute -RemoteIPAddress 192.168.50.10はスタックが選ぶインターフェースと次のホップを出力し、route print -4はプッシュされたプレフィックスがそもそも存在するかを見せる。

第二段階:サーバーがパケットを転送することを確認する

クライアントのルートが正しければ、パケットはサーバーに届き、サーバーは転送に同意しなければならない。カーネルのスイッチが最初の関門で、sysctl net.ipv4.ip_forwardが1を返す必要がある。echo 1 > /proc/sys/net/ipv4/ip_forwardで設定しても次の再起動までしかもたず、同じ苦情が数週間後に戻ってくる理由はまさにそこにある。

再起動を生き延びる場所に書き留める:

echo 'net.ipv4.ip_forward = 1' > /etc/sysctl.d/99-openvpn-forward.conf
sysctl --system

第二の関門はフィルターテーブルだ。Dockerが入っているホストはFORWARDポリシーがDROPであることが多く、トンネルはその判断を引き継ぐ。iptables -L FORWARD -v -nはポリシーとパケットカウンターの両方を表示し、ポリシーがDROPなら転送にはトンネルからLANへの向きに明示的な許可がひとつ、応答用にもうひとつ必要だ。

第三段階:パケットをLANまで追い、応答を探す

サーバーの両側を同時に見る。トンネルとLANインターフェースでキャプチャし、ひとつのクライアントとひとつのホストに絞って出力を読みやすく保つ:

tcpdump -ni tun0 host 192.168.50.10
tcpdump -ni eth0 host 192.168.50.10

tun0で現れ、続いてeth0でも10.8.0.xを送信元として現れ、その後に沈黙が続くなら、パケットは届いて応答はどこか別へ行ったということだ。LANホストは既定ゲートウェイに応答し、そのゲートウェイにはVPNプールへのルートがなく、応答はLANルーターで消える。サーバーからLANホストへpingしても、そのトラフィックはトンネルを決して越えないので、この経路については何も証明できない。

第四段階:変換と戻りルートのどちらかを選ぶ

ふたつの修理が穴を塞ぎ、その選択はpingが通るかどうかを超えた影響を持つ。送信元変換はサーバーを見かけ上の送信者にする:

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

ルールをプールとLANインターフェースに限定してから永続化しないと、次のファイアウォール再読み込みが静かに修正を消す。代償は身元で、LANのログやアクセスルールではすべてのクライアントがVPNサーバーに見え、per-client policy becomes guesswork。

LANルーターにVPNサーバーを指す10.8.0.0/24の静的ルートを置けば、クライアントのアドレスは見えたままで、そのルーターが自分のものなら長期的にはこちらが良い答えだ。多くのサイトはしばらく両方を走らせ、応急処置にはNAT、ファイアウォールポリシーを書いた後はルートを使う。サーバーがプールではなく拠点間のピアなら、サーバー側にもリモートサブネット用のirouteが必要で、そうでなければピアルートは存在してもクライアントのトラフィックが結び付かない。

第五段階:クライアントから検証し、何が変わったかを記録する

ループはサーバーではなくクライアント側で閉じる。LANホストの実サービスに接続し、そのうえでiptables -t nat -L POSTROUTING -v -nを使って変換カウンターが動いたことを確認する。パケットがゼロのルールは一度も一致しなかったルールなので、戻り方向が追跡されている証拠が要るときは、conntrack -L -s 10.8.0.5がフローとその状態を示す。

サーバー設定に、どのサブネット、どのインターフェース、どのルール、そしてLANルーターが戻りルートを持っているかというメモを残す。次にクライアント更新がプッシュされたルートを消したとき、そのメモが消火作業を一行の修正に変える。

関連記事