web-dev-qa-db-ja.com

送信元ポートはどのように決定されますか。また、特定のポートを使用するように強制するにはどうすればよいですか。

https://www.google.co.uk に接続すると、これは216.58.198.228:443に変わります。それから私への接続は[My IP Address]:63998で開かれます。

私の質問は、63998ポートがどのように選択されているか、そしてそれを強制的に63999にする方法があることです。

26
TheGathron

ローカルポートはどのように決定されますか

ポート番号は 一時ポート と呼ばれるポート番号の範囲からTCP実装ソフトウェアによって選択されます。

使用するポート番号と範囲を選択するための正確なメカニズムは、オペレーティングシステムによって異なります。


63999になるように強制する方法はありますか。

これはTCP実装ソフトウェアの設定を変更することで実行できます。

さまざまな異なるオペレーティングシステム用に 一時ポート 範囲を設定する方法については、 を参照してください。一時ポート範囲の変更 .

  • 参考のために、以下の回答にLinuxおよびWindowsの手順を示しています。

ただし、63999のように範囲を単一のポートに制限することはお勧めできません。

  • 実際、Windowsではこれは不可能です。

    設定できるポートの最小範囲は255です。


エフェメラルポート範囲

TCP/IPv4接続は2つのエンドポイントで構成され、各エンドポイントはIPアドレスとポート番号で構成されています。したがって、クライアントユーザーがサーバーコンピュータに接続するとき、確立された接続は(サーバーIP、サーバーポート、クライアントIP、クライアントポート)の4タプルと考えることができます。

通常、4つのうち3つはすぐにわかります。クライアントマシンは独自のIPアドレスを使用し、リモートサービスに接続するときにはサーバーマシンのIPアドレスとサービスポート番号が必要です。

すぐにはわかりませんが、接続が確立されたときに、接続のクライアント側がポート番号を使用しているということです。クライアントプログラムが特定のポート番号を明示的に要求しない限り、使用されるポート番号は一時的なポート番号です。

一時ポートは、マシンのIPスタックによって割り当てられる一時的なポートであり、この目的のために指定された範囲のポートから割り当てられます。接続が終了すると、エフェメラルポートは再利用可能になりますが、ほとんどのIPスタックは、エフェメラルポートのプール全体が使用されるまでそのポート番号を再利用しません。

そのため、クライアントプログラムが再接続すると、新しい接続の側には異なる一時ポート番号が割り当てられます。

出典 エフェメラルポート範囲


エフェメラルポート範囲の変更

Linux:

Linuxでは、ファイル/proc/sys/net/ipv4/ip_local_port_rangeを使用するだけでエフェメラルポート範囲を表示および変更できます。たとえば、これはカーネル2.2システムのデフォルト設定を示しています。

$ cat /proc/sys/net/ipv4/ip_local_port_range 
1024 4999

これを優先範囲に変更するには、(スーパーユーザーとして)次のようにします。

# echo "49152 65535" > /proc/sys/net/ipv4/ip_local_port_range 

システムを起動するたびにこれを実行する必要があるので、/etc/rc.localなどのシステム起動スクリプトに行を追加して、常に範囲を使用するようにしてください。

また、十分なカーネルメモリが利用できる場合、Linux 2.4カーネルは32768から61000までの範囲をデフォルトにするので、範囲を変更することは新しいLinuxシステムでは必要ないかもしれないことに注意してください。

最後に、/procファイルシステムを使用するのではなく、sysctlインターフェースを使用して設定を変更できることもあります。 sysctlパラメータの名前は "net.ipv4.ip_local_port_range"です。 /etc/sysctl.confファイルがある場合は編集します。sysctlを使用してこのパラメータを変更する場合は、スタートアップスクリプトでsysctlコマンドを手動で実行します。

Windows Vista/Windows Server 2008以降:

Microsoft Knowledgebase Article 929851 によると、Windows VistaおよびWindows Server 2008以降、Windowsはデフォルトで広い範囲(49152-65535)を使用します。同じ記事には、必要に応じて範囲を変更する方法も示されていますが、ほとんどのサーバーではデフォルトの範囲で十分です。

送信元 エフェメラルポート範囲の変更

次のnetshコマンドを使用して、Windows VistaまたはWindows Server 2008コンピューターを実行しているコンピューターで動的ポート範囲を表示できます。

netsh int ipv4 show dynamicport tcp
netsh int ipv4 show dynamicport udp
netsh int ipv6 show dynamicport tcp
netsh int ipv6 show dynamicport udp 

ノート:

  • 範囲はトランスポートごとおよびIPのバージョンごとに別々に設定されます。
  • ポート範囲は、始点と終点のある範囲になりました。
  • ファイアウォールが内部ネットワークで使用されている場合、Windows Server 2008を実行しているサーバーを展開するマイクロソフトのお客様は、サーバー間のRPC通信に問題がある可能性があります。
  • このような場合は、動的ポート範囲が49152から65535のサーバー間のトラフィックを許可するようにファイアウォールを再構成することをお勧めします。
  • この範囲は、サービスおよびアプリケーションによって使用される既知のポートに追加されています。
  • または、サーバーが使用するポート範囲を各サーバーで変更することもできます。

