NATがマシンのTCPおよびUDPポートプールからポートを予約しないのはなぜですか?


8

私は2つの実験を行いました。これは、両方のネットワークです。

        [private network]     [public network]
    A -------------------- R ----------------- B
192.168.0.5     192.168.0.1|192.0.2.1       192.0.2.8

AのデフォルトゲートウェイはRです。RにはIPv4転送がアクティブで、次のiptablesルールがあります。

iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 50000

その意図は、Aから TCPはすべて、Rのポート50000 を使用して192.0.2.1としてマスクされることです。

を使用して、Bのポート60000にTCPサービスを公開しましたnc -4l 192.0.2.8 60000

次に、Aから接続を開きました。nc -4 192.0.2.8 60000

Aはこのように見えたパケットの送信を開始しました:

192.168.0.5:53269 -> 192.0.2.8:60000

Rはそれを

192.0.2.1:50000 -> 192.0.2.8:60000

ここまでは順調ですね。

私はその後に、次のクライアントを開こうとしたRnc -4 192.0.2.8 60000 -p 50000。メッセージを送信しましたが、何も起こりません。Rのtcpdumpでパケットを確認できません。

マスカレードルールが存在するため、または少なくともアクティブであるため、Rのncがエラーメッセージ「nc:Address already in use」で失敗すると予想していました。これは、2つのncを同じポートにバインドした場合に発生します。

それから私はしばらく待ったので、conntrackのマッピングは死んでしまいました。

2番目の実験は、Rのクライアントを最初に開こうとする私から成っていました。RBとうまく話し始めます。次にAから接続を開くと、そのパケットは無視されます。AのSYNはRに到着しますが、ICMPエラーによっても応答されません。これがRがマスカレードポートを使い果たしたことがわかっているためか、Linuxが完全に混乱しているためか(技術的にはポートをマスクしていますが、すでに確立されている接続が何らかの形で干渉しているため)かどうかはわかりません。

NATの動作は間違っていると感じます。マスカレード(特に、--to-portsiptablesルールで指定しないこと)とサービスの両方のポートを誤って構成してしまう可能性があり、カーネルが接続をサイレントにドロップします。また、このドキュメントはどこにも記載されていません。

例えば:

  • ABに通常の要求を行います。ポート50kを使用するRマスク。
  • ARに DNSクエリを作成します。ことであるTは再帰的であり、R(薄手の一致のうち、エフェメラルポート50Kを使用して)クエリ権威あるネームサーバZポート53に。

衝突が発生しました。Rは2つの個別のTCP接続にポート50kを使用しています。

通常、ルーターでサービスを公開しないためだと思います。しかし、もう一度言いますが、TCPポートプールがアクティブにマスカレードされたときに、カーネルがTCPポートプールからポートを「借りる」のは難しいのでしょうか。

エフェメラルポートをから分離できることはわかってい--to-portsます。ただし、これはデフォルトの動作ではないようです。NATとエフェメラルポートはどちらもデフォルトで32768〜61000であり、これは気味が悪いです。

(私は/ proc / sys / net / ipv4 / ip_local_port_rangeをクエリすることで一時的な範囲を、別の実験で多数のUDPリクエストを単純にNAT処理してNAT範囲を見つけ、サーバー側でソースポートを出力しました。見つかりませんでした。 iptablesを使用して範囲を印刷する方法。)


2
NATがエセメラルポート範囲を使用するのはなぜ不気味なのですか?AのクライアントがRでも使用されているエセメラルポートを使用すると、新しいポートにNAT変換されます。そして、なぜRでDNSやDHCPのようなサービスを持つことは、これで何かしなければならないのですか?DNSおよびDHCPは、(サーバー側の)一時ポートを使用しません。そして、なぜマスカレードに単一のポートのみを使用するのですか?
Thomas Erker、2015

@Thomas:あなたの質問は実際に私を正しい方向に導いてくれました、そして私は非常にありがたいですが、あなたも少し誤解を持っているようです:AのクライアントがRでも使用されている一時ポートを使用する場合、それは必ずしもそうではありません新しいものにNAT変換されます。NATはTCP / UDPポートプールをクエリしません。実際に、NAT接続の衝突は正常で無害であることに気づきました。私の答えを見てください。
Yd Ahhrk 2015

@トーマス:私はDHCPを考えていませんでした。私は実際にDNSについて考えていました。DNSが再帰的なネームサーバーである場合(信頼できるものをクエリするため)、DNSは一時的なポートを使用すると思います。私の編集を参照してください。
Yd Ahhrk 2015

@Thomas:実験全体は、衝突があったときに何が起こるかを確認することを目的としています。一時的な範囲を1つのポートに減らして、衝突を強制しました。
Yd Ahhrk 2015

回答:


2

TCPポートプールがアクティブにマスカレードされたときに、カーネルがポートをTCPポートプールから「借用」するのに悪影響はありますか?

答えは「いいえ、でも大した問題ではない」でしょう。

私は誤って、Rが応答パケットの宛先トランスポートアドレスのみを使用して、それがAに向けられたのかそれ自体に向けられたのかを伝えるだけであると想定しました。実際には、ソースと宛先のトランスポートアドレスタプル全体を使用して接続を識別しているようです。したがって、NATが同じ(R所有)ポートを使用して複数の接続を作成するのは実際には正常です。混乱を招くことはありません。したがって、TCP / UDPポートプールは重要ではありません。

私がそれについて考えたのは今やかなり明白です。

私はその後に、次のクライアントを開こうとしたRnc -4 192.0.2.8 60000 -p 50000。メッセージを送信しましたが、何も起こりません。Rのtcpdumpでパケットを確認できません。

これは私が失敗した実験の一部です。

送信元アドレス宛先トランスポートアドレスが同じであるだけでなく、送信元アドレス宛先トランスポートアドレスが同じであるため、失敗が発生します。

私が言うならnc -4 192.0.2.8 60001 -p 50000、それは実際に機能します。NATマスクと同じポートを使用している場合でも。

NATの動作は間違っていると感じます。マスカレード(特に、--to-portsiptablesルールで指定しないこと)とサービスの両方のポートを誤って構成してしまう可能性があり、カーネルが接続をサイレントにドロップします。

マスクされた接続とRで開始された接続の宛先は異なる可能性が高いため、そうなりません。

マスカレードルールが存在するため、または少なくともアクティブであるため、Rのncがエラーメッセージ「nc:Address already in use」で失敗すると予想していました。これは、2つのncを同じポートにバインドした場合に発生します。

私はまだこれに対する完全な答えを探していますが、すべてが「それがどのように実装されているかは悪影響であり、私たちがそれを受け入れようとするのは非常に小さい」と指摘しているようです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.