同じ会話に二つの番号が現れ、どちらも間違いではありません。サーバーのログにはサービスを提供する待ち受けが、ノート PC にはデータグラムを送ったソケットが表示され、その間のルーターが送信時に二つ目の番号を書き換えることがあります。数字そのものを比べるより、会話の両端を比べるほうが役に立ちます。以下の比較では待ち受け、クライアントのソケット、変換後の送信元を分けて扱います。それぞれが別の問いに答えるからです。

相反する両端を表す二つの番号

サーバー側で設定されたポートは、クライアントが接続する宛先です。ポリシーで固定され、プロファイルに現れ、サーバー側で開いている必要があります。クライアントの送信元ポートはローカルで選ばれ、通常は一時ポート範囲から取られ、応答が戻る先を用意するために存在します。再接続のたびに変わり得て、設計のどこもその安定性を前提にしていません。

途中のルーターはその送信元を自分の 'NAT' 変換に書き換えることがあります。そのためサーバーで見える番号が、ノート PC が選んだ番号と関係しないことは珍しくありません。

送信元の番号が送出時に変わる場所

架空の IPv4 の例を考えます。変換するルーターの背後にいるクライアント、一つの 'UDP' 待ち受けを持つサーバー、両方を通る一つのデータグラムです。表は三つの観測点でパケットを再生するのではなく、各端点とそこで起きることを名指しします。

EndpointWhat stays fixedWhat changes on reconnectWho owns it
Server listenerThe service port and the address the profile namesNothing; the listener does not follow the clientThe server operator
Client socketThe destination it dialsThe local source port, chosen per socketThe client, or its operating system
Translated sourceUsually the public address of the routerThe port, and sometimes the address after a network switchThe NAT device or the upstream carrier

宛先はどの行でも一定で、変わるのは送信元の身元だけです。UDP NAT の要件は、内部のアドレスとポートを外部の変換と区別しており、これが二行目と三行目の違いそのものです。ルーターはクライアントの送信元ポートを保つことも、別のものを選ぶこともあります。保たれることをアプリケーションが前提にしてはいけません。

三つの端点をホスト自身から読む

以下の一覧は三台の異なるマシンから取ったもので、合わせて会話全体を示します。一つ目はサーバーで、二つ目はクライアントで、三つ目は変換が存在する場所で実行します。一行のログで三つすべてが分かることはありません。

ss -lunp 'sport = :1194'
ss -unp | grep 1194
conntrack -L -p udp | grep 1194

一つ目の一覧は、サーバーがサービス用ポートに束縛され、どのプロセスが所有しているかを示します。二つ目はクライアントのローカルソケットと、接続した宛先を示します。三つ目はルーターが作った変換を示し、変換後の送信元が現れる唯一の場所です。この順に読めば、二つの番号は矛盾して見えなくなります。

再接続が変えるもの、変えないもの

空いていれば送信元ポートを保つルーターもあれば、毎回別のポートを割り当てるルーターもあります。どちらも正常で、前者を必須とするアプリケーションは後者で壊れます。再接続やネットワーク切り替えの後の変換の変化はサーバーの障害ではありません。クライアントが新しいソケットを開き、ルーターが持っているものを割り当て、サーバーは同じ待ち受けで新しい送信元を見ます。障害といえるのは、任意のクライアントポート宛ての通信をサーバーが受け入れると期待することです。

コミュニティの OpenVPN クライアントは nobind によってこの動作を得ます。ローカルポートの選択を OS に任せる設定で、リモートポートは依然としてプロファイルから来ます。明示的に束縛するのは意図的な選択であり、プロトコルの要件ではありません。サーバーは一つの端点を提供し続け、クライアントはそれぞれのローカルな身元を選びます。

記録では層を分けてラベルを付ける

トンネルの内側には独自のポートを持つ二つ目の会話があります。トンネルが運ぶ HTTPS 要求の宛先は TCP 443 で、外側の暗号化接続は UDP 1194 を使うため、外側の送信元ポートを変えても内側のサービスには何の影響もありません。

外側の層でもプロトコルは重要です。UDP 1194 と TCP 1194 は別の端点であり、番号が一致するからといって 'TCP' の待ち受けが UDP のデータグラムを受け取ることはありません。配備を文書化するときは、サーバーの待ち受け、クライアントのソケット、変換後の送信元を三つの別物としてラベル付けし、それぞれにトランスポートを添えてください。

そのうえでポリシーを役割に従わせます。サーバーは待ち受けで想定したトランスポートを開き、相手の認証も行います。クライアントのファイアウォールは、内向きのサービスを公開せずに、自分の外向きのやり取りへの応答を通します。ステートレスなフィルターには戻り方向を明示する必要があり、整った図の外でもこの区別が重要になる実務上の理由はそこにあります。

関連記事