Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tcp 允许入站连接但不允许入站流量的IPTables_Tcp_Iptables - Fatal编程技术网

Tcp 允许入站连接但不允许入站流量的IPTables

Tcp 允许入站连接但不允许入站流量的IPTables,tcp,iptables,Tcp,Iptables,当前正在尝试设置iptables,以允许客户端连接到服务器,通过TCP侦听消息流。问题是,我们希望在连接后阻止客户端发送任何消息(在这种情况下,如果客户端是DROP,则可以) 是否有一种方法允许客户端仅连接并强制执行从服务器到客户端的单向通信 需要在iptables(没有类似于软件代理的解决方案)中完全工作。这里要解决的主要问题是,我们不能在建立连接后关闭来自客户端的所有流量,因为TCP是一种肯定的确认协议。如果服务器没有从客户端接收到ACK,它将重新传输,并最终超时。在下面的内容中,我将假设我

当前正在尝试设置iptables,以允许客户端连接到服务器,通过TCP侦听消息流。问题是,我们希望在连接后阻止客户端发送任何消息(在这种情况下,如果客户端是DROP,则可以)

是否有一种方法允许客户端仅连接并强制执行从服务器到客户端的单向通信


需要在iptables(没有类似于软件代理的解决方案)中完全工作。

这里要解决的主要问题是,我们不能在建立连接后关闭来自客户端的所有流量,因为TCP是一种肯定的确认协议。如果服务器没有从客户端接收到ACK,它将重新传输,并最终超时。在下面的内容中,我将假设我们正在使用IPV4

因此,我们要做的是允许建立连接,然后只允许来自客户端的确认,即不包含TCP负载的数据包

不幸的是,TCP有效负载的长度没有在中显式表示。我们可以尝试在中使用总长度,但由于IP报头和TCP报头都包含可变长度选项字段,因此这一点很复杂,因此有许多可能的总长度是在没有有效负载的情况下确定的

由于IP选项很少使用且通常经过过滤,让我们先删除IP头中包含选项的所有数据包(如果您的防火墙还没有这样做的话),从而简化事情。详细讨论了这样做的含义

为此,我们将删除服务器的所有通信量(此处为10.2.3.4:1234),其中IP报头长度(IP报头中字节0的第4-7位)不是5:

iptables -A INPUT -p tcp -d 10.2.3.4 --dport 1234 \
  -m u32 --u32 "0>>24&0xF=6:0xF" -j DROP
这使用
iptables
u32
模块从数据包中从字节0开始抓取4个字节,将其右移24位,屏蔽下半字节,如果数据包在6-15范围内,则丢弃数据包。请注意,5实际上是IP头的最小大小

TCP选项的情况要复杂一些。在建立连接时,可以使用许多不同的选项,例如协商窗口缩放。然而,一旦建立了连接,我们唯一需要担心的就是TCP时间戳和选择性ACK。因此,让我们建立连接:

iptables -A INPUT -p tcp -d 10.2.3.4 --dport 1234 \
  --tcp-flags SYN SYN -j ACCEPT
请注意,可以在SYN数据包中发送有效负载,因此在这里我们不能完全满足您的要求。大多数普通的TCP实现都不会这样做,尽管会。如果您想缓解这种情况,您可以丢弃作为片段的SYN数据包(可以重新组装成非常大的数据包),并将非片段的SYN数据包的总长度限制在合理的范围内,以允许TCP三方握手中出现通常的选项。注意,上面的规则被添加到输入链中,输入链在IP片段重新组装之后进行处理

好的,我们可以建立TCP连接,IP头被限制为5个字(20字节)

但是,TCP报头可能包含选择性ACK、TCP时间戳、两者或两者都不包含。让我们从没有选项的TCP头开始。无选项且无有效负载的ack将由5字IP报头、5字TCP报头和无数据组成。因此,IP报头中的总长度将为40。如果数据包是一个片段,它可能会在随后的片段中隐藏有效负载,但由于我们正在处理IP片段重组后处理的输入链,因此我们不必担心这一点

iptables -A INPUT -p tcp -d 10.2.3.4 --dport 1234 \
  -m u32 --u32 "32>>28=5 && 0&0xFFFF=40" -j ACCEPT
IP报头是20个字节,数据偏移半字节在字节12中,因此取从字节32=20+12开始的4个字节,我们将半字节下移并将其与5进行比较,然后确保IP报头的字0的字节2和3的总长度为40

如果TCP报头中有TCP时间戳,则TCP报头中将额外有12个字节(3个字)。我们可以以类似的方式接受:

iptables -A INPUT -p tcp -d 10.2.3.4 --dport 1234 \
  -m u32 --u32 "32>>28=8 && 0&0xFFFF=52" -j ACCEPT
我将把它作为练习留给读者,让他们计算出其他组合。(注意,处理选择性ack有几种情况,因为可以有1-4个选择性ack块,或1-3个带时间戳的选择性ack块。)

免责声明:我实际上并没有尝试过这个,所以如果有输入错误或者我忽略了什么,我表示歉意。我相信这个策略是正确的,如果有任何错误或遗漏,请告诉我,我会纠正