次のようにnetshコマンドを使用してこの範囲を調整します。

netsh int <ipv4|ipv6> set dynamic <tcp|udp> start=number num=range

このコマンドは、TCPの動的ポート範囲を設定します。開始ポートはnumber、ポートの総数はrangeです。以下はサンプルコマンドです。

netsh int ipv4 set dynamicport tcp start=10000 num=1000
netsh int ipv4 set dynamicport udp start=10000 num=1000
netsh int ipv6 set dynamicport tcp start=10000 num=1000
netsh int ipv6 set dynamicport udp start=10000 num=1000

これらのサンプルコマンドは、動的ポート範囲をポート10000から開始してポート10999(1000ポート)で終了するように設定します。

ノート:

  • 設定できるポートの最小範囲は255です。
  • 設定できる最小開始ポートは1025です。
  • 最大エンドポート(設定されている範囲に基づく)は65535を超えることはできません。
  • Windows Server 2003のデフォルトの動作を複製するには、開始ポートとして1025を使用し、次にTCPとUDPの両方の範囲として3976を使用します。これにより、開始ポートは1025、終了ポートは5000になります。

マイクロソフトサポート技術情報の記事 929851

Windows XP以前:

古いWindowsオペレーティングシステム(Windows XP以前)の場合、Windowsは一時ポート範囲として1024から4999までの従来のBSD範囲を使用します。残念ながら、一時ポート範囲の上限しか設定できないようです。これが、マイクロソフトサポート技術情報の記事 196271 からの抜粋です。

  • レジストリエディタ(Regedt32.exe)を起動します。
  • レジストリで次のキーを見つけます。

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

  • [編集]メニューの[値の追加]をクリックして、次のレジストリ値を追加します。

    値の名前:MaxUserPortデータ型:REG_DWORD値:65534(たとえば)

    有効範囲:5000-65534(10進数)デフォルト:0x1388(10進数5000)

    説明:このパラメータは、アプリケーションがシステムから利用可能なユーザーポートを要求するときに使用される最大ポート番号を制御します。通常、短命の(つまり、短命の)ポートは、10245000の値の間に割り当てられます。

  • レジストリエディタを終了します。

注:除外範囲を設定できると主張する関連のKB記事( 812873 )がもう1つあります。これは、ポートを除外できることを意味する可能性があります1024-9999(たとえば、一時ポート範囲を10000-65534にするには、ただし、これを機能させることはできませんでした(2004年10月現在)。

送信元 エフェメラルポート範囲の変更

37
DavidPostill

David Postillの答えは完全に正しいです。それに加えて、Linuxで一時ポートの範囲を変更するのはとても簡単で、OPには肯定的な答えがあることを強調しておきます。

次のようにEPRを変更します。

echo "40000 60000" > /proc/sys/net/ipv4/ip_local_port_range 

次のスクリプトで(例として)ポート50000を選択できます。

OLD_RANGE=$(cat /proc/sys/net/ipv4/ip_local_port_range)
MY_PORT=50000
echo "$MY_PORT $MY_PORT" > /proc/sys/net/ipv4/ip_local_port_range
Sudo -u SomeUser SomeApplication  & 
echo $OLD_RANGE" > /proc/sys/net/ipv4/ip_local_port_range 

ここで注意すべき点が1つあります。範囲内には単一のポートがあるため、上の3行目と4行目の実行の間に別のアプリケーションがそれをあなたから奪う可能性があります。また、競合状態がなくても、大きなEPRを復元するまで他のすべてのアプリケーションを麻痺させるため、できるだけ早く元の範囲に戻しました。

したがって、OPのオペレーティングシステムがLinuxの場合、答えは簡単に実行できると考えられます。

驚くべきことに、これはBSDではそれほど簡単ではありません。その中にはEPR用のランタイムカーネル設定さえ持っていないものがあります。 MacOS X、FreeBSD、およびOpenBSDでは、ファイル/ etc/sysctl.confを変更する必要がありますが、EPRにはさまざまな選択肢があります。

上記にもOSにもかかわらず、何かできるという事実は、ができるべきではない:なぜあなたは地球上でこれが必要ですか?単一のユースケースは考えられません。

8
MariusMatutiae

Linuxカーネルにもあることを付け加える価値があります

net.ipv4.ip_local_reserved_ports

やや反対の動作をしますが、それでもやはり一時的な範囲のポートで特定のポートを開くサービスに対して「穴を開ける」ことができるので非常に便利です。

ドキュメントからの抜粋

既知のサードパーティアプリケーション用に予約されているポートを指定します。これらのポートは自動ポート割り当てでは使用されません(例:ポート番号0でconnect()またはbind()を呼び出すとき)。明示的なポート割り当て動作は変わりません。

入力と出力の両方に使用されるフォーマットは、カンマで区切られた範囲のリストです(例えば、ポート1、2、3、4、および10の場合は「1,2-4、10-10」)。ファイルに書き込むと、以前に予約されたすべてのポートがクリアされ、現在のリストが入力で指定されたもので更新されます。

0
poige