mirror of
https://github.com/netbirdio/netbird.git
synced 2025-02-09 06:50:20 +01:00
[client] Support non-openresolv for DNS on Linux (#3176)
This commit is contained in:
parent
0c28099712
commit
9b5b632ff9
@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
@ -15,23 +16,64 @@ import (
|
|||||||
|
|
||||||
const resolvconfCommand = "resolvconf"
|
const resolvconfCommand = "resolvconf"
|
||||||
|
|
||||||
|
// resolvconfType represents the type of resolvconf implementation
|
||||||
|
type resolvconfType int
|
||||||
|
|
||||||
|
func (r resolvconfType) String() string {
|
||||||
|
switch r {
|
||||||
|
case typeOpenresolv:
|
||||||
|
return "openresolv"
|
||||||
|
case typeResolvconf:
|
||||||
|
return "resolvconf"
|
||||||
|
default:
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
typeOpenresolv resolvconfType = iota
|
||||||
|
typeResolvconf
|
||||||
|
)
|
||||||
|
|
||||||
type resolvconf struct {
|
type resolvconf struct {
|
||||||
ifaceName string
|
ifaceName string
|
||||||
|
implType resolvconfType
|
||||||
|
|
||||||
originalSearchDomains []string
|
originalSearchDomains []string
|
||||||
originalNameServers []string
|
originalNameServers []string
|
||||||
othersConfigs []string
|
othersConfigs []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// supported "openresolv" only
|
func detectResolvconfType() (resolvconfType, error) {
|
||||||
|
cmd := exec.Command(resolvconfCommand, "--version")
|
||||||
|
out, err := cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
return typeOpenresolv, fmt.Errorf("failed to determine resolvconf type: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(string(out), "openresolv") {
|
||||||
|
return typeOpenresolv, nil
|
||||||
|
}
|
||||||
|
return typeResolvconf, nil
|
||||||
|
}
|
||||||
|
|
||||||
func newResolvConfConfigurator(wgInterface string) (*resolvconf, error) {
|
func newResolvConfConfigurator(wgInterface string) (*resolvconf, error) {
|
||||||
resolvConfEntries, err := parseDefaultResolvConf()
|
resolvConfEntries, err := parseDefaultResolvConf()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("could not read original search domains from %s: %s", defaultResolvConfPath, err)
|
log.Errorf("could not read original search domains from %s: %s", defaultResolvConfPath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
implType, err := detectResolvconfType()
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("failed to detect resolvconf type, defaulting to openresolv: %v", err)
|
||||||
|
implType = typeOpenresolv
|
||||||
|
} else {
|
||||||
|
log.Infof("detected resolvconf type: %v", implType)
|
||||||
|
}
|
||||||
|
|
||||||
return &resolvconf{
|
return &resolvconf{
|
||||||
ifaceName: wgInterface,
|
ifaceName: wgInterface,
|
||||||
|
implType: implType,
|
||||||
originalSearchDomains: resolvConfEntries.searchDomains,
|
originalSearchDomains: resolvConfEntries.searchDomains,
|
||||||
originalNameServers: resolvConfEntries.nameServers,
|
originalNameServers: resolvConfEntries.nameServers,
|
||||||
othersConfigs: resolvConfEntries.others,
|
othersConfigs: resolvConfEntries.others,
|
||||||
@ -80,8 +122,15 @@ func (r *resolvconf) applyDNSConfig(config HostDNSConfig, stateManager *stateman
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *resolvconf) restoreHostDNS() error {
|
func (r *resolvconf) restoreHostDNS() error {
|
||||||
// openresolv only, debian resolvconf doesn't support "-f"
|
var cmd *exec.Cmd
|
||||||
cmd := exec.Command(resolvconfCommand, "-f", "-d", r.ifaceName)
|
|
||||||
|
switch r.implType {
|
||||||
|
case typeOpenresolv:
|
||||||
|
cmd = exec.Command(resolvconfCommand, "-f", "-d", r.ifaceName)
|
||||||
|
case typeResolvconf:
|
||||||
|
cmd = exec.Command(resolvconfCommand, "-d", r.ifaceName)
|
||||||
|
}
|
||||||
|
|
||||||
_, err := cmd.Output()
|
_, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("removing resolvconf configuration for %s interface: %w", r.ifaceName, err)
|
return fmt.Errorf("removing resolvconf configuration for %s interface: %w", r.ifaceName, err)
|
||||||
@ -91,10 +140,21 @@ func (r *resolvconf) restoreHostDNS() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *resolvconf) applyConfig(content bytes.Buffer) error {
|
func (r *resolvconf) applyConfig(content bytes.Buffer) error {
|
||||||
// openresolv only, debian resolvconf doesn't support "-x"
|
var cmd *exec.Cmd
|
||||||
cmd := exec.Command(resolvconfCommand, "-x", "-a", r.ifaceName)
|
|
||||||
|
switch r.implType {
|
||||||
|
case typeOpenresolv:
|
||||||
|
// OpenResolv supports exclusive mode with -x
|
||||||
|
cmd = exec.Command(resolvconfCommand, "-x", "-a", r.ifaceName)
|
||||||
|
case typeResolvconf:
|
||||||
|
cmd = exec.Command(resolvconfCommand, "-a", r.ifaceName)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unsupported resolvconf type: %v", r.implType)
|
||||||
|
}
|
||||||
|
|
||||||
cmd.Stdin = &content
|
cmd.Stdin = &content
|
||||||
_, err := cmd.Output()
|
out, err := cmd.Output()
|
||||||
|
log.Tracef("resolvconf output: %s", out)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("applying resolvconf configuration for %s interface: %w", r.ifaceName, err)
|
return fmt.Errorf("applying resolvconf configuration for %s interface: %w", r.ifaceName, err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user