mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-13 00:49:07 +02:00
Reaching an internal service meant installing the agent, which needs root for a TUN device. nblink runs the embedded client in netstack mode and forwards local HTTP listeners to upstreams inside the tunnel, so it works on managed machines and in rootless containers. Upstream names resolve in-process. Forwards bind loopback unless --allow-public-bind is given. The listener refuses rebound and cross-site browser requests and bounds stalled request bodies. It ships as release archives and a distroless image that runs under an arbitrary UID. An embedded client given no StatePath now keeps its state in memory rather than falling back to the installed agent's state file, which every embedded client in a proxy process also shared. The state manager gets an explicit in-memory store for it.
60 lines
1.6 KiB
Go
60 lines
1.6 KiB
Go
//go:build !js
|
|
|
|
package grpc
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net"
|
|
"os"
|
|
"runtime"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
"google.golang.org/grpc"
|
|
|
|
nbnet "github.com/netbirdio/netbird/client/net"
|
|
"github.com/netbirdio/netbird/client/netevents/sweep"
|
|
)
|
|
|
|
// Sweeper registers in-flight dials for the network change sweep.
|
|
type Sweeper interface {
|
|
StartDial(ctx context.Context) *sweep.Dial
|
|
}
|
|
|
|
func WithCustomDialer(_ bool, _ string) grpc.DialOption {
|
|
return grpc.WithContextDialer(dialContext)
|
|
}
|
|
|
|
// WithSweeper dials like WithCustomDialer but registers connections and
|
|
// dials with the sweeper. Append it after WithCustomDialer: gRPC applies
|
|
// dial options in order, so the later context dialer wins.
|
|
func WithSweeper(sweeper Sweeper) grpc.DialOption {
|
|
return grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) {
|
|
dial := sweeper.StartDial(ctx)
|
|
defer dial.Release()
|
|
|
|
conn, err := dialContext(dial.Ctx(), addr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return dial.WrapConn(conn)
|
|
})
|
|
}
|
|
|
|
func dialContext(ctx context.Context, addr string) (net.Conn, error) {
|
|
// The custom dialer requires root permissions which are not required for
|
|
// use cases run as non-root. The effective UID is read directly: a passwd
|
|
// lookup fails without cgo for a UID that has no entry, as on OpenShift.
|
|
if runtime.GOOS == "linux" && os.Geteuid() != 0 {
|
|
log.Debug("Not running as root, using standard dialer")
|
|
dialer := &net.Dialer{}
|
|
return dialer.DialContext(ctx, "tcp", addr)
|
|
}
|
|
|
|
conn, err := nbnet.NewDialer().DialContext(ctx, "tcp", addr)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("nbnet.NewDialer().DialContext: %w", err)
|
|
}
|
|
return conn, nil
|
|
}
|