Skip to content

Commit

Permalink
Extract peer real IP from Load Balancer when possible (netbirdio#1510)
Browse files Browse the repository at this point in the history
  • Loading branch information
surik authored Jan 31, 2024
1 parent 2746384 commit 8ac627d
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 14 deletions.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ require (
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6
golang.zx2c4.com/wireguard/windows v0.5.3
google.golang.org/grpc v1.56.3
google.golang.org/protobuf v1.30.0
google.golang.org/protobuf v1.31.0
gopkg.in/natefinch/lumberjack.v2 v2.0.0
)

Expand All @@ -47,6 +47,7 @@ require (
github.com/google/go-cmp v0.5.9
github.com/google/gopacket v1.1.19
github.com/google/nftables v0.0.0-20220808154552-2eca00135732
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.2-0.20240129190346-220740bc30b1
github.com/hashicorp/go-secure-stdlib/base62 v0.1.2
github.com/hashicorp/go-version v1.6.0
github.com/libp2p/go-netroute v0.2.0
Expand Down
5 changes: 4 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ 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.20240129190346-220740bc30b1 h1:AKSzml3dShaejT9YPRSjPmtx9i1FsevIxUll3vyitDo=
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.2-0.20240129190346-220740bc30b1/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=
Expand Down Expand Up @@ -940,8 +942,9 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
18 changes: 17 additions & 1 deletion management/cmd/management.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"io/fs"
"net"
"net/http"
"net/netip"
"net/url"
"os"
"path"
Expand All @@ -30,6 +31,7 @@ import (
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/keepalive"

"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/realip"
"github.com/netbirdio/netbird/encryption"
mgmtProto "github.com/netbirdio/netbird/management/proto"
"github.com/netbirdio/netbird/management/server"
Expand Down Expand Up @@ -168,7 +170,21 @@ var (

turnManager := server.NewTimeBasedAuthSecretsManager(peersUpdateManager, config.TURNConfig)

gRPCOpts := []grpc.ServerOption{grpc.KeepaliveEnforcementPolicy(kaep), grpc.KeepaliveParams(kasp)}
trustedPeers := config.TrustedHTTPProxies
if len(trustedPeers) == 0 {
trustedPeers = []netip.Prefix{netip.MustParsePrefix("0.0.0.0/0")}
}
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),
),
}
var certManager *autocert.Manager
var tlsConfig *tls.Config
tlsEnabled := false
Expand Down
3 changes: 3 additions & 0 deletions management/server/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package server

import (
"net/netip"
"net/url"

"github.com/netbirdio/netbird/management/server/idp"
Expand Down Expand Up @@ -40,6 +41,8 @@ type Config struct {

HttpConfig *HttpServerConfig

TrustedHTTPProxies []netip.Prefix

IdpManagerConfig *idp.Config

DeviceAuthorizationFlow *DeviceAuthorizationFlow
Expand Down
24 changes: 13 additions & 11 deletions management/server/grpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import (

pb "github.com/golang/protobuf/proto" // nolint
"github.com/golang/protobuf/ptypes/timestamp"
"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/realip"
log "github.com/sirupsen/logrus"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
"google.golang.org/grpc/codes"
gRPCPeer "google.golang.org/grpc/peer"
"google.golang.org/grpc/status"

"github.com/netbirdio/netbird/encryption"
Expand Down Expand Up @@ -109,17 +109,22 @@ func (s *GRPCServer) GetServerKey(ctx context.Context, req *proto.Empty) (*proto
}, nil
}

func getRealIP(ctx context.Context) string {
if ip, ok := realip.FromContext(ctx); ok {
return ip.String()
}
return ""
}

// Sync validates the existence of a connecting peer, sends an initial state (all available for the connecting peers) and
// notifies the connected peer of any updates (e.g. new peers under the same account)
func (s *GRPCServer) Sync(req *proto.EncryptedMessage, srv proto.ManagementService_SyncServer) error {
reqStart := time.Now()
if s.appMetrics != nil {
s.appMetrics.GRPCMetrics().CountSyncRequest()
}
p, ok := gRPCPeer.FromContext(srv.Context())
if ok {
log.Debugf("Sync request from peer [%s] [%s]", req.WgPubKey, p.Addr.String())
}
realIP := getRealIP(srv.Context())
log.Debugf("Sync request from peer [%s] [%s]", req.WgPubKey, realIP)

syncReq := &proto.SyncRequest{}
peerKey, err := s.parseRequest(req, syncReq)
Expand Down Expand Up @@ -290,10 +295,8 @@ func (s *GRPCServer) Login(ctx context.Context, req *proto.EncryptedMessage) (*p
if s.appMetrics != nil {
s.appMetrics.GRPCMetrics().CountLoginRequest()
}
p, ok := gRPCPeer.FromContext(ctx)
if ok {
log.Debugf("Login request from peer [%s] [%s]", req.WgPubKey, p.Addr.String())
}
realIP := getRealIP(ctx)
log.Debugf("Login request from peer [%s] [%s]", req.WgPubKey, realIP)

loginReq := &proto.LoginRequest{}
peerKey, err := s.parseRequest(req, loginReq)
Expand All @@ -303,8 +306,7 @@ func (s *GRPCServer) Login(ctx context.Context, req *proto.EncryptedMessage) (*p

if loginReq.GetMeta() == nil {
msg := status.Errorf(codes.FailedPrecondition,
"peer system meta has to be provided to log in. Peer %s, remote addr %s", peerKey.String(),
p.Addr.String())
"peer system meta has to be provided to log in. Peer %s, remote addr %s", peerKey.String(), realIP)
log.Warn(msg)
return nil, msg
}
Expand Down

0 comments on commit 8ac627d

Please sign in to comment.