12 月 28 日下午,发现 LUG VPN 服务器的 syslog 里开始出现 nf_conntrack: table full, dropping packet 的内核警告。这是由于内核的 TCP/UDP 连接跟踪(conntrack)模块对最大连接数有限制,默认值为 32768。超过这个限制,内核就会丢弃数据包,导致连接无法建立。由于内核对所有网络连接一视同仁,达到最大连接数限制时,甚至可能出现无法 SSH 的情况,是比较危险的。

解决方法是修改 /etc/sysctl.conf,添加


net.ipv4.netfilter.ip_conntrack_max = 655360

然后用 sysctl -p 载入新配置。

两年前科大开源软件镜像(mirrors)的峰值并发连接数也刚刚达到 32768,说明目前 VPN 服务的 TCP/UDP 连接数已经达到两年前 mirrors 的水平。经过了两年的发展,12 月 29 日 23:44,mirrors 有 62733 个连接,这还是在非高峰期。同一时刻,LUG VPN 有 22106 个连接。(conntrack 对去和回来方向分别记录了一次,因此这里看到的 “连接数” 大约是实际连接数的两倍,因此标题中写的是 32768/2 = 16384 个 TCP/UDP 连接)

这 2.2 万个连接来自 168 个 VPN 客户端。目前 LUG VPN 共有 459 个用户,23:59 有 96 人在线(每个用户可能有多个客户端在线)。这些用户共连接了 1871 个不同的 IP 地址。

哪些 VPN 客户端的连接数最多呢?conntrack 是个好东西。

lug@lug-vpn:~$ sudo conntrack -L | awk '{print $5}' | grep 'src=10\.' | sort | uniq -c | sort -nr | head
   8687 src=10.8.0.30
    917 src=10.7.0.65
    799 src=10.8.0.10
    613 src=10.7.0.71
    299 src=10.8.0.16
    214 src=10.8.0.41
    206 src=10.7.0.18
    175 src=10.8.0.42
    175 src=10.7.0.67
    163 src=10.8.0.29

mirrors 上的 6.2 万连接来自 4919 个不同的 IP 地址。如下可见,这些连接中有 29 K 个连到了 mirrors 移动线路,9 K 个连到了电信线路,2 K 个连到了教育网线路。存在个别 IP 向 mirrors 发起数百个连接的情况。

boj@mirrors:~$ sudo conntrack -L | awk '{print $5}' | sort | uniq -c | sort -nr | head
conntrack v1.2.1 (conntrack-tools): 61609 flow entries have been shown.
  28902 src=202.141.176.110
   9499 src=202.141.160.110
   1883 src=202.38.95.110
    869 src=218.68.6.50
    347 src=106.51.241.108
    235 src=1.84.167.85
    227 src=123.65.246.193
    182 src=58.249.125.86
    159 src=1.203.145.10
    157 dst=202.141.160.110

从目标端口来看,LUG VPN 的连接数较为分散,P2P 流量占据了连接数较大的比例。

lug@lug-vpn:~$ sudo conntrack -L | grep ESTABLISHED | awk '{print $8}' | sort | uniq -c | sort -nr | head
   7983 dport=29333
   3106 dport=80
    865 dport=443
    731 dport=20350
    424 dport=4466
    358 dport=8080
     89 dport=8000
     76 dport=993
     48 dport=14000
     42 dport=5223

而 mirrors 连接数的大头显然来自 HTTP。rsync 连接数不多(由于之前我们做了比较严格的限制),FTP 用户也很少。

boj@mirrors:~$ sudo conntrack -L | grep ESTABLISHED | awk '{print $8}' | sort | uniq -c | sort -nr | head
  14935 dport=80
     47 dport=443
     24 dport=873
     14 dport=21
      8 dport=49784
      6 dport=56885
      6 dport=56422
      6 dport=54439
      6 dport=5352
      6 dport=52377