Expose trusted proxy list and counter configuration for realip middleware (#1535)

This commit is contained in:
Yury Gargay 2024-02-08 14:40:40 +01:00 committed by GitHub
parent a7547b9990
commit fb30931365
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 48 additions and 14 deletions

2
go.mod
View File

@ -171,3 +171,5 @@ replace github.com/getlantern/systray => github.com/netbirdio/systray v0.0.0-202
replace golang.zx2c4.com/wireguard => github.com/netbirdio/wireguard-go v0.0.0-20240105182236-6c340dd55aed
replace github.com/cloudflare/circl => github.com/cunicu/circl v0.0.0-20230801113412-fec58fc7b5f6
replace github.com/grpc-ecosystem/go-grpc-middleware/v2 => github.com/surik/go-grpc-middleware/v2 v2.0.0-20240206110057-98a38fc1f86f

4
go.sum
View File

@ -286,8 +286,6 @@ github.com/gopherjs/gopherjs v0.0.0-20220410123724-9e86199038b0 h1:fWY+zXdWhvWnd
github.com/gopherjs/gopherjs v0.0.0-20220410123724-9e86199038b0/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.2-0.20240202184442-37827591b26c h1:Kvw2BIua5WGDnknpnODn9K74PYWLhhqt8G3l0chyzEI=
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.2-0.20240202184442-37827591b26c/go.mod h1:w9Y7gY31krpLmrVU5ZPG9H7l9fZuRu5/3R3S3FMtVQ4=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hashicorp/go-secure-stdlib/base62 v0.1.2 h1:ET4pqyjiGmY09R5y+rSd70J2w45CtbWDNvGqWp/R3Ng=
github.com/hashicorp/go-secure-stdlib/base62 v0.1.2/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw=
@ -519,6 +517,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/surik/go-grpc-middleware/v2 v2.0.0-20240206110057-98a38fc1f86f h1:J+egXEDkpg/vOYYzPO5IwF8OufGb7g+KcwEF1AWIzhQ=
github.com/surik/go-grpc-middleware/v2 v2.0.0-20240206110057-98a38fc1f86f/go.mod h1:w9Y7gY31krpLmrVU5ZPG9H7l9fZuRu5/3R3S3FMtVQ4=
github.com/things-go/go-socks5 v0.0.4 h1:jMQjIc+qhD4z9cITOMnBiwo9dDmpGuXmBlkRFrl/qD0=
github.com/things-go/go-socks5 v0.0.4/go.mod h1:sh4K6WHrmHZpjxLTCHyYtXYH8OUuD+yZun41NomR1IQ=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=

View File

@ -15,6 +15,7 @@ import (
"net/url"
"os"
"path"
"slices"
"strings"
"time"
@ -170,21 +171,31 @@ var (
turnManager := server.NewTimeBasedAuthSecretsManager(peersUpdateManager, config.TURNConfig)
trustedPeers := config.TrustedHTTPProxies
if len(trustedPeers) == 0 {
trustedPeers = []netip.Prefix{netip.MustParsePrefix("0.0.0.0/0")}
trustedPeers := config.ReverseProxy.TrustedPeers
defaultTrustedPeers := []netip.Prefix{netip.MustParsePrefix("0.0.0.0/0"), netip.MustParsePrefix("::/0")}
if len(trustedPeers) == 0 || slices.Equal[[]netip.Prefix](trustedPeers, defaultTrustedPeers) {
log.Warn("TrustedPeers are configured to default value '0.0.0.0/0', '::/0'. This allows connection IP spoofing.")
trustedPeers = defaultTrustedPeers
}
trustedHTTPProxies := config.ReverseProxy.TrustedHTTPProxies
trustedProxiesCount := config.ReverseProxy.TrustedHTTPProxiesCount
if len(trustedHTTPProxies) > 0 && trustedProxiesCount > 0 {
log.Warn("TrustedHTTPProxies and TrustedHTTPProxiesCount both are configured. " +
"This is not recommended way to extract X-Forwarded-For. Consider using one of these options.")
}
realipOpts := realip.Opts{
TrustedPeers: trustedPeers,
TrustedProxies: trustedHTTPProxies,
TrustedProxiesCount: trustedProxiesCount,
Headers: []string{realip.XForwardedFor, realip.XRealIp},
}
headers := []string{realip.XForwardedFor, realip.XRealIp}
gRPCOpts := []grpc.ServerOption{
grpc.KeepaliveEnforcementPolicy(kaep),
grpc.KeepaliveParams(kasp),
grpc.ChainUnaryInterceptor(
realip.UnaryServerInterceptor(trustedPeers, headers),
),
grpc.ChainStreamInterceptor(
realip.StreamServerInterceptor(trustedPeers, headers),
),
grpc.ChainUnaryInterceptor(realip.UnaryServerInterceptorOpts(realipOpts)),
grpc.ChainStreamInterceptor(realip.StreamServerInterceptorOpts(realipOpts)),
}
var certManager *autocert.Manager
var tlsConfig *tls.Config
tlsEnabled := false

View File

@ -41,8 +41,6 @@ type Config struct {
HttpConfig *HttpServerConfig
TrustedHTTPProxies []netip.Prefix
IdpManagerConfig *idp.Config
DeviceAuthorizationFlow *DeviceAuthorizationFlow
@ -50,6 +48,8 @@ type Config struct {
PKCEAuthorizationFlow *PKCEAuthorizationFlow
StoreConfig StoreConfig
ReverseProxy ReverseProxy
}
// GetAuthAudiences returns the audience from the http config and device authorization flow config
@ -146,6 +146,27 @@ type StoreConfig struct {
Engine StoreEngine
}
// ReverseProxy contains reverse proxy configuration in front of management.
type ReverseProxy struct {
// TrustedHTTPProxies represents a list of trusted HTTP proxies by their IP prefixes.
// When extracting the real IP address from request headers, the middleware will verify
// if the peer's address falls within one of these trusted IP prefixes.
TrustedHTTPProxies []netip.Prefix
// TrustedHTTPProxiesCount specifies the count of trusted HTTP proxies between the internet
// and the server. When using the trusted proxy count method to extract the real IP address,
// the middleware will search the X-Forwarded-For IP list from the rightmost by this count
// minus one.
TrustedHTTPProxiesCount uint
// TrustedPeers represents a list of trusted peers by their IP prefixes.
// These peers are considered trustworthy by the gRPC server operator,
// and the middleware will attempt to extract the real IP address from
// request headers if the peer's address falls within one of these
// trusted IP prefixes.
TrustedPeers []netip.Prefix
}
// validateURL validates input http url
func validateURL(httpURL string) bool {
_, err := url.ParseRequestURI(httpURL)