<p>The best method is via the response policy zone in Bind 9.8.1 or newer. It allows you to override single records in arbitrary zones (and there’s no need to create a whole subdomain for that, only the single record you want to change), it allows you to override CNAMEs, etc. Other solutions such as Unbound cannot override CNAMEs.</p>
<p><a href="https://www.redpill-linpro.com/sysadvent/2015/12/08/dns-rpz.html">https://www.redpill-linpro.com/sysadvent/2015/12/08/dns-rpz.html</a></p>
<p><strong>EDIT:</strong> Let’s do this properly then. I will document what I’ve done based on the tutorial linked above.</p>
<p>My OS is Raspbian 4.4 for Raspberry Pi, but the technique should work without any changes on Debian and Ubuntu, or with minimal changes on other platforms.</p>
<p>Go to where your Bind config files are kept on your system - here it’s in <code>/etc/bind</code>. Create in there a file called <code>db.rpz</code> with the following contents:</p>
<pre><code class="lang-auto">$TTL 60
@ IN SOA localhost. root.localhost. (
2015112501 ; serial
1h ; refresh
30m ; retry
1w ; expiry
30m) ; minimum
IN NS localhost.
localhost A 127.0.0.1
www.some-website.com A 127.0.0.1
www.other-website.com CNAME fake-hostname.com.
</code></pre>
<p>What does it do?</p>
<ul>
<li>
<p>it overrides the IP address for <code>www.some-website.com</code> with the fake address <code>127.0.0.1</code>, effectively sending all traffic for that site to the loopback address</p>
</li>
<li>
<p>it sends traffic for <code>www.other-website.com</code> to another site called <code>fake-hostname.com</code></p>
</li>
</ul>
<p>Anything that could go in a Bind zone file you can use here.</p>
<p>To activate these changes there are a few more steps:</p>
<p>Edit <code>named.conf.local</code> and add this section:</p>
<pre><code class="lang-auto">zone "rpz" {
type master;
file "/etc/bind/db.rpz";
};
</code></pre>
<p>The tutorial linked above tells you to add more stuff to <code>zone "rpz" { }</code> but that’s not necessary in simple setups - what I’ve shown here is the minimum to make it work on your local resolver.</p>
<p>Edit <code>named.conf.options</code> and somewhere in the <code>options { }</code> section add the <code>response-policy</code> option:</p>
<pre><code class="lang-auto">options {
// bunch
// of
// stuff
// please
// ignore
response-policy { zone "rpz"; };
}
</code></pre>
<p>Now restart Bind:</p>
<pre><code class="lang-auto">service bind9 restart
</code></pre>
<p>That’s it. The nameserver should begin overriding those records now.</p>
<p>If you need to make changes, just edit <code>db.rpz</code>, then restart Bind again.</p>
<p>Bonus: if you want to log DNS queries to syslog, so you can keep an eye on the proceedings, edit <code>named.conf.local</code> and make sure there’s a <code>logging</code> section that includes these statements:</p>
<pre><code class="lang-auto">logging {
// stuff
// already
// there
channel my_syslog {
syslog daemon;
severity info;
};
category queries { my_syslog; };
};
</code></pre>
<p>Restart Bind again and that’s it.</p>
<p>Test it on the machine running Bind:</p>
<pre><code class="lang-auto">dig @127.0.0.1 www.other-website.com. any
</code></pre>
<p>If you run dig on a different machine just use <span class="mention">@the-ip-address-of-Bind-server</span> instead of <span class="mention">@127.0.0.1</span></p>
<p>I’ve used this technique with great success to override the CNAME for a website I was working on, sending it to a new AWS load balancer that I was just testing. A Raspberry Pi was used to run Bind, and the RPi was also configured to function as a WiFi router - so by connecting devices to the SSID running on the RPi I would get the DNS overrides I needed for testing.</p>