miniupnp / miniupnp

UPnP IGD implementation
http://miniupnp.free.fr/
BSD 3-Clause "New" or "Revised" License
1.41k stars 445 forks source link

miniupnpd: duplicate rules with pf backend #719

Closed Inevitable closed 3 months ago

Inevitable commented 3 months ago

Was seeing a constantly expanding list of rules on my gateway (opnsense), and managed to narrow it down to a specific piece of software which requests some pseudorandom port forwards. Checked with the maintainers and they loop the request for keepalive purposes, but were doing so on a short interval. This resulted in repeating duplicate rules slowly stacking up over time in pf

OPNsense 24.1.3_1-amd64 FreeBSD 13.2-RELEASE-p10

miniupnpd 2.3.3 Mar 5 2024 using pf backend

root@central:~ # pfctl -a miniupnpd -sn
rdr pass quick on ice1 inet proto udp from any to any port = 32807 keep state label "app" rtable 0 -> 10.10.10.50 port 32807
rdr pass quick on ice1 inet proto udp from any to any port = 23807 keep state label "app" rtable 0 -> 10.10.10.50 port 23807
rdr pass quick on ice1 inet proto udp from any to any port = 23808 keep state label "app" rtable 0 -> 10.10.10.50 port 23808
rdr pass quick on ice1 inet proto udp from any to any port = 23809 keep state label "app" rtable 0 -> 10.10.10.50 port 23809
rdr pass quick on ice1 inet proto udp from any to any port = 23810 keep state label "app" rtable 0 -> 10.10.10.50 port 23810
rdr pass quick on ice1 inet proto udp from any to any port = 32807 keep state label "app" rtable 0 -> 10.10.10.50 port 32807
rdr pass quick on ice1 inet proto udp from any to any port = 23807 keep state label "app" rtable 0 -> 10.10.10.50 port 23807
rdr pass quick on ice1 inet proto udp from any to any port = 23808 keep state label "app" rtable 0 -> 10.10.10.50 port 23808
rdr pass quick on ice1 inet proto udp from any to any port = 23809 keep state label "app" rtable 0 -> 10.10.10.50 port 23809
rdr pass quick on ice1 inet proto udp from any to any port = 23810 keep state label "app" rtable 0 -> 10.10.10.50 port 23810
rdr pass quick on ice1 inet proto udp from any to any port = 32807 keep state label "app" rtable 0 -> 10.10.10.50 port 32807
rdr pass quick on ice1 inet proto udp from any to any port = 23807 keep state label "app" rtable 0 -> 10.10.10.50 port 23807
rdr pass quick on ice1 inet proto udp from any to any port = 23808 keep state label "app" rtable 0 -> 10.10.10.50 port 23808
rdr pass quick on ice1 inet proto udp from any to any port = 23809 keep state label "app" rtable 0 -> 10.10.10.50 port 23809
rdr pass quick on ice1 inet proto udp from any to any port = 23810 keep state label "app" rtable 0 -> 10.10.10.50 port 23810
rdr pass quick on ice1 inet proto udp from any to any port = 32807 keep state label "app" rtable 0 -> 10.10.10.50 port 32807
rdr pass quick on ice1 inet proto udp from any to any port = 23807 keep state label "app" rtable 0 -> 10.10.10.50 port 23807
rdr pass quick on ice1 inet proto udp from any to any port = 23808 keep state label "app" rtable 0 -> 10.10.10.50 port 23808
rdr pass quick on ice1 inet proto udp from any to any port = 23809 keep state label "app" rtable 0 -> 10.10.10.50 port 23809
rdr pass quick on ice1 inet proto udp from any to any port = 23810 keep state label "app" rtable 0 -> 10.10.10.50 port 23810
rdr pass quick on ice1 inet proto udp from any to any port = 32807 keep state label "app" rtable 0 -> 10.10.10.50 port 32807
nat quick on ice1 inet proto udp from 10.10.10.50 port = 32807 to any keep state label "app" rtable 0 -> 50.220.58.158 port 32807
nat quick on ice1 inet proto udp from 10.10.10.50 port = 23807 to any keep state label "app" rtable 0 -> 50.220.58.158 port 23807
nat quick on ice1 inet proto udp from 10.10.10.50 port = 23808 to any keep state label "app" rtable 0 -> 50.220.58.158 port 23808
nat quick on ice1 inet proto udp from 10.10.10.50 port = 23809 to any keep state label "app" rtable 0 -> 50.220.58.158 port 23809
nat quick on ice1 inet proto udp from 10.10.10.50 port = 23810 to any keep state label "app" rtable 0 -> 50.220.58.158 port 23810
nat quick on ice1 inet proto udp from 10.10.10.50 port = 32807 to any keep state label "app" rtable 0 -> 50.220.58.158 port 32807
nat quick on ice1 inet proto udp from 10.10.10.50 port = 23807 to any keep state label "app" rtable 0 -> 50.220.58.158 port 23807
nat quick on ice1 inet proto udp from 10.10.10.50 port = 23808 to any keep state label "app" rtable 0 -> 50.220.58.158 port 23808
nat quick on ice1 inet proto udp from 10.10.10.50 port = 23809 to any keep state label "app" rtable 0 -> 50.220.58.158 port 23809
nat quick on ice1 inet proto udp from 10.10.10.50 port = 23810 to any keep state label "app" rtable 0 -> 50.220.58.158 port 23810
nat quick on ice1 inet proto udp from 10.10.10.50 port = 32807 to any keep state label "app" rtable 0 -> 50.220.58.158 port 32807
nat quick on ice1 inet proto udp from 10.10.10.50 port = 23807 to any keep state label "app" rtable 0 -> 50.220.58.158 port 23807
nat quick on ice1 inet proto udp from 10.10.10.50 port = 23808 to any keep state label "app" rtable 0 -> 50.220.58.158 port 23808
nat quick on ice1 inet proto udp from 10.10.10.50 port = 23809 to any keep state label "app" rtable 0 -> 50.220.58.158 port 23809
nat quick on ice1 inet proto udp from 10.10.10.50 port = 23810 to any keep state label "app" rtable 0 -> 50.220.58.158 port 23810
nat quick on ice1 inet proto udp from 10.10.10.50 port = 32807 to any keep state label "app" rtable 0 -> 50.220.58.158 port 32807
nat quick on ice1 inet proto udp from 10.10.10.50 port = 23807 to any keep state label "app" rtable 0 -> 50.220.58.158 port 23807
nat quick on ice1 inet proto udp from 10.10.10.50 port = 23808 to any keep state label "app" rtable 0 -> 50.220.58.158 port 23808
nat quick on ice1 inet proto udp from 10.10.10.50 port = 23809 to any keep state label "app" rtable 0 -> 50.220.58.158 port 23809
nat quick on ice1 inet proto udp from 10.10.10.50 port = 23810 to any keep state label "app" rtable 0 -> 50.220.58.158 port 23810
nat quick on ice1 inet proto udp from 10.10.10.50 port = 32807 to any keep state label "app" rtable 0 -> 50.220.58.158 port 32807

