add new option: 'respond_with_ip'

This commit is contained in:
James Newell 2019-06-09 14:15:38 -05:00 committed by Frank Denis
parent e43b85d9f9
commit 87bbfbfc10
6 changed files with 48 additions and 9 deletions

1
.gitignore vendored
View File

@ -9,3 +9,4 @@
*~
dnscrypt-proxy/dnscrypt-proxy2
dnscrypt-proxy/dnscrypt-proxy
.idea

View File

@ -81,6 +81,7 @@ type Config struct {
OfflineMode bool `toml:"offline_mode"`
HTTPProxyURL string `toml:"http_proxy"`
RefusedCodeInResponses bool `toml:"refused_code_in_responses"`
RespondWithIP string `toml:"respond_with_ip"`
}
func newConfig() Config {
@ -291,6 +292,7 @@ func ConfigLoad(proxy *Proxy, svcFlag *string) error {
proxy.xTransport.rebuildTransport()
proxy.refusedCodeInResponses = config.RefusedCodeInResponses
proxy.respondWithIP = config.RespondWithIP
proxy.timeout = time.Duration(config.Timeout) * time.Millisecond
proxy.maxClients = config.MaxClients
proxy.mainProto = "udp"

View File

@ -2,6 +2,7 @@ package main
import (
"encoding/binary"
"net"
"strings"
"time"
@ -31,7 +32,7 @@ func EmptyResponseFromMessage(srcMsg *dns.Msg) (*dns.Msg, error) {
return dstMsg, nil
}
func RefusedResponseFromMessage(srcMsg *dns.Msg, refusedCode bool) (*dns.Msg, error) {
func RefusedResponseFromMessage(srcMsg *dns.Msg, refusedCode bool, ip net.IP, ttl uint32) (*dns.Msg, error) {
dstMsg, err := EmptyResponseFromMessage(srcMsg)
if err != nil {
return dstMsg, err
@ -42,12 +43,38 @@ func RefusedResponseFromMessage(srcMsg *dns.Msg, refusedCode bool) (*dns.Msg, er
dstMsg.Rcode = dns.RcodeSuccess
questions := srcMsg.Question
if len(questions) > 0 {
hinfo := new(dns.HINFO)
hinfo.Hdr = dns.RR_Header{Name: questions[0].Name, Rrtype: dns.TypeHINFO,
Class: dns.ClassINET, Ttl: 1}
hinfo.Cpu = "This query has been locally blocked"
hinfo.Os = "by dnscrypt-proxy"
dstMsg.Answer = []dns.RR{hinfo}
question := questions[0]
sendHInfoResponse := true
if ip != nil {
if question.Qtype == dns.TypeA {
rr := new(dns.A)
rr.Hdr = dns.RR_Header{Name: question.Name, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: ttl}
rr.A = ip.To4()
if rr.A != nil {
dstMsg.Answer = []dns.RR{rr}
sendHInfoResponse = false
}
} else if question.Qtype == dns.TypeAAAA {
rr := new(dns.AAAA)
rr.Hdr = dns.RR_Header{Name: question.Name, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: ttl}
rr.AAAA = ip.To16()
if rr.AAAA != nil {
dstMsg.Answer = []dns.RR{rr}
sendHInfoResponse = false
}
}
}
if sendHInfoResponse {
hinfo := new(dns.HINFO)
hinfo.Hdr = dns.RR_Header{Name: question.Name, Rrtype: dns.TypeHINFO,
Class: dns.ClassINET, Ttl: 1}
hinfo.Cpu = "This query has been locally blocked"
hinfo.Os = "by dnscrypt-proxy"
dstMsg.Answer = []dns.RR{hinfo}
}
}
}
return dstMsg, nil

View File

@ -117,6 +117,12 @@ keepalive = 30
refused_code_in_responses = false
## If refused_code_in_responses is `false`, use this optional setting
## to redirect blocked respones to an IP address (e.g. pixelserv-tls)
## instead of returning an HINFO record
# respond_with_ip = '192.168.1.4'
## Load-balancing strategy: 'p2' (default), 'ph', 'first' or 'random'

View File

@ -26,6 +26,7 @@ type PluginsGlobals struct {
responsePlugins *[]Plugin
loggingPlugins *[]Plugin
refusedCodeInResponses bool
respondWithIP net.IP
}
type PluginsReturnCode int
@ -136,6 +137,7 @@ func InitPluginsGlobals(pluginsGlobals *PluginsGlobals, proxy *Proxy) error {
(*pluginsGlobals).responsePlugins = responsePlugins
(*pluginsGlobals).loggingPlugins = loggingPlugins
(*pluginsGlobals).refusedCodeInResponses = proxy.refusedCodeInResponses
(*pluginsGlobals).respondWithIP = net.ParseIP(proxy.respondWithIP)
return nil
}
@ -186,7 +188,7 @@ func (pluginsState *PluginsState) ApplyQueryPlugins(pluginsGlobals *PluginsGloba
return packet, ret
}
if pluginsState.action == PluginsActionReject {
synth, err := RefusedResponseFromMessage(&msg, pluginsGlobals.refusedCodeInResponses)
synth, err := RefusedResponseFromMessage(&msg, pluginsGlobals.refusedCodeInResponses, pluginsGlobals.respondWithIP, pluginsState.cacheMinTTL)
if err != nil {
return nil, err
}
@ -234,7 +236,7 @@ func (pluginsState *PluginsState) ApplyResponsePlugins(pluginsGlobals *PluginsGl
return packet, ret
}
if pluginsState.action == PluginsActionReject {
synth, err := RefusedResponseFromMessage(&msg, pluginsGlobals.refusedCodeInResponses)
synth, err := RefusedResponseFromMessage(&msg, pluginsGlobals.refusedCodeInResponses, pluginsGlobals.respondWithIP, pluginsState.cacheMinTTL)
if err != nil {
return nil, err
}

View File

@ -64,6 +64,7 @@ type Proxy struct {
logMaxAge int
logMaxBackups int
refusedCodeInResponses bool
respondWithIP string
showCerts bool
}