[management] Read X-Real-IP when extracting the peer connection IP (#7561)

This commit is contained in:
Bethuel Mmbaga
2026-09-17 12:45:03 +03:00
committed by GitHub
parent 85a3913331
commit f8c3e565f3
2 changed files with 14 additions and 8 deletions
+3 -4
View File
@@ -373,9 +373,8 @@ func streamInterceptor(
// is used directly. Operators terminating connections at a reverse proxy should
// configure TrustedPeers with that proxy's address or network.
//
// Only X-Forwarded-For is trusted. X-Real-IP contains a single client-supplied
// address with no proxy chain to validate, and none of the reverse proxies we ship
// use it on the gRPC path.
// X-Forwarded-For is consulted first. X-Real-IP is read when X-Forwarded-For is
// absent or has no entries left after TrustedHTTPProxiesCount is applied.
func realIPOptions(cfg nbconfig.ReverseProxy) []realip.Option {
if idx := slices.IndexFunc(cfg.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 "+
@@ -393,6 +392,6 @@ func realIPOptions(cfg nbconfig.ReverseProxy) []realip.Option {
realip.WithTrustedPeers(cfg.TrustedPeers),
realip.WithTrustedProxies(cfg.TrustedHTTPProxies),
realip.WithTrustedProxiesCount(cfg.TrustedHTTPProxiesCount),
realip.WithHeaders([]string{realip.XForwardedFor}),
realip.WithHeaders([]string{realip.XForwardedFor, realip.XRealIp}),
}
}
+11 -4
View File
@@ -9,14 +9,13 @@ import (
"time"
"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/require"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/metadata"
"google.golang.org/protobuf/types/known/emptypb"
nbconfig "github.com/netbirdio/netbird/management/internals/server/config"
)
const (
@@ -161,11 +160,19 @@ func TestRealIPTrustedPeerHonoursForwardedHeaders(t *testing.T) {
)
}
func TestRealIPIgnoresXRealIPWhenProxyCountIsSet(t *testing.T) {
func TestRealIPReadsXRealIPWhenProxyCountSkipsForwardedFor(t *testing.T) {
cfg := nbconfig.ReverseProxy{
TrustedPeers: []netip.Prefix{netip.MustParsePrefix("127.0.0.1/32")},
TrustedHTTPProxiesCount: 1,
}
assertRealIP(t, cfg, "127.0.0.1", realip.XRealIp, "203.0.113.44")
t.Run("no X-Forwarded-For", func(t *testing.T) {
assertRealIP(t, cfg, "203.0.113.44", realip.XRealIp, "203.0.113.44")
})
t.Run("single-entry X-Forwarded-For", func(t *testing.T) {
assertRealIP(t, cfg, "198.51.100.7",
realip.XForwardedFor, "203.0.113.44",
realip.XRealIp, "198.51.100.7",
)
})
}