mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-07-04 01:07:49 +02:00
all: ignoring local interfaces RFC1918 IP for private resolver
Otherwises, the discovery may make a looping with new PTR query flow.
This commit is contained in:
committed by
Cuong Manh Le
parent
5897c174d3
commit
c3ff8182af
+1
-16
@@ -114,7 +114,7 @@ func (p *prog) serveDNS(listenerNum string) error {
|
|||||||
// addresses of the machine. So ctrld could receive queries from LAN clients.
|
// addresses of the machine. So ctrld could receive queries from LAN clients.
|
||||||
if needRFC1918Listeners(listenerConfig) {
|
if needRFC1918Listeners(listenerConfig) {
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
for _, addr := range rfc1918Addresses() {
|
for _, addr := range ctrld.Rfc1918Addresses() {
|
||||||
func() {
|
func() {
|
||||||
listenAddr := net.JoinHostPort(addr, strconv.Itoa(listenerConfig.Port))
|
listenAddr := net.JoinHostPort(addr, strconv.Itoa(listenerConfig.Port))
|
||||||
s, errCh := runDNSServer(listenAddr, proto, handler)
|
s, errCh := runDNSServer(listenAddr, proto, handler)
|
||||||
@@ -737,21 +737,6 @@ func needRFC1918Listeners(lc *ctrld.ListenerConfig) bool {
|
|||||||
return lc.IP == "127.0.0.1" && lc.Port == 53
|
return lc.IP == "127.0.0.1" && lc.Port == 53
|
||||||
}
|
}
|
||||||
|
|
||||||
func rfc1918Addresses() []string {
|
|
||||||
var res []string
|
|
||||||
interfaces.ForeachInterface(func(i interfaces.Interface, prefixes []netip.Prefix) {
|
|
||||||
addrs, _ := i.Addrs()
|
|
||||||
for _, addr := range addrs {
|
|
||||||
ipNet, ok := addr.(*net.IPNet)
|
|
||||||
if !ok || !ipNet.IP.IsPrivate() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
res = append(res, ipNet.IP.String())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// ipFromARPA parses a FQDN arpa domain and return the IP address if valid.
|
// ipFromARPA parses a FQDN arpa domain and return the IP address if valid.
|
||||||
func ipFromARPA(arpa string) net.IP {
|
func ipFromARPA(arpa string) net.IP {
|
||||||
if arpa, ok := strings.CutSuffix(arpa, ".in-addr.arpa."); ok {
|
if arpa, ok := strings.CutSuffix(arpa, ".in-addr.arpa."); ok {
|
||||||
|
|||||||
+1
-1
@@ -438,7 +438,7 @@ func (p *prog) setDNS() {
|
|||||||
|
|
||||||
nameservers := []string{ns}
|
nameservers := []string{ns}
|
||||||
if needRFC1918Listeners(lc) {
|
if needRFC1918Listeners(lc) {
|
||||||
nameservers = append(nameservers, rfc1918Addresses()...)
|
nameservers = append(nameservers, ctrld.Rfc1918Addresses()...)
|
||||||
}
|
}
|
||||||
if err := setDNS(netIface, nameservers); err != nil {
|
if err := setDNS(netIface, nameservers); err != nil {
|
||||||
logger.Error().Err(err).Msgf("could not set DNS for interface")
|
logger.Error().Err(err).Msgf("could not set DNS for interface")
|
||||||
|
|||||||
+27
-1
@@ -5,10 +5,12 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
|
"tailscale.com/net/interfaces"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -245,12 +247,16 @@ func NewBootstrapResolver(servers ...string) Resolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewPrivateResolver returns an OS resolver, which includes only private DNS servers,
|
// NewPrivateResolver returns an OS resolver, which includes only private DNS servers,
|
||||||
// excluding nameservers from /etc/resolv.conf file.
|
// excluding:
|
||||||
|
//
|
||||||
|
// - Nameservers from /etc/resolv.conf file.
|
||||||
|
// - Nameservers which is local RFC1918 addresses.
|
||||||
//
|
//
|
||||||
// This is useful for doing PTR lookup in LAN network.
|
// This is useful for doing PTR lookup in LAN network.
|
||||||
func NewPrivateResolver() Resolver {
|
func NewPrivateResolver() Resolver {
|
||||||
nss := nameservers()
|
nss := nameservers()
|
||||||
resolveConfNss := nameserversFromResolvconf()
|
resolveConfNss := nameserversFromResolvconf()
|
||||||
|
localRfc1918Addrs := Rfc1918Addresses()
|
||||||
n := 0
|
n := 0
|
||||||
for _, ns := range nss {
|
for _, ns := range nss {
|
||||||
host, _, _ := net.SplitHostPort(ns)
|
host, _, _ := net.SplitHostPort(ns)
|
||||||
@@ -263,6 +269,10 @@ func NewPrivateResolver() Resolver {
|
|||||||
if sliceContains(resolveConfNss, host) {
|
if sliceContains(resolveConfNss, host) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
// Ignoring local RFC 1918 addresses.
|
||||||
|
if sliceContains(localRfc1918Addrs, host) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
ip := net.ParseIP(host)
|
ip := net.ParseIP(host)
|
||||||
if ip != nil && ip.IsPrivate() && !ip.IsLoopback() {
|
if ip != nil && ip.IsPrivate() && !ip.IsLoopback() {
|
||||||
nss[n] = ns
|
nss[n] = ns
|
||||||
@@ -285,6 +295,22 @@ func NewResolverWithNameserver(nameservers []string) Resolver {
|
|||||||
return &osResolver{nameservers: nameservers}
|
return &osResolver{nameservers: nameservers}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rfc1918Addresses returns the list of local interfaces private IP addresses
|
||||||
|
func Rfc1918Addresses() []string {
|
||||||
|
var res []string
|
||||||
|
interfaces.ForeachInterface(func(i interfaces.Interface, prefixes []netip.Prefix) {
|
||||||
|
addrs, _ := i.Addrs()
|
||||||
|
for _, addr := range addrs {
|
||||||
|
ipNet, ok := addr.(*net.IPNet)
|
||||||
|
if !ok || !ipNet.IP.IsPrivate() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
res = append(res, ipNet.IP.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
func newDialer(dnsAddress string) *net.Dialer {
|
func newDialer(dnsAddress string) *net.Dialer {
|
||||||
return &net.Dialer{
|
return &net.Dialer{
|
||||||
Resolver: &net.Resolver{
|
Resolver: &net.Resolver{
|
||||||
|
|||||||
Reference in New Issue
Block a user