Skip to content

Commit

Permalink
all: custom autohost tlds
Browse files Browse the repository at this point in the history
  • Loading branch information
ainar-g committed Mar 24, 2021
1 parent ba3fc24 commit 21b4532
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 37 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to

### Added

- The ability to set a custom TLD for known local-network hosts ([#2393]).
- The ability to serve DNS queries on multiple hosts and interfaces ([#1401]).
- `ips` and `text` DHCP server options ([#2385]).
- `SRV` records support in `$dnsrewrite` filters ([#2533]).
Expand All @@ -41,6 +42,7 @@ and this project adheres to

[#1401]: https://github.com/AdguardTeam/AdGuardHome/issues/1401
[#2385]: https://github.com/AdguardTeam/AdGuardHome/issues/2385
[#2393]: https://github.com/AdguardTeam/AdGuardHome/issues/2393
[#2412]: https://github.com/AdguardTeam/AdGuardHome/issues/2412
[#2498]: https://github.com/AdguardTeam/AdGuardHome/issues/2498
[#2533]: https://github.com/AdguardTeam/AdGuardHome/issues/2533
Expand Down
8 changes: 4 additions & 4 deletions internal/dnsforward/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ func (s *Server) prepareUpstreamSettings() error {
s := util.SplitNext(&d, '\n')
upstreams = append(upstreams, s)
}
log.Debug("DNS: using %d upstream servers from file %s", len(upstreams), s.conf.UpstreamDNSFileName)
log.Debug("dns: using %d upstream servers from file %s", len(upstreams), s.conf.UpstreamDNSFileName)
} else {
upstreams = s.conf.UpstreamDNS
}
Expand Down Expand Up @@ -357,11 +357,11 @@ func (s *Server) prepareTLS(proxyConfig *proxy.Config) error {
}
if len(x.DNSNames) != 0 {
s.conf.dnsNames = x.DNSNames
log.Debug("DNS: using DNS names from certificate's SAN: %v", x.DNSNames)
log.Debug("dns: using DNS names from certificate's SAN: %v", x.DNSNames)
sort.Strings(s.conf.dnsNames)
} else {
s.conf.dnsNames = append(s.conf.dnsNames, x.Subject.CommonName)
log.Debug("DNS: using DNS name from certificate's CN: %s", x.Subject.CommonName)
log.Debug("dns: using DNS name from certificate's CN: %s", x.Subject.CommonName)
}
}

Expand All @@ -377,7 +377,7 @@ func (s *Server) prepareTLS(proxyConfig *proxy.Config) error {
// If the server name (from SNI) supplied by client is incorrect - we terminate the ongoing TLS handshake.
func (s *Server) onGetCertificate(ch *tls.ClientHelloInfo) (*tls.Certificate, error) {
if s.conf.StrictSNICheck && !matchDNSName(s.conf.dnsNames, ch.ServerName) {
log.Info("DNS: TLS: unknown SNI in Client Hello: %s", ch.ServerName)
log.Info("dns: tls: unknown SNI in Client Hello: %s", ch.ServerName)
return nil, fmt.Errorf("invalid SNI")
}
return &s.conf.cert, nil
Expand Down
49 changes: 27 additions & 22 deletions internal/dnsforward/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (

// To transfer information between modules
type dnsContext struct {
// TODO(a.garipov): Remove this and rewrite processors to be methods of
// *Server instead.
srv *Server
proxyCtx *proxy.DNSContext
// setts are the filtering settings for the client.
Expand Down Expand Up @@ -75,7 +77,7 @@ func (s *Server) handleDNSRequest(_ *proxy.Proxy, d *proxy.DNSContext) error {
// appropriate handler.
mods := []modProcessFunc{
processInitial,
processInternalHosts,
s.processInternalHosts,
processInternalIPAddrs,
processClientID,
processFilteringBeforeRequest,
Expand Down Expand Up @@ -136,7 +138,7 @@ func isHostnameOK(hostname string) bool {
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') ||
c == '.' || c == '-') {
log.Debug("DNS: skipping invalid hostname %s from DHCP", hostname)
log.Debug("dns: skipping invalid hostname %s from DHCP", hostname)
return false
}
}
Expand Down Expand Up @@ -172,7 +174,7 @@ func (s *Server) onDHCPLeaseChanged(flags int) {
hostToIP[lowhost] = ip
}

log.Debug("DNS: added %d A/PTR entries from DHCP", len(m))
log.Debug("dns: added %d A/PTR entries from DHCP", len(m))

s.tableHostToIPLock.Lock()
s.tableHostToIP = hostToIP
Expand All @@ -183,20 +185,20 @@ func (s *Server) onDHCPLeaseChanged(flags int) {
s.tablePTRLock.Unlock()
}

// Respond to A requests if the target host name is associated with a lease from our DHCP server
func processInternalHosts(ctx *dnsContext) (rc resultCode) {
s := ctx.srv
// processInternalHosts respond to A and AAAA requests if the target hostname
// is known to the server.
func (s *Server) processInternalHosts(ctx *dnsContext) (rc resultCode) {
req := ctx.proxyCtx.Req
if !(req.Question[0].Qtype == dns.TypeA || req.Question[0].Qtype == dns.TypeAAAA) {
q := req.Question[0]
if q.Qtype != dns.TypeA && q.Qtype != dns.TypeAAAA {
return resultCodeSuccess
}

host := req.Question[0].Name
host = strings.ToLower(host)
if !strings.HasSuffix(host, ".lan.") {
reqHost := strings.ToLower(q.Name)
host := strings.TrimSuffix(reqHost, s.autohostSuffix)
if host == reqHost {
return resultCodeSuccess
}
host = strings.TrimSuffix(host, ".lan.")

s.tableHostToIPLock.Lock()
if s.tableHostToIP == nil {
Expand All @@ -209,24 +211,27 @@ func processInternalHosts(ctx *dnsContext) (rc resultCode) {
return resultCodeSuccess
}

log.Debug("DNS: internal record: %s -> %s", req.Question[0].Name, ip)
log.Debug("dns: internal record: %s -> %s", req.Question[0].Name, ip)

resp := s.makeResponse(req)

if req.Question[0].Qtype == dns.TypeA {
a := &dns.A{}
a.Hdr = dns.RR_Header{
Name: req.Question[0].Name,
Rrtype: dns.TypeA,
Ttl: s.conf.BlockedResponseTTL,
Class: dns.ClassINET,
if q.Qtype == dns.TypeA {
a := &dns.A{
Hdr: dns.RR_Header{
Name: q.Name,
Rrtype: dns.TypeA,
Ttl: s.conf.BlockedResponseTTL,
Class: dns.ClassINET,
},
}
a.A = make([]byte, 4)

a.A = make([]byte, len(ip))
copy(a.A, ip)
resp.Answer = append(resp.Answer, a)
}

ctx.proxyCtx.Res = resp

return resultCodeSuccess
}

Expand Down Expand Up @@ -257,7 +262,7 @@ func processInternalIPAddrs(ctx *dnsContext) (rc resultCode) {
return resultCodeSuccess
}

log.Debug("DNS: reverse-lookup: %s -> %s", arpa, host)
log.Debug("dns: reverse-lookup: %s -> %s", arpa, host)

resp := s.makeResponse(req)
ptr := &dns.PTR{}
Expand Down Expand Up @@ -325,7 +330,7 @@ func processUpstream(ctx *dnsContext) (rc resultCode) {
if s.conf.EnableDNSSEC {
opt := d.Req.IsEdns0()
if opt == nil {
log.Debug("DNS: Adding OPT record with DNSSEC flag")
log.Debug("dns: Adding OPT record with DNSSEC flag")
d.Req.SetEdns0(4096, true)
} else if !opt.Do() {
opt.SetDo(true)
Expand Down
36 changes: 28 additions & 8 deletions internal/dnsforward/dnsforward.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/http"
"os"
"runtime"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -56,6 +57,8 @@ type Server struct {
stats stats.Stats
access *accessCtx

autohostSuffix string

ipset ipsetCtx

tableHostToIP map[string]net.IP // "hostname -> IP" table for internal addresses (DHCP)
Expand All @@ -74,21 +77,38 @@ type Server struct {
conf ServerConfig
}

// DNSCreateParams - parameters for NewServer()
const defaultAutohostSuffix = ".lan."

// DNSCreateParams are parameters to create a new server.
type DNSCreateParams struct {
DNSFilter *dnsfilter.DNSFilter
Stats stats.Stats
QueryLog querylog.QueryLog
DHCPServer dhcpd.ServerInterface
DNSFilter *dnsfilter.DNSFilter
Stats stats.Stats
QueryLog querylog.QueryLog
DHCPServer dhcpd.ServerInterface
AutohostTLD string
}

// NewServer creates a new instance of the dnsforward.Server
// Note: this function must be called only once
func NewServer(p DNSCreateParams) *Server {
var autohostSuffix string
if p.AutohostTLD == "" {
autohostSuffix = defaultAutohostSuffix
} else {
b := &strings.Builder{}
b.Grow(len(p.AutohostTLD) + 2)
_, _ = b.WriteString(".")
_, _ = b.WriteString(p.AutohostTLD)
_, _ = b.WriteString(".")

autohostSuffix = b.String()
}

s := &Server{
dnsFilter: p.DNSFilter,
stats: p.Stats,
queryLog: p.QueryLog,
dnsFilter: p.DNSFilter,
stats: p.Stats,
queryLog: p.QueryLog,
autohostSuffix: autohostSuffix,
}

if p.DHCPServer != nil {
Expand Down
2 changes: 2 additions & 0 deletions internal/home/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ type dnsConfig struct {
FilteringEnabled bool `yaml:"filtering_enabled"` // whether or not use filter lists
FiltersUpdateIntervalHours uint32 `yaml:"filters_update_interval"` // time period to update filters (in hours)
DnsfilterConf dnsfilter.Config `yaml:",inline"`
AutohostTLD string `yaml:"autohost_tld"`
}

type tlsConfigSettings struct {
Expand Down Expand Up @@ -144,6 +145,7 @@ var config = configuration{
},
FilteringEnabled: true, // whether or not use filter lists
FiltersUpdateIntervalHours: 24,
AutohostTLD: "lan",
},
TLS: tlsConfigSettings{
PortHTTPS: 443,
Expand Down
7 changes: 4 additions & 3 deletions internal/home/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ func initDNSServer() error {
Context.dnsFilter = dnsfilter.New(&filterConf, nil)

p := dnsforward.DNSCreateParams{
DNSFilter: Context.dnsFilter,
Stats: Context.stats,
QueryLog: Context.queryLog,
DNSFilter: Context.dnsFilter,
Stats: Context.stats,
QueryLog: Context.queryLog,
AutohostTLD: config.DNS.AutohostTLD,
}
if Context.dhcpServer != nil {
p.DHCPServer = Context.dhcpServer
Expand Down
1 change: 1 addition & 0 deletions staticcheck.conf
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ initialisms = [
, "SDNS"
, "SLAAC"
, "SVCB"
, "TLD"
]
dot_import_whitelist = []
http_status_code_whitelist = []

0 comments on commit 21b4532

Please sign in to comment.