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/dnsfilter/dnsfilter.go b/dnsfilter/dnsfilter.go
index 3843f1dc..ae91164f 100644
--- a/dnsfilter/dnsfilter.go
+++ b/dnsfilter/dnsfilter.go
@@ -334,6 +334,13 @@ func (d *Dnsfilter) CheckHost(host string, qtype uint16, setts *RequestFiltering
 	return Result{}, nil
 }
 
+// Return TRUE of host name matches a wildcard pattern
+func matchDomainWildcard(host, wildcard string) bool {
+	return len(wildcard) >= 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) {