我试图压制出站UDP数据包,而不让这些数据包的生产者知道。我的想法是使用iptables丢弃这样的数据包:
iptables -A OUTPUT -p udp -d 127.0.0.1 -j DROP
问题是发送应用程序获取-1作为sendto()的返回值而不是发送的字节数,然后将其作为错误处理。我需要发送应用程序不知道它的输出被丢弃。有没有办法做到这一点?
如果您知道UDP流量指向哪个端口,则可以将它们重定向到localhost上的另一个端口,而不是丢弃它们。这样你就可以提供一个监听接收器,除了接收数据包之外什么都不做。由于数据包现在已经传送,虽然不是它们最初的目的地,但sendto()
不会返回-1,而是返回字节。
接收器的一个例子是这样的:
#!/usr/bin/perl
use IO::Socket::INET;
# flush after every write
$| = 1;
my $sock;
my $data;
$socket = new IO::Socket::INET ( LocalPort => '55555', Proto => 'udp',);
while(1) { $socket->recv($data,1024); }
$socket->close();
# end of file.
上面的内容将永远高兴地坐在55555端口上,并且不会对它收到的数据做任何事情。接下来是重定向目标数据包,将任何发往端口555的任何主机的内容改为本地端口55555:
iptables -t nat -A OUTPUT -p udp --dport 555 -j DNAT --to-destination 127.0.0.1:55555
如果您不想将所有流量重定向到端口555的所有目标,请使用适当的源/目标地址规范限制上述规则。
Semi的asnwer给了我一个有用的想法:首先重定向到另一个端口,然后使用INPUT规则来丢弃流量(按预期工作)。
iptables -t nat -A OUTPUT -p udp --dport 555 -j DNAT --to-destination 127.0.0.1:55555
iptables -I INPUT 1 -p udp --dport 55555 -j DROP
你可以使用nftables
:
nft add table nat
nft add chain nat drop_my_udp_app {type nat hook output priority 0\;}
nft add rule nat drop_my_udp_app ip protocol udp udp dport 555 drop
显然,nat
表中的下降(与filter
表不同)不会导致应用程序在sendto
(内核版本4.19)中以-1通知。
如果您有其他NAT规则/链,您可能希望调整链优先级。