mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-30 17:53:21 -04:00 
			
		
		
		
	plugin/acl : add support for Extended DNS Errors (#5532)
* plugin/acl : add support for Extended DNS Errors Signed-off-by: Ondřej Benkovský <ondrej.benkovsky@jamf.com> * fixup! plugin/acl : add support for Extended DNS Errors Signed-off-by: Ondřej Benkovský <ondrej.benkovsky@jamf.com>
This commit is contained in:
		| @@ -69,8 +69,11 @@ RulesCheckLoop: | |||||||
| 		switch action { | 		switch action { | ||||||
| 		case actionBlock: | 		case actionBlock: | ||||||
| 			{ | 			{ | ||||||
| 				m := new(dns.Msg) | 				m := new(dns.Msg). | ||||||
| 				m.SetRcode(r, dns.RcodeRefused) | 					SetRcode(r, dns.RcodeRefused). | ||||||
|  | 					SetEdns0(4096, true) | ||||||
|  | 				ede := dns.EDNS0_EDE{InfoCode: dns.ExtendedErrorCodeBlocked} | ||||||
|  | 				m.IsEdns0().Option = append(m.IsEdns0().Option, &ede) | ||||||
| 				w.WriteMsg(m) | 				w.WriteMsg(m) | ||||||
| 				RequestBlockCount.WithLabelValues(metrics.WithServer(ctx), zone).Inc() | 				RequestBlockCount.WithLabelValues(metrics.WithServer(ctx), zone).Inc() | ||||||
| 				return dns.RcodeSuccess, nil | 				return dns.RcodeSuccess, nil | ||||||
| @@ -81,8 +84,11 @@ RulesCheckLoop: | |||||||
| 			} | 			} | ||||||
| 		case actionFilter: | 		case actionFilter: | ||||||
| 			{ | 			{ | ||||||
| 				m := new(dns.Msg) | 				m := new(dns.Msg). | ||||||
| 				m.SetRcode(r, dns.RcodeSuccess) | 					SetRcode(r, dns.RcodeSuccess). | ||||||
|  | 					SetEdns0(4096, true) | ||||||
|  | 				ede := dns.EDNS0_EDE{InfoCode: dns.ExtendedErrorCodeFiltered} | ||||||
|  | 				m.IsEdns0().Option = append(m.IsEdns0().Option, &ede) | ||||||
| 				w.WriteMsg(m) | 				w.WriteMsg(m) | ||||||
| 				RequestFilterCount.WithLabelValues(metrics.WithServer(ctx), zone).Inc() | 				RequestFilterCount.WithLabelValues(metrics.WithServer(ctx), zone).Inc() | ||||||
| 				return dns.RcodeSuccess, nil | 				return dns.RcodeSuccess, nil | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ import ( | |||||||
| type testResponseWriter struct { | type testResponseWriter struct { | ||||||
| 	test.ResponseWriter | 	test.ResponseWriter | ||||||
| 	Rcode int | 	Rcode int | ||||||
|  | 	Msg   *dns.Msg | ||||||
| } | } | ||||||
|  |  | ||||||
| func (t *testResponseWriter) setRemoteIP(ip string) { | func (t *testResponseWriter) setRemoteIP(ip string) { | ||||||
| @@ -26,6 +27,7 @@ func (t *testResponseWriter) setZone(zone string) { | |||||||
| // 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 | ||||||
|  | 	t.Msg = m | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -48,367 +50,357 @@ func TestACLServeDNS(t *testing.T) { | |||||||
| 		args                  args | 		args                  args | ||||||
| 		wantRcode             int | 		wantRcode             int | ||||||
| 		wantErr               bool | 		wantErr               bool | ||||||
|  | 		wantExtendedErrorCode uint16 | ||||||
| 	}{ | 	}{ | ||||||
| 		// IPv4 tests. | 		// IPv4 tests. | ||||||
| 		{ | 		{ | ||||||
| 			"Blacklist 1 BLOCKED", | 			name: "Blacklist 1 BLOCKED", | ||||||
| 			`acl example.org { | 			config: `acl example.org { | ||||||
| 				block type A net 192.168.0.0/16 | 				block type A net 192.168.0.0/16 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{}, | 			zones: []string{}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"www.example.org.", | 				domain:   "www.example.org.", | ||||||
| 				"192.168.0.2", | 				sourceIP: "192.168.0.2", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeRefused, | 			wantRcode:             dns.RcodeRefused, | ||||||
| 			false, | 			wantExtendedErrorCode: dns.ExtendedErrorCodeBlocked, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Blacklist 1 ALLOWED", | 			name: "Blacklist 1 ALLOWED", | ||||||
| 			`acl example.org { | 			config: `acl example.org { | ||||||
| 				block type A net 192.168.0.0/16 | 				block type A net 192.168.0.0/16 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{}, | 			zones: []string{}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"www.example.org.", | 				domain:   "www.example.org.", | ||||||
| 				"192.167.0.2", | 				sourceIP: "192.167.0.2", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeSuccess, | 			wantRcode: dns.RcodeSuccess, | ||||||
| 			false, |  | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Blacklist 2 BLOCKED", | 			name: "Blacklist 2 BLOCKED", | ||||||
| 			` | 			config: ` | ||||||
| 			acl example.org { | 			acl example.org { | ||||||
| 				block type * net 192.168.0.0/16 | 				block type * net 192.168.0.0/16 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{}, | 			zones: []string{}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"www.example.org.", | 				domain:   "www.example.org.", | ||||||
| 				"192.168.0.2", | 				sourceIP: "192.168.0.2", | ||||||
| 				dns.TypeAAAA, | 				qtype:    dns.TypeAAAA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeRefused, | 			wantRcode:             dns.RcodeRefused, | ||||||
| 			false, | 			wantExtendedErrorCode: dns.ExtendedErrorCodeBlocked, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Blacklist 3 BLOCKED", | 			name: "Blacklist 3 BLOCKED", | ||||||
| 			`acl example.org { | 			config: `acl example.org { | ||||||
| 				block type A | 				block type A | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{}, | 			zones: []string{}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"www.example.org.", | 				domain:   "www.example.org.", | ||||||
| 				"10.1.0.2", | 				sourceIP: "10.1.0.2", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeRefused, | 			wantRcode:             dns.RcodeRefused, | ||||||
| 			false, | 			wantExtendedErrorCode: dns.ExtendedErrorCodeBlocked, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Blacklist 3 ALLOWED", | 			name: "Blacklist 3 ALLOWED", | ||||||
| 			`acl example.org { | 			config: `acl example.org { | ||||||
| 				block type A | 				block type A | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{}, | 			zones: []string{}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"www.example.org.", | 				domain:   "www.example.org.", | ||||||
| 				"10.1.0.2", | 				sourceIP: "10.1.0.2", | ||||||
| 				dns.TypeAAAA, | 				qtype:    dns.TypeAAAA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeSuccess, | 			wantRcode: dns.RcodeSuccess, | ||||||
| 			false, |  | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Blacklist 4 Single IP BLOCKED", | 			name: "Blacklist 4 Single IP BLOCKED", | ||||||
| 			`acl example.org { | 			config: `acl example.org { | ||||||
| 				block type A net 192.168.1.2 | 				block type A net 192.168.1.2 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{}, | 			zones: []string{}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"www.example.org.", | 				domain:   "www.example.org.", | ||||||
| 				"192.168.1.2", | 				sourceIP: "192.168.1.2", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeRefused, | 			wantRcode:             dns.RcodeRefused, | ||||||
| 			false, | 			wantExtendedErrorCode: dns.ExtendedErrorCodeBlocked, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Blacklist 4 Single IP ALLOWED", | 			name: "Blacklist 4 Single IP ALLOWED", | ||||||
| 			`acl example.org { | 			config: `acl example.org { | ||||||
| 				block type A net 192.168.1.2 | 				block type A net 192.168.1.2 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{}, | 			zones: []string{}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"www.example.org.", | 				domain:   "www.example.org.", | ||||||
| 				"192.168.1.3", | 				sourceIP: "192.168.1.3", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeSuccess, | 			wantRcode: dns.RcodeSuccess, | ||||||
| 			false, |  | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Filter 1 FILTERED", | 			name: "Filter 1 FILTERED", | ||||||
| 			`acl example.org { | 			config: `acl example.org { | ||||||
| 				filter type A net 192.168.0.0/16 | 				filter type A net 192.168.0.0/16 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{}, | 			zones: []string{}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"www.example.org.", | 				domain:   "www.example.org.", | ||||||
| 				"192.168.0.2", | 				sourceIP: "192.168.0.2", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeSuccess, | 			wantRcode:             dns.RcodeSuccess, | ||||||
| 			false, | 			wantExtendedErrorCode: dns.ExtendedErrorCodeFiltered, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Filter 1 ALLOWED", | 			name: "Filter 1 ALLOWED", | ||||||
| 			`acl example.org { | 			config: `acl example.org { | ||||||
| 				filter type A net 192.168.0.0/16 | 				filter type A net 192.168.0.0/16 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{}, | 			zones: []string{}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"www.example.org.", | 				domain:   "www.example.org.", | ||||||
| 				"192.167.0.2", | 				sourceIP: "192.167.0.2", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeSuccess, | 			wantRcode: dns.RcodeSuccess, | ||||||
| 			false, |  | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Whitelist 1 ALLOWED", | 			name: "Whitelist 1 ALLOWED", | ||||||
| 			`acl example.org { | 			config: `acl example.org { | ||||||
| 				allow net 192.168.0.0/16 | 				allow net 192.168.0.0/16 | ||||||
| 				block | 				block | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{}, | 			zones: []string{}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"www.example.org.", | 				domain:   "www.example.org.", | ||||||
| 				"192.168.0.2", | 				sourceIP: "192.168.0.2", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeSuccess, | 			wantRcode: dns.RcodeSuccess, | ||||||
| 			false, |  | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Whitelist 1 REFUSED", | 			name: "Whitelist 1 REFUSED", | ||||||
| 			`acl example.org { | 			config: `acl example.org { | ||||||
| 				allow type * net 192.168.0.0/16 | 				allow type * net 192.168.0.0/16 | ||||||
| 				block | 				block | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{}, | 			zones: []string{}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"www.example.org.", | 				domain:   "www.example.org.", | ||||||
| 				"10.1.0.2", | 				sourceIP: "10.1.0.2", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeRefused, | 			wantRcode:             dns.RcodeRefused, | ||||||
| 			false, | 			wantExtendedErrorCode: dns.ExtendedErrorCodeBlocked, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Fine-Grained 1 REFUSED", | 			name: "Fine-Grained 1 REFUSED", | ||||||
| 			`acl a.example.org { | 			config: `acl a.example.org { | ||||||
| 				block type * net 192.168.1.0/24 | 				block type * net 192.168.1.0/24 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{"example.org"}, | 			zones: []string{"example.org"}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"a.example.org.", | 				domain:   "a.example.org.", | ||||||
| 				"192.168.1.2", | 				sourceIP: "192.168.1.2", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeRefused, | 			wantRcode:             dns.RcodeRefused, | ||||||
| 			false, | 			wantExtendedErrorCode: dns.ExtendedErrorCodeBlocked, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Fine-Grained 1 ALLOWED", | 			name: "Fine-Grained 1 ALLOWED", | ||||||
| 			`acl a.example.org { | 			config: `acl a.example.org { | ||||||
| 				block net 192.168.1.0/24 | 				block net 192.168.1.0/24 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{"example.org"}, | 			zones: []string{"example.org"}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"www.example.org.", | 				domain:   "www.example.org.", | ||||||
| 				"192.168.1.2", | 				sourceIP: "192.168.1.2", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeSuccess, | 			wantRcode: dns.RcodeSuccess, | ||||||
| 			false, |  | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Fine-Grained 2 REFUSED", | 			name: "Fine-Grained 2 REFUSED", | ||||||
| 			`acl example.org { | 			config: `acl example.org { | ||||||
| 				block net 192.168.1.0/24 | 				block net 192.168.1.0/24 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{"example.org"}, | 			zones: []string{"example.org"}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"a.example.org.", | 				domain:   "a.example.org.", | ||||||
| 				"192.168.1.2", | 				sourceIP: "192.168.1.2", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeRefused, | 			wantRcode:             dns.RcodeRefused, | ||||||
| 			false, | 			wantExtendedErrorCode: dns.ExtendedErrorCodeBlocked, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Fine-Grained 2 ALLOWED", | 			name: "Fine-Grained 2 ALLOWED", | ||||||
| 			`acl { | 			config: `acl { | ||||||
| 				block net 192.168.1.0/24 | 				block net 192.168.1.0/24 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{"example.org"}, | 			zones: []string{"example.org"}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"a.example.com.", | 				domain:   "a.example.com.", | ||||||
| 				"192.168.1.2", | 				sourceIP: "192.168.1.2", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeSuccess, | 			wantRcode: dns.RcodeSuccess, | ||||||
| 			false, |  | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Fine-Grained 3 REFUSED", | 			name: "Fine-Grained 3 REFUSED", | ||||||
| 			`acl a.example.org { | 			config: `acl a.example.org { | ||||||
| 				block net 192.168.1.0/24 | 				block net 192.168.1.0/24 | ||||||
| 			} | 			} | ||||||
| 			acl b.example.org { | 			acl b.example.org { | ||||||
| 				block type * net 192.168.2.0/24 | 				block type * net 192.168.2.0/24 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{"example.org"}, | 			zones: []string{"example.org"}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"b.example.org.", | 				domain:   "b.example.org.", | ||||||
| 				"192.168.2.2", | 				sourceIP: "192.168.2.2", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeRefused, | 			wantRcode:             dns.RcodeRefused, | ||||||
| 			false, | 			wantExtendedErrorCode: dns.ExtendedErrorCodeBlocked, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Fine-Grained 3 ALLOWED", | 			name: "Fine-Grained 3 ALLOWED", | ||||||
| 			`acl a.example.org { | 			config: `acl a.example.org { | ||||||
| 				block net 192.168.1.0/24 | 				block net 192.168.1.0/24 | ||||||
| 			} | 			} | ||||||
| 			acl b.example.org { | 			acl b.example.org { | ||||||
| 				block net 192.168.2.0/24 | 				block net 192.168.2.0/24 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{"example.org"}, | 			zones: []string{"example.org"}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"b.example.org.", | 				domain:   "b.example.org.", | ||||||
| 				"192.168.1.2", | 				sourceIP: "192.168.1.2", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeSuccess, | 			wantRcode: dns.RcodeSuccess, | ||||||
| 			false, |  | ||||||
| 		}, | 		}, | ||||||
| 		// IPv6 tests. | 		// IPv6 tests. | ||||||
| 		{ | 		{ | ||||||
| 			"Blacklist 1 BLOCKED IPv6", | 			name: "Blacklist 1 BLOCKED IPv6", | ||||||
| 			`acl example.org { | 			config: `acl example.org { | ||||||
| 				block type A net 2001:db8:abcd:0012::0/64 | 				block type A net 2001:db8:abcd:0012::0/64 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{}, | 			zones: []string{}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"www.example.org.", | 				domain:   "www.example.org.", | ||||||
| 				"2001:db8:abcd:0012::1230", | 				sourceIP: "2001:db8:abcd:0012::1230", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeRefused, | 			wantRcode:             dns.RcodeRefused, | ||||||
| 			false, | 			wantExtendedErrorCode: dns.ExtendedErrorCodeBlocked, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Blacklist 1 ALLOWED IPv6", | 			name: "Blacklist 1 ALLOWED IPv6", | ||||||
| 			`acl example.org { | 			config: `acl example.org { | ||||||
| 				block type A net 2001:db8:abcd:0012::0/64 | 				block type A net 2001:db8:abcd:0012::0/64 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{}, | 			zones: []string{}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"www.example.org.", | 				domain:   "www.example.org.", | ||||||
| 				"2001:db8:abcd:0013::0", | 				sourceIP: "2001:db8:abcd:0013::0", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeSuccess, | 			wantRcode: dns.RcodeSuccess, | ||||||
| 			false, |  | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Blacklist 2 BLOCKED IPv6", | 			name: "Blacklist 2 BLOCKED IPv6", | ||||||
| 			`acl example.org { | 			config: `acl example.org { | ||||||
| 				block type A | 				block type A | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{}, | 			zones: []string{}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"www.example.org.", | 				domain:   "www.example.org.", | ||||||
| 				"2001:0db8:85a3:0000:0000:8a2e:0370:7334", | 				sourceIP: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeRefused, | 			wantRcode:             dns.RcodeRefused, | ||||||
| 			false, | 			wantExtendedErrorCode: dns.ExtendedErrorCodeBlocked, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Blacklist 3 Single IP BLOCKED IPv6", | 			name: "Blacklist 3 Single IP BLOCKED IPv6", | ||||||
| 			`acl example.org { | 			config: `acl example.org { | ||||||
| 				block type A net 2001:0db8:85a3:0000:0000:8a2e:0370:7334 | 				block type A net 2001:0db8:85a3:0000:0000:8a2e:0370:7334 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{}, | 			zones: []string{}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"www.example.org.", | 				domain:   "www.example.org.", | ||||||
| 				"2001:0db8:85a3:0000:0000:8a2e:0370:7334", | 				sourceIP: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeRefused, | 			wantRcode:             dns.RcodeRefused, | ||||||
| 			false, | 			wantExtendedErrorCode: dns.ExtendedErrorCodeBlocked, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Blacklist 3 Single IP ALLOWED IPv6", | 			name: "Blacklist 3 Single IP ALLOWED IPv6", | ||||||
| 			`acl example.org { | 			config: `acl example.org { | ||||||
| 				block type A net 2001:0db8:85a3:0000:0000:8a2e:0370:7334 | 				block type A net 2001:0db8:85a3:0000:0000:8a2e:0370:7334 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{}, | 			zones: []string{}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"www.example.org.", | 				domain:   "www.example.org.", | ||||||
| 				"2001:0db8:85a3:0000:0000:8a2e:0370:7335", | 				sourceIP: "2001:0db8:85a3:0000:0000:8a2e:0370:7335", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeSuccess, | 			wantRcode: dns.RcodeSuccess, | ||||||
| 			false, |  | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Fine-Grained 1 REFUSED IPv6", | 			name: "Fine-Grained 1 REFUSED IPv6", | ||||||
| 			`acl a.example.org { | 			config: `acl a.example.org { | ||||||
| 				block type * net 2001:db8:abcd:0012::0/64 | 				block type * net 2001:db8:abcd:0012::0/64 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{"example.org"}, | 			zones: []string{"example.org"}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"a.example.org.", | 				domain:   "a.example.org.", | ||||||
| 				"2001:db8:abcd:0012:2019::0", | 				sourceIP: "2001:db8:abcd:0012:2019::0", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeRefused, | 			wantRcode:             dns.RcodeRefused, | ||||||
| 			false, | 			wantExtendedErrorCode: dns.ExtendedErrorCodeBlocked, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Fine-Grained 1 ALLOWED IPv6", | 			name: "Fine-Grained 1 ALLOWED IPv6", | ||||||
| 			`acl a.example.org { | 			config: `acl a.example.org { | ||||||
| 				block net 2001:db8:abcd:0012::0/64 | 				block net 2001:db8:abcd:0012::0/64 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{"example.org"}, | 			zones: []string{"example.org"}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"www.example.org.", | 				domain:   "www.example.org.", | ||||||
| 				"2001:db8:abcd:0012:2019::0", | 				sourceIP: "2001:db8:abcd:0012:2019::0", | ||||||
| 				dns.TypeA, | 				qtype:    dns.TypeA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeSuccess, | 			wantRcode: dns.RcodeSuccess, | ||||||
| 			false, |  | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"Blacklist Address%ifname", | 			name: "Blacklist Address%ifname", | ||||||
| 			`acl example.org { | 			config: `acl example.org { | ||||||
| 				block type AAAA net 2001:0db8:85a3:0000:0000:8a2e:0370:7334 | 				block type AAAA net 2001:0db8:85a3:0000:0000:8a2e:0370:7334 | ||||||
| 			}`, | 			}`, | ||||||
| 			[]string{"eth0"}, | 			zones: []string{"eth0"}, | ||||||
| 			args{ | 			args: args{ | ||||||
| 				"www.example.org.", | 				domain:   "www.example.org.", | ||||||
| 				"2001:0db8:85a3:0000:0000:8a2e:0370:7334", | 				sourceIP: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", | ||||||
| 				dns.TypeAAAA, | 				qtype:    dns.TypeAAAA, | ||||||
| 			}, | 			}, | ||||||
| 			dns.RcodeRefused, | 			wantRcode:             dns.RcodeRefused, | ||||||
| 			false, | 			wantExtendedErrorCode: dns.ExtendedErrorCodeBlocked, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -438,6 +430,20 @@ func TestACLServeDNS(t *testing.T) { | |||||||
| 			if w.Rcode != tt.wantRcode { | 			if w.Rcode != tt.wantRcode { | ||||||
| 				t.Errorf("Error: acl.ServeDNS() Rcode = %v, want %v", w.Rcode, tt.wantRcode) | 				t.Errorf("Error: acl.ServeDNS() Rcode = %v, want %v", w.Rcode, tt.wantRcode) | ||||||
| 			} | 			} | ||||||
|  | 			if tt.wantExtendedErrorCode != 0 { | ||||||
|  | 				matched := false | ||||||
|  | 				for _, opt := range w.Msg.IsEdns0().Option { | ||||||
|  | 					if ede, ok := opt.(*dns.EDNS0_EDE); ok { | ||||||
|  | 						if ede.InfoCode != tt.wantExtendedErrorCode { | ||||||
|  | 							t.Errorf("Error: acl.ServeDNS() Extended DNS Error = %v, want %v", ede.InfoCode, tt.wantExtendedErrorCode) | ||||||
|  | 						} | ||||||
|  | 						matched = true | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				if !matched { | ||||||
|  | 					t.Error("Error: acl.ServeDNS() missing Extended DNS Error option") | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user