going-flying.com gemini git repository
ddba112a57a4b710cc0a18df182f56f2d84b2fc7 - Matthew Ernisse - 1616199636
new post
diff --git a/users/mernisse/articles/21.gmi b/users/mernisse/articles/21.gmi new file mode 100644 index 0000000..7fbd541 --- /dev/null +++ b/users/mernisse/articles/21.gmi @@ -0,0 +1,233 @@ +--- +Title: Sysadmining: DNS Two, Authoritative +Date: 3/19/2021 20:20 + +## Why should you care? +It's pretty obvious why running your own resolver is something worth doing, +the privacy, security and performance advantages versus using someone else's +DNS resolver is obvious. Now that we're going to talk about serving our own +authoritative domains we should probably answer the question as to why you should +care? There are two reasons, the easiest and most obvious is to provide DNS +for services you are putting on the Internet, after all no one will be able +to find your domain if you don't serve it. + +## Back to BIND +Lets think about setting up a hypothetical, example domain, it will ultimately +serve a Gemini capsule and accept mail. The first thing you will want to do +is setup at least two servers, preferably on different providers, with static +IP (and preferably IPv6) addresses. These can do other things as well, but +in my case my second server is just a $5/month droplet on Digital Ocean. Once +you have BIND installed you just need to tell it that it is going to answer +questions about your domain. I am going to show examples based on Debian +Linux because that's what I like. You can adjust for which ever distribution +you prefer. Often the named(8) manpage will tell you where the default +configuration files are. + +### /etc/bind/named.conf.local +To tell BIND that we are going to answer questions for our hypothetical +going-flying.com domain we add the following to named.conf.local on our +primary server. + +``` +zone "going-flying.com" IN { + type master; + notify yes; + file "going-flying.com"; + allow-update { none; }; + allow-transfer { peers; }; +}; +``` + +On the rest of our servers we will add a slightly different stanza. + +``` +zone "going-flying.com" IN { + type slave; + masters { ip.address.of.primary; }; +}; +``` + +Also in named.conf.local on all of your servers you should make an ACL to +prevent just any random host on the Internet from being able to download your +entire zone. + +``` +acl peers { + ip.address.of.each.server; + can.also.be.a.network/cidr; + also:takes:v6:prefixes/cidr; +}; +``` + +You should also probably setup TSIG authentication for your servers but I'll +leave that as an advanced exercise for the reader. It's not that difficult +and BIND provides a utility (dnssec-keygen) to generate the keys needed. + +### /var/cache/bind/going-flying.com +This is your actual zonefile. There are many many many more record types +than what I will list in this simple example but these are enough to get +your first zone online. + +``` +$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. +``` + +This is the top of my zonefile. The first line specifies the default TTL for +negative caching. You can read more about that in RFC-2308, but in a nutshell +it is how long a client will cache the fact that there is no answer for the +question. In the above case if we asked the server where we should send +mail for going-flying.com the answer would be NXDOMAIN. This answer would be +cached for 21600 seconds because of the $TTL line. + +=> /cgi-bin/rfc/rfc2308.txt RFC-2308: Negative Caching of DNS Queries (DNS NCACHE) + +Next we have RR or resource records. The format of the RR is a bit flexible +since most of the fields have defaults that will be used if not specified. + +``` +Name | TTL | Class | Type | Data +``` + +Name can be thought of as the 'question' part of the RR. If I am asking for +'www.going-flying.com.' then BIND is trying to match on the Name field of the +zone. Name can be specified as either a bare name or as a fully-qualified +domain name. In the case of a bare name BIND with append the zone we are +configuring to it automatically. To specify a FQDN you need to use the full +name which includes the trailing '.'. In our example 'www' and +'www.going-flying.com.' refer to the same name. + +The TTL and class are almost always omitted. If the TTL is omitted then +the value of the default TTL is used (more on this later). Class is always +IN. There are other classes but IN is Internet and that is the default. + +Now we have the meat of the RR, the type. Each DNS question has a type +associated with it. The most commonly used are the A and AAAA which map +from a name to an IP (or IPv6) address. + +Finally we have the data. This is the answer to the question. The format +of the answer depends on the type of the RR. Looking back at our example +zone file after the $TTL line we have a special RR that uses the @ name. +This RR is of type SOA which means Start of Authority. This defines the +metadata associated with the zone. @ is a special name that resolves to the +zone that we are configuring. The SOA data starts with the primary DNS server +that is serving the domain, then the admin e-mail address (with the @ replaced +with a .) then a set of values in parenthesis. The values in the +parenthesis are as follows + +``` +Serial Number | Refresh Interval | Retry Interval | Expire | Minimum TTL +``` + +The serial number can be anything, but it MUST increment. A secondary server +will not download a new zonefile from the primary server if the serial number +is less than or equal to what it already has. Getting this wrong can cause +all sorts of problems with your servers falling out of sync. The rule of +thumb (for as long as I have been doing this, so c. 1997) has been to use +YYYYMMDDHHMM## as a format, so the 3rd update on 2021-03-19 would have a serial +of 2021031902 (note the zero index). The TTL time in the SOA is the default +TTL used on any other RR if it is omitted. The Refresh, Retry and Expire times +are all used by the secondary servers to determine how often they check in +to see if there are updates. Note that the 'notify yes' line in the +named.conf.local file earlier will cause the primary DNS server to tell the +secondary server when it updates are available. RIPE has provided some +guidance on reasonable defaults for these values. The example contains +the values that I use on my production domains. + +=> https://www.ripe.net/publications/docs/ripe-203 Recommendations for DNS SOA Values + +After the SOA we have the A and AAAA records that I talked about. Because we +specified @ before BIND assumes we are still talking about the same name. It +will continue to assume that until we specify a new name. After the A and +AAAA records we ourselves the NS records. Here we list the names of all the +DNS servers that are serving our zone. Note that we could use the short +names or the FQDNs here. In my case my DNS servers serve several domains so +I just refer to them by FQDN here. + +Finally we are going to add one last RR type so we can receive mail on our +going-flying.com domain. + +``` + MX 10 mail.provider.com. +``` + +This 'MX' record stands for 'mail exchanger' and was created to allow mail +servers to discover the proper server (or servers) when presented with +an e-mail address to deliver to. A mail server will look for an MX record +first and if it doesn't find it may try to connect to the IP address for the +domain (if there is an A or AAAA record for the root of the zone). The format +of the data part of this RR type is as follows. + +``` +Preference | Exchange +``` + +=> /cgi-bin/rfc/rfc1035.txt Domain Implementation and Specification +=> /cgi-bin/rfc/rfc2821.txt Simple Mail Transfer Protocol +=> /cgi-bin/rfc/rfc7505.txt A "Null MX" No Service Resource Record for Domains That Accept No Mail + +The preference is a 16 bit integer which provides a preference for the +server. The exchange is the name of the server. A mail sever should work +their way though the list of available exchangers starting with the lowest +preference number first. Any exchangers with the same preference number should +be tried round-robin. + + +## Say it with authority +Once you have this up and running you should be able to query your server and +get back an authoritative answer for your domain. + +``` +; <<>> DiG 9.11.5-P4-5.1+deb10u3-Debian <<>> soa going-flying.com @ns01.ub3rgeek.net +;; global options: +cmd +;; Got answer: +;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14819 +;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 5 +;; WARNING: recursion requested but not available + +;; OPT PSEUDOSECTION: +; EDNS: version: 0, flags:; udp: 1232 +; COOKIE: 085f3ba17163fef87b9206a260553dd380c61eb48d9fc0f9 (good) +;; QUESTION SECTION: +;going-flying.com. IN SOA + +;; ANSWER SECTION: +going-flying.com. 21600 IN SOA ns01.ub3rgeek.net. hostmaster.ub3rgeek.net. 2021030200 3600 1800 1209600 21600 + +;; AUTHORITY SECTION: +going-flying.com. 21600 IN NS ns01.ub3rgeek.net. +going-flying.com. 21600 IN NS ns02.ub3rgeek.net. + +;; ADDITIONAL SECTION: +ns01.ub3rgeek.net. 21600 IN AAAA 2606:c380:c001:3::3 +ns02.ub3rgeek.net. 21600 IN AAAA 2604:a880:1:20::5ff:7001 +ns01.ub3rgeek.net. 21600 IN A 69.55.65.182 +ns02.ub3rgeek.net. 21600 IN A 198.199.103.32 + +;; Query time: 75 msec +;; SERVER: 2606:c380:c001:3::3#53(2606:c380:c001:3::3) +;; WHEN: Fri Mar 19 20:12:03 EDT 2021 +;; MSG SIZE rcvd: 258 +``` + +From the ->>HEADER<<- section you can see that this was answered with AUTHORITY +which means we asked the authoritative server the question. That would be 0 +if we asked a recursive resolver and it had to go fetch the answer on our +behalf. + +Next time, we'll put this all together and talk about a useful BIND feature +(and the reason I run such a strange setup with BIND forwarding to Unbound +to get DNS over TLS) called views, that lets us serve different zones based on +where our client is coming from.