mirror of
https://github.com/netbirdio/netbird.git
synced 2026-09-26 08:39:06 +02:00
[management] Handle empty trusted peer (#7589)
This commit is contained in:
@@ -808,9 +808,8 @@ server:
|
|||||||
|
|
||||||
# Trust X-Forwarded-* only from the Traefik container's static address. Both
|
# Trust X-Forwarded-* only from the Traefik container's static address. Both
|
||||||
# keys must stay in step with the ipv4_address pinned in docker-compose.yml:
|
# keys must stay in step with the ipv4_address pinned in docker-compose.yml:
|
||||||
# trustedPeers decides whether forwarded headers are read at all. Leaving it
|
# trustedPeers restricts which sources may supply forwarded headers. Leaving
|
||||||
# unset trusts nothing and records Traefik's own address as every peer's
|
# it unset trusts all IPv4 and IPv6 sources.
|
||||||
# connection IP.
|
|
||||||
reverseProxy:
|
reverseProxy:
|
||||||
trustedPeers:
|
trustedPeers:
|
||||||
- "${TRAEFIK_IP}/32"
|
- "${TRAEFIK_IP}/32"
|
||||||
|
|||||||
@@ -586,9 +586,9 @@ configure_reverse_proxy() {
|
|||||||
TRUSTED_PEERS="${NETBIRD_TRUSTED_PEERS:-}"
|
TRUSTED_PEERS="${NETBIRD_TRUSTED_PEERS:-}"
|
||||||
if [[ -z "$TRUSTED_PEERS" ]]; then
|
if [[ -z "$TRUSTED_PEERS" ]]; then
|
||||||
echo "" > /dev/stderr
|
echo "" > /dev/stderr
|
||||||
echo "Note: reverseProxy.trustedPeers is unset, so NetBird will use the address your" > /dev/stderr
|
echo "Warning: reverseProxy.trustedPeers is unset, so all IPv4 and IPv6 sources" > /dev/stderr
|
||||||
echo "proxy connects from as each peer's connection IP. To record real client IPs," > /dev/stderr
|
echo "are trusted to provide forwarded client-IP headers. Set NETBIRD_TRUSTED_PEERS" > /dev/stderr
|
||||||
echo "set NETBIRD_TRUSTED_PEERS to your proxy's address (e.g. 172.20.0.5/32) and re-run." > /dev/stderr
|
echo "to your proxy's address (e.g. 172.20.0.5/32) and re-run." > /dev/stderr
|
||||||
echo "" > /dev/stderr
|
echo "" > /dev/stderr
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -366,20 +366,24 @@ func streamInterceptor(
|
|||||||
return handler(srv, wrapped)
|
return handler(srv, wrapped)
|
||||||
}
|
}
|
||||||
|
|
||||||
// realIPOptions builds the real-IP middleware options from the reverse proxy config.
|
// realIPOptions builds the real-IP middleware options.
|
||||||
//
|
//
|
||||||
// TrustedPeers controls which transport peers are allowed to supply forwarded-IP
|
// Empty TrustedPeers trusts all IPv4 and IPv6 sources. Configure TrustedPeers
|
||||||
// headers. If empty, forwarded headers are ignored and the transport peer address
|
// with the reverse proxy address or network.
|
||||||
// is used directly. Operators terminating connections at a reverse proxy should
|
|
||||||
// configure TrustedPeers with that proxy's address or network.
|
|
||||||
//
|
//
|
||||||
// X-Forwarded-For is consulted first. X-Real-IP is read when X-Forwarded-For is
|
// X-Forwarded-For takes precedence over X-Real-IP.
|
||||||
// absent or has no entries left after TrustedHTTPProxiesCount is applied.
|
|
||||||
func realIPOptions(cfg nbconfig.ReverseProxy) []realip.Option {
|
func realIPOptions(cfg nbconfig.ReverseProxy) []realip.Option {
|
||||||
if idx := slices.IndexFunc(cfg.TrustedPeers, func(p netip.Prefix) bool { return p.Bits() == 0 }); idx >= 0 {
|
trustedPeers := cfg.TrustedPeers
|
||||||
|
if len(trustedPeers) == 0 {
|
||||||
|
trustedPeers = []netip.Prefix{
|
||||||
|
netip.MustParsePrefix("0.0.0.0/0"),
|
||||||
|
netip.MustParsePrefix("::/0"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if idx := slices.IndexFunc(trustedPeers, func(p netip.Prefix) bool { return p.Bits() == 0 }); idx >= 0 {
|
||||||
log.WithContext(context.Background()).Warnf("TrustedPeers contains the default route %s, which trusts "+
|
log.WithContext(context.Background()).Warnf("TrustedPeers contains the default route %s, which trusts "+
|
||||||
"X-Forwarded-For from every client and allows connection IP spoofing. Set TrustedPeers to the address "+
|
"X-Forwarded-For from every client and allows connection IP spoofing. Set TrustedPeers to the address "+
|
||||||
"of your reverse proxy, or leave it empty to use the connection's source address.", cfg.TrustedPeers[idx])
|
"of your reverse proxy.", trustedPeers[idx])
|
||||||
}
|
}
|
||||||
if cfg.TrustedHTTPProxiesCount > 0 {
|
if cfg.TrustedHTTPProxiesCount > 0 {
|
||||||
log.WithContext(context.Background()).Warn(
|
log.WithContext(context.Background()).Warn(
|
||||||
@@ -389,7 +393,7 @@ func realIPOptions(cfg nbconfig.ReverseProxy) []realip.Option {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return []realip.Option{
|
return []realip.Option{
|
||||||
realip.WithTrustedPeers(cfg.TrustedPeers),
|
realip.WithTrustedPeers(trustedPeers),
|
||||||
realip.WithTrustedProxies(cfg.TrustedHTTPProxies),
|
realip.WithTrustedProxies(cfg.TrustedHTTPProxies),
|
||||||
realip.WithTrustedProxiesCount(cfg.TrustedHTTPProxiesCount),
|
realip.WithTrustedProxiesCount(cfg.TrustedHTTPProxiesCount),
|
||||||
realip.WithHeaders([]string{realip.XForwardedFor, realip.XRealIp}),
|
realip.WithHeaders([]string{realip.XForwardedFor, realip.XRealIp}),
|
||||||
|
|||||||
@@ -9,13 +9,14 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/realip"
|
"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/realip"
|
||||||
nbconfig "github.com/netbirdio/netbird/management/internals/server/config"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
"google.golang.org/protobuf/types/known/emptypb"
|
"google.golang.org/protobuf/types/known/emptypb"
|
||||||
|
|
||||||
|
nbconfig "github.com/netbirdio/netbird/management/internals/server/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -135,8 +136,8 @@ func assertRealIP(t *testing.T, cfg nbconfig.ReverseProxy, want string, kv ...st
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRealIPDefaultIgnoresClientForwardedHeaders(t *testing.T) {
|
func TestRealIPDefaultTrustsForwardedHeaders(t *testing.T) {
|
||||||
assertRealIP(t, nbconfig.ReverseProxy{}, "127.0.0.1",
|
assertRealIP(t, nbconfig.ReverseProxy{}, "203.0.113.44",
|
||||||
realip.XForwardedFor, "203.0.113.44",
|
realip.XForwardedFor, "203.0.113.44",
|
||||||
realip.XRealIp, "203.0.113.44",
|
realip.XRealIp, "203.0.113.44",
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user