我正在尝试配置firewalld(Fedora 21),以便响应从使用临时UDP源端口的客户端应用程序发送到多播目标的MDNS查询。响应是单播的。序列如下(使用wireshark捕获)
- UDP:本地地址:45325(临时)-> 224.0.0.251:5353;查询
- UDP: 某些系统:5353 -> 本地地址:45325;响应
- ICMP:本地地址 -> 某些系统:类型:3(目标无法到达),代码:10(主机管理禁止)
启用了添加端口 5353 UDP 的 firewalld mdns 服务,但这对响应没有帮助。
任何指示将不胜感激。
答案1
恭喜,您发现了数据包过滤概念的局限性。跟踪多播协议:响应无法从同一地址返回,因为绝对禁止发送从多播地址。防火墙无法匹配对您的请求的响应,因此会阻止它。显然,系统 MDNS 守护进程 avahi 通过从固定端口 5353 发送来避免这种情况,因此它也是从该端口获得响应的。防火墙规则特别允许端口 5353。如果可以的话让软件与 avahi 对话,这就是 avahi 推荐的解决方案。
或者也可以依赖默认的 avahi 选项disallow-other-stacks=no
,并且配置客户端应用程序以使用固定端口 5353。目前尚不清楚这对 Avahi 的可靠性有何影响。或者,如果不需要,您可以简单地禁用 Avahi。当然,如果应用程序允许您选择一个固定的源端口,您只需将其添加到防火墙即可工作......
...除非您说“客户端应用程序”,否则您可能指的是理论上应该能够同时运行多个实例的一类软件。它不是通过单个守护进程运行所有网络请求。和我敢打赌该应用程序不会使用 avahi 实现的 SO_REUSEPORT hack disallow-other-stacks=no
,因此这只会让您一次运行该应用程序的一个实例。
许多用于桌面或小型本地网络盒的 Linux 软件可能并未设计为与主机防火墙一起运行。 Fedora 是这样做的主要发行版。 Fedora Workstation 最近将其防火墙默认区域更改为“FedoraWorkstation”,允许连接到 1024 以上的任何 TCP 或 UDP 端口。 无论是 FedoraWorkstation 配置,还是在没有防火墙的情况下运行,都可以让您的软件无需更改即可运行。
很难表达像 Firewalld 这样的主机防火墙的意义。它不支持像 Shorewall 这样的区域之间的路由。它确实允许您选择将默认区域设置为更严格的区域,为您的家庭无线网络或 VPN 提供更宽松的设置。也许如果您在 NetworkManager 上努力工作,您也可以让它适用于家庭有线网络。但这对于默认启用的东西来说太晦涩了。
运行是完全安全的默认在没有防火墙的情况下安装 Fedora(或 Ubuntu)。您放弃的是开放端口的集中策略 - 以防您后来设置一些随机软件,并且没有意识到它想要侦听端口。
人们试图比较 Linux 和 Windows 上的防火墙,但与 Firewalld 不同,Windows 防火墙显然是必要的,而且实际上是普通人可以理解的。 Windows 默认情况下开放端口,并依赖主机防火墙来保护它们。它为有线网络实现可信/不可信区域。新网络默认为不可信,会弹出询问是否要更改。不同的有线网络通过DHCP服务器的MAC地址来识别。至少从 Window 8 开始,“express”首次运行也会将当前网络标记为受信任,我觉得这在理论上很烦人,但在实践中可能非常有帮助。
从技术上讲,您还可以修改软件以通过 dbus 与 Firewalld 通信,并请求打开其绑定的临时端口以进行响应。但不知何故,我认为这不是一个有用的建议。
答案2
已经有一个可用的服务模板:
firewall-cmd --add-service=mdns # runtime
firewall-cmd --permanent --add-service=mdns # permanent
也许你需要安装firewalld-config-workstation
.
如果你仍然无法让它工作。您能否将规则添加到您的问题中?例如:
iptables-save | grep ' 5353 '
或者也许只是尝试:
firewall-cmd --remove-service=mdns
firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -d 224.0.0.251/32 -p udp -m udp --dport 5353 -m conntrack --ctstate NEW,RELATED -j ACCEPT
答案3
我对连接到服务器的几个特定设备也遇到了同样的问题。无论我尝试什么,防火墙都会阻止请求。
根据知识库,Redhat 推荐了两种方法:
解决方案一:
打开传入流量所在的 UDP 端口:
firewall-cmd --permanent --zone=public --add-port=12345/udp
firewall-cmd --reload
这可能不起作用,因为该mdns
服务打开 UDP 5353,并且您提到这没有帮助。
解决方案2:
创建服务:
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>My Multicast Listener</short>
<description>A service which allows traffic to a fictitious multicast listener.</description>
<port protocol="udp" port="12345"/>
<destination ipv4="224.0.0.251"/>
</service>
然而,这个例子似乎是针对传出而不是传入。相反,您可以尝试切换<destination>
for<source address="xx.xx.xx.xx">
并查看是否有帮助。
解决方案3:
就我个人而言,两者都无法工作。我最终基本上将所有端口的源 IP 列入白名单。我不推荐这样做,但我厌倦了花几个小时摆弄firewalld,而且因为有问题的客户端是私有LAN上的Raspberry Pi设备,所以风险很小。
firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="xx.xx.xx.xx" accept'
如果您使用不同的东西,您将需要调整区域。我也只会对 LAN 上的内部 IPv4 客户端执行此操作。
答案4
在 Fedora 29 上,我遇到了 mdns 在我的 LAN 上默认无法工作的问题(仅安装了 avahi 和 nss-mdns 后)。 firewall-cmd --permanent --add-service=mdns
为我工作。