mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-16 07:16:38 +00:00
[client] Run registerdns before flushing (#3926)
* Run registerdns before flushing * Disable WINS, dynamic updates and registration
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
package dns
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
log "github.com/sirupsen/logrus"
|
||||
@@ -41,6 +44,20 @@ const (
|
||||
interfaceConfigNameServerKey = "NameServer"
|
||||
interfaceConfigSearchListKey = "SearchList"
|
||||
|
||||
// Network interface DNS registration settings
|
||||
disableDynamicUpdateKey = "DisableDynamicUpdate"
|
||||
registrationEnabledKey = "RegistrationEnabled"
|
||||
maxNumberOfAddressesToRegisterKey = "MaxNumberOfAddressesToRegister"
|
||||
|
||||
// NetBIOS/WINS settings
|
||||
netbtInterfacePath = `SYSTEM\CurrentControlSet\Services\NetBT\Parameters\Interfaces`
|
||||
netbiosOptionsKey = "NetbiosOptions"
|
||||
|
||||
// NetBIOS option values: 0 = from DHCP, 1 = enabled, 2 = disabled
|
||||
netbiosFromDHCP = 0
|
||||
netbiosEnabled = 1
|
||||
netbiosDisabled = 2
|
||||
|
||||
// RP_FORCE: Reapply all policies even if no policy change was detected
|
||||
rpForce = 0x1
|
||||
)
|
||||
@@ -67,16 +84,85 @@ func newHostManager(wgInterface WGIface) (*registryConfigurator, error) {
|
||||
log.Infof("detected GPO DNS policy configuration, using policy store")
|
||||
}
|
||||
|
||||
return ®istryConfigurator{
|
||||
configurator := ®istryConfigurator{
|
||||
guid: guid,
|
||||
gpo: useGPO,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if err := configurator.configureInterface(); err != nil {
|
||||
log.Errorf("failed to configure interface settings: %v", err)
|
||||
}
|
||||
|
||||
return configurator, nil
|
||||
}
|
||||
|
||||
func (r *registryConfigurator) supportCustomPort() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *registryConfigurator) configureInterface() error {
|
||||
var merr *multierror.Error
|
||||
|
||||
if err := r.disableDNSRegistrationForInterface(); err != nil {
|
||||
merr = multierror.Append(merr, fmt.Errorf("disable DNS registration: %w", err))
|
||||
}
|
||||
|
||||
if err := r.disableWINSForInterface(); err != nil {
|
||||
merr = multierror.Append(merr, fmt.Errorf("disable WINS: %w", err))
|
||||
}
|
||||
|
||||
return nberrors.FormatErrorOrNil(merr)
|
||||
}
|
||||
|
||||
func (r *registryConfigurator) disableDNSRegistrationForInterface() error {
|
||||
regKey, err := r.getInterfaceRegistryKey()
|
||||
if err != nil {
|
||||
return fmt.Errorf("get interface registry key: %w", err)
|
||||
}
|
||||
defer closer(regKey)
|
||||
|
||||
var merr *multierror.Error
|
||||
|
||||
if err := regKey.SetDWordValue(disableDynamicUpdateKey, 1); err != nil {
|
||||
merr = multierror.Append(merr, fmt.Errorf("set %s: %w", disableDynamicUpdateKey, err))
|
||||
}
|
||||
|
||||
if err := regKey.SetDWordValue(registrationEnabledKey, 0); err != nil {
|
||||
merr = multierror.Append(merr, fmt.Errorf("set %s: %w", registrationEnabledKey, err))
|
||||
}
|
||||
|
||||
if err := regKey.SetDWordValue(maxNumberOfAddressesToRegisterKey, 0); err != nil {
|
||||
merr = multierror.Append(merr, fmt.Errorf("set %s: %w", maxNumberOfAddressesToRegisterKey, err))
|
||||
}
|
||||
|
||||
if merr == nil || len(merr.Errors) == 0 {
|
||||
log.Infof("disabled DNS registration for interface %s", r.guid)
|
||||
}
|
||||
|
||||
return nberrors.FormatErrorOrNil(merr)
|
||||
}
|
||||
|
||||
func (r *registryConfigurator) disableWINSForInterface() error {
|
||||
netbtKeyPath := fmt.Sprintf(`%s\Tcpip_%s`, netbtInterfacePath, r.guid)
|
||||
|
||||
regKey, err := registry.OpenKey(registry.LOCAL_MACHINE, netbtKeyPath, registry.SET_VALUE)
|
||||
if err != nil {
|
||||
regKey, _, err = registry.CreateKey(registry.LOCAL_MACHINE, netbtKeyPath, registry.SET_VALUE)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create NetBT interface key %s: %w", netbtKeyPath, err)
|
||||
}
|
||||
}
|
||||
defer closer(regKey)
|
||||
|
||||
// NetbiosOptions: 2 = disabled
|
||||
if err := regKey.SetDWordValue(netbiosOptionsKey, netbiosDisabled); err != nil {
|
||||
return fmt.Errorf("set %s: %w", netbiosOptionsKey, err)
|
||||
}
|
||||
|
||||
log.Infof("disabled WINS/NetBIOS for interface %s", r.guid)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *registryConfigurator) applyDNSConfig(config HostDNSConfig, stateManager *statemanager.Manager) error {
|
||||
if config.RouteAll {
|
||||
if err := r.addDNSSetupForAll(config.ServerIP); err != nil {
|
||||
@@ -119,9 +205,7 @@ func (r *registryConfigurator) applyDNSConfig(config HostDNSConfig, stateManager
|
||||
return fmt.Errorf("update search domains: %w", err)
|
||||
}
|
||||
|
||||
if err := r.flushDNSCache(); err != nil {
|
||||
log.Errorf("failed to flush DNS cache: %v", err)
|
||||
}
|
||||
go r.flushDNSCache()
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -191,7 +275,25 @@ func (r *registryConfigurator) string() string {
|
||||
return "registry"
|
||||
}
|
||||
|
||||
func (r *registryConfigurator) flushDNSCache() error {
|
||||
func (r *registryConfigurator) registerDNS() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// nolint:misspell
|
||||
cmd := exec.CommandContext(ctx, "ipconfig", "/registerdns")
|
||||
out, err := cmd.CombinedOutput()
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("failed to register DNS: %v, output: %s", err, out)
|
||||
return
|
||||
}
|
||||
|
||||
log.Info("registered DNS names")
|
||||
}
|
||||
|
||||
func (r *registryConfigurator) flushDNSCache() {
|
||||
r.registerDNS()
|
||||
|
||||
// dnsFlushResolverCacheFn.Call() may panic if the func is not found
|
||||
defer func() {
|
||||
if rec := recover(); rec != nil {
|
||||
@@ -202,13 +304,14 @@ func (r *registryConfigurator) flushDNSCache() error {
|
||||
ret, _, err := dnsFlushResolverCacheFn.Call()
|
||||
if ret == 0 {
|
||||
if err != nil && !errors.Is(err, syscall.Errno(0)) {
|
||||
return fmt.Errorf("DnsFlushResolverCache failed: %w", err)
|
||||
log.Errorf("DnsFlushResolverCache failed: %v", err)
|
||||
return
|
||||
}
|
||||
return fmt.Errorf("DnsFlushResolverCache failed")
|
||||
log.Errorf("DnsFlushResolverCache failed")
|
||||
return
|
||||
}
|
||||
|
||||
log.Info("flushed DNS cache")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *registryConfigurator) updateSearchDomains(domains []string) error {
|
||||
@@ -263,9 +366,7 @@ func (r *registryConfigurator) restoreHostDNS() error {
|
||||
return fmt.Errorf("remove interface registry key: %w", err)
|
||||
}
|
||||
|
||||
if err := r.flushDNSCache(); err != nil {
|
||||
log.Errorf("failed to flush DNS cache: %v", err)
|
||||
}
|
||||
go r.flushDNSCache()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user