gemini.git

going-flying.com gemini git repository

summary

tree

log

refs

8a1c2e85b31911f2030533478bdf3b9c55ed87c1 - Matthew Ernisse - 1618355309

new post

view tree

view raw

diff --git a/users/mernisse/articles/22.gmi b/users/mernisse/articles/22.gmi
new file mode 100644
index 0000000..8cc941a
--- /dev/null
+++ b/users/mernisse/articles/22.gmi
@@ -0,0 +1,287 @@
+---
+Title: Sysadmining: DNS Three, ACLs and Views
+Date: 4/13/2021 19:06
+
+## Why should you care?
+Views are one of the more powerful features of BIND.  In the previous two
+issues we talked about providing a recursive resolver and an authoritative
+resolver, but we provided them to anyone who asked us, equally.  What if
+we only wanted to provide recursion to our local network but provide
+authoritative resolution to everyone?  Well we can do that with BIND ACLs.
+Now lets say we want to provide our LAN with *different* answers than to
+the Internet at large, we can use BIND ACLs and Views to do that.  This opens
+up a huge amount of power in providing DNS to our clients.
+
+## ACLs
+So first we have to classify clients.  As you might expect we do this with
+ACLs (access control lists).  We saw one last time in our primary resolver
+configuration but for this time lets expand on our hypothetical example domain
+with some IP address space.  We will use 192.168.242.0/23 and
+fd00:0242::/48 as our LAN.  To start with we want to create an ACL that
+identifies our IP space.
+
+### /etc/bind/named.conf.local
+```
+acl internal-networks {
+	127.0.0.1/32;
+	::1/128;
+	192.168.242.0/23;
+	fd00:0242::/48;
+};
+```
+
+## Restricting recursive resolution
+Now that we have an ACL lets look at locking down our server.  It is
+generally good practice with DNS to not provide rescursive services on your
+authoritative servers.  This prevents people from causing your server to
+query others.  There are many vulnerable DNS servers out there (mostly the
+embedded ones running on consumer Internet gateways) can be used for
+traffic amplification DDoS attacks and by denying recursion you prevent your
+server from being used in this manner.  In the main named.conf on Debian
+you should have an options section, in there you can use the following
+directives with our ACL.
+
+* allow-query
+* allow-query-cache
+* allow-recursion
+
+allow-query is what it says on the tin.  You can use this to restrict answers
+of any kind to listed clients.  In our case we want to use the built-in ACL
+'any' to allow all clients to at least ask us questions.
+
+allow-query-cache restricts access to cached data.  This means that if the
+answer is in the cache, the server will reply with it, it doesn't mean the
+server will to get the answer though.  In my case I restrict this to the
+same group that can trigger a recursive lookup. 
+
+allow-recursion controls who can trigger a recursive lookup.  Only members
+of this group can cause our server to ask other servers questions.
+
+### /etc/bind/named.conf
+```
+options {
+	allow-query { any; };
+	allow-query-cache { internal-networks; };
+	allow-recursion { internal-networks; };
+};
+```
+
+## Beyond ACLs, Views
+So now that we have locked down our server to split who can query our
+zones versus who can get us to go out and query other zones on their behalf
+let us look at a much more powerful feature in BIND called views.  This lets
+you create a different picture of your DNS configuration based on the client.
+In our example lets say we split our IP space up into trusted clients and
+guests.  We can say 192.168.242.0/24 and fd00:0242::/64 are 'trusted' and
+192.168.243.0/24 and fd00:0242::1::/64 are our 'guest' networks.  First we
+need to setup our ACLs.
+
+```
+acl trusted-networks {
+	192.168.242.0/24;
+	fd00:0242::/64;
+};
+
+acl guest-networks {
+	192.168.243.0/24;
+	fd00:0242::1::/64;
+};
+```
+
+Lets look at our primary server from last time and setup our server to
+serve our zone to both groups.
+
+```
+view "guests" {
+	match-clients { guest-networks; };
+
+	zone "going-flying.com" IN {
+	        type master;
+		notify yes;
+		file "going-flying.com";
+		allow-update { none; };
+		allow-transfer { peers; };
+	};
+
+};
+
+view "trusted" {
+	match-clients { trusted-networks; };
+	zone "going-flying.com" IN {
+	        type master;
+		notify yes;
+		file "going-flying.com";
+		allow-update { none; };
+		allow-transfer { peers; };
+	};
+};
+
+view "public" {
+	match-clients { any; };
+	zone "going-flying.com" IN {
+	        type master;
+		notify yes;
+		file "going-flying.com";
+		allow-update { none; };
+		allow-transfer { peers; };
+	};
+};
+```
+
+This configuration will serve our zone to anyone who asks.  It is functionally
+the same as doing nothing different from last time.  Lets add some filtering
+to our guest network by using the quad9.net DNS service.  They provide a
+filtered view of the Internet, blocking malware domains at the lowest level.
+If we add the following into our 'guests' view it will force any queries for
+things our server doesn't know to the quad9.net service.
+
+```
+forwarders {
+	9.9.9.9;
+	2620:fe::9;
+};
+forward only;
+```
+
+Next lets say we want our LAN clients to get an internally hosted version of
+our website instead of the public version.  Recall from last time our example
+zone:
+
+```
+$TTL 21600
+@               IN SOA  ns01.ub3rgeek.net. hostmaster.ub3rgeek.net. (
+                        2021030200 ; serial
+                        3600       ; refresh (1 hour)
+                        1800       ; retry (30 mins)
+                        1209600    ; expire (2 weeks)
+                        21600      ; minimum (6 hrs)
+                        )
+
+                        A       69.55.65.182
+                        AAAA    2606:c380:c001:3::2
+
+                        NS      ns01.ub3rgeek.net.
+                        NS      ns02.ub3rgeek.net.
+```
+
+We can create a copy of this for our internal clients and change our A and
+AAAA records to our internal webserver.  We will save this in a separate
+file, for example 'trusted-going-flying.com'.
+
+```
+$TTL 21600
+@               IN SOA  ns01.ub3rgeek.net. hostmaster.ub3rgeek.net. (
+                        2021030200 ; serial
+                        3600       ; refresh (1 hour)
+                        1800       ; retry (30 mins)
+                        1209600    ; expire (2 weeks)
+                        21600      ; minimum (6 hrs)
+                        )
+
+                        A       192.168.242.2
+                        AAAA    fd00:0242::1
+
+                        NS      ns01.ub3rgeek.net.
+                        NS      ns02.ub3rgeek.net.
+```
+
+Now we change the zone stanza in our trusted view to reference our new zone.
+
+```
+	zone "going-flying.com" IN {
+	        type master;
+		notify yes;
+		file "trusted-going-flying.com";
+		allow-update { none; };
+		allow-transfer { peers; };
+	};
+```
+
+Finally lets hook up our trusted clients to the DNS over TLS forwarder we
+built back in the first part of this series.  If you have followed along
+I bet you'll be able to guess how we do it, since it is essentially the
+same as our quad9 filtering.  In the 'trusted' view add the following.
+
+```
+	forwarders {
+		::1 port 5300;
+	};
+	forward only;
+```
+
+Hopefully you can start to see how powerful this is.  I use this extensively
+along with other technologies like VLANs, VPNs, firewalls and proxies to
+provide segmentation and protection to clients and servers that are under my
+control.  You can steer almost any client anywhere you want if you control
+DNS and with views you can do this with great granularity.  Our hypothetical
+configuration looks like the below now, provides quad9.net protection for
+our guests, a custom version of 'going-flying.com' and DNS over TLS recursion
+for our trusted clients and the default version of our domain to everyone else.
+
+```
+options {
+	allow-query { any; };
+	allow-query-cache { internal-networks; };
+	allow-recursion { internal-networks; };
+};
+
+acl internal-networks {
+	127.0.0.1/32;
+	::1/128;
+	192.168.242.0/23;
+	fd00:0242::/48;
+};
+
+acl trusted-networks {
+	192.168.242.0/24;
+	fd00:0242::/64;
+};
+
+acl guest-networks {
+	192.168.243.0/24;
+	fd00:0242::1::/64;
+};
+
+view "guests" {
+	match-clients { guest-networks; };
+
+	zone "going-flying.com" IN {
+	        type master;
+		notify yes;
+		file "going-flying.com";
+		allow-update { none; };
+		allow-transfer { peers; };
+	};
+
+};
+
+view "trusted" {
+	match-clients { trusted-networks; };
+	zone "going-flying.com" IN {
+	        type master;
+		notify yes;
+		file "going-flying.com";
+		allow-update { none; };
+		allow-transfer { peers; };
+	};
+
+	forwarders {
+		::1 port 5300;
+	};
+	forward only;
+};
+
+view "public" {
+	match-clients { any; };
+	zone "going-flying.com" IN {
+	        type master;
+		notify yes;
+		file "going-flying.com";
+		allow-update { none; };
+		allow-transfer { peers; };
+	};
+};
+```
+
+Now in the last part of the DNS series I'll mention some higher level things
+like DNSSEC and give some hints on how I automated all of this with Puppet.