哪个 Linux 进程负责响应 ping?

哪个 Linux 进程负责响应 ping?

我有一个基于 Linux 的进程控制器,有时会锁定到无法 ping 它的程度(即我可以 ping 它,然后在不对网络设置进行任何修改的情况下,它就不再可 ping 通)。

我很好奇,哪个进程/系统负责实际响应 ping?看来这个进程正在崩溃。

答案1

内核网络堆栈正在处理 ICMP 消息,这些消息是由ping命令发送的。

如果您没有得到回复,除了网络问题或过滤,以及基于主机的过滤/速率限制/黑洞/等。这意味着机器可能因某些原因而过载,这可能是暂时的,或者内核崩溃,这种情况很少见,但可能会发生(硬件故障等),不一定是因为 ICMP 流量(但试图用此类流量使其过载)可以在服务器生命周期之初进行很好的测试,看看它如何维持事物)。在后一种内核崩溃的情况下,您应该在日志文件或控制台上有足够的信息。

另请注意,ping检查服务是否在线的工具几乎总是错误的。出于多种原因,但主要是因为根据定义,它没有模拟真实的应用程序流量。例如,如果您需要检查网络服务器是否仍处于活动状态,则应该对其执行 HTTP 查询(TCP 端口 80 或 443),如果您需要检查邮件服务器,则执行 SMTP 查询(TCP 端口 25),如果DNS 服务器、UDP对端口 53 等的 TCP 查询

答案2

没有用户态进程负责响应 ping。 Ping 只是发送 ICMP 回显数据包的实用程序。这些由内核的网络堆栈接收和处理

答案3

内核本身(不是任何用户进程)负责发送ICMP 回显回复回复消息ICMP 回显请求消息。因此,如果主机停止响应 ping,通常是由于以下原因造成的:

  • 您和被 ping 的主机之间的网络连接可能已被切断。这可能是由于多种原因本身造成的:电缆的物理损坏、无线情况下的噪音、路由表损坏、您受到 DDoS 攻击、中间的路由器/交换机有问题等。在这种情况下,您可以通过以下方式开始故障排除在目标主机上使用ethtool(8)iwconfig(8)route(8)ping(8)其路由器等。tcpdump(8)

  • 目标主机(或您和目标主机之间的任何路由器/防火墙)上的防火墙设置可能会限制 ping 数量(或流量流量)。这也可能是由于fail2ban(8)按需防火墙之类的工具造成的。看看iptables(8)检查一下。

  • 目标主机出现软件/硬件故障。目标主机上的网络内核模块可能发生 OOPSed 和/或变得混乱,甚至整个内核可能发生 PANICked。您将在目标主机上看到有关 at in 的消息dmesg(8),或者在物理控制台上看到屏幕输出(如果物理访问不切实际,则可以使用另一台具有串行控制台可以提供帮助。)如果内核 OOPS/PANIC 是问题所在,具有更好驱动程序的更新内核可能会有所帮助,或者您可以使用watchdog(8)辅助驱动程序来解决系统锁定问题。或者您可以更换硬件部件。

答案4

一种让自己相信 Linux 内核直接处理它的有趣方法是观察它的内核设置:

tail /proc/sys/net/ipv4/icmp*

可能会输出类似以下内容:

==> /proc/sys/net/ipv4/icmp_echo_enable_probe <==
0

==> /proc/sys/net/ipv4/icmp_echo_ignore_all <==
0

==> /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts <==
1

==> /proc/sys/net/ipv4/icmp_errors_use_inbound_ifaddr <==
0

==> /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses <==
1

==> /proc/sys/net/ipv4/icmp_msgs_burst <==
50

==> /proc/sys/net/ipv4/icmp_msgs_per_sec <==
1000

==> /proc/sys/net/ipv4/icmp_ratelimit <==
1000

==> /proc/sys/net/ipv4/icmp_ratemask <==
6168

这已经表明 ICMP 是由内核处理的,因为/proc/sys是一个用于配置和检查内核状态的特殊文件系统:/dev、/proc 和 /sys 中有什么?

接下来,如果您在典型的家庭调制解调器路由器后面的同一 LAN 上连接 2 台计算机,然后您可以通过ping以下方式从计算机 A 到计算机 B:

ping 192.168.1.102

然后,您可以在计算机 B 上使用以下命令关闭 ping 回复:

echo 1 | sudo tee /proc/sys/net/ipv4/icmp_echo_ignore_all

一旦你这样做,ping计算机 A 就会开始出现故障。并重新启用:

echo 0 | sudo tee /proc/sys/net/ipv4/icmp_echo_ignore_all

所以我们可以通过与内核对话来直接控制 ICMP。

icmp_echo_ignore_all可以在 Ruslan 在评论中指出的内核代码中看到对 的引用https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/ipv4/icmp.c?id=24cac7009cb1b211f1c793ecb6a462c03dc35818#n935

static bool icmp_echo(struct sk_buff *skb)
{
    struct net *net;

    net = dev_net(skb_dst(skb)->dev);
    if (!net->ipv4.sysctl_icmp_echo_ignore_all) {
        struct icmp_bxm icmp_param;

        icmp_param.data.icmph      = *icmp_hdr(skb);
        icmp_param.data.icmph.type = ICMP_ECHOREPLY;
        icmp_param.skb         = skb;
        icmp_param.offset      = 0;
        icmp_param.data_len    = skb->len;
        icmp_param.head_len    = sizeof(struct icmphdr);
        icmp_reply(&icmp_param, skb);
    }
    /* should there be an ICMP stat for ignored echos? */
    return true;
}

使用两台连接到家庭无线 LAN 的运行 Linux 6.5.0 的 Ubuntu 23.10 计算机进行测试。

相关内容