Add proxy <-> management authentication

This commit is contained in:
Viktor Liu
2026-02-06 02:06:24 +08:00
parent 2f263bf7e6
commit 0a3a9f977d
17 changed files with 1256 additions and 17 deletions

View File

@@ -2,6 +2,7 @@ package cmd
import (
"context"
"fmt"
"os"
"strconv"
"strings"
@@ -16,6 +17,9 @@ import (
const DefaultManagementURL = "https://api.netbird.io:443"
// envProxyToken is the environment variable name for the proxy access token.
const envProxyToken = "NB_PROXY_TOKEN"
var (
Version = "dev"
Commit = "unknown"
@@ -42,11 +46,12 @@ var (
)
var rootCmd = &cobra.Command{
Use: "proxy",
Short: "NetBird reverse proxy server",
Long: "NetBird reverse proxy server for proxying traffic to NetBird networks.",
Version: Version,
RunE: runServer,
Use: "proxy",
Short: "NetBird reverse proxy server",
Long: "NetBird reverse proxy server for proxying traffic to NetBird networks.",
Version: Version,
SilenceUsage: true,
RunE: runServer,
}
func init() {
@@ -85,6 +90,11 @@ func SetVersionInfo(version, commit, buildDate, goVersion string) {
}
func runServer(cmd *cobra.Command, args []string) error {
proxyToken := os.Getenv(envProxyToken)
if proxyToken == "" {
return fmt.Errorf("proxy token is required: set %s environment variable", envProxyToken)
}
level := "error"
if debugLogs {
level = "debug"
@@ -100,6 +110,7 @@ func runServer(cmd *cobra.Command, args []string) error {
Version: Version,
ManagementAddress: mgmtAddr,
ProxyURL: proxyURL,
ProxyToken: proxyToken,
CertificateDirectory: certDir,
GenerateACMECertificates: acmeCerts,
ACMEChallengeAddress: acmeAddr,

View File

@@ -49,6 +49,13 @@ spec:
value: "https://proxy.local"
- name: NB_PROXY_CERTIFICATE_DIRECTORY
value: "/certs"
- name: NB_PROXY_TOKEN
valueFrom:
secretKeyRef:
name: netbird-proxy-token
key: token
- name: NB_PROXY_ALLOW_INSECURE
value: "true" # Required for HTTP management connection in dev
volumeMounts:
- name: tls-certs
mountPath: /certs

View File

@@ -0,0 +1,48 @@
// Package grpc provides gRPC utilities for the proxy client.
package grpc
import (
"context"
"os"
"strconv"
log "github.com/sirupsen/logrus"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
// EnvProxyAllowInsecure controls whether the proxy token can be sent over non-TLS connections.
const EnvProxyAllowInsecure = "NB_PROXY_ALLOW_INSECURE"
var _ credentials.PerRPCCredentials = (*proxyAuthToken)(nil)
type proxyAuthToken struct {
token string
allowInsecure bool
}
func (t proxyAuthToken) GetRequestMetadata(context.Context, ...string) (map[string]string, error) {
return map[string]string{
"authorization": "Bearer " + t.token,
}, nil
}
// RequireTransportSecurity returns true by default to protect the token in transit.
// Set NB_PROXY_ALLOW_INSECURE=true to allow non-TLS connections (not recommended for production).
func (t proxyAuthToken) RequireTransportSecurity() bool {
return !t.allowInsecure
}
// WithProxyToken returns a DialOption that sets the proxy access token on each outbound RPC.
func WithProxyToken(token string) grpc.DialOption {
allowInsecure := false
if val := os.Getenv(EnvProxyAllowInsecure); val != "" {
parsed, err := strconv.ParseBool(val)
if err != nil {
log.Warnf("invalid value for %s: %v", EnvProxyAllowInsecure, err)
} else {
allowInsecure = parsed
}
}
return grpc.WithPerRPCCredentials(proxyAuthToken{token: token, allowInsecure: allowInsecure})
}

View File

@@ -32,6 +32,7 @@ import (
"github.com/netbirdio/netbird/proxy/internal/acme"
"github.com/netbirdio/netbird/proxy/internal/auth"
"github.com/netbirdio/netbird/proxy/internal/debug"
proxygrpc "github.com/netbirdio/netbird/proxy/internal/grpc"
"github.com/netbirdio/netbird/proxy/internal/health"
"github.com/netbirdio/netbird/proxy/internal/proxy"
"github.com/netbirdio/netbird/proxy/internal/roundtrip"
@@ -76,6 +77,8 @@ type Server struct {
DebugEndpointAddress string
// HealthAddress is the address for the health probe endpoint (default: "localhost:8080").
HealthAddress string
// ProxyToken is the access token for authenticating with the management server.
ProxyToken string
}
// NotifyStatus sends a status update to management about tunnel connectivity
@@ -153,6 +156,7 @@ func (s *Server) ListenAndServe(ctx context.Context, addr string) (err error) {
Timeout: 10 * time.Second,
PermitWithoutStream: true,
}),
proxygrpc.WithProxyToken(s.ProxyToken),
)
if err != nil {
return fmt.Errorf("could not create management connection: %w", err)