如何防止进程知道网络已启动?

如何防止进程知道网络已启动?

首先让我们
通过 iptables 阻止所有传入、传出信号。

六、/etc/sysconfig/iptables

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A OUTPUT -j DROP
-A INPUT -j DROP
-A FORWARD -j DROP
COMMIT

启动 iptables:

 service iptables start

我的以太网电缆已插入。让我们通过终端尝试一下

ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.

就这些。只有一行。之后它摊位. 显然 iptables 成功阻止了它

现在我要断开我的以太网电缆。我的互联网已断开。

我们再试一次:

ping 8.8.8.8
connect: Network is unreachable

这次..它立即..返回该消息。

显然,无论是“ping”还是其他任何程序,它都会在执行互联网命令之前确定网络接口是否启动。

当然,一旦执行,它就无法通过 iptable 规则。但显而易见的是,它并没有首先咨询 iptables。

它首先检查网络接口是否已连接。

我想弄清楚如何手动让它知道网络接口已连接。

换句话说,除非我告诉它网络接口已启动,否则它的行为应该与网络接口未连接时(即未插入以太网电缆时)的行为相同

如何才能做到这一点 ?

答案1

显然,无论是“ping”还是其他任何程序,它都会在执行互联网命令之前确定网络接口是否启动。

不是。以下是strace ping 8.8.8.8系统输出的部分内容没有功能性网络接口

connect(4, {sa_family=AF_INET, sin_port=htons(1025), sin_addr=inet_addr("8.8.8.8")}, 16) = -1 NETUNREACH (Network is unreachable)

为了回答你的具体的问题是,当用户空间进程要求内核在没有可用网络子系统的情况下将数据发送到远程系统时,它会返回与情况相符的错误。请注意,没有任何询问网络是否可用;用户空间程序会直接请求连接,但会立即出错,因为内核知道它无法满足。这与尝试在空间不足的文件系统上写入文件(错误 28,设备上没有剩余空间)或超出磁盘配额(错误 122,超出磁盘配额)没有什么不同(错误代码取自这里)。

编辑:我猜你的下一个问题可能是“我如何根据具体情况返回此错误“,但我认为让你问这个问题是明智的。正如你已经多次被告知的那样,最好的方法是使用iptables -j REJECT,因为产生的错误将以完全相同的方式传播回请求进程。这是一个在同一个系统上的示例,网络已启动,但一条iptables -I OUTPUT 1 -j REJECT规则禁止所有OUTPUT流量(NB在现实生活中这不是一个好主意):

sendmsg(3, {msg_name(16)={sa_family=AF_INET, sin_port=htons(0), sin_add=inet_addr("8.8.8.8")}, msg_iov(1)=[{"...."..., 64}], msg_controlln=0, msg_flags=0}, 0) = -1 EPERM (Operation not permitted)

随着不同的调用,-j REJECT --reject-with ...不同的错误被传回给请求进程,但所有错误都会导致传回错误。

编辑2:你对 UNIX 网络堆栈的思维模型是完全错误的,你从中形成的想法也是错误的;特别是 iptables内核(*)。部分问题可能是某些程序忽略某些错误,某些程序记录错误但继续,而某些程序终止。任何给定的程序都可以决定对任何给定错误做什么。ping例如,程序在 终止ENETUNREACH,但在 上EPERM它只是记录错误stderr并继续。如果我理解正确的话,这就是您反对的行为。

除非你正在编写程序,否则这是你无法控制的。我理解您希望内核发送软件不会忽略的错误,但内核不会(就目前情况而言)为您做到这一点。没有什么可以阻止您编写一个修改过的内核来发出信号全部使用 SIGKILL 来处理错误,但是 Linux 目前还不能这样做,而且我们大多数人也不希望它这样做。

(*) 准确地说,iptables是允许我们在内核中操纵 netfilter 结构的用户空间程序。但由此产生的数据包和错误处理绝对是内核空间现象,而不是用户空间现象。

相关内容