mirror of
https://github.com/netbirdio/netbird.git
synced 2024-11-28 19:13:31 +01:00
4fec709bb1
* compile client under freebsd (#1620) Compile netbird client under freebsd and now support netstack and userspace modes. Refactoring linux specific code to share same code with FreeBSD, move to *_unix.go files. Not implemented yet: Kernel mode not supported DNS probably does not work yet Routing also probably does not work yet SSH support did not tested yet Lack of test environment for freebsd (dedicated VM for github runners under FreeBSD required) Lack of tests for freebsd specific code info reporting need to review and also implement, for example OS reported as GENERIC instead of FreeBSD (lack of FreeBSD icon in management interface) Lack of proper client setup under FreeBSD Lack of FreeBSD port/package * Add DNS routes (#1943) Given domains are resolved periodically and resolved IPs are replaced with the new ones. Unless the flag keep_route is set to true, then only new ones are added. This option is helpful if there are long-running connections that might still point to old IP addresses from changed DNS records. * Add process posture check (#1693) Introduces a process posture check to validate the existence and active status of specific binaries on peer systems. The check ensures that files are present at specified paths, and that corresponding processes are running. This check supports Linux, Windows, and macOS systems. Co-authored-by: Evgenii <mail@skillcoder.com> Co-authored-by: Pascal Fischer <pascal@netbird.io> Co-authored-by: Zoltan Papp <zoltan.pmail@gmail.com> Co-authored-by: Viktor Liu <17948409+lixmal@users.noreply.github.com> Co-authored-by: Bethuel Mmbaga <bethuelmbaga12@gmail.com>
160 lines
3.4 KiB
Go
160 lines
3.4 KiB
Go
//go:build (linux && !android) || freebsd
|
|
|
|
package dns
|
|
|
|
import (
|
|
"path"
|
|
"path/filepath"
|
|
"sync"
|
|
|
|
"github.com/fsnotify/fsnotify"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
var (
|
|
eventTypes = []fsnotify.Op{
|
|
fsnotify.Create,
|
|
fsnotify.Write,
|
|
fsnotify.Remove,
|
|
fsnotify.Rename,
|
|
}
|
|
)
|
|
|
|
type repairConfFn func([]string, string, *resolvConf) error
|
|
|
|
type repair struct {
|
|
operationFile string
|
|
updateFn repairConfFn
|
|
watchDir string
|
|
|
|
inotify *fsnotify.Watcher
|
|
inotifyWg sync.WaitGroup
|
|
}
|
|
|
|
func newRepair(operationFile string, updateFn repairConfFn) *repair {
|
|
targetFile := targetFile(operationFile)
|
|
return &repair{
|
|
operationFile: targetFile,
|
|
watchDir: path.Dir(targetFile),
|
|
updateFn: updateFn,
|
|
}
|
|
}
|
|
|
|
func (f *repair) watchFileChanges(nbSearchDomains []string, nbNameserverIP string) {
|
|
if f.inotify != nil {
|
|
return
|
|
}
|
|
|
|
log.Infof("start to watch resolv.conf: %s", f.operationFile)
|
|
inotify, err := fsnotify.NewWatcher()
|
|
if err != nil {
|
|
log.Errorf("failed to start inotify watcher for resolv.conf: %s", err)
|
|
return
|
|
}
|
|
f.inotify = inotify
|
|
|
|
f.inotifyWg.Add(1)
|
|
go func() {
|
|
defer f.inotifyWg.Done()
|
|
for event := range f.inotify.Events {
|
|
if !f.isEventRelevant(event) {
|
|
continue
|
|
}
|
|
|
|
log.Tracef("%s changed, check if it is broken", f.operationFile)
|
|
|
|
rConf, err := parseResolvConfFile(f.operationFile)
|
|
if err != nil {
|
|
log.Warnf("failed to parse resolv conf: %s", err)
|
|
continue
|
|
}
|
|
|
|
log.Debugf("check resolv.conf parameters: %s", rConf)
|
|
if !isNbParamsMissing(nbSearchDomains, nbNameserverIP, rConf) {
|
|
log.Tracef("resolv.conf still correct, skip the update")
|
|
continue
|
|
}
|
|
log.Info("broken params in resolv.conf, repairing it...")
|
|
|
|
err = f.inotify.Remove(f.watchDir)
|
|
if err != nil {
|
|
log.Errorf("failed to rm inotify watch for resolv.conf: %s", err)
|
|
}
|
|
|
|
err = f.updateFn(nbSearchDomains, nbNameserverIP, rConf)
|
|
if err != nil {
|
|
log.Errorf("failed to repair resolv.conf: %v", err)
|
|
}
|
|
|
|
err = f.inotify.Add(f.watchDir)
|
|
if err != nil {
|
|
log.Errorf("failed to re-add inotify watch for resolv.conf: %s", err)
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
|
|
err = f.inotify.Add(f.watchDir)
|
|
if err != nil {
|
|
log.Errorf("failed to add inotify watch for resolv.conf: %s", err)
|
|
return
|
|
}
|
|
}
|
|
|
|
func (f *repair) stopWatchFileChanges() {
|
|
if f.inotify == nil {
|
|
return
|
|
}
|
|
err := f.inotify.Close()
|
|
if err != nil {
|
|
log.Warnf("failed to close resolv.conf inotify: %v", err)
|
|
}
|
|
f.inotifyWg.Wait()
|
|
f.inotify = nil
|
|
}
|
|
|
|
func (f *repair) isEventRelevant(event fsnotify.Event) bool {
|
|
var ok bool
|
|
for _, et := range eventTypes {
|
|
if event.Has(et) {
|
|
ok = true
|
|
break
|
|
}
|
|
}
|
|
if !ok {
|
|
return false
|
|
}
|
|
|
|
if event.Name == f.operationFile {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// nbParamsAreMissing checks if the resolv.conf file contains all the parameters that NetBird needs
|
|
// check the NetBird related nameserver IP at the first place
|
|
// check the NetBird related search domains in the search domains list
|
|
func isNbParamsMissing(nbSearchDomains []string, nbNameserverIP string, rConf *resolvConf) bool {
|
|
if !isContains(nbSearchDomains, rConf.searchDomains) {
|
|
return true
|
|
}
|
|
|
|
if len(rConf.nameServers) == 0 {
|
|
return true
|
|
}
|
|
|
|
if rConf.nameServers[0] != nbNameserverIP {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func targetFile(filename string) string {
|
|
target, err := filepath.EvalSymlinks(filename)
|
|
if err != nil {
|
|
log.Errorf("evarl err: %s", err)
|
|
}
|
|
return target
|
|
}
|