Automate local DNS with Bind and Terraform

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
if there's one thing I really hate in it it is doing manual configuration just like with managing DNS records in my home lab where I had all the servers and application names in a huge config file needed to fill in IP addresses all the time and remove outdated entries ah thank God these days are over now because from now on I'm managing all my local DNS entries fully automatic in terraform if I want to install a virtual machine on proxmox or deploy applications where I just need new DNS records no problem I can just add them as a resource to my terraform files and it will be automatically configured on my local DNS server this is really cool and today I'm going to show you exactly how I've done that note this video is kind of a c assette of a symbol to my previous DNS tutorial so if you are entirely new to this and you're not sure about how to set up a local DNS server you probably should go and check out my other videos as well of course I'll put links for you in the description down below but still as always I like to go over all the things that are important here step by step so don't worry you can easily follow along with me and you can also check out the full write-up of this tutorial with all the commands and configs on GitHub link also below okay so I hope you're ready let's do this and let's automate your DNS records with terraform this video is supported by teleport a free and open source access proxy that helps you to securely authenticate to all your it infrastructure like Linux servers databases kubernetes clusters web applications or remote desktop you can easily protect your accounts with modern security features such as two-factor authentication or a password that's locked in and access your services through the browser or the CLI tool with audit logging and session recording and the best it's completely free in the community version so you can just download and run it in your entire home lab or if you would like to use it in your company teleport offers many professional features like auditing single sign-on and more it's a great tool so just check it out you will find a link to their website in the description of this video okay so the first thing that we need to do is we need to prepare my bind DNS server to allow updates to its configuration from outside usually byte is configured in static config files such as the named.conf that contains the general configuration and the Zone files that hold all the DNS records with names in IP addresses for a given DNS zone so far so good but you can also set it up to allow Dynamic updates to its configuration and that's what we are using later in terraform to configure new DNS records fully remote to make this all work and send these Dynamic updates securely to our DNS server we need to set up a so-called t-sig key a transaction signature key this is simply just a shared secret that we need to put on the server and use it to authenticate with our client this is all part of the RFC 8945 the secret key transaction authentication for DNS you don't need to remember all of that but it is worth reading one thing that I need to highlight from this document is that tzig supports a couple of different hash algorithms such as md5 sha1 sha2 and so on and although md5 is still in common use to create TZ Keys these days you actually shouldn't be using it anymore it is already known to be insecure so what I always would do is make sure when you're creating such a key always use at least sha2 that you can easily do with a simple command in your terminal so here I'm for example using the tzig key generator tool to create a new shared secret with an sha2 hash if you're wondering where you get this tool from this should always be included in the DNS server packages so you can just either execute this with a Docker execute command inside your bind 9 container or just download the byte9 installation packages on your workstation and then call it from your Mac Linux or Windows terminal the tzig key generator then creates a config setting that you just need to put in your bind configuration file you can either directly add it through the name.conf or include it for example on my bind DNS server that is deployed in a Docker container I've just put this key into a separate file that I've called name.conf.key and edit and include statement into my main config file the name.conf so here you can just reference any other configuration files the transaction signature key file is no different always make sure to protect this key file on your server with the correct permissions of course and that's how you can get this shared secret on your DNS server there's just one more thing to do for us because we've just included this key but we also need to tell our DNS server to accept Dynamic updates to our DNS Zone from any client that authenticates with this key and in my DNS servers config duration you can see I've created one DNS Zone where I'm storing all the DNS entries for my local home lab so this is just using the home.cocreative.de domain and in this Zone configuration we need to add another section that is called update policy Grant the permission to our TC key to make updates to the Zone file by the way make sure that you're using the same name in here as you have defined in your config it's important that these names match and then you can just restart your DNS server by stopping and starting the container to make these changes active on your DNS server so you can see it's actually pretty simple to configure automatic updates in bind by the way you can also use the transaction signature keys with any other client or CLI tool as well and send automatic updates to your DNS zone or administrate your whole DNS server I will later show you a quick example of how to use it with the rndc tool however I have found it pretty useful to update all my DNS records using terraform as this allows me to manage the entire life cycle of my DNS record that means when you need new DNS records for one project you can easily create them automatically but you can also make sure that these records are removed again once you're terminating the project that's perfect for lazy admins just like me by the way if you are entirely new to terraform this is an infrastructure as code automation tool I've covered it in a previous video here on this channel many it Pros use it to manage infrastructure for example it's really incredible to deploy new virtual machines I've also made one video about how to create new virtual machines on my proxmox server just using templates or I've created entire kubernetes clusters with it in the cloud just by using terraform if you want to check out these videos as well I've added them to the description and by the way if you're enjoying watching these videos why not give this a like And subscribe because that's really helping us with the YouTube algorithm okay back to the topic so for managing our our DNS records I'm quickly going to create another terraform project just for a quick demonstration so we'll start with a new terraform file where I'm defining the provider settings first in this project we only need one provider that is called DNS and I'm going to use the provider which is managed by hashicorp and also simply called DNS pretty simple I'm also defining the latest version that is currently out there here so by the way if you're watching this video a few months later for example it probably has a new version but you can easily check out the latest version number of the DNS provider on the official terraform registry page so just copy and paste this value into your terraform file and this is also the place where you would typically find the entire documentation for this provider so if you want to create all sorts of different DNS records then you'll find great examples for this as you can probably imagine we also need to configure a couple of things for this provider so here are all the settings that we need to add in our terraform file because we need to authenticate with our transaction signature key that we've just created and you can just copy this stuff from the documentation and paste it into the terraform file of course we would need to change some of the values in here like the server should be the real IP address of my DNS server the key name should be the same name as we've configured in the named dot conf the algorithm is whatever you have used to create this key in our example this was hmac sha 256 and the secret is then just the transaction signature key note that you probably should not store this one here in plain text because this is a very sensitive key that's why I'm always using a terraform variable in here I'm quickly defining this as a new secret variable and set the type to string and I also enable the sensitive setting to true so this is important when you are executing the terraform command that this will obfuscate your secret variables you then just need to add this secret for example by using an auto variables file in terraform I've shown you that in my terraform tutorial so I hope you're all very familiar with that and then you should also make sure these secret variable files are securely stored on your device so that no one can get access to your DNS server and manipulate your records sure in your local home lab that might not be so dangerous but if you are messing this up in a production environment this can become pretty dramatic this is by the way also called DNS spoofing or a DNS hijacking attack in cyber security so make sure to keep all your secrets safe okay so now that we have that ready we can start adding new DNS records as resources in my terraform files and just going to create a new file for our DNS entries and there I will just add a simple a record set this is what I would use when I deploy new devices or applications in my home lab I often just create a new dnsa record for them that points to the internal IP address of the server or load balancer you first need to add the correct DNS Zone this of course needs to match with whatever your DNS zone is in your home lab and then we can give this DNS record a host name something like example let let's just keep it simple you know so the fully qualified domain name for this new DNS record or this new server would be example.home.crcreative.te that's how we should be able to look up this record later with an NS looker of course we also need to specify the IP address or IP addresses actually because you cannot just put one IP address in here you can also make this a list and add more than one then your client will just connect to one of these IP addresses by using DNS round robin that's pretty useful if you have something like a load balancer like any kubernetes cluster for example where you have multiple servers and you just want to distribute traffic across them you can just use a set of IP addresses in a dnsa ruggage but again you can define basically anything that you need in here just take a look at the officials terraform registry documentation for this provider there you will find examples for creating a records ipv6a records cnames MX name server PTR SRV and txt that's what you would typically need when you're administrating a DNS server you can also set a TDL value so that stands for time to live and this is a time for how long the client should keep this record in the cache by default this is set to one hour but I tend to make this TTL value shorter in my home lab I know this is not very efficient because my client would need to make a new DNS query every five minutes I'm just doing this because my DNS records for test machines might change pretty quickly here I'm always creating new projects and I don't want my clients to keep the DNS records for too long in the cache that's how you can avoid stupid issues like ah your client can't connect to your new deployment because it has an old DNS record somewhere in the cache but that's of course up to you how you want to handle that in your home lab okay great so now that we have defined our dnsa record we could start making these changes happening on our DNS server first we need to call the terraform init command in our terminal this will just download the DNS provider and initialize our terraform project and once it was successful let's try to run the plan command so this won't change anything on the server it will just tell us what would happen if we would apply these changes and as you can see it will try to create a newer dnsa record on all server for these three IP addresses okay that's all good let's now apply these changes prove them and if you've done everything right you should see a success message if you get an error in here like me you probably messed up something in the terraform configure something with your TZ key or DNS isn't right I've already got some weird issues in here so for example in the terraform resources when they are formatted in a wrong way so I can just say make sure to always use underscores in such objects not dashes I also had problems with my DNS server that didn't have the correct permissions to create the journal file inside the config directory more about that in a second so if something doesn't work as you expect Don't Panic just take a quick look in the darker compose locks and it should actually tell you what's the problem finally after I had fixed my permissions error on the server you can see we now got our DNS record updated correctly let's now try to do a simple NS lookup on our machine this is how a client would try to resolve this name to IP addresses and you can see there are our three IP addresses really cool however there are a few things I'd still like to show you because some of you will now say ah why make this all so complicated for me it's just simpler to log into SSH to my server and just edit the config file or even use tools like ansible look there's nothing wrong with doing it this way I'm just saying if you're using terraform in other projects it probably will fit more to your workflows one of the biggest advantages for me is I'm often deploying new servers or applications and I can't even keep track of all the things that I'm doing in my home lab yeah I know this is not a technical problem apparently this is more a problem with my chaotic project management but if you're changing things quickly in your home lab and you're working on multiple projects the entire form probably will just work better than anything else for example I'm doing this mostly when I'm automating my virtual machines on proxmox where I meet new DNS records and this can be automated so easy in terraform because you can just Define all the resources like the settings the provisioning script aesthetic IP address all the stuff that you need on this virtual machine and then it's so simple to just add another resource in here for adding the correct dnest record you can apply all of this in a single project with a single command and when you're done with it you can completely destroy all that again with a single command and that makes sure you're not forgetting to remove this DNS record from your server or there are any other resource is left you can you can instantly reuse this DNS record or the IP address in another project without being worried that you're running into any conflicts for me this workflow is much easier to manage than keeping track of all my entries in a static config file however you might still ask so how do these DNS records actually look on the DNS servers config and what's happening in my existing Zone file let's have a quick look so when we open our Zone file you can see that our example DNS record that I've just traded using terraform is missing in here and that is because the dynamic updates are not directly written to the steady config file in bind they are stored in a journal file which is a temporary file that stores all the changes we have made to the Zone data during Dynamic updates and this journal file can be then merged into the aesthetic config file either manually or automatically there is a small tool that I'm using for that and this is called the rndc the remote name demon control tool or is it called Damon I still don't know you can execute this with a simple command directly on your DNS server or also on a client it authenticates to our DNS server using the transaction signature key so it actually is the same authentication that we've configured in terraform we just need to add one new config file for this tool in the config directory of bind that is called rndc.conf and when I open this file we need to add some configuration settings here so first the shared secret I've just included it like in the name.com and we also need to Define some options you just need to set the default key to this transaction signature key in here and the server will be just the local IP address because we are running this command line tool not on my Mac workstation but we're running it inside the docker container where bind is running so we can just use the localhost IP and I'm also using the default Port 953 so using the secure DNS protocol of course when you're using this r NDC tool you also need to enable settings for it in your DNS servers config so let's jump back to myname.com and in here you need to add another section that is called controls there you just Define listen on the local IP address using the secure DNS port and allow incoming connections from the local machine using our T6 key that we have already included just the same one we've used for terraform just to say technically you could also set up different key is one for rndc one for terraform or configure it to allow rndc to run on your local workstation but for me it is just simpler to do it this way because then I don't need to install the rndc tool on my Mac I can just execute the rndc command inside the bind 9 Docker container by the way this tool can be used to do so many other different administrative tasks on the bind server maybe this would be an interesting topic for another video but for now we'll just use the sync command this will perform a synchronization between the journal configuration and our static configuration and as you can see I've done another mistake in this config man I just hate these semicolons so much in the buying config that's exactly the reason why I'm so sick of this manual configuration crap anyway let's fix this problem quickly and continue now our Command execution was successful so no you won't get anything back but if you don't get an error that means it worked and when we know open our static config file you can see it has synchronized our DNS record from the journal file to the static Zone configuration if you often change your DNS records and you'd like to always have this journal file written back to the static config you can think about running this tool periodically maybe using ansible or any other shell script that's how I'm doing it currently but please I need to say don't worry too much about this because the journal file is still storage persistent so it's not really a temporary file somewhere in the cache it's basically just two separate ways of configuring bind DNS record so synchronizing the journal file with aesthetic config this is just for you for instance if you want to use your static config file as a read-only source to know what actually are all the DNS records that are currently active on the system because you can't really open this journal file in an easy way so then you should probably from time to time sync the journal file with aesthetic config and by the way if you want to delete your DNS records again you can just destroy the terraform project where you have defined them using a simple terraform destroy command and this will delete all the resources that this terraform project has applied on the server a you can automate all your DNS records in your home lab I'm very excited about this because it is helping me a ton to keep track of all the things that I am configuring in my home lab without leaving some outdated resources somewhere on the server but what do you say will you start automating your local DNS records with bind and terraform please tell me in the comments and as always thank you so much for watching I will catch you in the next video take care bye bye
Info
Channel: Christian Lempa
Views: 25,121
Rating: undefined out of 5
Keywords:
Id: eSUtsDUTzuc
Channel Id: undefined
Length: 20min 56sec (1256 seconds)
Published: Tue May 23 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.