https://www.google.co.ukに接続すると、これは216.58.198.228:443に変わります。次に、[私のIPアドレス]:63998で私への接続が開きます。
私の質問は、63998ポートがどのように選択されるかであり、63999に強制する方法があります。
https://www.google.co.ukに接続すると、これは216.58.198.228:443に変わります。次に、[私のIPアドレス]:63998で私への接続が開きます。
私の質問は、63998ポートがどのように選択されるかであり、63999に強制する方法があります。
回答:
ポート番号は、Ephemeral Portsと呼ばれるポート番号の範囲からTCP実装ソフトウェアによって選択されます。
使用するポート番号と範囲を選択する正確なメカニズムは、オペレーティングシステムに依存します。
これは、TCP実装ソフトウェアの構成を変更することで実行できます。
さまざまなオペレーティングシステム用にエフェメラルポート範囲を構成する手順については、「エフェメラルポート範囲の変更」を参照してください。
ただし、範囲を1つのポートに制限することはお勧めできません(例:)63999
。
実際、Windowsではこれは次のように不可能です。
設定できるポートの最小範囲は255です。
TCP / IPv4接続は2つのエンドポイントで構成され、各エンドポイントはIPアドレスとポート番号で構成されます。したがって、クライアントユーザーがサーバーコンピューターに接続するとき、確立された接続は、4つのタプル(サーバーIP、サーバーポート、クライアントIP、クライアントポート)と考えることができます。
通常、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システムでは範囲を変更する必要はありません。
最後に、ファイルシステム
sysctl
を使用するのではなく、インターフェイスを使用して設定を変更できる場合もあることに注意してください/proc
。sysctl
パラメーターの名前は「net.ipv4.ip_local_port_range」です。/etc/sysctl.conf
ファイルがある場合は編集するか、sysctl
を使用してこのパラメーターを変更する場合は、スタートアップスクリプトにコマンドを手動で実行させますsysctl
。
Windows Vista / Windows Server 2008以降:
Windows VistaおよびWindows Server 2008では、Microsoft Knowledgebase Article 929851に従って、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を実行しているサーバーを展開するMicrosoftのお客様は、内部ネットワークでファイアウォールが使用されている場合、サーバー間のRPC通信で問題が発生する場合があります。
- このような場合は、ファイアウォールを再構成して、動的ポート範囲が
49152
〜のサーバー間のトラフィックを許可することをお勧めします65535
。- この範囲は、サービスおよびアプリケーションで使用される既知のポートに追加されます。
- または、サーバーが使用するポート範囲を各サーバーで変更できます。
netsh
次のコマンドを使用して、この範囲を調整します。netsh int <ipv4|ipv6> set dynamic <tcp|udp> start=number num=range
このコマンドは、TCPの動的ポート範囲を設定します。開始ポートは数値であり、ポートの総数は範囲です。以下はサンプルコマンドです。
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
、開始ポート3976
として使用し、TCPとUDPの両方の範囲として使用します。これにより、開始ポート1025
と終了ポートがになり5000
ます。
Windows XP以前:
古いWindowsオペレーティングシステム(Windows XPおよびそれ以前)の場合、Windowsは一時ポート範囲に1024から4999の従来のBSD範囲を使用します。残念ながら、一時ポート範囲の上限しか設定できないようです。以下は、Microsoft Knowledgebase Article 196271から抜粋した情報です。
- レジストリエディター(
Regedt32.exe
)を起動します。レジストリで次のキーを見つけます。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
[編集]メニューで[値の追加]をクリックし、次のレジストリ値を追加します。
値の名前:
MaxUserPort
データ型:REG_DWORD
値:(65534
例)有効範囲:
5000-65534
(10進数)デフォルト:0x1388
(10進数5000)説明:このパラメーターは、アプリケーションがシステムに使用可能なユーザーポートを要求するときに使用される最大ポート番号を制御します。通常は、(、短命である)エフェメラルポートは、の値の間に割り当てられる
1024
と5000
包括。レジストリエディターを終了します。
注意:他の関連するKB記事(あり812873主張はあなたがポートを除外することができることを意味する可能性が除外範囲、設定することを可能にする)
1024-9999
一時的なポートが可能レンジ持っている(たとえば)が10000-65534
。ただし、これを機能させることはできませんでした(2004年10月現在)。
bind
呼び出す前にアプリケーションがシステムコールを呼び出す方がずっと良いでしょうconnect
。一部のアプリケーションにはオプションがありますが、他のアプリケーションにはありません。
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つあります。範囲内にポートが1つしかないため、別のアプリケーションが上記の3行目と4行目の実行の間にそれを奪う可能性があります。また、競合状態がなくても、大きなEPRを復元するまで他のすべてのアプリケーションを麻痺させます。そのため、できるだけ早く元の範囲を復元しました。
したがって、場合のOPのオペレーティングシステムがLinuxをしていた、その答えは、それが簡単に行うことができるということだったでしょう。
驚くべきことに、これはBSDではそれほど単純ではなく、そのいくつかはEPRの実行時カーネル設定さえもしていません。MacOS X、FreeBSD、およびOpenBSDでは、ファイル/etc/sysctl.confを変更する必要がありますが、EPRには異なる選択肢があります。
かかわらず、上記とOSのの、何かがあるという事実ができて行うことは、それが意味するものではありませんべき行われるように:なぜ地球上であなたはこれが必要なのですか?単一のユースケースを考えることはできません。
BIND_PORT
、コードを元のコードとまったく同じように使用できるように、オプションにすることをお勧めします。私htons(bind_port_env ? atoi(bind_port_env) : 0)
は正しいことをすると思います。
Linuxカーネルも持っていることを追加する価値があります
net.ipv4.ip_local_reserved_ports
少し反対のノブですが、それでも非常に便利な場合があります。そうすると、そうでなければ一時的なポート範囲で特定のポートを開くサービスに「穴を開ける」ことができるからです。
ドキュメントからの短い抜粋:
既知のサードパーティアプリケーション用に予約されているポートを指定します。これらのポートは、自動ポート割り当てでは使用されません(たとえば、ポート番号0でconnect()またはbind()を呼び出す場合)。明示的なポート割り当て動作は変更されていません。
入力と出力の両方に使用される形式は、コンマで区切られた範囲のリストです(ポート1、2、3、4、および10の場合は「1,2-4,10-10」など)。ファイルに書き込むと、以前に予約されたすべてのポートがクリアされ、現在のリストが入力で指定されたもので更新されます。