diff --git a/AGHTechDoc.md b/AGHTechDoc.md index ea2ed95a..4ed2c4e3 100644 --- a/AGHTechDoc.md +++ b/AGHTechDoc.md @@ -916,6 +916,8 @@ Response: ... ] +`domain` can be an exact host name (`www.host.com`) or a wildcard (`*.host.com`). + ### API: Add a rewrite entry diff --git a/client/src/__locales/en.json b/client/src/__locales/en.json index 926ee7a5..48f0af48 100644 --- a/client/src/__locales/en.json +++ b/client/src/__locales/en.json @@ -302,7 +302,7 @@ "setup_guide": "Setup guide", "dns_addresses": "DNS addresses", "dns_start": "DNS server is starting up", - "dns_status_error": "Error of getting DNS server status", + "dns_status_error": "Error checking the DNS server status", "down": "Down", "fix": "Fix", "dns_providers": "Here is a <0>list of known DNS providers to choose from.", @@ -372,7 +372,7 @@ "rewrite_desc": "Allows to easily configure custom DNS response for a specific domain name.", "rewrite_applied": "Applied Rewrite rule", "dns_rewrites": "DNS rewrites", - "form_domain": "Enter domain", + "form_domain": "Enter domain name or wildcard", "form_answer": "Enter IP address or domain name", "form_error_domain_format": "Invalid domain format", "form_error_answer_format": "Invalid answer format", @@ -428,5 +428,8 @@ "whois": "Whois", "filtering_rules_learn_more": "<0>Learn more about creating your own hosts blocklists.", "blocked_by_response": "Blocked by CNAME or IP in response", - "try_again": "Try again" -} \ No newline at end of file + "try_again": "Try again", + "domain_desc": "Enter the domain name or wildcard you want to be rewritten.", + "example_rewrite_domain": "rewrite responses for this domain name only.", + "example_rewrite_wildcard": "rewrite responses for all <0>example.org subdomains." +} diff --git a/client/src/components/Settings/Dns/Config/Form.js b/client/src/components/Settings/Dns/Config/Form.js index d6139fc6..33c25f06 100644 --- a/client/src/components/Settings/Dns/Config/Form.js +++ b/client/src/components/Settings/Dns/Config/Form.js @@ -6,7 +6,7 @@ import { Trans, withNamespaces } from 'react-i18next'; import flow from 'lodash/flow'; import { - renderField, + renderInputField, renderRadioField, renderSelectField, required, @@ -45,7 +45,7 @@ let Form = ({ { return (
+
+ domain_desc +
{ validate={[required, domain]} />
+ + examples_title: +
    +
  1. + example.orgexample_rewrite_domain +
  2. +
  3. + *.example.org –  + + text]}> + example_rewrite_wildcard + + +
  4. +
+
= 2 && + wildcard[0] == '*' && wildcard[1] == '.' && + strings.HasSuffix(host, wildcard[1:]) +} + // Process rewrites table // . Find CNAME for a domain name // . if found, set domain name to canonical name @@ -347,7 +354,9 @@ func (d *Dnsfilter) processRewrites(host string, qtype uint16) Result { for _, r := range d.Rewrites { if r.Domain != host { - continue + if !matchDomainWildcard(host, r.Domain) { + continue + } } ip := net.ParseIP(r.Answer) @@ -362,7 +371,9 @@ func (d *Dnsfilter) processRewrites(host string, qtype uint16) Result { for _, r := range d.Rewrites { if r.Domain != host { - continue + if !matchDomainWildcard(host, r.Domain) { + continue + } } ip := net.ParseIP(r.Answer) diff --git a/dnsfilter/dnsfilter_test.go b/dnsfilter/dnsfilter_test.go index 96d7a256..02176539 100644 --- a/dnsfilter/dnsfilter_test.go +++ b/dnsfilter/dnsfilter_test.go @@ -474,6 +474,60 @@ func TestClientSettings(t *testing.T) { assert.True(t, r.IsFiltered && r.Reason == FilteredBlockedService) } +func TestRewrites(t *testing.T) { + d := Dnsfilter{} + // CNAME, A, AAAA + d.Rewrites = []RewriteEntry{ + RewriteEntry{"somecname", "somehost.com"}, + RewriteEntry{"somehost.com", "0.0.0.0"}, + + RewriteEntry{"host.com", "1.2.3.4"}, + RewriteEntry{"host.com", "1.2.3.5"}, + RewriteEntry{"host.com", "1:2:3::4"}, + RewriteEntry{"www.host.com", "host.com"}, + } + r := d.processRewrites("host2.com", dns.TypeA) + assert.Equal(t, NotFilteredNotFound, r.Reason) + + r = d.processRewrites("www.host.com", dns.TypeA) + assert.Equal(t, ReasonRewrite, r.Reason) + assert.Equal(t, "host.com", r.CanonName) + assert.True(t, len(r.IPList) == 2) + assert.True(t, r.IPList[0].Equal(net.ParseIP("1.2.3.4"))) + assert.True(t, r.IPList[1].Equal(net.ParseIP("1.2.3.5"))) + + r = d.processRewrites("www.host.com", dns.TypeAAAA) + assert.Equal(t, ReasonRewrite, r.Reason) + assert.True(t, len(r.IPList) == 1) + assert.True(t, r.IPList[0].Equal(net.ParseIP("1:2:3::4"))) + + // wildcard + d.Rewrites = []RewriteEntry{ + RewriteEntry{"*.host.com", "1.2.3.5"}, + RewriteEntry{"host.com", "1.2.3.4"}, + } + r = d.processRewrites("host.com", dns.TypeA) + assert.Equal(t, ReasonRewrite, r.Reason) + assert.True(t, r.IPList[0].Equal(net.ParseIP("1.2.3.4"))) + + r = d.processRewrites("www.host.com", dns.TypeA) + assert.Equal(t, ReasonRewrite, r.Reason) + assert.True(t, r.IPList[0].Equal(net.ParseIP("1.2.3.5"))) + + r = d.processRewrites("www.host2.com", dns.TypeA) + assert.Equal(t, NotFilteredNotFound, r.Reason) + + // wildcard + CNAME + d.Rewrites = []RewriteEntry{ + RewriteEntry{"*.host.com", "host.com"}, + RewriteEntry{"host.com", "1.2.3.4"}, + } + r = d.processRewrites("www.host.com", dns.TypeA) + assert.Equal(t, ReasonRewrite, r.Reason) + assert.Equal(t, "host.com", r.CanonName) + assert.True(t, r.IPList[0].Equal(net.ParseIP("1.2.3.4"))) +} + // BENCHMARKS func BenchmarkSafeBrowsing(b *testing.B) {