iptables:丢弃传入的 UDP 数据包,目标端口 1900

iptables:丢弃传入的 UDP 数据包,目标端口 1900

我正在尝试使用 iptables 删除目标端口为 1900 的 UDP 数据包。这将影响两个方向,因此我为过滤表的 INPUT 和 OUTPUT 链各添加了一条规则。

root@hostname:~# iptables --table filter --list --numeric --verbose
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:1900

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:1900

传入数据包如下所示:

root@hostname:~# tcpdump -i enp2s0 -n "udp and port 1900"
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp2s0, link-type EN10MB (Ethernet), capture size 262144 bytes
11:17:35.845252 IP 192.168.0.1.56189 > 239.255.255.250.1900: UDP, length 123
11:17:36.285268 IP 192.168.0.1.36900 > 239.255.255.250.1900: UDP, length 133
11:17:36.285758 IP 192.168.0.1.36900 > 239.255.255.250.1900: UDP, length 127
11:17:36.286157 IP 192.168.0.1.36900 > 239.255.255.250.1900: UDP, length 127
11:17:36.286566 IP 192.168.0.1.36900 > 239.255.255.250.1900: UDP, length 129
11:17:36.286971 IP 192.168.0.1.36900 > 239.255.255.250.1900: UDP, length 129
11:17:36.287390 IP 192.168.0.1.36900 > 239.255.255.250.1900: UDP, length 124
11:17:40.845707 IP 192.168.0.1.56189 > 239.255.255.250.1900: UDP, length 123
11:17:41.285393 IP 192.168.0.1.36900 > 239.255.255.250.1900: UDP, length 133
11:17:41.285810 IP 192.168.0.1.36900 > 239.255.255.250.1900: UDP, length 127
11:17:41.286220 IP 192.168.0.1.36900 > 239.255.255.250.1900: UDP, length 127
11:17:41.286613 IP 192.168.0.1.36900 > 239.255.255.250.1900: UDP, length 129
11:17:41.287029 IP 192.168.0.1.36900 > 239.255.255.250.1900: UDP, length 129
11:17:41.287405 IP 192.168.0.1.36900 > 239.255.255.250.1900: UDP, length 124
^C
14 packets captured
14 packets received by filter
0 packets dropped by kernel

通常 iptables 工作得很好,我有其他按预期工作的过滤规则。此 OUTPUT 规则也按预期工作。以下输出显示此 OUTPUT 规则捕获(并丢弃)了一些数据包。

