going-flying.com gemini git repository
8a1c2e85b31911f2030533478bdf3b9c55ed87c1 - Matthew Ernisse - 1618355309
new post
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.