我的防火墙配置的核心部分是:
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
似乎RELATED
对多播响应不起作用:当主机发送到多播组(在我的情况下是 UPnP SSDP 发现,发送到 239.255.255.250:1900)时,从特定 IP 地址返回到发送方随机选择的端口的相应响应将被丢弃。
保留--state ESTABLISHED,RELATED
语义但使响应匹配适用于多播的正确方法是什么?
答案1
这就是多播的问题:netfilter 永远无法确定它是否相关。
因此,允许 UPnP SSDP 的唯一方法是:
-A INPUT -p udp --sport 1900 -j ACCEPT
除了现有的ESTABLISHED,RELATED
规则之外。
答案2
使用最新的 Linux 内核(>= 2.6.39),您可以使用内核的 ipset 来解决连接跟踪的限制。您不需要编写任何用户空间或内核帮助程序。对于 UPnP SSDP,它可以写成:
$ ipset create upnp hash:ip,port timeout 3
$ iptables -A OUTPUT -d 239.255.255.250/32 -p udp -m udp --dport 1900 -j SET --add-set upnp src,src --exist
$ iptables -A INPUT -p udp -m set --match-set upnp dst,dst -j ACCEPT
第一个命令创建一个名为即插即用它存储元组(ip 地址、ip 协议、ip 端口),并且每个插入的记录在 3 秒内过期。
第二条命令匹配传出的 UPnP SSDP 数据包(目标是 UDP 端口 1900 上的多播地址 239.255.255.250)并存储源 IP 地址和源 UDP 端口将数据包放入 ipset即插即用. 第一个关键字源码方法源 IP 地址和第二个关键字源码方法源端口作为类型为哈希:ip,端口总是需要这样的一对。关键字--存在表示对已有记录重置定时器,该存储记录将在 3 秒内自动删除。
第三个命令匹配传入的 UDP 数据包,并检查其目标地址和目标端口是否与 ipset 中的某些记录匹配即插即用那么这个数据包将被接受。语法夏令时,夏令时方法目标 IP 地址和目的端口。
UPnP 客户端通常将 udp 数据包发送到 239.255.255.250:1090,并等待 2 秒钟的响应。因此,ipset 中 3 秒的自动过期时间就足够了。
我在互联网上没有找到任何适用于 UPnP 客户端的防火墙/iptables 配置,这些配置不是太宽松(例如接受所有传入的 UDP 数据包)或没有一些用户空间跟踪或需要修补内核。因此,我希望这个示例对您有所帮助。