diff --git a/.goreleaser.yaml b/.goreleaser.yaml index e718b3fcd..d6479763e 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -179,6 +179,51 @@ dockers: - "--label=org.opencontainers.image.revision={{.FullCommit}}" - "--label=org.opencontainers.image.version={{.Version}}" - "--label=maintainer=dev@netbird.io" + + - image_templates: + - netbirdio/netbird:{{ .Version }}-rootless-amd64 + ids: + - netbird + goarch: amd64 + use: buildx + dockerfile: client/Dockerfile-rootless + build_flag_templates: + - "--platform=linux/amd64" + - "--label=org.opencontainers.image.created={{.Date}}" + - "--label=org.opencontainers.image.title={{.ProjectName}}" + - "--label=org.opencontainers.image.version={{.Version}}" + - "--label=org.opencontainers.image.revision={{.FullCommit}}" + - "--label=maintainer=dev@netbird.io" + - image_templates: + - netbirdio/netbird:{{ .Version }}-rootless-arm64v8 + ids: + - netbird + goarch: arm64 + use: buildx + dockerfile: client/Dockerfile-rootless + build_flag_templates: + - "--platform=linux/arm64" + - "--label=org.opencontainers.image.created={{.Date}}" + - "--label=org.opencontainers.image.title={{.ProjectName}}" + - "--label=org.opencontainers.image.version={{.Version}}" + - "--label=org.opencontainers.image.revision={{.FullCommit}}" + - "--label=maintainer=dev@netbird.io" + - image_templates: + - netbirdio/netbird:{{ .Version }}-rootless-arm + ids: + - netbird + goarch: arm + goarm: 6 + use: buildx + dockerfile: client/Dockerfile-rootless + build_flag_templates: + - "--platform=linux/arm" + - "--label=org.opencontainers.image.created={{.Date}}" + - "--label=org.opencontainers.image.title={{.ProjectName}}" + - "--label=org.opencontainers.image.version={{.Version}}" + - "--label=org.opencontainers.image.revision={{.FullCommit}}" + - "--label=maintainer=dev@netbird.io" + - image_templates: - netbirdio/relay:{{ .Version }}-amd64 ids: @@ -377,6 +422,18 @@ docker_manifests: - netbirdio/netbird:{{ .Version }}-arm - netbirdio/netbird:{{ .Version }}-amd64 + - name_template: netbirdio/netbird:{{ .Version }}-rootless + image_templates: + - netbirdio/netbird:{{ .Version }}-rootless-arm64v8 + - netbirdio/netbird:{{ .Version }}-rootless-arm + - netbirdio/netbird:{{ .Version }}-rootless-amd64 + + - name_template: netbirdio/netbird:rootless-latest + image_templates: + - netbirdio/netbird:{{ .Version }}-rootless-arm64v8 + - netbirdio/netbird:{{ .Version }}-rootless-arm + - netbirdio/netbird:{{ .Version }}-rootless-amd64 + - name_template: netbirdio/relay:{{ .Version }} image_templates: - netbirdio/relay:{{ .Version }}-arm64v8 diff --git a/client/Dockerfile-rootless b/client/Dockerfile-rootless new file mode 100644 index 000000000..f206debb5 --- /dev/null +++ b/client/Dockerfile-rootless @@ -0,0 +1,15 @@ +FROM alpine:3.21.0 + +COPY netbird /usr/local/bin/netbird + +RUN apk add --no-cache ca-certificates \ + && adduser -D -h /var/lib/netbird netbird +WORKDIR /var/lib/netbird +USER netbird:netbird + +ENV NB_FOREGROUND_MODE=true +ENV NB_USE_NETSTACK_MODE=true +ENV NB_CONFIG=config.json +ENV NB_DAEMON_ADDR=unix://netbird.sock + +ENTRYPOINT [ "/usr/local/bin/netbird", "up" ] diff --git a/client/iface/netstack/env.go b/client/iface/netstack/env.go index c77e39fe0..09889a57e 100644 --- a/client/iface/netstack/env.go +++ b/client/iface/netstack/env.go @@ -15,6 +15,10 @@ func IsEnabled() bool { func ListenAddr() string { sPort := os.Getenv("NB_SOCKS5_LISTENER_PORT") + if sPort == "" { + return listenAddr(DefaultSocks5Port) + } + port, err := strconv.Atoi(sPort) if err != nil { log.Warnf("invalid socks5 listener port, unable to convert it to int, falling back to default: %d", DefaultSocks5Port) diff --git a/client/internal/routemanager/manager.go b/client/internal/routemanager/manager.go index 389e97e2d..e25192398 100644 --- a/client/internal/routemanager/manager.go +++ b/client/internal/routemanager/manager.go @@ -17,6 +17,7 @@ import ( firewall "github.com/netbirdio/netbird/client/firewall/manager" "github.com/netbirdio/netbird/client/iface" "github.com/netbirdio/netbird/client/iface/configurer" + "github.com/netbirdio/netbird/client/iface/netstack" "github.com/netbirdio/netbird/client/internal/dns" "github.com/netbirdio/netbird/client/internal/listener" "github.com/netbirdio/netbird/client/internal/peer" @@ -104,22 +105,43 @@ func NewManager( peerStore: peerStore, } - dm.routeRefCounter = refcounter.New( + dm.setupRefCounters() + + if runtime.GOOS == "android" { + cr := dm.initialClientRoutes(initialRoutes) + dm.notifier.SetInitialClientRoutes(cr) + } + return dm +} + +func (m *DefaultManager) setupRefCounters() { + m.routeRefCounter = refcounter.New( func(prefix netip.Prefix, _ struct{}) (struct{}, error) { - return struct{}{}, sysOps.AddVPNRoute(prefix, wgInterface.ToInterface()) + return struct{}{}, m.sysOps.AddVPNRoute(prefix, m.wgInterface.ToInterface()) }, func(prefix netip.Prefix, _ struct{}) error { - return sysOps.RemoveVPNRoute(prefix, wgInterface.ToInterface()) + return m.sysOps.RemoveVPNRoute(prefix, m.wgInterface.ToInterface()) }, ) - dm.allowedIPsRefCounter = refcounter.New( + if netstack.IsEnabled() { + m.routeRefCounter = refcounter.New( + func(netip.Prefix, struct{}) (struct{}, error) { + return struct{}{}, refcounter.ErrIgnore + }, + func(netip.Prefix, struct{}) error { + return nil + }, + ) + } + + m.allowedIPsRefCounter = refcounter.New( func(prefix netip.Prefix, peerKey string) (string, error) { // save peerKey to use it in the remove function - return peerKey, wgInterface.AddAllowedIP(peerKey, prefix.String()) + return peerKey, m.wgInterface.AddAllowedIP(peerKey, prefix.String()) }, func(prefix netip.Prefix, peerKey string) error { - if err := wgInterface.RemoveAllowedIP(peerKey, prefix.String()); err != nil { + if err := m.wgInterface.RemoveAllowedIP(peerKey, prefix.String()); err != nil { if !errors.Is(err, configurer.ErrPeerNotFound) && !errors.Is(err, configurer.ErrAllowedIPNotFound) { return err } @@ -128,12 +150,6 @@ func NewManager( return nil }, ) - - if runtime.GOOS == "android" { - cr := dm.initialClientRoutes(initialRoutes) - dm.notifier.SetInitialClientRoutes(cr) - } - return dm } // Init sets up the routing diff --git a/client/internal/routemanager/systemops/systemops_generic.go b/client/internal/routemanager/systemops/systemops_generic.go index 3038c3ec5..31b7f3ac2 100644 --- a/client/internal/routemanager/systemops/systemops_generic.go +++ b/client/internal/routemanager/systemops/systemops_generic.go @@ -17,6 +17,7 @@ import ( nberrors "github.com/netbirdio/netbird/client/errors" "github.com/netbirdio/netbird/client/iface" + "github.com/netbirdio/netbird/client/iface/netstack" "github.com/netbirdio/netbird/client/internal/routemanager/refcounter" "github.com/netbirdio/netbird/client/internal/routemanager/util" "github.com/netbirdio/netbird/client/internal/routemanager/vars" @@ -62,6 +63,17 @@ func (r *SysOps) setupRefCounter(initAddresses []net.IP, stateManager *statemana r.removeFromRouteTable, ) + if netstack.IsEnabled() { + refCounter = refcounter.New( + func(netip.Prefix, struct{}) (Nexthop, error) { + return Nexthop{}, refcounter.ErrIgnore + }, + func(netip.Prefix, Nexthop) error { + return nil + }, + ) + } + r.refCounter = refCounter return r.setupHooks(initAddresses, stateManager)