diff --git a/tunnel/dns/dns.go b/tunnel/dns/dns.go new file mode 100644 index 000000000..ff303588f --- /dev/null +++ b/tunnel/dns/dns.go @@ -0,0 +1,29 @@ +//go:build !linux + +/* + Copyright NetFoundry Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package dns + +// these functions are only implemented when OS=linux + +func NewDnsServer(addr string) (Resolver, error) { + return nil, nil +} + +func flushDnsCaches() { + // not implemented +} diff --git a/tunnel/dns/dns_linux.go b/tunnel/dns/dns_linux.go new file mode 100644 index 000000000..4b5d24844 --- /dev/null +++ b/tunnel/dns/dns_linux.go @@ -0,0 +1,97 @@ +//go:build linux + +/* + Copyright NetFoundry Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package dns + +import ( + "fmt" + "github.com/miekg/dns" + "github.com/sirupsen/logrus" + "net" + "os/exec" + "sync" + "time" +) + +func NewDnsServer(addr string) (Resolver, error) { + log.Infof("starting dns server...") + s := &dns.Server{ + Addr: addr, + Net: "udp", + } + + names := make(map[string]net.IP) + r := &resolver{ + server: s, + names: names, + ips: make(map[string]string), + namesMtx: sync.Mutex{}, + domains: make(map[string]*domainEntry), + domainsMtx: sync.Mutex{}, + } + s.Handler = r + + errChan := make(chan error) + go func() { + errChan <- s.ListenAndServe() + }() + + select { + case err := <-errChan: + if err != nil { + return nil, fmt.Errorf("dns server failed to start: %w", err) + } else { + return nil, fmt.Errorf("dns server stopped prematurely") + } + case <-time.After(2 * time.Second): + log.Infof("dns server running at %s", s.Addr) + } + + const resolverConfigHelp = "ziti-tunnel runs an internal DNS server which must be first in the host's\n" + + "resolver configuration. On systems that use NetManager/dhclient, this can\n" + + "be achieved by adding the following to /etc/dhcp/dhclient.conf:\n" + + "\n" + + " prepend domain-name-servers %s;\n\n" + + err := r.testSystemResolver() + if err != nil { + log.Errorf("system resolver test failed: %s\n\n"+resolverConfigHelp, err, addr) + } + + return r, nil +} + +func flushDnsCaches() { + bin, err := exec.LookPath("systemd-resolve") + arg := "--flush-caches" + if err != nil { + bin, err = exec.LookPath("resolvectl") + if err != nil { + logrus.WithError(err).Warn("unable to find systemd-resolve or resolvectl in path, consider adding a dns flush to your restart process") + return + } + arg = "flush-caches" + } + + cmd := exec.Command(bin, arg) + if err = cmd.Run(); err != nil { + logrus.WithError(err).Warn("unable to flush dns caches, consider adding a dns flush to your restart process") + } else { + logrus.Info("dns caches flushed") + } +} diff --git a/tunnel/dns/server.go b/tunnel/dns/server.go index e728d6e07..2d99a4a62 100644 --- a/tunnel/dns/server.go +++ b/tunnel/dns/server.go @@ -23,10 +23,8 @@ import ( "github.com/sirupsen/logrus" "net" "net/url" - "os/exec" "strings" "sync" - "time" ) var log = logrus.StandardLogger() @@ -40,26 +38,6 @@ type resolver struct { domainsMtx sync.Mutex } -func flushDnsCaches() { - bin, err := exec.LookPath("systemd-resolve") - arg := "--flush-caches" - if err != nil { - bin, err = exec.LookPath("resolvectl") - if err != nil { - logrus.WithError(err).Warn("unable to find systemd-resolve or resolvectl in path, consider adding a dns flush to your restart process") - return - } - arg = "flush-caches" - } - - cmd := exec.Command(bin, arg) - if err = cmd.Run(); err != nil { - logrus.WithError(err).Warn("unable to flush dns caches, consider adding a dns flush to your restart process") - } else { - logrus.Info("dns caches flushed") - } -} - func NewResolver(config string) (Resolver, error) { flushDnsCaches() if config == "" { @@ -85,54 +63,6 @@ func NewResolver(config string) (Resolver, error) { return nil, fmt.Errorf("invalid resolver configuration '%s'. must be 'file://' or 'udp://' URL", config) } -func NewDnsServer(addr string) (Resolver, error) { - log.Infof("starting dns server...") - s := &dns.Server{ - Addr: addr, - Net: "udp", - } - - names := make(map[string]net.IP) - r := &resolver{ - server: s, - names: names, - ips: make(map[string]string), - namesMtx: sync.Mutex{}, - domains: make(map[string]*domainEntry), - domainsMtx: sync.Mutex{}, - } - s.Handler = r - - errChan := make(chan error) - go func() { - errChan <- s.ListenAndServe() - }() - - select { - case err := <-errChan: - if err != nil { - return nil, fmt.Errorf("dns server failed to start: %w", err) - } else { - return nil, fmt.Errorf("dns server stopped prematurely") - } - case <-time.After(2 * time.Second): - log.Infof("dns server running at %s", s.Addr) - } - - const resolverConfigHelp = "ziti-tunnel runs an internal DNS server which must be first in the host's\n" + - "resolver configuration. On systems that use NetManager/dhclient, this can\n" + - "be achieved by adding the following to /etc/dhcp/dhclient.conf:\n" + - "\n" + - " prepend domain-name-servers %s;\n\n" - - err := r.testSystemResolver() - if err != nil { - log.Errorf("system resolver test failed: %s\n\n"+resolverConfigHelp, err, addr) - } - - return r, nil -} - func (r *resolver) testSystemResolver() error { const resolverTestHostname = "ziti-tunnel.resolver.test" resolverTestIP := net.IP{19, 65, 28, 94}