Linuxnetworking端口耗尽

我已经做了尽可能多的研究,而不用在内核源代码中进行挖掘。 关于这个问题似乎有大量的虚假信息/不正确的信息,所以我希望这个答案为我和其他人一劳永逸。

严格的讲IPv4,实际上是端口耗尽的可能吗? 让我解释:

  • 貌似有65535个端口可供使用。 0不可用。
  • 我已经读过,端口耗尽需要(src ip,src端口,dst ip,dst端口)元组是唯一的。
  • 要清楚,并假设我可以通过sysctl net.ipv4.ip_local_port_range设置使用100%的临时端口

这就是问题:这是如何工作的?

  • 我可以从127.0.0.1:(x)到127.0.0.1:80有65k连接
  • 我可以从127.0.0.1:(x)到127.0.0.1:555有65k连接
  • 基本上再一次,问题是(srcip,srcport,dstip,dstport)必须是唯一的,正确的?
  • 我无法打开 IP“A”到IP“B”,端口“N”
  • 同样,一个IP不能打开超过65k连接到我的web服务器在xxxx:80,但是我可以支持多于65k整体,只要他们来自不同的来源IP

最后,我对输出的临时端口和正在监听的input端口有些困惑。 我意识到一旦build立连接,连接的每一边都是对等的,但在此之前:

例如,如果确实(srcip,srcport,dstip,dstport)元组必须是唯一的,为什么如果我启用,例如

net.ipv4.ip_local_port_range = 1024 65535 

它允许使用从1024-65535的短暂端口,如果我的服务绑定在端口3306上(例如mySQL),它们有时会因端口正在使用而无法启动。

这与这个事实有关:(这是我要求validation的一个陈述):

  • (srcip,srcport,dstip,dstport)对端口范围1-65535的每个连接都是唯一的(不注意操作系统使用临时端口)
  • 但是,对于要绑定的套接字,可以将其视为(srcip,srcport,*,*)。 或者另一种方式来说明,是否IP不能以任何理由使用该端口绑定?

我可以validation上述行为,即我使用上面的确切的sysctl行,因为它我把mySQL移动到一个低于1024的端口,因为它会偶尔和非常随机地重新启动,因为假设操作系统使用该端口(3306)为一个短暂的港口。

这里有两个主要的问题:

1。

严格的讲IPv4,实际上是端口耗尽的可能吗?

是。 以负载平衡路由器为例,将所有连接发送到NAT IP地址。 当您有许多SRC IP连接到单个DST IP的瓶颈时,可能会发生这种情况。

这意味着您的networking服务器可能有一堆连接,如:

 root@buglab:~# netstat -pnt Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 173.200.1.18:80 10.100.1.100:49923 ESTABLISHED 13939/nginx: worker tcp 0 0 173.200.1.18:80 10.200.1.200:10155 ESTABLISHED 13939/nginx: worker tcp 0 0 173.200.1.18:80 10.10.1.10:14400 ESTABLISHED 13939/nginx: worker tcp 0 0 173.200.1.18:80 10.10.1.10:50652 ESTABLISHED 13939/nginx: worker tcp 0 0 173.200.1.18:80 10.20.1.20:57554 ESTABLISHED 13939/nginx: worker 

这很好。 但是,如果所有的“外部地址”都是相同的,这可能会导致一个问题(例如,“一个IP地址执行NAT的大型路由器”)。

如果我不得不假设为什么短暂的端口耗尽不是一个普遍的问题,我build议这是因为每个端口都需要一个监听服务和足够的资源来响应 – 另一个资源(内存,CPU)通常是第一个瓶颈。

但是,在负载均衡公司工作时,我亲自遇到了一些端口耗尽问题。

2.为什么使用的端口可能会出现聆听服务的问题?

“这允许使用从1024-65535的短暂端口,如果我的服务绑定在端口3306上(例如mySQL),它们有时会因为端口正在使用而无法启动。

如果mySQL服务器正在使用,则不能绑定到该端口 – 比如localhost:3306或所有接口。 例如,请参阅以下netstat输出中的0.0.0.0:80行?

 root@buglab:~# netstat -lnp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 964/php-fpm.conf) tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 1660/mysqld tcp 0 0 0.0.0.0:842 0.0.0.0:* LISTEN 1317/inetd tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 13938/nginx 

这意味着端口80正在监听服务器本地的所有接口。 如果另一个进程在我的nginx服务器启动之前持有端口80,那么nginx将无法控制该端口,并且可能会失败其启动过程。

通常情况下,端口3306是好的,因为侦听服务具有从主机请求的预定义的端口(或范围) – 例如用于web服务器的端口80和443。