mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-28 22:23:24 +00:00
cmd/ctrld: add --iface for setting DNS on specific interface
This commit is contained in:
committed by
Cuong Manh Le
parent
d5344aea52
commit
b00a7c34ee
@@ -1,7 +1,18 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"tailscale.com/net/dns"
|
||||
"tailscale.com/util/dnsname"
|
||||
|
||||
"github.com/Control-D-Inc/ctrld/internal/resolvconffile"
|
||||
)
|
||||
|
||||
// allocate loopback ip
|
||||
@@ -23,3 +34,84 @@ func deAllocateIP(ip string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// set the dns server for the provided network interface
|
||||
func setDNS(iface *net.Interface, nameservers []string) error {
|
||||
logf := func(format string, args ...any) {
|
||||
mainLog.Debug().Msgf(format, args...)
|
||||
}
|
||||
|
||||
r, err := dns.NewOSConfigurator(logf, iface.Name)
|
||||
if err != nil {
|
||||
mainLog.Error().Err(err).Msg("failed to create DNS OS configurator")
|
||||
return err
|
||||
}
|
||||
|
||||
ns := make([]netip.Addr, 0, len(nameservers))
|
||||
for _, nameserver := range nameservers {
|
||||
ns = append(ns, netip.MustParseAddr(nameserver))
|
||||
}
|
||||
return r.SetDNS(dns.OSConfig{
|
||||
Nameservers: ns,
|
||||
SearchDomains: []dnsname.FQDN{},
|
||||
})
|
||||
}
|
||||
|
||||
func resetDNS(iface *net.Interface, nameservers []string) error {
|
||||
if err := setDNS(iface, nameservers); err != nil {
|
||||
mainLog.Error().Err(err).Msg("resetDNS failed.")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func currentDNS(iface *net.Interface) []string {
|
||||
for _, fn := range []getDNS{getDNSByResolvectl, getDNSByNmcli, resolvconffile.NameServers} {
|
||||
if ns := fn(iface.Name); len(ns) > 0 {
|
||||
return ns
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getDNSByResolvectl(iface string) []string {
|
||||
b, err := exec.Command("resolvectl", "dns", "-i", iface).Output()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
parts := strings.SplitN(string(b), "%", 2)
|
||||
if len(parts) != 2 {
|
||||
return nil
|
||||
}
|
||||
parts = strings.Fields(parts[0])
|
||||
if len(parts) > 2 {
|
||||
fmt.Println(parts)
|
||||
return parts[3:]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getDNSByNmcli(iface string) []string {
|
||||
b, err := exec.Command("nmcli", "dev", "show", iface).Output()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
s := bufio.NewScanner(bytes.NewReader(b))
|
||||
var dns []string
|
||||
do := func(line string) {
|
||||
parts := strings.SplitN(line, ":", 2)
|
||||
if len(parts) > 1 {
|
||||
dns = append(dns, strings.TrimSpace(parts[1]))
|
||||
}
|
||||
}
|
||||
for s.Scan() {
|
||||
line := s.Text()
|
||||
switch {
|
||||
case strings.HasPrefix(line, "IP4.DNS"):
|
||||
fallthrough
|
||||
case strings.HasPrefix(line, "IP6.DNS"):
|
||||
do(line)
|
||||
}
|
||||
}
|
||||
return dns
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user