From 304ff79dc5c672293a755c025114a78b2a7960b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 30 Dec 2020 11:22:12 +0100 Subject: [PATCH 1/2] Update and extend description from STUN output People sometimes do not understand where is the problem, so include also hints what they needs to check, change and re-configure. --- miniupnpd/miniupnpd.c | 18 +++++++++++++++--- miniupnpd/miniupnpd.conf | 2 +- miniupnpd/upnpstun.c | 6 +++--- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/miniupnpd/miniupnpd.c b/miniupnpd/miniupnpd.c index e9f9f61..70925dc 100644 --- a/miniupnpd/miniupnpd.c +++ b/miniupnpd/miniupnpd.c @@ -1090,11 +1090,20 @@ int update_ext_ip_addr_from_stun(int init) if ((init || disable_port_forwarding) && !restrictive_nat) { if (addr_is_reserved(&if_addr)) - syslog(LOG_INFO, "STUN: ext interface %s with IP address %s is now behind unrestricted NAT 1:1 with public IP address %s: Port forwarding is now enabled", ext_if_name, if_addr_str, ext_addr_str); + syslog(LOG_INFO, "STUN: ext interface %s with IP address %s is now behind unrestricted full-cone NAT 1:1 with public IP address %s and firewall does not block incoming connections set by miniunnpd", ext_if_name, if_addr_str, ext_addr_str); else - syslog(LOG_INFO, "STUN: ext interface %s has now public IP address %s: Port forwarding is now enabled", ext_if_name, if_addr_str); + syslog(LOG_INFO, "STUN: ext interface %s has now public IP address %s and firewall does not blocks incoming connections set by miniunnpd", ext_if_name, if_addr_str); + syslog(LOG_INFO, "Port forwarding is now enabled"); } else if ((init || !disable_port_forwarding) && restrictive_nat) { - syslog(LOG_WARNING, "STUN: ext interface %s with IP address %s is now behind restrictive NAT with public IP address %s: Port forwarding is now impossible", ext_if_name, if_addr_str, ext_addr_str); + if (addr_is_reserved(&if_addr)) { + syslog(LOG_WARNING, "STUN: ext interface %s with private IP address %s is now behind restrictive or symmetric NAT with public IP address %s which does not support port forwarding", ext_if_name, if_addr_str, ext_addr_str); + syslog(LOG_WARNING, "NAT on upstream router blocks incoming connections set by miniupnpd"); + syslog(LOG_WARNING, "Turn off NAT on upstream router or change it to full-cone NAT 1:1 type"); + } else { + syslog(LOG_WARNING, "STUN: ext interface %s has now public IP address %s but firewall filters incoming connections set by miniunnpd", ext_if_name, if_addr_str); + syslog(LOG_WARNING, "Check configuration of firewall on local machine and also on upstream router"); + } + syslog(LOG_WARNING, "Port forwarding is now disabled"); } else { syslog(LOG_INFO, "STUN: ... done"); } @@ -2178,6 +2187,7 @@ main(int argc, char * * argv) syslog(LOG_INFO, "Reserved / private IP address %s on ext interface %s: Port forwarding is impossible", if_addr, ext_if_name); syslog(LOG_INFO, "You are probably behind NAT, enable option ext_perform_stun=yes to detect public IP address"); syslog(LOG_INFO, "Or use ext_ip= / -o option to declare public IP address"); + syslog(LOG_INFO, "Public IP address is required by UPnP/PCP/PMP protocols and clients do not work without it"); disable_port_forwarding = 1; } } @@ -2449,6 +2459,8 @@ main(int argc, char * * argv) } else if (!disable_port_forwarding && reserved) { syslog(LOG_INFO, "Reserved / private IP address %s on ext interface %s: Port forwarding is impossible", if_addr, ext_if_name); syslog(LOG_INFO, "You are probably behind NAT, enable option ext_perform_stun=yes to detect public IP address"); + syslog(LOG_INFO, "Or use ext_ip= / -o option to declare public IP address"); + syslog(LOG_INFO, "Public IP address is required by UPnP/PCP/PMP protocols and clients do not work without it"); } disable_port_forwarding = reserved; } diff --git a/miniupnpd/miniupnpd.conf b/miniupnpd/miniupnpd.conf index 6274f67..6355532 100644 --- a/miniupnpd/miniupnpd.conf +++ b/miniupnpd/miniupnpd.conf @@ -11,7 +11,7 @@ #ext_ip= # WAN interface must have public IP address. Otherwise it is behind NAT # and port forwarding is impossible. In some cases WAN interface can be -# behind unrestricted NAT 1:1 when all incoming traffic is NAT-ed and +# behind unrestricted full-cone NAT 1:1 when all incoming traffic is NAT-ed and # routed to WAN interfaces without any filtering. In this cases miniupnpd # needs to know public IP address and it can be learnt by asking external # server via STUN protocol. Following option enable retrieving external diff --git a/miniupnpd/upnpstun.c b/miniupnpd/upnpstun.c index c87ac40..f1b03f3 100644 --- a/miniupnpd/upnpstun.c +++ b/miniupnpd/upnpstun.c @@ -393,9 +393,9 @@ static int parse_stun_response(unsigned char *buffer, size_t len, struct sockadd } /* Perform main STUN operation, return external IP address and check - * if host is behind restrictive NAT. + * if host is behind restrictive, symmetric NAT or behind firewall. * Restrictive NAT means any NAT which do some filtering and - * which is not static 1:1, basically NAT which is not usable + * which is not static full-cone NAT 1:1, basically NAT which is not usable * for port forwarding */ int perform_stun(const char *if_name, const char *if_addr, const char *stun_host, unsigned short stun_port, struct in_addr *ext_addr, int *restrictive_nat) { @@ -524,7 +524,7 @@ int perform_stun(const char *if_name, const char *if_addr, const char *stun_host } } - /* Otherwise we are either directly connected or behind unrestricted NAT 1:1 */ + /* Otherwise we are either directly connected or behind unrestricted full-cone NAT 1:1 without filtering */ /* There is no filtering, so port forwarding would work fine */ return 0; } From e6bf74a691994face1d71c5c97056d95d47dca0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 30 Dec 2020 11:23:29 +0100 Subject: [PATCH 2/2] Add check that miniupnpd is not going to listen on WAN interface with public IP address Option listen= is used for LAN interface/address and option ext_addr= is used for public IP address. If users by mistake swap WAN and LAN interface or public and private IP addresses then miniupnpd obviously would not work and instead of hacking miniupnpd code users should rather check their miniupnpd configuration or local firewall settings. So add checks and hints which prevents security issues like swapping LAN and WAN interfaces/addresses and therefore prevent exposing port forwarding and firewall configuration on public Internet. --- miniupnpd/miniupnpd.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/miniupnpd/miniupnpd.c b/miniupnpd/miniupnpd.c index 70925dc..31bd9e4 100644 --- a/miniupnpd/miniupnpd.c +++ b/miniupnpd/miniupnpd.c @@ -953,6 +953,13 @@ parselanaddr(struct lan_addr_s * lan_addr, const char * str) if(!inet_aton(lan_addr->str, &lan_addr->addr)) goto parselan_error; } + if(!addr_is_reserved(&lan_addr->addr)) { + fprintf(stderr, "Error: LAN address contains public ip address : %s\n", lan_addr->str); + fprintf(stderr, "Public ip address can be configured via ext_ip= option\n"); + fprintf(stderr, "LAN address should contain private address, e.g. from 192.168. block\n"); + fprintf(stderr, "Listening on public ip address is a security issue\n"); + return -1; + } if(*p == '/') { const char * q = ++p;