net/portmapper: relax handling of UPnP resp (#6946)
Gateway devices operating as an HA pair w/VRRP or CARP may send UPnP replies from static addresses rather than the floating gateway address. This commit relaxes our source address verification such that we parse responses from non-gateway IPs, and re-point the UPnP root desc URL to the gateway IP. This ensures we are still interfacing with the gateway device (assuming L2 security intact), even though we got a root desc from a non-gateway address. This relaxed handling is required for ANY port mapping to work on certain OPNsense/pfsense distributions using CARP at the time of writing, as miniupnpd may only listen on the static, non-gateway interface address for PCP and PMP. Fixes #5502 Signed-off-by: Jordan Whited <jordan@tailscale.com>
This commit is contained in:
@@ -14,6 +14,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"net/url"
|
||||
@@ -174,8 +175,10 @@ func getUPnPClient(ctx context.Context, logf logger.Logf, gw netip.Addr, meta uP
|
||||
return nil, fmt.Errorf("unexpected host %q in %q", u.Host, meta.Location)
|
||||
}
|
||||
if ipp.Addr() != gw {
|
||||
return nil, fmt.Errorf("UPnP discovered root %q does not match gateway IP %v; ignoring UPnP",
|
||||
// https://github.com/tailscale/tailscale/issues/5502
|
||||
logf("UPnP discovered root %q does not match gateway IP %v; repointing at gateway which is assumed to be floating",
|
||||
meta.Location, gw)
|
||||
u.Host = net.JoinHostPort(gw.String(), u.Port())
|
||||
}
|
||||
|
||||
// We're fetching a smallish XML document over plain HTTP
|
||||
|
||||
Reference in New Issue
Block a user