Linux:跟踪 netstat -s“失败的连接尝试”的来源

Gra*_*lls 5 networking linux tcpip redhat tcpdump

我有几台服务器,其中 netstat -s(来自 /proc/net/snmp)返回的失败连接尝试指标大约每秒增长 1 个,我想诊断这些的来源。

通过使用这个 ipTables 规则(在不同的服务器上):

-A 输出 -p tcp --dport 23 -j 拒绝

我正在阻止传出的 telnet,所以我可以运行这个循环:

虽然是真的;做
telnet www.google.co.uk
netstat -s | grep“连接失败”
完成

正在尝试 209.85.203.94...
telnet:无法连接到远程主机:连接被拒绝
52 次连接尝试失败
正在尝试 209.85.203.94... telnet:无法连接到远程主机:连接被拒绝
53 次连接尝试失败
尝试 209.85.203.94... . telnet:无法连接到远程主机:连接被拒绝
54 次连接尝试失败

因此证明计数器因尝试连接到远程套接字失败而增加。(当然,这并不能证明这是增加的唯一原因)。

问题是,我如何才能找到失败的远程地址和端口(或两者的复数)的特定组合,以便我可以查看下一步;路由/防火墙问题?
顺便说一句,如果我运行这个:

观看 -n1 的 ss | grep "\<23\>"'

我希望看到处于 SYN-SENT 状态的套接字,但没有。这是因为我使用了 REJECT,而不是 DROP?谢谢

Ant*_*lov 4

让我们尝试用另一种方式(困难的方式)来回答这个问题。阅读内核的源代码,看看只有一个地方,这个度量递增 - tcp_done函数。正如我们在代码中看到的,增量仅发生在 SYN_SEND 或 SYN_RECV 状态的连接中。然后我们检查从哪里可以调用 tcp_done。我们可以发现几个地方:

  1. tcp_reset - 在连接中止时调用(收到带有 rst 标志的回复数据包)。是的,它可能发生在 SYN_SENT 和 SYN_RECV 状态(理论上,也可能发生在其他状态)。
  2. tcp_rcv_state_process - 在状态 TCP_FIN_WAIT1 和 TCP_LAST_ACK 中调用,因此度量不会增加 - 这不是我们的情况。
  3. tcp_v4_error - 在 SYN_SENT 或 SYN_RECV 情况下调用。ICMP 处理程序调用的 tcp_v4_error 函数。
  4. tcp_time_wait - 在将套接字移动到 time-wait 或 fin-wait-2 状态时调用 - 也不是我们的情况。
  5. tcp_write_error - 在超时和超出重传计数时从多个位置调用。这也可能是我们的嫌疑人。

现在,打开任何 TCP FSM 图来检查,在什么情况下我们的连接可以处于 SYN_SENT 或 SYN_RECV 状态。

在客户端情况下,它只能是 SYN_SENT 状态,其中 syn 数据包正在传输,并且由于收到拒绝(tcp-rst 或 icmp 错误)或未收到回复而中止连接。

在服务器情况下,它只能是 SYN_RECV 状态(syn 已收到,syn+ack 已发送),并且连接由于接收拒绝而中止(syn+ack 在某处被拒绝)或超过回复等待超时(未收到 ack)已收到)。

现在您知道了此指标更新的原因,并可以在您的系统中检查其可能的来源。在现代内核中,有一个强大的工具可以在内核级别进行故障排除。从 Brendan Gregg 的简短教程开始。