I'm far from an expert, or able to contribute much in the way of actually fixing the issue, but would guess it's something similar to the previously patched issue with nft https://github.com/miniupnp/miniupnp/issues/582

nick-owens-eero commented 3 months ago

i have the same bug on openbsd 7.4 with miniupnpd-2.3.0pl20220601p0. additionally, enumerating the existing redirections results in an empty list, even though the rules in the pf anchor keep growing.

fugu# upnpc -m vport0 -L
upnpc : miniupnpc library test client, version 2.1.
 (c) 2005-2018 Thomas Bernard.
Go to http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
for more information.
List of UPNP devices found on the network :
 desc: http://192.168.0.1:22301/rootDesc.xml
 st: urn:schemas-upnp-org:device:InternetGatewayDevice:1

Found valid IGD : http://192.168.0.1:22301/ctl/IPConn
Local LAN ip address : 192.168.0.1
 i protocol exPort->inAddr:inPort description remoteHost leaseTime
fugu# pfctl -a "miniupnpd" -s rules | wc -l
     798

the only software i have making use of upnp right now is ipfs, which appears to use libp2p for UPNP.

nick-owens-eero commented 3 months ago

my apologies for the noise, it seems that this was fixed and openbsd 7.4 simply never updated the available package. everything seems fine with miniupnpd 2.3.5.

@Inevitable what version are you running? can you try a new version?

Inevitable commented 3 months ago

Ah, of course, relevant troubleshooting info does help I'd bet. It's running on an Opnsense install, so I'd have to see about overriding the default pkg.

OPNsense 24.1.3_1-amd64 FreeBSD 13.2-RELEASE-p10

miniupnpd 2.3.3 Mar 5 2024 using pf backend

miniupnp commented 3 months ago

@Inevitable have you tried to upgrade to miniupnpd 2.3.5 ? https://github.com/miniupnp/miniupnp/blob/master/miniupnpd/Changelog.txt#L23

Inevitable commented 3 months ago

I've not, seems ports is not yet updated to that version, and as this is a semi-appliance gateway, I'll probably just live with it until it rolls forward. I assume it's fixed though, if others are not reporting on it. If it updates and I still see the behavior I'll report back. Thanks for having a look!

Inevitable commented 3 months ago

Updating for posterity/searches. I was able to update to 2.3.6, and can confirm that the behavior is no longer present. Single entries which function as expected!