-
-
Notifications
You must be signed in to change notification settings - Fork 283
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[fix] Several long-standing issues with UPnP port forwarding #1204
base: dev
Are you sure you want to change the base?
Conversation
Fixes local firewall rules to allow discovery of SSDP servers. No longer disables UPnP forwarding when refreshing fails. No longer disables UPnP forwarding on system reboot. Cron job runs every 10 minutes to refresh the router tables more promptly after the system or router reboots. Removes the deprecated UPnP "reload" option.
Hello, how can we test this PR ?? |
I put my reply in YunoHost/issues#1463 |
src/yunohost/firewall.py
Outdated
# Add cron job | ||
with open(UPNP_CRON_JOB, "w+") as f: | ||
f.write( | ||
"*/50 * * * * root " | ||
"*/10 * * * * root " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This frequencies could block other yunohost-api/cli yunohost call. I think we shouldn't run this every 10 minutes. This command could take more than 3 seconds due to the discover delay.
Opening a port is not action we should do to often. We might condition that with an independent code that check port diagnosis result before.
It's strange that a command called status
make change on network. We probably should rename it...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing to a frequency of once per 12 minutes would reduce the possibility of a clash - is this ok?
There is an alternative to repeatedly opening the port here:
https://github.com/mqus/nft-rules/blob/master/files/SSDP_client.md
This would involve using nft rules - is this acceptable?
I agree that the command name is misleading, but thought it risky to change it if it works...
src/yunohost/firewall.py
Outdated
upnpc = miniupnpc.UPnP(localport=1) | ||
# Open port to receive discovery message | ||
process.run_commands( | ||
["iptables -w -A INPUT -p udp --dport %d -j ACCEPT" % SSDP_CLIENT_PORT], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could upnp could use ipv6 ?
Is there a security risk to let firewall open on this port ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe upnp specifically uses an IPv4 broadcast address.
See above re an alternative firewall methodology.
src/yunohost/firewall.py
Outdated
# Discover UPnP device(s) | ||
logger.debug("discovering UPnP devices...") | ||
nb_dev = upnpc.discover() | ||
logger.debug("found %d UPnP device(s)", int(nb_dev)) | ||
# Close discovery port | ||
process.run_commands( | ||
["iptables -w -D INPUT -p udp --dport %d -j ACCEPT" % SSDP_CLIENT_PORT], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
["iptables -w -D INPUT -p udp --dport %d -j ACCEPT" % SSDP_CLIENT_PORT], | |
["iptables -w -D INPUT -p udp --dport %d -j DENY" % SSDP_CLIENT_PORT], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current code deletes the firewall rule which opens the port, while proposed change adds a new rule which overrides the existing rule - this would cause a conflict the next time the port is opened.
No longer requires opening a fixed port and then closing it again. Uses nftables sets to recognise the client port.
Also removed reference to port 1901
Super quick review (sorry for the late feedback) : the changes sounds kinda legit, but I'm always strugglng to know how to properly test and validate this. @dbuscher : do you have some tips regarding how you tested this ? What brand of router are you using ? |
Thanks for having a look at this. In partial answer to your question, I will quote what I said in the issue comments:
I would add to this that one can quickly check that it is working by installing the miniupnpc executable using apt and then doing
which lists the current upnp port forwarding configuration of the router. My router is my ISP-provided router, the Virgin Media Hub 3.0. I changed ISP about a year ago and previously had a router from Sky TV. It had very similar behaviour with the yunohost upnp software, but I changed ISP before I made all the bugfixes, so I was not able to test the final version on this earlier router. From what I can tell, all the problems that I fixed were to do with maintaining the state of the yunohost system (port access settings/recovering from temporary errors/ keeping track of whether upnp has been activated) and not to do with communication protocol with the router (although communication errors would trigger some of the underlying bugs, which is part of the reason why changing the version of miniupnp that was shipped with debian was so helpful). This should mean that any aspects of the software which worked with any given router before should continue to work with these fixes. This is a roundabout way of saying that lack of testing with a large variety of routers is not likely to be a problem - to me it would seem more useful to test with a number of different yunohost installations to check that the changes do not accidentally interfere with anything else in the system. |
Alrighty thanks for the quick and extensive answer 👍 That looks promising, I shall have a look at my home router to check if it supports UPnP and give this a try 👍 |
I have recently noticed on my machine that the changes introduced here cause problems with fail2ban, because fail2ban is currently using iptables commands and not nftables. There is no legacy equivalent to the nftables commands used to fix UPNP, so my fix was to move fail2ban over to using nft using the approach documented here. This works for me, but obviously if others want to use this UPNP fix the fail2ban package would need to be altered. So my question is, would submitting a PR for fail2ban to fix a problem due to a change in firewall.py be an acceptable route to go? It would seem to me that yunohost should upgrade fully to nftables, the only question is the timing. |
This reverts commit 667dba4.
…yunohost into fix-1463-make-upnp-great-again
OK, so I decided that the best thing to do was to revert the changes which introduce nftables rules in order to reduce the propagation of these changes into everything which currently uses iptables, e.g. fail2ban and possibly wireguard. The only downside is the slight inefficiency of explicitly opening and closing the SSDP discovery port every 12 minutes compared to using an automatic nftables rule. Hopefully this can be accepted into the main branch sometime soon... |
The problem
See YunoHost/issues#1463
...
Solution
Fixes local firewall rules to allow discovery of SSDP servers.
No longer disables UPnP forwarding when refreshing fails.
No longer disables UPnP forwarding on system reboot.
Cron job runs every 10 minutes to refresh the router tables more
promptly after the system or router reboots.
Removes the deprecated UPnP "reload" option.
...
PR Status
Works on my system (yunohost 4.2.0 testing) behind a home router. Others need to check it works with their networks.
...
How to test
...