Skip to content

Commit

Permalink
[client] Add rootless container and fix client routes in netstack mode (
Browse files Browse the repository at this point in the history
  • Loading branch information
lixmal authored Jan 6, 2025
1 parent 668aead commit 6848e1e
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 12 deletions.
57 changes: 57 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,51 @@ dockers:
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
- "--label=org.opencontainers.image.version={{.Version}}"
- "[email protected]"

- 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}}"
- "[email protected]"
- 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}}"
- "[email protected]"
- 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}}"
- "[email protected]"

- image_templates:
- netbirdio/relay:{{ .Version }}-amd64
ids:
Expand Down Expand Up @@ -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
Expand Down
15 changes: 15 additions & 0 deletions client/Dockerfile-rootless
Original file line number Diff line number Diff line change
@@ -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" ]
4 changes: 4 additions & 0 deletions client/iface/netstack/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
40 changes: 28 additions & 12 deletions client/internal/routemanager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
}
Expand All @@ -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
Expand Down
12 changes: 12 additions & 0 deletions client/internal/routemanager/systemops/systemops_generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 6848e1e

Please sign in to comment.