Merge branch 'master' into 1920-client-find
This commit is contained in:
@@ -5,16 +5,17 @@ import (
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"sort"
|
||||
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
"github.com/joomcode/errorx"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/dnsfilter"
|
||||
"github.com/AdguardTeam/AdGuardHome/util"
|
||||
"github.com/AdguardTeam/dnsproxy/proxy"
|
||||
"github.com/AdguardTeam/dnsproxy/upstream"
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
"github.com/joomcode/errorx"
|
||||
)
|
||||
|
||||
// FilteringConfig represents the DNS filtering configuration of AdGuard Home
|
||||
@@ -55,10 +56,11 @@ type FilteringConfig struct {
|
||||
// Upstream DNS servers configuration
|
||||
// --
|
||||
|
||||
UpstreamDNS []string `yaml:"upstream_dns"`
|
||||
BootstrapDNS []string `yaml:"bootstrap_dns"` // a list of bootstrap DNS for DoH and DoT (plain DNS only)
|
||||
AllServers bool `yaml:"all_servers"` // if true, parallel queries to all configured upstream servers are enabled
|
||||
FastestAddr bool `yaml:"fastest_addr"` // use Fastest Address algorithm
|
||||
UpstreamDNS []string `yaml:"upstream_dns"`
|
||||
UpstreamDNSFileName string `yaml:"upstream_dns_file"`
|
||||
BootstrapDNS []string `yaml:"bootstrap_dns"` // a list of bootstrap DNS for DoH and DoT (plain DNS only)
|
||||
AllServers bool `yaml:"all_servers"` // if true, parallel queries to all configured upstream servers are enabled
|
||||
FastestAddr bool `yaml:"fastest_addr"` // use Fastest Address algorithm
|
||||
|
||||
// Access settings
|
||||
// --
|
||||
@@ -92,6 +94,7 @@ type FilteringConfig struct {
|
||||
// TLSConfig is the TLS configuration for HTTPS, DNS-over-HTTPS, and DNS-over-TLS
|
||||
type TLSConfig struct {
|
||||
TLSListenAddr *net.TCPAddr `yaml:"-" json:"-"`
|
||||
QUICListenAddr *net.UDPAddr `yaml:"-" json:"-"`
|
||||
StrictSNICheck bool `yaml:"strict_sni_check" json:"-"` // Reject connection if the client uses server name (in SNI) that doesn't match the certificate
|
||||
|
||||
CertificateChain string `yaml:"certificate_chain" json:"certificate_chain"` // PEM-encoded certificates chain
|
||||
@@ -184,7 +187,7 @@ func (s *Server) createProxyConfig() (proxy.Config, error) {
|
||||
|
||||
// Validate proxy config
|
||||
if proxyConfig.UpstreamConfig == nil || len(proxyConfig.UpstreamConfig.Upstreams) == 0 {
|
||||
return proxyConfig, errors.New("no upstream servers configured")
|
||||
return proxyConfig, errors.New("no default upstream servers configured")
|
||||
}
|
||||
|
||||
return proxyConfig, nil
|
||||
@@ -211,14 +214,55 @@ func (s *Server) initDefaultSettings() {
|
||||
if s.conf.TCPListenAddr == nil {
|
||||
s.conf.TCPListenAddr = defaultValues.TCPListenAddr
|
||||
}
|
||||
if len(s.conf.BlockedHosts) == 0 {
|
||||
s.conf.BlockedHosts = defaultBlockedHosts
|
||||
}
|
||||
}
|
||||
|
||||
// prepareUpstreamSettings - prepares upstream DNS server settings
|
||||
func (s *Server) prepareUpstreamSettings() error {
|
||||
upstreamConfig, err := proxy.ParseUpstreamsConfig(s.conf.UpstreamDNS, s.conf.BootstrapDNS, DefaultTimeout)
|
||||
// We're setting a customized set of RootCAs
|
||||
// The reason is that Go default mechanism of loading TLS roots
|
||||
// does not always work properly on some routers so we're
|
||||
// loading roots manually and pass it here.
|
||||
// See "util.LoadSystemRootCAs"
|
||||
upstream.RootCAs = s.conf.TLSv12Roots
|
||||
|
||||
// See util.InitTLSCiphers -- removed unsafe ciphers
|
||||
if len(s.conf.TLSCiphers) > 0 {
|
||||
upstream.CipherSuites = s.conf.TLSCiphers
|
||||
}
|
||||
|
||||
// Load upstreams either from the file, or from the settings
|
||||
var upstreams []string
|
||||
if s.conf.UpstreamDNSFileName != "" {
|
||||
data, err := ioutil.ReadFile(s.conf.UpstreamDNSFileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d := string(data)
|
||||
for len(d) != 0 {
|
||||
s := util.SplitNext(&d, '\n')
|
||||
upstreams = append(upstreams, s)
|
||||
}
|
||||
log.Debug("DNS: using %d upstream servers from file %s", len(upstreams), s.conf.UpstreamDNSFileName)
|
||||
} else {
|
||||
upstreams = s.conf.UpstreamDNS
|
||||
}
|
||||
upstreamConfig, err := proxy.ParseUpstreamsConfig(upstreams, s.conf.BootstrapDNS, DefaultTimeout)
|
||||
if err != nil {
|
||||
return fmt.Errorf("DNS: proxy.ParseUpstreamsConfig: %s", err)
|
||||
}
|
||||
|
||||
if len(upstreamConfig.Upstreams) == 0 {
|
||||
log.Info("Warning: no default upstream servers specified, using %v", defaultDNS)
|
||||
uc, err := proxy.ParseUpstreamsConfig(defaultDNS, s.conf.BootstrapDNS, DefaultTimeout)
|
||||
if err != nil {
|
||||
return fmt.Errorf("DNS: failed to parse default upstreams: %v", err)
|
||||
}
|
||||
upstreamConfig.Upstreams = uc.Upstreams
|
||||
}
|
||||
|
||||
s.conf.UpstreamConfig = &upstreamConfig
|
||||
return nil
|
||||
}
|
||||
@@ -235,36 +279,49 @@ func (s *Server) prepareIntlProxy() {
|
||||
|
||||
// prepareTLS - prepares TLS configuration for the DNS proxy
|
||||
func (s *Server) prepareTLS(proxyConfig *proxy.Config) error {
|
||||
if s.conf.TLSListenAddr != nil && len(s.conf.CertificateChainData) != 0 && len(s.conf.PrivateKeyData) != 0 {
|
||||
if len(s.conf.CertificateChainData) == 0 || len(s.conf.PrivateKeyData) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if s.conf.TLSListenAddr == nil &&
|
||||
s.conf.QUICListenAddr == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if s.conf.TLSListenAddr != nil {
|
||||
proxyConfig.TLSListenAddr = []*net.TCPAddr{s.conf.TLSListenAddr}
|
||||
var err error
|
||||
s.conf.cert, err = tls.X509KeyPair(s.conf.CertificateChainData, s.conf.PrivateKeyData)
|
||||
}
|
||||
|
||||
if s.conf.QUICListenAddr != nil {
|
||||
proxyConfig.QUICListenAddr = []*net.UDPAddr{s.conf.QUICListenAddr}
|
||||
}
|
||||
|
||||
var err error
|
||||
s.conf.cert, err = tls.X509KeyPair(s.conf.CertificateChainData, s.conf.PrivateKeyData)
|
||||
if err != nil {
|
||||
return errorx.Decorate(err, "Failed to parse TLS keypair")
|
||||
}
|
||||
|
||||
if s.conf.StrictSNICheck {
|
||||
x, err := x509.ParseCertificate(s.conf.cert.Certificate[0])
|
||||
if err != nil {
|
||||
return errorx.Decorate(err, "Failed to parse TLS keypair")
|
||||
return errorx.Decorate(err, "x509.ParseCertificate(): %s", err)
|
||||
}
|
||||
|
||||
if s.conf.StrictSNICheck {
|
||||
x, err := x509.ParseCertificate(s.conf.cert.Certificate[0])
|
||||
if err != nil {
|
||||
return errorx.Decorate(err, "x509.ParseCertificate(): %s", err)
|
||||
}
|
||||
if len(x.DNSNames) != 0 {
|
||||
s.conf.dnsNames = 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)
|
||||
}
|
||||
}
|
||||
|
||||
proxyConfig.TLSConfig = &tls.Config{
|
||||
GetCertificate: s.onGetCertificate,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
if len(x.DNSNames) != 0 {
|
||||
s.conf.dnsNames = 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)
|
||||
}
|
||||
}
|
||||
upstream.RootCAs = s.conf.TLSv12Roots
|
||||
upstream.CipherSuites = s.conf.TLSCiphers
|
||||
|
||||
proxyConfig.TLSConfig = &tls.Config{
|
||||
GetCertificate: s.onGetCertificate,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,9 @@ var defaultDNS = []string{
|
||||
}
|
||||
var defaultBootstrap = []string{"9.9.9.10", "149.112.112.10", "2620:fe::10", "2620:fe::fe:10"}
|
||||
|
||||
// Often requested by all kinds of DNS probes
|
||||
var defaultBlockedHosts = []string{"version.bind", "id.server", "hostname.bind"}
|
||||
|
||||
var webRegistered bool
|
||||
|
||||
// Server is the main way to start a DNS server.
|
||||
|
||||
@@ -22,8 +22,9 @@ func httpError(r *http.Request, w http.ResponseWriter, code int, format string,
|
||||
}
|
||||
|
||||
type dnsConfigJSON struct {
|
||||
Upstreams []string `json:"upstream_dns"`
|
||||
Bootstraps []string `json:"bootstrap_dns"`
|
||||
Upstreams []string `json:"upstream_dns"`
|
||||
UpstreamsFile string `json:"upstream_dns_file"`
|
||||
Bootstraps []string `json:"bootstrap_dns"`
|
||||
|
||||
ProtectionEnabled bool `json:"protection_enabled"`
|
||||
RateLimit uint32 `json:"ratelimit"`
|
||||
@@ -43,6 +44,7 @@ func (s *Server) handleGetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
resp := dnsConfigJSON{}
|
||||
s.RLock()
|
||||
resp.Upstreams = stringArrayDup(s.conf.UpstreamDNS)
|
||||
resp.UpstreamsFile = s.conf.UpstreamDNSFileName
|
||||
resp.Bootstraps = stringArrayDup(s.conf.BootstrapDNS)
|
||||
|
||||
resp.ProtectionEnabled = s.conf.ProtectionEnabled
|
||||
@@ -74,7 +76,7 @@ func (s *Server) handleGetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func checkBlockingMode(req dnsConfigJSON) bool {
|
||||
bm := req.BlockingMode
|
||||
if !(bm == "default" || bm == "nxdomain" || bm == "null_ip" || bm == "custom_ip") {
|
||||
if !(bm == "default" || bm == "refused" || bm == "nxdomain" || bm == "null_ip" || bm == "custom_ip") {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -157,6 +159,11 @@ func (s *Server) handleSetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
restart = true
|
||||
}
|
||||
|
||||
if js.Exists("upstream_dns_file") {
|
||||
s.conf.UpstreamDNSFileName = req.UpstreamsFile
|
||||
restart = true
|
||||
}
|
||||
|
||||
if js.Exists("bootstrap_dns") {
|
||||
s.conf.BootstrapDNS = req.Bootstraps
|
||||
restart = true
|
||||
@@ -270,7 +277,7 @@ func ValidateUpstreams(upstreams []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var protocols = []string{"tls://", "https://", "tcp://", "sdns://"}
|
||||
var protocols = []string{"tls://", "https://", "tcp://", "sdns://", "quic://"}
|
||||
|
||||
func validateUpstream(u string) (bool, error) {
|
||||
// Check if user tries to specify upstream for domain
|
||||
|
||||
@@ -8,13 +8,18 @@ import (
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"net"
|
||||
"os"
|
||||
"sort"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/util"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/dhcpd"
|
||||
"github.com/AdguardTeam/AdGuardHome/dnsfilter"
|
||||
"github.com/AdguardTeam/dnsproxy/proxy"
|
||||
@@ -128,6 +133,41 @@ func TestDotServer(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDoqServer(t *testing.T) {
|
||||
// Prepare the proxy server
|
||||
_, certPem, keyPem := createServerTLSConfig(t)
|
||||
s := createTestServer(t)
|
||||
|
||||
s.conf.TLSConfig = TLSConfig{
|
||||
QUICListenAddr: &net.UDPAddr{Port: 0},
|
||||
CertificateChainData: certPem,
|
||||
PrivateKeyData: keyPem,
|
||||
}
|
||||
|
||||
_ = s.Prepare(nil)
|
||||
// Starting the server
|
||||
err := s.Start()
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Create a DNS-over-QUIC upstream
|
||||
addr := s.dnsProxy.Addr(proxy.ProtoQUIC)
|
||||
opts := upstream.Options{InsecureSkipVerify: true}
|
||||
u, err := upstream.AddressToUpstream(fmt.Sprintf("quic://%s", addr), opts)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Send the test message
|
||||
req := createGoogleATestMessage()
|
||||
res, err := u.Exchange(req)
|
||||
assert.Nil(t, err)
|
||||
assertGoogleAResponse(t, res)
|
||||
|
||||
// Stop the proxy
|
||||
err = s.Stop()
|
||||
if err != nil {
|
||||
t.Fatalf("DNS server failed to stop: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerRace(t *testing.T) {
|
||||
s := createTestServer(t)
|
||||
err := s.Start()
|
||||
@@ -227,7 +267,7 @@ func TestBlockedRequest(t *testing.T) {
|
||||
addr := s.dnsProxy.Addr(proxy.ProtoUDP)
|
||||
|
||||
//
|
||||
// NXDomain blocking
|
||||
// Default blocking - REFUSED
|
||||
//
|
||||
req := dns.Msg{}
|
||||
req.Id = dns.Id()
|
||||
@@ -240,9 +280,7 @@ func TestBlockedRequest(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Couldn't talk to server %s: %s", addr, err)
|
||||
}
|
||||
if reply.Rcode != dns.RcodeNameError {
|
||||
t.Fatalf("Wrong response: %s", reply.String())
|
||||
}
|
||||
assert.Equal(t, dns.RcodeRefused, reply.Rcode)
|
||||
|
||||
err = s.Stop()
|
||||
if err != nil {
|
||||
@@ -404,7 +442,7 @@ func TestBlockCNAME(t *testing.T) {
|
||||
req := createTestMessage("badhost.")
|
||||
reply, err := dns.Exchange(req, addr.String())
|
||||
assert.Nil(t, err, nil)
|
||||
assert.Equal(t, dns.RcodeNameError, reply.Rcode)
|
||||
assert.Equal(t, dns.RcodeRefused, reply.Rcode)
|
||||
|
||||
// 'whitelist.example.org' has a canonical name 'null.example.org' which is blocked by filters
|
||||
// but 'whitelist.example.org' is in a whitelist:
|
||||
@@ -419,7 +457,7 @@ func TestBlockCNAME(t *testing.T) {
|
||||
req = createTestMessage("example.org.")
|
||||
reply, err = dns.Exchange(req, addr.String())
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, dns.RcodeNameError, reply.Rcode)
|
||||
assert.Equal(t, dns.RcodeRefused, reply.Rcode)
|
||||
|
||||
_ = s.Stop()
|
||||
}
|
||||
@@ -630,17 +668,17 @@ func TestBlockedBySafeBrowsing(t *testing.T) {
|
||||
func TestRewrite(t *testing.T) {
|
||||
c := dnsfilter.Config{}
|
||||
c.Rewrites = []dnsfilter.RewriteEntry{
|
||||
dnsfilter.RewriteEntry{
|
||||
{
|
||||
Domain: "test.com",
|
||||
Answer: "1.2.3.4",
|
||||
Type: dns.TypeA,
|
||||
},
|
||||
dnsfilter.RewriteEntry{
|
||||
{
|
||||
Domain: "alias.test.com",
|
||||
Answer: "test.com",
|
||||
Type: dns.TypeCNAME,
|
||||
},
|
||||
dnsfilter.RewriteEntry{
|
||||
{
|
||||
Domain: "my.alias.example.org",
|
||||
Answer: "example.org",
|
||||
Type: dns.TypeCNAME,
|
||||
@@ -988,7 +1026,7 @@ func (d *testDHCP) SetOnLeaseChanged(onLeaseChanged dhcpd.OnLeaseChangedT) {
|
||||
return
|
||||
}
|
||||
|
||||
func TestPTRResponse(t *testing.T) {
|
||||
func TestPTRResponseFromDHCPLeases(t *testing.T) {
|
||||
dhcp := &testDHCP{}
|
||||
|
||||
c := dnsfilter.Config{}
|
||||
@@ -1016,3 +1054,45 @@ func TestPTRResponse(t *testing.T) {
|
||||
|
||||
s.Close()
|
||||
}
|
||||
|
||||
func TestPTRResponseFromHosts(t *testing.T) {
|
||||
c := dnsfilter.Config{
|
||||
AutoHosts: &util.AutoHosts{},
|
||||
}
|
||||
|
||||
// Prepare test hosts file
|
||||
hf, _ := ioutil.TempFile("", "")
|
||||
defer func() { _ = os.Remove(hf.Name()) }()
|
||||
defer hf.Close()
|
||||
|
||||
_, _ = hf.WriteString(" 127.0.0.1 host # comment \n")
|
||||
_, _ = hf.WriteString(" ::1 localhost#comment \n")
|
||||
|
||||
// Init auto hosts
|
||||
c.AutoHosts.Init(hf.Name())
|
||||
defer c.AutoHosts.Close()
|
||||
|
||||
f := dnsfilter.New(&c, nil)
|
||||
s := NewServer(DNSCreateParams{DNSFilter: f})
|
||||
s.conf.UDPListenAddr = &net.UDPAddr{Port: 0}
|
||||
s.conf.TCPListenAddr = &net.TCPAddr{Port: 0}
|
||||
s.conf.UpstreamDNS = []string{"127.0.0.1:53"}
|
||||
s.conf.FilteringConfig.ProtectionEnabled = true
|
||||
err := s.Prepare(nil)
|
||||
assert.True(t, err == nil)
|
||||
assert.Nil(t, s.Start())
|
||||
|
||||
addr := s.dnsProxy.Addr(proxy.ProtoUDP)
|
||||
req := createTestMessage("1.0.0.127.in-addr.arpa.")
|
||||
req.Question[0].Qtype = dns.TypePTR
|
||||
|
||||
resp, err := dns.Exchange(req, addr.String())
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, len(resp.Answer))
|
||||
assert.Equal(t, dns.TypePTR, resp.Answer[0].Header().Rrtype)
|
||||
assert.Equal(t, "1.0.0.127.in-addr.arpa.", resp.Answer[0].Header().Name)
|
||||
ptr := resp.Answer[0].(*dns.PTR)
|
||||
assert.Equal(t, "host.", ptr.Ptr)
|
||||
|
||||
s.Close()
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ func (s *Server) filterDNSRequest(ctx *dnsContext) (*dnsfilter.Result, error) {
|
||||
return nil, errorx.Decorate(err, "dnsfilter failed to check host '%s'", host)
|
||||
|
||||
} else if res.IsFiltered {
|
||||
// log.Tracef("Host %s is filtered, reason - '%s', matched rule: '%s'", host, res.Reason, res.Rule)
|
||||
log.Tracef("Host %s is filtered, reason - '%s', matched rule: '%s'", host, res.Reason, res.Rule)
|
||||
d.Res = s.genDNSFilterMessage(d, &res)
|
||||
|
||||
} else if res.Reason == dnsfilter.ReasonRewrite && len(res.CanonName) != 0 && len(res.IPList) == 0 {
|
||||
@@ -60,6 +60,19 @@ func (s *Server) filterDNSRequest(ctx *dnsContext) (*dnsfilter.Result, error) {
|
||||
// resolve canonical name, not the original host name
|
||||
d.Req.Question[0].Name = dns.Fqdn(res.CanonName)
|
||||
|
||||
} else if res.Reason == dnsfilter.RewriteEtcHosts && len(res.ReverseHost) != 0 {
|
||||
|
||||
resp := s.makeResponse(req)
|
||||
ptr := &dns.PTR{}
|
||||
ptr.Hdr = dns.RR_Header{
|
||||
Name: req.Question[0].Name,
|
||||
Rrtype: dns.TypePTR,
|
||||
Ttl: s.conf.BlockedResponseTTL,
|
||||
Class: dns.ClassINET,
|
||||
}
|
||||
ptr.Ptr = res.ReverseHost
|
||||
resp.Answer = append(resp.Answer, ptr)
|
||||
d.Res = resp
|
||||
} else if res.Reason == dnsfilter.ReasonRewrite || res.Reason == dnsfilter.RewriteEtcHosts {
|
||||
resp := s.makeResponse(req)
|
||||
|
||||
@@ -82,20 +95,6 @@ func (s *Server) filterDNSRequest(ctx *dnsContext) (*dnsfilter.Result, error) {
|
||||
}
|
||||
|
||||
d.Res = resp
|
||||
|
||||
} else if res.Reason == dnsfilter.RewriteEtcHosts && len(res.ReverseHost) != 0 {
|
||||
|
||||
resp := s.makeResponse(req)
|
||||
ptr := &dns.PTR{}
|
||||
ptr.Hdr = dns.RR_Header{
|
||||
Name: req.Question[0].Name,
|
||||
Rrtype: dns.TypePTR,
|
||||
Ttl: s.conf.BlockedResponseTTL,
|
||||
Class: dns.ClassINET,
|
||||
}
|
||||
ptr.Ptr = res.ReverseHost
|
||||
resp.Answer = append(resp.Answer, ptr)
|
||||
d.Res = resp
|
||||
}
|
||||
|
||||
return &res, err
|
||||
|
||||
@@ -88,7 +88,7 @@ func processInitial(ctx *dnsContext) int {
|
||||
// disable Mozilla DoH
|
||||
if (d.Req.Question[0].Qtype == dns.TypeA || d.Req.Question[0].Qtype == dns.TypeAAAA) &&
|
||||
d.Req.Question[0].Name == "use-application-dns.net." {
|
||||
d.Res = s.genNXDomain(d.Req)
|
||||
d.Res = s.makeResponseREFUSED(d.Req)
|
||||
return resultFinish
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ func (s *Server) genDNSFilterMessage(d *proxy.DNSContext, result *dnsfilter.Resu
|
||||
m := d.Req
|
||||
|
||||
if m.Question[0].Qtype != dns.TypeA && m.Question[0].Qtype != dns.TypeAAAA {
|
||||
return s.genNXDomain(m)
|
||||
return s.makeResponseREFUSED(m)
|
||||
}
|
||||
|
||||
switch result.Reason {
|
||||
@@ -64,15 +64,20 @@ func (s *Server) genDNSFilterMessage(d *proxy.DNSContext, result *dnsfilter.Resu
|
||||
// means that we should return NXDOMAIN for any blocked request
|
||||
|
||||
return s.genNXDomain(m)
|
||||
|
||||
} else if s.conf.BlockingMode == "refused" {
|
||||
// means that we should return NXDOMAIN for any blocked request
|
||||
|
||||
return s.makeResponseREFUSED(m)
|
||||
}
|
||||
|
||||
// Default blocking mode
|
||||
// If there's an IP specified in the rule, return it
|
||||
// If there is no IP, return NXDOMAIN
|
||||
// If there is no IP, return REFUSED
|
||||
if result.IP != nil {
|
||||
return s.genResponseWithIP(m, result.IP)
|
||||
}
|
||||
return s.genNXDomain(m)
|
||||
return s.makeResponseREFUSED(m)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,6 +187,14 @@ func (s *Server) genCNAMEAnswer(req *dns.Msg, cname string) *dns.CNAME {
|
||||
return answer
|
||||
}
|
||||
|
||||
// Create REFUSED DNS response
|
||||
func (s *Server) makeResponseREFUSED(request *dns.Msg) *dns.Msg {
|
||||
resp := dns.Msg{}
|
||||
resp.SetRcode(request, dns.RcodeRefused)
|
||||
resp.RecursionAvailable = true
|
||||
return &resp
|
||||
}
|
||||
|
||||
func (s *Server) genNXDomain(request *dns.Msg) *dns.Msg {
|
||||
resp := dns.Msg{}
|
||||
resp.SetRcode(request, dns.RcodeNameError)
|
||||
|
||||
Reference in New Issue
Block a user