Skip to content

miniupnpd: Learn public IP address and detect NAT via STUN protocol

Thomas Bernard requested to merge pali:master into master

Created by: pali

Normally port forwarding works only in case miniupnpd have public IP address and it is not running on network hidden behind NAT.

There is one exception: when miniupnpd host has private IP address with unrestricted NAT 1:1 -- i.e. it private IP address has 1:1 mapping with some public IP address and all incoming packets to public IP address are NAT-ed to private IP address without any filtering or dropping. In some countries this is common behavior of ISPs how to provide public external IP address.

This pull request implements STUN client protocol for learning external IP address and NAT type via external STUN server. This feature is disabled by default and user can enable it via config options ext_perform_stun, ext_stun_host and ext_stun_port.

When sending STUN binding requests we need to enable incoming UDP traffic to selected ports as responses to sent packets comes from different IP addresses/ports as to which were sent. This is how STUN protocol is working and tests if NAT allows and passes inbound connections.

When miniupnpd detects that IP address on external interface was changed (either by watching for notifications or when user instruct upnpnd via SIGUSR1 signal), then miniupnpd perform STUN requests again to learn new external IP address and NAT type. All this happens only in case config option ext_perform_stun is enabled (disabled by default).

In case miniupnpd detects that is behind restrictive NAT (all types expects above NAT 1:1) or upstream router does some filtering of incoming packets which leads to dropping packets on forwarded ports, then miniupnpd rejects all port forwarding requests from UPnP IGD/PCP clients (as port forwarding in this case does not work).

Also when clients ask for public IP address then miniupnpd checks that it really knows external public IP address. And if not, then it correctly send error message instead of sending incorrect internal / private IP address.

See also discussion: https://github.com/miniupnp/miniupnp/issues/298

Merge request reports