Implement the IPv6 block plugin
This commit is contained in:
parent
fb16eadb24
commit
f283105866
|
@ -17,6 +17,7 @@ type Config struct {
|
|||
ForceTCP bool `toml:"force_tcp"`
|
||||
Timeout int `toml:"timeout_ms"`
|
||||
CertRefreshDelay int `toml:"cert_refresh_delay"`
|
||||
BlockIPv6 bool `toml:"block_ipv6"`
|
||||
ServersConfig map[string]ServerConfig `toml:"servers"`
|
||||
}
|
||||
|
||||
|
@ -56,6 +57,7 @@ func ConfigLoad(proxy *Proxy, config_file string) error {
|
|||
}
|
||||
proxy.listenAddresses = config.ListenAddresses
|
||||
proxy.daemonize = config.Daemonize
|
||||
proxy.pluginBlockIPv6 = config.BlockIPv6
|
||||
if len(config.ServerNames) == 0 {
|
||||
for serverName := range config.ServersConfig {
|
||||
config.ServerNames = append(config.ServerNames, serverName)
|
||||
|
|
|
@ -40,6 +40,13 @@ timeout = 2500
|
|||
cert_refresh_delay = 30
|
||||
|
||||
|
||||
############## Filters ##############
|
||||
|
||||
## Immediately respond to IPv6-related queries with an empty response
|
||||
## This makes things faster when there is no IPv6 connectivity
|
||||
|
||||
block_ipv6 = false
|
||||
|
||||
|
||||
############## Servers ##############
|
||||
|
||||
|
|
|
@ -18,6 +18,15 @@ func TruncatedResponse(packet []byte) ([]byte, error) {
|
|||
return dstMsg.Pack()
|
||||
}
|
||||
|
||||
func EmptyResponseFromMessage(srcMsg *dns.Msg) (*dns.Msg, error) {
|
||||
dstMsg := srcMsg
|
||||
dstMsg.Response = true
|
||||
dstMsg.Answer = make([]dns.RR, 0)
|
||||
dstMsg.Ns = make([]dns.RR, 0)
|
||||
dstMsg.Extra = make([]dns.RR, 0)
|
||||
return dstMsg, nil
|
||||
}
|
||||
|
||||
func HasTCFlag(packet []byte) bool {
|
||||
return packet[2]&2 == 2
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ type Proxy struct {
|
|||
listenAddresses []string
|
||||
daemonize bool
|
||||
registeredServers []RegisteredServer
|
||||
pluginBlockIPv6 bool
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
@ -163,14 +164,24 @@ func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, serverProto str
|
|||
if clientAddr == nil {
|
||||
clientProto = "tcp"
|
||||
}
|
||||
pluginsState := NewPluginsState(clientProto)
|
||||
pluginsState := NewPluginsState(proxy, clientProto)
|
||||
query, _ = pluginsState.ApplyQueryPlugins(query)
|
||||
var response []byte
|
||||
var err error
|
||||
if pluginsState.action != PluginsActionForward {
|
||||
if pluginsState.synthResponse != nil {
|
||||
response, err = pluginsState.synthResponse.PackBuffer(response)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(response) == 0 {
|
||||
encryptedQuery, clientNonce, err := proxy.Encrypt(serverInfo, query, serverProto)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
serverInfo.noticeBegin(proxy)
|
||||
var response []byte
|
||||
if serverProto == "udp" {
|
||||
response, err = proxy.exchangeWithUDPServer(serverInfo, encryptedQuery, clientNonce)
|
||||
} else {
|
||||
|
@ -180,6 +191,7 @@ func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, serverProto str
|
|||
serverInfo.noticeFailure(proxy)
|
||||
return
|
||||
}
|
||||
}
|
||||
if clientAddr != nil {
|
||||
if len(response) > MaxDNSUDPPacketSize {
|
||||
response, err = TruncatedResponse(response)
|
||||
|
|
|
@ -11,6 +11,7 @@ const (
|
|||
PluginsActionForward = 1
|
||||
PluginsActionDrop = 2
|
||||
PluginsActionReject = 3
|
||||
PluginsActionSynth = 4
|
||||
)
|
||||
|
||||
type PluginsState struct {
|
||||
|
@ -21,6 +22,7 @@ type PluginsState struct {
|
|||
proto string
|
||||
queryPlugins *[]Plugin
|
||||
responsePlugins *[]Plugin
|
||||
synthResponse *dns.Msg
|
||||
}
|
||||
|
||||
type Plugin interface {
|
||||
|
@ -29,9 +31,15 @@ type Plugin interface {
|
|||
Eval(pluginsState *PluginsState, msg *dns.Msg) error
|
||||
}
|
||||
|
||||
func NewPluginsState(proto string) PluginsState {
|
||||
queryPlugins := &[]Plugin{Plugin(new(PluginGetSetPayloadSize))}
|
||||
func NewPluginsState(proxy *Proxy, proto string) PluginsState {
|
||||
queryPlugins := &[]Plugin{}
|
||||
if proxy.pluginBlockIPv6 {
|
||||
*queryPlugins = append(*queryPlugins, Plugin(new(PluginBlockIPv6)))
|
||||
}
|
||||
*queryPlugins = append(*queryPlugins, Plugin(new(PluginGetSetPayloadSize)))
|
||||
|
||||
responsePlugins := &[]Plugin{}
|
||||
|
||||
return PluginsState{action: PluginsActionForward, maxPayloadSize: MaxDNSUDPPacketSize - ResponseOverhead,
|
||||
queryPlugins: queryPlugins, responsePlugins: responsePlugins, proto: proto}
|
||||
}
|
||||
|
@ -47,6 +55,9 @@ func (pluginsState *PluginsState) ApplyQueryPlugins(packet []byte) ([]byte, erro
|
|||
pluginsState.action = PluginsActionDrop
|
||||
return packet, ret
|
||||
}
|
||||
if pluginsState.action != PluginsActionForward {
|
||||
break
|
||||
}
|
||||
}
|
||||
packet2, err := msg.PackBuffer(packet)
|
||||
if err != nil {
|
||||
|
@ -55,6 +66,8 @@ func (pluginsState *PluginsState) ApplyQueryPlugins(packet []byte) ([]byte, erro
|
|||
return packet2, nil
|
||||
}
|
||||
|
||||
// -------- get_set_payload_size plugin --------
|
||||
|
||||
type PluginGetSetPayloadSize struct{}
|
||||
|
||||
func (plugin *PluginGetSetPayloadSize) Name() string {
|
||||
|
@ -86,3 +99,33 @@ func (plugin *PluginGetSetPayloadSize) Eval(pluginsState *PluginsState, msg *dns
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// -------- block_ipv6 plugin --------
|
||||
|
||||
type PluginBlockIPv6 struct{}
|
||||
|
||||
func (plugin *PluginBlockIPv6) Name() string {
|
||||
return "block_ipv6"
|
||||
}
|
||||
|
||||
func (plugin *PluginBlockIPv6) Description() string {
|
||||
return "Immediately return a synthetic response to AAAA queries"
|
||||
}
|
||||
|
||||
func (plugin *PluginBlockIPv6) Eval(pluginsState *PluginsState, msg *dns.Msg) error {
|
||||
questions := msg.Question
|
||||
if len(questions) != 1 {
|
||||
return nil
|
||||
}
|
||||
question := questions[0]
|
||||
if question.Qclass != dns.ClassINET || question.Qtype != dns.TypeAAAA {
|
||||
return nil
|
||||
}
|
||||
synth, err := EmptyResponseFromMessage(msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pluginsState.synthResponse = synth
|
||||
pluginsState.action = PluginsActionSynth
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue