Well, you may try this, it worked for me (i.e. - I verified that incoming connections to ports in question succeed). YMMV.
- Enable ssdp user helper in conntrackd.conf:
General {
HashSize 32768
HashLimit 131072
Syslog on
LockFile /var/run/lock/conntrackd.lock
UNIX {
Path /var/run/conntrackd.sock
}
SocketBufferSize 262142
SocketBufferSizeMaxGrown 655355
# default SUSE systemd service unit file is of Type=notify
Systemd off
}
Stats {
LogFile on
}
Helper {
Type ssdp inet udp {
QueueNum 5
QueueLen 10240
Policy ssdp {
ExpectMax 8
ExpectTimeout 300
}
}
Type ssdp inet tcp {
QueueNum 5
QueueLen 10240
Policy ssdp {
ExpectMax 8
ExpectTimeout 300
}
}
}
- Register ssdp helper in kernel:
nfct add helper ssdp inet tcp
nfct add helper ssdp inet udp
- Connect user helper to kernel:
systemctl start conntrackd.service
- Add rules to invoke ssdp helper:
iptables -t raw -A OUTPUT -p udp --dport 1900 -j CT --helper ssdp
iptables -t raw -A OUTPUT -p tcp --dport 9791 -j CT --helper ssdp
Both UDP and TCP work. Below are created “expectations” (“client” is 192.168.1.1, “server” is 192.168.1.2).
For UDP (SSDP discovery):
296 proto=17 src=0.0.0.0 dst=192.168.1.1 sport=0 dport=12345 mask-src=0.0.0.0 mask-dst=0.0.0.0 sport=0 dport=65535 master-src=192.168.1.1 master-dst=239.255.255.250 sport=12345 dport=1900 PERMANENT class=0 helper=ssdp
It simply tells kernel that incoming packets to UDP (protocol 17) port 12345 are related to existing connection which was to multicast address 239.255.255.250 from port 12345 and so should be accepted as long as firewall rules allow “related” packets (is normal default case).
For TCP (event notification subscription):
296 proto=6 src=192.168.1.2 dst=192.168.1.1 sport=0 dport=40813 mask-src=0.0.0.0 mask-dst=0.0.0.0 sport=0 dport=65535 master-src=192.168.1.1 master-dst=192.168.1.2 sport=58078 dport=9791 class=0 helper=ssdp
It is more or less the same. It says that incoming TCP (protocol 6) connections to port 40813 from host 192.168.1.2 are related to existing connection from host 192.168.1.1 to host 192.168.1.2 port 9791 and so should be accepted as “related”. Note that original connection was from port 58078 (randomly selected) and port 40813 was extracted from SUBSCRIBE packet.
Caveats
- In TW conntrackd is configured as Type=notify systemd service. It does not work (conntrackd loops consuming 100% of CPU). When changed to “simple” it works.
- There is no start-up service to register user helpers. If you want to automate it you need to write your own service.
- conntrackd must
be started after all helpers in its configuration file have been registered in kernel, otherwise it fails to start. 1. iptables rules must
be configured after helpers have been registered in kernel, otherwise iptables invocation fails. 1. When firewalld is stopped it removes all netfilter rules and registered helpers. So you cannot simply restart firewall. I think when firewalld is reloaded (using firewall-cmd --reload) helpers are preserved, but I am not sure and I am not going to test it (my curiosity is satisfied so far).
- Assuming firewalld preserves user helpers on startup, it is possible to use direct rules. In this case helpers must be registered before
firewalld is started, otherwise iptables invocation fails. conntrackd itself may be started at any time (as long as it is not started helpers simply will not work). 1. For TCP part you also need to somehow examine incoming packets (notifications) to renew expectation, otherwise it will timeout. But there is no way to match notifications in advance. So either you need to pass every incoming packet to ssdp helper (with obvious performance hit) or jump through the hoops by creating additional rule after SUBSCRIBE packet was parsed and incoming port is known.
- Finally - I have no idea whether port 9791 is always correct. UPnP is most firewall-unfriendly protocol I have ever seen. In particular, the actual URL that client must use to subscribe to notifications is part of device description; client gets URL to this description in discovery response, it needs to fetch and parse it. So if you are going to take this route you really need to ask maintainer of your software whether the same fixed port is always used for this purpose. This was the port in your packet capture and this is one of ports mentioned on application site.
What is “original fix”? You do realize that in this 6 pages thread nobody understands anymore to which exact post you refer, do not you?
I was under the impression that even with the nftables backend set, iptable settings would still take precedence.
That’s wrong. Direct rules will be processed by kernel before other nftables rules added by firewalld, that’s correct. Whether they “take precedence” depends on what exactly you mean. For most people this means “I want to allow something that cannot be allowed by firewalld configuration”. I already wrote in multiple threads here that it is impossible to allow anything that is not allowed by firewalld configuration using direct rules with nftables backend. That is how kernel netfilter works.