7

I'm trying to configure firewalld (Fedora 21) so that responses get through for MDNS queries sent from a client application using an ephemeral UDP source port to a multicast target. The responses are unicast. The sequence goes like this (as captured using wireshark)

  1. UDP: local-address:45325 (ephemeral) -> 224.0.0.251:5353; the query
  2. UDP: some-system:5353 -> local-address:45325; the response
  3. ICMP: local-address -> some-system: Type: 3 (Destination unreachable), Code: 10 (Host administratively prohibited)

The firewalld mdns service, which adds port 5353 UDP is enabled but this does not help with the response.

Any pointers would be appreciated.

awy
  • 301
  • 2
  • 6
  • Did you ever resolve this? I'm having a similar problem with a specific set of devices using multicast connecting to a server and noticed the same ICMP error you've mentioned in a tcpdump capture. – James White Jan 31 '16 at 21:11
  • No, no reply, and I have not worked out any solution myself. – awy Feb 02 '16 at 08:09
  • I gave up and to workaround the issue, I added special rich rule to allow all from the specific source IP. Not the best security practice but works for this special case. – James White Feb 02 '16 at 08:36
  • Hopefully, my findings might help you. – James White Feb 02 '16 at 10:12

4 Answers4

6

Congratulations, you discovered a limitation in the concept of packet filtering. Tracking multicast protocols: the response can't come back from the same address, because you're absolutely forbidden to send from a multicast address. The firewall can't match the response to your request, so it blocks it. Obviously the system MDNS dameon, avahi, avoids this by sending from the fixed port 5353, so that's where it gets responses as well. Port 5353 is allowed specifically by a firewall rule. If you can get the software to talk to avahi instead, that's the solution avahi would recommend.

It may alternatively be possible to rely on the default avahi option disallow-other-stacks=no, and configure the client app to use the fixed port 5353. It's not clear what effect this has on the reliability of Avahi. Or you could simply disable Avahi if you don't need it. Of course if the app lets you choose a fixed source port, you can just add that to the firewall & it will work...

...except when you say "client application", you probably mean a class of software that should in theory be able to run multiple instances at the same time. It's not running all the network requests through a single daemon. And I bet the app doesn't use the SO_REUSEPORT hack that avahi implements for disallow-other-stacks=no, so this would only let you run one instance of the app at once.

A lot of Linux software for Desktops or dinky local network boxes probably isn't designed to run with a host firewall. Fedora is the main distribution that does so. Fedora Workstation recently changed their firewall default zone to "FedoraWorkstation", which allows connections to any TCP or UDP port above 1024. Either the FedoraWorkstation configuration, or running without a firewall, would allow your software to work unchanged.

It's hard to express the point of a host firewall like Firewalld. It doesn't have support for routing between zones like Shorewall. It does let you choose to set the default zone to something more restrictive, with more permissive settings for your home wireless network, or a VPN. Maybe if you work hard on NetworkManager you can get that to work for a home wired network too. But that's so obscure for something that's enabled by default.

It's entirely safe to run a default install of Fedora (or Ubuntu) without a firewall. What you give up is a centralized policy for which ports are open - in case you later set up some random software, and didn't realize that it wants to listen on a port.

People try to compare firewalls on Linux and Windows, but Windows Firewall is both clearly necessary and actually possible to understand by mortals, unlike Firewalld. Windows has open ports by default, and relies on a host firewall to protect them. It implements trusted/untrusted zones for wired networks. New networks default to untrusted, and it pops up to ask if you want to change it. Different wired networks are identified by the MAC address of the DHCP server. At least since Window 8, the "express" first-run also marks the current network as trusted, which I find theoretically annoying but in practice it's probably quite helpful.

Technically you could also modify the software to talk to Firewalld over dbus and request that the ephemeral port it bound be made open for responses. Somehow I don't think that's a helpful suggestion though.

sourcejedi
  • 48,311
  • 17
  • 143
  • 296
4

There is a Service-Template available already:

firewall-cmd --add-service=mdns              # runtime
firewall-cmd --permanent --add-service=mdns  # permanent

maybe you need to install firewalld-config-workstation.

If you still won't get it working. Could you maybe add the rule to your question? E.g. with:

iptables-save | grep ' 5353 '

or maybe just try:

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
xx4h
  • 2,392
  • 16
  • 17
2

I had the same issue with a couple of specific devices that connected to a server. No matter what I tried the firewall kept blocking the requests.

Redhat recommends two methods, as per the knowledgebase:

Solution 1:

Open up the UDP port the incoming traffic will be on:

firewall-cmd --permanent --zone=public --add-port=12345/udp
firewall-cmd --reload

This probably won't work because the mdns service opens up UDP 5353 and you've mentioned this doesn't help.

Solution 2:

Create a service:

<?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>

However this example appears to be for outgoing rather than incoming. Instead you could try switching the <destination> for <source address="xx.xx.xx.xx"> and see if that helps.

Solution 3:

I personally, couldn't get either to work. I ended up basically whitelisting the source IP to all ports. Something I would not recommend, but I got fed up spending hours messing around with firewalld and because the clients in question are Raspberry Pi devices on a private LAN, the risk is minimal.

firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="xx.xx.xx.xx" accept'

You will want to adjust the zone if you use something different. I'd also only do this for internal IPv4 clients on a LAN.

Source: https://access.redhat.com/solutions/1587673

James White
  • 645
  • 2
  • 7
  • 22
1

On Fedora 29 I had the problem that mdns didn't work by default on my LAN (after only installing avahi and nss-mdns). firewall-cmd --permanent --add-service=mdns worked for me.

ecloud
  • 201
  • 2
  • 2