固定した UDP ポートはポート転送を省けるが、すべての NAT では省けない
両端が一つのポートを固定すると、ステートフルなファイアウォールは相手のパケットを戻りの通信として受け入れます。それが機能する条件と、静かに終わらせるものを示します。
家庭用ルーターが二台、ポート転送はなし、それでも時々つながる VPN。UDP がそれを許すのは、ファイアウォールが、マシンがすでに開始したフローと照合できるパケットを受け入れるからです。これは機能ではなく条件付きの小技で、ファイアウォールが何を比較するかを知れば条件は簡単に言えます。同じプロファイルがネットワークによって違う挙動をする理由もここにあります。
ファイアウォールが行う比較
外向きのデータグラムはそれぞれ短命なエントリを作ります。送信元アドレス、送信元ポート、宛先アドレス、宛先ポートです。エントリに一致するものは応答とみなされて通過します。受信ルールはここには関係しません。
つまり問題は、ファイアウォールが相手を通すかどうかではありません。相手のパケットが、エントリが待っている応答に見えるかどうかです。その四項目のタプルの一つを変えれば、パケットは他人になります。だからポート番号だけが変わると動いていた設定が壊れることがあり、同じポートが一方のルーターでは動き、次のルーターでは失敗するのです。
ローカルの送信元ポートを固定すれば、同じ番号がやり取りの両側に現れます。仕組みはこれだけであり、小技が不思議ではなく脆い理由もここにあります。
両端で一つのポートを固定する
OpenVPN の既定の UDP ポートは1194で、lportが送信元ポートを設定します。両方のピアで固定すれば、それぞれの外向きタプルは相手が待ち受けているポートを指します。
# peer A
lport 1194
remote 198.51.100.20 1194
# peer B
lport 1194
remote 203.0.113.10 1194
これが機能するのは、間にいるどのルーターも送信元ポートを書き換えない間だけです。キャプチャにパケットが現れるのにトンネルが上がらないとき、まず疑うべきは書き換えです。
タプルが一致しなくなる場所
宛先ごとにマッピングする NAT は、ピアごとに異なる外部ポートを割り当てます。ピアに使うよう伝えたアドレスは、実際に届くアドレスではありません。そのため受信パケットはどれとも一致せず、静かに捨てられます。
キャリアグレードの変換、多段 NAT、ポートのランダム化はどれも同じ結末です。アドレスはそのままにポートだけを書き換える中間装置も同じです。
ストリーム系のトランスポートはさらに不利です。TCP のハンドシェイクは段階ごとに追跡されるため、TCP ベースの VPN はこの方法ではまったく穴を開けられず、経路上のどこかに待ち受けが必要です。
通常は片側が先に失敗する
実際には二つのネットワークが同じように振る舞うことはまれです。一方のルーターが予測可能なマッピングを返し、もう一方が宛先ごとのポートを返すと、二つの家庭の間では動くのにモバイル回線からは失敗する設定になります。互いに矛盾する報告は、たいてい二組の異なるルーターを語っています。どちらの書き手も間違っておらず、どちらの結果も一般化できません。
プロファイルに触る前に、どちら側がパケットを落としたのかを突き止めます。両端のキャプチャで一度に決着します。A を出て B に届かないデータグラムは途中でフローが書き換えられたことを意味し、B に届いて応答が返らないデータグラムはファイアウォールが関連づけて受け入れなかったことを意味します。
パブリックな IPv6 アドレスを持つ二つのピアは問題そのものを回避します。変換がなければ照合するものもないので、ピアを名指しするファイアウォールルールで足り、設計はルーターの挙動に依存しなくなります。
いつ試すのをやめるか
パブリックアドレスを持つホストが確実な答えです。両方のピアのためにトンネルを終端することも、互いの現在の外部アドレスを見つける手助けをすることもでき、NAT が何をしていてもどちらの構成も機能します。ポリシーが許せば、管理されたオーバーレイが同じ調整を提供します。
これらのどれもファイアウォールを無効にする必要はありません。直接接続を得るために保護を切るのは、直接の試みが魅力的だった理由を捨てることになり、テストの間ずっとマシンを開いたままにします。
まず直接の構成を試し、それから見たことを記録します。NAT の挙動とそれを示したキャプチャは、最終的に使ったポートの組より価値があります。次のネットワークは違うからです。OpenVPN 2.6 のマニュアルには、lportと、これが依存する remote オプションが記載されています。