root@hostname:~# iptables --table filter --list OUTPUT --numeric --verbose
Chain OUTPUT (policy ACCEPT 412 packets, 87079 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    6  1128 DROP       udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:1900

但是 INPUT 规则不起作用。我现在已经尝试了几种规则变体来捕获传入的数据包,但没有成功。

root@hostname:~# iptables --table filter --list INPUT --numeric --verbose
Chain INPUT (policy ACCEPT 385 packets, 138K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:1900
    0     0 DROP       udp  --  enp0s2 *       0.0.0.0/0            0.0.0.0/0            udp dpt:1900
    0     0 DROP       all  --  *      *       0.0.0.0/0            239.255.255.250     
    0     0 DROP       all  --  enp0s2 *       0.0.0.0/0            239.255.255.250     
    0     0 DROP       udp  --  *      *       0.0.0.0/0            239.255.255.250     
    0     0 DROP       udp  --  enp0s2 *       0.0.0.0/0            239.255.255.250     
    0     0 DROP       all  --  enp0s2 *       0.0.0.0/0            224.0.0.0/4         

在我看来,规则似乎是正确的,但传入的数据包甚至对 INPUT 链不可见。每个链策略显示的计数器与我在 tcpdump 中看到的数据包数量不匹配。有一次我在 tcpdump 中看到了 20 个 UDP 数据包,但计数器只显示 1 个数据包:Chain INPUT (policy ACCEPT 1 packets, 52 bytes)

当我添加一条记录 INPUT 链中每个数据包的规则时,传入的数据包在日志文件中也不可见:

Chain INPUT (policy ACCEPT 655 packets, 573K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:1900
   46  5527 LOG        udp  --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 0 level 4 prefix "[INPUT UDP] "
  657  573K LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 0 level 4 prefix "[INPUT all] "

日志中唯一的数据包是 HTTPS 和 DNS。

我的问题是:

  1. 为什么 INPUT 规则无效?也许 iptables 不处理传入的数据包,因为它们被发送到某种广播地址?
  2. 如何使用 iptables 丢弃数据包(UDP,目标端口 1900)?

这都是关于 IPv4 的,我并不担心 IPv6。

Linux内核版本:5.8.0-44-generic#50~20.04.1-Ubuntu SMP

更新(2021-05-26):我尝试了几个较旧的内核,阅读了一些更新日志和已知错误。没有成功。最后我买了一个专用防火墙。

答案1

这不是一个答案,而是一个支持你的结论的东西。

在我看来,规则似乎是正确的,但传入的数据包甚至对 INPUT 链不可见。每个链策略显示的计数器与我在 tcpdump 中看到的数据包数量不匹配。有一次我在 tcpdump 中看到了 20 个 UDP 数据包,但计数器只显示 1 个数据包:Chain INPUT(策略接受 1 个数据包,52 字节)。

我得到了同样的结果。这是我的规则集脚本:

doug@rpi2:~ $ cat test-iptables
#!/bin/sh
FWVER=0.01
#
# test_firewall 2021.03.05 Ver:0.01
#       Just some simple rules for a test.
#       Currently for this question:
#       https://askubuntu.com/questions/1321344/iptables-drop-incoming-udp-packets-destination-port-1900
#

echo "Loading test_firewall version $FWVER..\n"

# The location of the iptables program
#
IPTABLES=/usr/sbin/iptables

#Set some stuff
#
EXTIF="eth0"
UNIVERSE="0.0.0.0/0"

#Clearing any previous configuration
#
#echo "  Clearing any existing rules and setting default policies.."
$IPTABLES -P INPUT ACCEPT
$IPTABLES -F INPUT
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -F OUTPUT

# Otherwise, I can not seem to delete it later on
$IPTABLES -F
# Delete user defined chains
$IPTABLES -X

# Reset all IPTABLES counters
$IPTABLES -Z
$IPTABLES -t nat -Z

# try to prevent accidental loss of my SSH connection.
# added after I did exactly that.
#
$IPTABLES -A INPUT -i $EXTIF -p tcp --dport 22 -j ACCEPT

# loopback interfaces are valid.
#
$IPTABLES -A INPUT -i lo -s $UNIVERSE -d $UNIVERSE -j ACCEPT

$IPTABLES -A INPUT -i $EXTIF -p udp --dport 1900 -j LOG --log-prefix "U1900:" --log-level info
$IPTABLES -A INPUT -i $EXTIF -p udp --dport 1900 -j DROP

$IPTABLES -A INPUT -d 224.0.0.7 -j LOG --log-prefix "IP224:" --log-level info
$IPTABLES -A INPUT -d 224.0.0.7 -j DROP

$IPTABLES -A INPUT -p udp --dport 8001 -j LOG --log-prefix "U8001:" --log-level info
$IPTABLES -A INPUT -p udp --dport 8001 -j DROP

$IPTABLES -A INPUT -m pkttype --pkt-type broadcast -j LOG --log-prefix "BROAD:" --log-level info
$IPTABLES -A INPUT -m pkttype --pkt-type broadcast -j DROP
$IPTABLES -A INPUT -m pkttype --pkt-type multicast -j LOG --log-prefix "MULTI:" --log-level info
$IPTABLES -A INPUT -m pkttype --pkt-type multicast -j DROP
$IPTABLES -A INPUT -m pkttype --pkt-type UNICAST -j LOG --log-prefix "UNI:" --log-level info
$IPTABLES -A INPUT -m pkttype --pkt-type UNICAST -j DROP
#$IPTABLES -A INPUT -m pkttype --pkt-type ANYCAST -j LOG --log-prefix "ANY:" --log-level info
#$IPTABLES -A INPUT -m pkttype --pkt-type ANYCAST -j DROP

$IPTABLES -A INPUT -s 192.168.111.123  -p udp --sport 8001 -j DROP

$IPTABLES -A INPUT -s 192.168.111.122 -j DROP
$IPTABLES -A INPUT -d 224.0.0.0/4 -j LOG --log-prefix "IP224B:" --log-level info
$IPTABLES -A INPUT -d 224.0.0.0/4 -j DROP

# $IPTABLES -A FORWARD -p udp -i $EXTIF --dport 8001 -j DROP

$IPTABLES -A INPUT -j LOG --log-prefix "CATCH:" --log-level info

echo test_iptables $FWVER done.
echo "test_iptables $FWVER done..." >> /dev/kmsg

就我的情况来说,我有一台地址为 192.168.111.123 的三星电视,它不断向端口 8001 发送数据包:

doug@rpi2:~ $ sudo tcpdump -n -tttt -vvv host 192.168.111.123
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
2021-03-06 13:26:24.073438 IP (tos 0x0, ttl 64, id 57376, offset 0, flags [DF], proto UDP (17), length 63)
    192.168.111.123.36088 > 192.168.111.255.15600: [udp sum ok] UDP, length 35
2021-03-06 13:26:24.840570 IP (tos 0x0, ttl 1, id 35446, offset 0, flags [DF], proto UDP (17), length 232)
    192.168.111.123.8001 > 224.0.0.7.8001: [udp sum ok] UDP, length 204
2021-03-06 13:26:26.849469 IP (tos 0x0, ttl 1, id 35532, offset 0, flags [DF], proto UDP (17), length 232)
    192.168.111.123.8001 > 224.0.0.7.8001: [udp sum ok] UDP, length 204
^C

我也同意他们根本就没有进入 INPUT 链:

doug@rpi2:~ $ sudo iptables -xvnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination
     194    15856 ACCEPT     tcp  --  eth0   *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22
       0        0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
       0        0 LOG        udp  --  eth0   *       0.0.0.0/0            0.0.0.0/0            udp dpt:1900 LOG flags 0 level 6 prefix "U1900:"
       0        0 DROP       udp  --  eth0   *       0.0.0.0/0            0.0.0.0/0            udp dpt:1900
       0        0 LOG        all  --  *      *       0.0.0.0/0            224.0.0.7            LOG flags 0 level 6 prefix "IP224:"
       0        0 DROP       all  --  *      *       0.0.0.0/0            224.0.0.7
       0        0 LOG        udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:8001 LOG flags 0 level 6 prefix "U8001:"
       0        0 DROP       udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:8001
    1612   173750 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            PKTTYPE = broadcast LOG flags 0 level 6 prefix "BROAD:"
    1612   173750 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            PKTTYPE = broadcast
     460    69304 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            PKTTYPE = multicast LOG flags 0 level 6 prefix "MULTI:"
     460    69304 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            PKTTYPE = multicast
      96    13068 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            PKTTYPE = unicast LOG flags 0 level 6 prefix "UNI:"
      96    13068 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            PKTTYPE = unicast
       0        0 DROP       udp  --  *      *       192.168.111.123      0.0.0.0/0            udp spt:8001
       0        0 DROP       all  --  *      *       192.168.111.122      0.0.0.0/0
       0        0 LOG        all  --  *      *       0.0.0.0/0            224.0.0.0/4          LOG flags 0 level 6 prefix "IP224B:"
       0        0 DROP       all  --  *      *       0.0.0.0/0            224.0.0.0/4
       0        0 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 0 level 6 prefix "CATCH:"

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 264 packets, 39247 bytes)
    pkts      bytes target     prot opt in     out     source               destination

我们在 syslog 文件中没有看到任何相关内容:

doug@rpi2:~ $ grep -a "DPT=8001" /var/log/syslog
doug@rpi2:~ $

相关内容