如何确定源端口以及如何强制它使用特定端口

如何确定源端口以及如何强制它使用特定端口

当我连接到https://www.google.co.uk这更改为 216.58.198.228:443。然后会在 [我的 IP 地址]:63998 上打开与我的连接。

我的问题是如何选择 63998 端口,以及有没有办法强制将其设为 63999。

答案1

本地端口如何确定

端口号是由 TCP 实现软件从一系列端口号中选择出来的,这些端口号称为临时端口

选择端口号和使用范围的具体机制取决于操作系统。


有没有办法强制将其设置为 63999?

这可以通过改变TCP实现软件的配置来实现。

配置说明临时端口适用于各种不同操作系统的更改临时端口范围

  • 以下答案中包含了针对 Linux 和 Windows 的说明,仅供参考。

但是,将范围限制为单个端口并不是一个好主意63999

  • 事实上在 Windows 上这是不可能的,因为:

    可设置的端口最小范围为255。


临时端口范围

TCP/IPv4 连接由两个端点组成,每个端点由一个 IP 地址和一个端口号组成。因此,当客户端用户连接到服务器计算机时,建立的连接可以被认为是 (服务器 IP、服务器端口、客户端 IP、客户端端口) 的四元组。

通常这四个中有三个是众所周知的——客户端机器使用自己的 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 及更新版本:

根据 Microsoft 知识库文章,从 Windows Vista 和 Windows Server 2008 开始,Windows 现在默认使用较大的范围 (49152-65535)929851。同一篇文章还展示了如何根据需要更改范围,但默认范围现在已足以满足大多数服务器的需求。

来源更改临时端口范围

您可以使用以下命令查看运行 Windows Vista 或 Windows Server 2008 的计算机上的动态端口范围 netsh

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 的动态端口范围。起始端口为 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

10999这些示例命令将动态端口范围设置为从端口 10000 开始到端口(1000 端口)结束。

笔记:

  • 可设置的最小端口范围是255
  • 可设置的最小起始端口为1025
  • 最大结束端口(基于正在配置的范围)不能超过65535
  • 要复制 Windows Server 2003 的默认行为,请使用1025作为起始端口,然后使用3976作为 TCP 和 UDP 的范围。这样会得到起始端口为1025和结束端口为5000

来源 Microsoft 知识库文章929851

Windows XP 及更早版本:

对于较旧的 Windows 操作系统(Windows XP 及更早版本),Windows 使用传统的 BSD 范围 1024 到 4999 作为其临时端口范围。不幸的是,您似乎只能设置临时端口范围的上限。以下是摘自 Microsoft 知识库文章的信息196271

  • 启动注册表编辑器 ( Regedt32.exe)。
  • 在注册表中找到以下项:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

  • 在“编辑”菜单上,单击“添加值”,然后添加以下注册表值:

    值名称:MaxUserPort数据类型:REG_DWORD值:(65534例如)

    有效范围:(5000-65534十进制)默认值:(0x1388十进制 5000)

    描述:此参数控制应用程序从系统请求任何可用用户端口时使用的最大端口号。通常,临时(即短暂)端口分配在和10245000含)之间的值。

  • 退出注册表编辑器。

注意:还有另一篇相关的知识库文章 (812873) 声称允许您设置排除范围,这可能意味着您可以排除端口1024-9999(例如)以使临时端口范围为10000-65534。但是,我们无法使其工作(截至 2004 年 10 月)。

来源更改临时端口范围

答案2

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 

这里需要注意一点:由于范围内只有一个端口,另一个应用程序可能会在执行上述第三行和第四行之间将其从您手中夺走;此外,即使没有竞争条件,您也会瘫痪所有其他应用程序,直到您恢复一个大的 EPR,这就是我尽快恢复原始范围的原因。

因此,如果如果 OP 的操作系统是 Linux,那么答案就是这很容易做到。

令人惊讶的是,这在 BSD 上并不那么简单,其中一些甚至没有 EPR 的运行时内核设置。MacOS X、FreeBSD 和 OpenBSD 需要修改文件/etc/sysctl.conf,但对于EPR的选择却有所不同。

不管上述内容和操作系统如何,事实上有些东西完成并不意味着它應該待办事项:你到底为什么需要这个?我想不出一个用例。

答案3

值得补充的是,Linux 内核还具有

net.ipv4.ip_local_reserved_ports

旋钮的作用有些相反,但尽管如此,它可能非常有用,因为这样您就可以为在其他短暂的端口范围内打开特定端口的服务“打一个洞”。

摘录自文档

指定为已知第三方应用程序保留的端口。这些端口不会被自动端口分配使用(例如,当使用端口号 0 调用 connect() 或 bind() 时)。显式端口分配行为保持不变。

输入和输出使用的格式都是以逗号分隔的范围列表(例如,端口 1、2、3、4 和 10 的格式为“1,2-4,10-10”)。写入文件将清除所有先前保留的端口,并使用输入中给出的列表更新当前列表。

相关内容