Fixing issue #5376 by adding a check to parse out Zone info (#5387)

* Fixing #5376 by adding a check to parse out Zone information

Signed-off-by: Tintin <samrath.sodi@gmail.com>

* using IndexByte instead of strings.Split()

Signed-off-by: Tintin <samrath.sodi@gmail.com>

* using plugin logger for logging parsing failure

Signed-off-by: Tintin <samrath.sodi@gmail.com>

* using var keywork instead of short declaration operator

Signed-off-by: Tintin <samrath.sodi@gmail.com>

* reordering imports

Signed-off-by: Tintin <samrath.sodi@gmail.com>
This commit is contained in:
Tintin 2022-05-20 10:22:30 +05:30 committed by GitHub
parent d594d61341
commit 71f68a3363
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 3 deletions

View file

@ -3,9 +3,11 @@ package acl
import ( import (
"context" "context"
"net" "net"
"strings"
"github.com/coredns/coredns/plugin" "github.com/coredns/coredns/plugin"
"github.com/coredns/coredns/plugin/metrics" "github.com/coredns/coredns/plugin/metrics"
clog "github.com/coredns/coredns/plugin/pkg/log"
"github.com/coredns/coredns/request" "github.com/coredns/coredns/request"
"github.com/infobloxopen/go-trees/iptree" "github.com/infobloxopen/go-trees/iptree"
@ -49,6 +51,8 @@ const (
actionFilter actionFilter
) )
var log = clog.NewWithPlugin("acl")
// ServeDNS implements the plugin.Handler interface. // ServeDNS implements the plugin.Handler interface.
func (a ACL) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { func (a ACL) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
state := request.Request{W: w, Req: r} state := request.Request{W: w, Req: r}
@ -96,7 +100,19 @@ RulesCheckLoop:
func matchWithPolicies(policies []policy, w dns.ResponseWriter, r *dns.Msg) action { func matchWithPolicies(policies []policy, w dns.ResponseWriter, r *dns.Msg) action {
state := request.Request{W: w, Req: r} state := request.Request{W: w, Req: r}
ip := net.ParseIP(state.IP()) var ip net.IP
if idx := strings.IndexByte(state.IP(), '%'); idx >= 0 {
ip = net.ParseIP(state.IP()[:idx])
} else {
ip = net.ParseIP(state.IP())
}
// if the parsing did not return a proper response then we simply return 'actionBlock' to
// block the query
if ip == nil {
log.Errorf("Blocking request. Unable to parse source address: %v", state.IP())
return actionBlock
}
qtype := state.QType() qtype := state.QType()
for _, policy := range policies { for _, policy := range policies {
// dns.TypeNone matches all query types. // dns.TypeNone matches all query types.

View file

@ -19,6 +19,10 @@ func (t *testResponseWriter) setRemoteIP(ip string) {
t.RemoteIP = ip t.RemoteIP = ip
} }
func (t *testResponseWriter) setZone(zone string) {
t.Zone = zone
}
// WriteMsg implement dns.ResponseWriter interface. // WriteMsg implement dns.ResponseWriter interface.
func (t *testResponseWriter) WriteMsg(m *dns.Msg) error { func (t *testResponseWriter) WriteMsg(m *dns.Msg) error {
t.Rcode = m.Rcode t.Rcode = m.Rcode
@ -392,6 +396,20 @@ func TestACLServeDNS(t *testing.T) {
dns.RcodeSuccess, dns.RcodeSuccess,
false, false,
}, },
{
"Blacklist Address%ifname",
`acl example.org {
block type AAAA net 2001:0db8:85a3:0000:0000:8a2e:0370:7334
}`,
[]string{"eth0"},
args{
"www.example.org.",
"2001:0db8:85a3:0000:0000:8a2e:0370:7334",
dns.TypeAAAA,
},
dns.RcodeRefused,
false,
},
} }
ctx := context.Background() ctx := context.Background()
@ -408,6 +426,9 @@ func TestACLServeDNS(t *testing.T) {
w := &testResponseWriter{} w := &testResponseWriter{}
m := new(dns.Msg) m := new(dns.Msg)
w.setRemoteIP(tt.args.sourceIP) w.setRemoteIP(tt.args.sourceIP)
if len(tt.zones) > 0 {
w.setZone(tt.zones[0])
}
m.SetQuestion(tt.args.domain, tt.args.qtype) m.SetQuestion(tt.args.domain, tt.args.qtype)
_, err = a.ServeDNS(ctx, w, m) _, err = a.ServeDNS(ctx, w, m)
if (err != nil) != tt.wantErr { if (err != nil) != tt.wantErr {

View file

@ -12,6 +12,7 @@ import (
type ResponseWriter struct { type ResponseWriter struct {
TCP bool // if TCP is true we return an TCP connection instead of an UDP one. TCP bool // if TCP is true we return an TCP connection instead of an UDP one.
RemoteIP string RemoteIP string
Zone string
} }
// LocalAddr returns the local address, 127.0.0.1:53 (UDP, TCP if t.TCP is true). // LocalAddr returns the local address, 127.0.0.1:53 (UDP, TCP if t.TCP is true).
@ -33,9 +34,9 @@ func (t *ResponseWriter) RemoteAddr() net.Addr {
ip := net.ParseIP(remoteIP) ip := net.ParseIP(remoteIP)
port := 40212 port := 40212
if t.TCP { if t.TCP {
return &net.TCPAddr{IP: ip, Port: port, Zone: ""} return &net.TCPAddr{IP: ip, Port: port, Zone: t.Zone}
} }
return &net.UDPAddr{IP: ip, Port: port, Zone: ""} return &net.UDPAddr{IP: ip, Port: port, Zone: t.Zone}
} }
// WriteMsg implements dns.ResponseWriter interface. // WriteMsg implements dns.ResponseWriter interface.