Skip to content

Commit

Permalink
Merge branch 'main' into remove-outbound-rules
Browse files Browse the repository at this point in the history
  • Loading branch information
lixmal authored Jan 7, 2025
2 parents 6ec9205 + d9905d1 commit 1a0b62b
Show file tree
Hide file tree
Showing 20 changed files with 808 additions and 512 deletions.
1 change: 1 addition & 0 deletions client/Dockerfile-rootless
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ ENV NB_FOREGROUND_MODE=true
ENV NB_USE_NETSTACK_MODE=true
ENV NB_CONFIG=config.json
ENV NB_DAEMON_ADDR=unix://netbird.sock
ENV NB_DISABLE_DNS=true

ENTRYPOINT [ "/usr/local/bin/netbird", "up" ]
31 changes: 31 additions & 0 deletions client/cmd/system.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package cmd

// Flag constants for system configuration
const (
disableClientRoutesFlag = "disable-client-routes"
disableServerRoutesFlag = "disable-server-routes"
disableDNSFlag = "disable-dns"
disableFirewallFlag = "disable-firewall"
)

var (
disableClientRoutes bool
disableServerRoutes bool
disableDNS bool
disableFirewall bool
)

func init() {
// Add system flags to upCmd
upCmd.PersistentFlags().BoolVar(&disableClientRoutes, disableClientRoutesFlag, false,
"Disable client routes. If enabled, the client won't process client routes received from the management service.")

upCmd.PersistentFlags().BoolVar(&disableServerRoutes, disableServerRoutesFlag, false,
"Disable server routes. If enabled, the client won't act as a router for server routes received from the management service.")

upCmd.PersistentFlags().BoolVar(&disableDNS, disableDNSFlag, false,
"Disable DNS. If enabled, the client won't configure DNS settings.")

upCmd.PersistentFlags().BoolVar(&disableFirewall, disableFirewallFlag, false,
"Disable firewall configuration. If enabled, the client won't modify firewall rules.")
}
26 changes: 26 additions & 0 deletions client/cmd/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,19 @@ func runInForegroundMode(ctx context.Context, cmd *cobra.Command) error {
ic.DNSRouteInterval = &dnsRouteInterval
}

if cmd.Flag(disableClientRoutesFlag).Changed {
ic.DisableClientRoutes = &disableClientRoutes
}
if cmd.Flag(disableServerRoutesFlag).Changed {
ic.DisableServerRoutes = &disableServerRoutes
}
if cmd.Flag(disableDNSFlag).Changed {
ic.DisableDNS = &disableDNS
}
if cmd.Flag(disableFirewallFlag).Changed {
ic.DisableFirewall = &disableFirewall
}

providedSetupKey, err := getSetupKey()
if err != nil {
return err
Expand Down Expand Up @@ -264,6 +277,19 @@ func runInDaemonMode(ctx context.Context, cmd *cobra.Command) error {
loginRequest.DnsRouteInterval = durationpb.New(dnsRouteInterval)
}

if cmd.Flag(disableClientRoutesFlag).Changed {
loginRequest.DisableClientRoutes = &disableClientRoutes
}
if cmd.Flag(disableServerRoutesFlag).Changed {
loginRequest.DisableServerRoutes = &disableServerRoutes
}
if cmd.Flag(disableDNSFlag).Changed {
loginRequest.DisableDns = &disableDNS
}
if cmd.Flag(disableFirewallFlag).Changed {
loginRequest.DisableFirewall = &disableFirewall
}

var loginErr error

var loginResp *proto.LoginResponse
Expand Down
2 changes: 2 additions & 0 deletions client/firewall/uspfilter/uspfilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,8 @@ func (m *Manager) trackICMPOutbound(d *decoder, srcIP, dstIP net.IP) {

// dropFilter implements filtering logic for incoming packets
func (m *Manager) dropFilter(packetData []byte, rules map[string]RuleSet) bool {
// TODO: Disable router if --disable-server-router is set

m.mutex.RLock()
defer m.mutex.RUnlock()

Expand Down
50 changes: 50 additions & 0 deletions client/internal/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ type ConfigInput struct {
DNSRouteInterval *time.Duration
ClientCertPath string
ClientCertKeyPath string

DisableClientRoutes *bool
DisableServerRoutes *bool
DisableDNS *bool
DisableFirewall *bool
}

// Config Configuration type
Expand All @@ -78,6 +83,12 @@ type Config struct {
RosenpassEnabled bool
RosenpassPermissive bool
ServerSSHAllowed *bool

DisableClientRoutes bool
DisableServerRoutes bool
DisableDNS bool
DisableFirewall bool

// SSHKey is a private SSH key in a PEM format
SSHKey string

Expand Down Expand Up @@ -402,7 +413,46 @@ func (config *Config) apply(input ConfigInput) (updated bool, err error) {
config.DNSRouteInterval = dynamic.DefaultInterval
log.Infof("using default DNS route interval %s", config.DNSRouteInterval)
updated = true
}

if input.DisableClientRoutes != nil && *input.DisableClientRoutes != config.DisableClientRoutes {
if *input.DisableClientRoutes {
log.Infof("disabling client routes")
} else {
log.Infof("enabling client routes")
}
config.DisableClientRoutes = *input.DisableClientRoutes
updated = true
}

if input.DisableServerRoutes != nil && *input.DisableServerRoutes != config.DisableServerRoutes {
if *input.DisableServerRoutes {
log.Infof("disabling server routes")
} else {
log.Infof("enabling server routes")
}
config.DisableServerRoutes = *input.DisableServerRoutes
updated = true
}

if input.DisableDNS != nil && *input.DisableDNS != config.DisableDNS {
if *input.DisableDNS {
log.Infof("disabling DNS configuration")
} else {
log.Infof("enabling DNS configuration")
}
config.DisableDNS = *input.DisableDNS
updated = true
}

if input.DisableFirewall != nil && *input.DisableFirewall != config.DisableFirewall {
if *input.DisableFirewall {
log.Infof("disabling firewall configuration")
} else {
log.Infof("enabling firewall configuration")
}
config.DisableFirewall = *input.DisableFirewall
updated = true
}

if input.ClientCertKeyPath != "" {
Expand Down
5 changes: 5 additions & 0 deletions client/internal/connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,11 @@ func createEngineConfig(key wgtypes.Key, config *Config, peerConfig *mgmProto.Pe
RosenpassPermissive: config.RosenpassPermissive,
ServerSSHAllowed: util.ReturnBoolWithDefaultTrue(config.ServerSSHAllowed),
DNSRouteInterval: config.DNSRouteInterval,

DisableClientRoutes: config.DisableClientRoutes,
DisableServerRoutes: config.DisableServerRoutes,
DisableDNS: config.DisableDNS,
DisableFirewall: config.DisableFirewall,
}

if config.PreSharedKey != "" {
Expand Down
14 changes: 14 additions & 0 deletions client/internal/dns/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,17 @@ func dnsConfigToHostDNSConfig(dnsConfig nbdns.Config, ip string, port int) HostD

return config
}

type noopHostConfigurator struct{}

func (n noopHostConfigurator) applyDNSConfig(HostDNSConfig, *statemanager.Manager) error {
return nil
}

func (n noopHostConfigurator) restoreHostDNS() error {
return nil
}

func (n noopHostConfigurator) supportCustomPort() bool {
return true
}
104 changes: 66 additions & 38 deletions client/internal/dns/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type registeredHandlerMap map[string]handlerWithStop
type DefaultServer struct {
ctx context.Context
ctxCancel context.CancelFunc
disableSys bool
mux sync.Mutex
service service
dnsMuxMap registeredHandlerMap
Expand Down Expand Up @@ -84,7 +85,14 @@ type muxUpdate struct {
}

// NewDefaultServer returns a new dns server
func NewDefaultServer(ctx context.Context, wgInterface WGIface, customAddress string, statusRecorder *peer.Status, stateManager *statemanager.Manager) (*DefaultServer, error) {
func NewDefaultServer(
ctx context.Context,
wgInterface WGIface,
customAddress string,
statusRecorder *peer.Status,
stateManager *statemanager.Manager,
disableSys bool,
) (*DefaultServer, error) {
var addrPort *netip.AddrPort
if customAddress != "" {
parsedAddrPort, err := netip.ParseAddrPort(customAddress)
Expand All @@ -101,7 +109,7 @@ func NewDefaultServer(ctx context.Context, wgInterface WGIface, customAddress st
dnsService = newServiceViaListener(wgInterface, addrPort)
}

return newDefaultServer(ctx, wgInterface, dnsService, statusRecorder, stateManager), nil
return newDefaultServer(ctx, wgInterface, dnsService, statusRecorder, stateManager, disableSys), nil
}

// NewDefaultServerPermanentUpstream returns a new dns server. It optimized for mobile systems
Expand All @@ -112,9 +120,10 @@ func NewDefaultServerPermanentUpstream(
config nbdns.Config,
listener listener.NetworkChangeListener,
statusRecorder *peer.Status,
disableSys bool,
) *DefaultServer {
log.Debugf("host dns address list is: %v", hostsDnsList)
ds := newDefaultServer(ctx, wgInterface, NewServiceViaMemory(wgInterface), statusRecorder, nil)
ds := newDefaultServer(ctx, wgInterface, NewServiceViaMemory(wgInterface), statusRecorder, nil, disableSys)
ds.hostsDNSHolder.set(hostsDnsList)
ds.permanent = true
ds.addHostRootZone()
Expand All @@ -131,17 +140,26 @@ func NewDefaultServerIos(
wgInterface WGIface,
iosDnsManager IosDnsManager,
statusRecorder *peer.Status,
disableSys bool,
) *DefaultServer {
ds := newDefaultServer(ctx, wgInterface, NewServiceViaMemory(wgInterface), statusRecorder, nil)
ds := newDefaultServer(ctx, wgInterface, NewServiceViaMemory(wgInterface), statusRecorder, nil, disableSys)
ds.iosDnsManager = iosDnsManager
return ds
}

func newDefaultServer(ctx context.Context, wgInterface WGIface, dnsService service, statusRecorder *peer.Status, stateManager *statemanager.Manager) *DefaultServer {
func newDefaultServer(
ctx context.Context,
wgInterface WGIface,
dnsService service,
statusRecorder *peer.Status,
stateManager *statemanager.Manager,
disableSys bool,
) *DefaultServer {
ctx, stop := context.WithCancel(ctx)
defaultServer := &DefaultServer{
ctx: ctx,
ctxCancel: stop,
disableSys: disableSys,
service: dnsService,
handlerChain: NewHandlerChain(),
dnsMuxMap: make(registeredHandlerMap),
Expand Down Expand Up @@ -220,6 +238,13 @@ func (s *DefaultServer) Initialize() (err error) {
}

s.stateManager.RegisterState(&ShutdownState{})

if s.disableSys {
log.Info("system DNS is disabled, not setting up host manager")
s.hostManager = &noopHostConfigurator{}
return nil
}

s.hostManager, err = s.initialize()
if err != nil {
return fmt.Errorf("initialize: %w", err)
Expand Down Expand Up @@ -268,47 +293,47 @@ func (s *DefaultServer) OnUpdatedHostDNSServer(hostsDnsList []string) {

// UpdateDNSServer processes an update received from the management service
func (s *DefaultServer) UpdateDNSServer(serial uint64, update nbdns.Config) error {
select {
case <-s.ctx.Done():
if s.ctx.Err() != nil {
log.Infof("not updating DNS server as context is closed")
return s.ctx.Err()
default:
if serial < s.updateSerial {
return fmt.Errorf("not applying dns update, error: "+
"network update is %d behind the last applied update", s.updateSerial-serial)
}
s.mux.Lock()
defer s.mux.Unlock()
}

if s.hostManager == nil {
return fmt.Errorf("dns service is not initialized yet")
}
if serial < s.updateSerial {
return fmt.Errorf("not applying dns update, error: "+
"network update is %d behind the last applied update", s.updateSerial-serial)
}

hash, err := hashstructure.Hash(update, hashstructure.FormatV2, &hashstructure.HashOptions{
ZeroNil: true,
IgnoreZeroValue: true,
SlicesAsSets: true,
UseStringer: true,
})
if err != nil {
log.Errorf("unable to hash the dns configuration update, got error: %s", err)
}
s.mux.Lock()
defer s.mux.Unlock()

if s.previousConfigHash == hash {
log.Debugf("not applying the dns configuration update as there is nothing new")
s.updateSerial = serial
return nil
}
if s.hostManager == nil {
return fmt.Errorf("dns service is not initialized yet")
}

if err := s.applyConfiguration(update); err != nil {
return fmt.Errorf("apply configuration: %w", err)
}
hash, err := hashstructure.Hash(update, hashstructure.FormatV2, &hashstructure.HashOptions{
ZeroNil: true,
IgnoreZeroValue: true,
SlicesAsSets: true,
UseStringer: true,
})
if err != nil {
log.Errorf("unable to hash the dns configuration update, got error: %s", err)
}

if s.previousConfigHash == hash {
log.Debugf("not applying the dns configuration update as there is nothing new")
s.updateSerial = serial
s.previousConfigHash = hash

return nil
}

if err := s.applyConfiguration(update); err != nil {
return fmt.Errorf("apply configuration: %w", err)
}

s.updateSerial = serial
s.previousConfigHash = hash

return nil
}

func (s *DefaultServer) SearchDomains() []string {
Expand Down Expand Up @@ -627,8 +652,11 @@ func (s *DefaultServer) upstreamCallbacks(
s.currentConfig.RouteAll = true
s.registerHandler([]string{nbdns.RootZone}, handler, PriorityDefault)
}
if err := s.hostManager.applyDNSConfig(s.currentConfig, s.stateManager); err != nil {
l.WithError(err).Error("reactivate temporary disabled nameserver group, DNS update apply")

if s.hostManager != nil {
if err := s.hostManager.applyDNSConfig(s.currentConfig, s.stateManager); err != nil {
l.WithError(err).Error("reactivate temporary disabled nameserver group, DNS update apply")
}
}

s.updateNSState(nsGroup, nil, true)
Expand Down
Loading

0 comments on commit 1a0b62b

Please sign in to comment.