You want a real DNS Server at home? (bind9 + docker)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everybody this is Christian and welcome to the first video in 2023 I hope you all had a wonderful Christmas and New Year's party I actually spent some time with my family and I could really use the time to relax a little but yeah the new year just begun and I have so many ideas for projects and videos that I all want to do with you and in this one I want to cover a topic I know many of you were waiting for and it's really about time that I do this because I recently changed my entire DNS setup in my home lab I completely changed the way how I'm resolving DNS entries I installed a local DNS server and I changed my domain I think this is such a great project to learn and practice all of this stuff and how DNS works and you can do some really cool things with it yeah like access all your internal devices and services with a recognizable name maybe as part of your public domain to be able to issue trusted SSL certificates for all your devices and services or you can manage your DNS lookups in your network by adding four borders and access control is to protect your internal networks and even do things like malware and content blocking that's all what we're covering today we will install and set up the free and open source DNS server bind and of course we will use Docker to easily deploy it to a Linux server and if you haven't really worked with DNS before or you're probably wondering how you should manage your DNS resolving in your internal Network trust me after watching this video you will have a solid understanding of how it works so I hope you will enjoy it and yeah let's get started 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 logged in and access your services through the browser or the seal itool 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 before we start with the actual tutorial and start installing a DNS server I want to give you a bit more background about what was my DNS setup before running bind and why I've actually changed it because I had a working DNS solution before as you might know we have covered in many different videos things like setting up virtual machines Linux servers Nas systems and I never needed to type in IP addresses whenever I want to access these systems that's why you would want to use a DNS server in your home API when you're lazy like me you don't like remembering IP addresses and the strategy that I've been using in the past was pretty simple I just used effect domain for my internal Network that's not publicly resolvable in my case that was seal creative.home and then I just use my firewall the surface XG as my primary DNS server so when my PC wanted to resolve an internal DNS name the request was sent to my firewall where I was maintaining a list of names and corresponding IP addresses and then the firewall just sent back the IP address of the DNS name to my PC so I could connect to the internal servers this system had been working great for a pretty long time but there were a couple of issues with that so first because I was using a fake domain I always had to use self-signed certificates for all my web services because you can't just go to Let's encrypt and say Hey I want to issue a certificate for a fake domain you always need a real public domain that you register somewhere to be able to issue trusted SSL certificates so that was a big problem that I wanted to change but there also were other things like the limitations of the surface XG firewall when it comes to DNS it's not really meant to be a fully featured DNS server it's foremost a firewall and that's a reason why you can't add any wildcat DNS records on it which is certainly annoying for example when I wanted to deploy a new application on my kubernetes cluster which needs a new DNS name for traffic I always needed to add a DNS entry on the firewall as well for every new app obviously it would be so much easier to just create one Wild Card DNS entry that I can use for all my apps on the cluster and there was also a third issue that someone wanted to address because it wasn't easy to automate this whole stuff even though the surface XG has an API that I could use to create static DNS records programmatically but I wanted to have a system that has the capabilities to update these entries with other tools because I'm already using things like ansible or terraform and I really wanted to have the option to use that in the future to manage DNS records so my preview setup worked somehow but it had a lot of upgrade potential let's let's phrase it positively right that's why I've recently asked you on Twitter and by the way thank you so much for all your your contributions there so how are you actually managing DNS resolutions in your home lab are you running a DNS server or do you use a public domain or effect domain and it seems like everybody is solving that task somehow differently but what most people came up with and that seemed to be a great solution in my opinion is the first instead of a fake domain using a real public domain from now on for example I'm using my primary domain steel creative.de now where I can issue trusted SSL certificates from let's encrypt and then I can install a DNS server that is running somewhere in my local network which will be an alternative DNS server for a subdomain of my public domain so this DNS server should be able to create all kinds of DNS records like eight records that resolve to servers load balanced IPS or Wildcat records that are valid for any app deployments on my kubernetes clusters even MX records when I want to test out mail servers just for my local network so that is really a nice solution and with this setup I'd also have the possibility to set up a so-called split Horizon DNS so you kind of have the same domain internally and externally but the internal DNS servers resolve to only internal IP addresses via the external servers can resolve to public IPS or you can also hide your DNS entries entirely from the internet because you're just using a subdomain that's only used internally and so that is what I've done in my home lab and of course I want to show you how that exactly works so you can install and set up a DNS server and then just use it for internal name resolving or even if your primary DNS server to serve all DNS queries in your home network the possibilities are endless the only question was which software I'd like to use as my DNS server and I've seen many people who just use services like pie hole or ad guard that are primarily not meant to be in the NS servers but they are actually running on top of a DNS server and that you can also use as for internal DNS resolving but I wanted to step up the game a little and familiarize my yourself with a more Enterprise ready solution which has a big Advantage because I could learn something new about DNS server management and how it's done in the corporate world and that should also be the best choice for future improvements and if I'd ever want to automate DNS entries with ansible or terraform so that should be easily possible with a more commonly used DNS server so I've decided to use bind as my primary DNS server at home and this is a free and open source DNS server developed by the internet systems Consortium shortly called ICS and it's a very versatile classic and complete name server software if you want to install bind ICS is offering downloads of buy and foremost popular Linux distributions but we are not going to use the ICS maintained versions of bind instead I'm going to use the bind 9 Docker image which is maintained as part of the LTS container images by canonical this is basically just a version of bind that canonical chips with Ubuntu and because that's also my preferred Linux distribution that I'm running on all my servers at home I thought it's a great fit to just run their LTS container images whenever it's possible just to say you can of course also run the 9 DNS server on Ubuntu itself without using Docker but if you're following my channel for a while you probably know that I really love containerization and I just do everything with Docker when I can just to mention if you're not sure about it and you don't know what Docker or Docker composes and how to use it I've made several tutorials about that in the past I'll link to them in the video description and by the way when we are just speaking about my videos if you haven't really liked this one and subscribe to my channel why not consider doing this yeah you would do me a big favor because it helps a ton with YouTube algorithm and supports me to make more free tutorials for you guys so just hit that small button below okay so that was it for the introduction I probably could talk even more and more about DNS and how DNS works but I believe you just want to get started and don't worry we will learn all the theoretical stuff along the way because we have to configure a couple of different things so let's just do that and let's jump right into my Linux server as in all my tutorials I've already prepared one server running Ubuntu Docker and darker compose that's one of my demo servers and here I've just simply created a new folder which I've called DNS demo 2 that's located in my home directory and here we will store all the configs and decompose files the volumes everything that we need for this project and I've also connected my vs code Editor to this remote Linux server and I've opened this project folder so here we can work remotely on this machine and just trade and upload all the files in one step that's pretty comfortable so first let's create a new Docker compose file so this is our template that will tell Docker which container to run and how to run it this file I've started with the version 3 and defined a new service called bind9 where I've set the container name to DNS demo 2. so this is just the name of our Docker container just pick whatever name makes sense to you and the image will be set to the Ubuntu bind 9 image again this is the canonicals LTS container image for bind in the latest version and what I've also needed to do is to configure their permissions on the folders and configs correctly I added one environment variable to set the bind 9 user to root and I also added a second one that will configure the time zone so nothing really so special in the next section we also need to expose the network ports for the byte9 servers and you probably might know that DNS is always using the port 53 but unlike most other services it's not using only the TCP protocol for this pot instead it's also using UDP which is a stateless protocol and that requires a different setting in Docker compose because by default when you just type in the port 53 it always exposes the port with the TCP protocol only so what I've done is I've exposed the part 53 once with the TCP protocol and the same port as well with the UDP protocol we also need to mount three volumes into the Container so we just pick our root path and edit the mount points the first is for the config folder which is mounted directly into the ETC bind folder and as you probably can guess that is where we put our config files in later I also added a cache folder where I buy 9 might store any cache info and the records folder which is actually not so relevant for our tutorial but we might need it in future so these are all the relevant config directories that we need don't forget to create them on the remote server as well and finally we also want to configure the restart policy for the container I've just chosen unless stopped but you could also use always that would be a great fit because we would like to make sure our DNS server is always started on our machine even after a reboot of the host okay so that's it about the compose file that was the simple part no we need to tell the DNS server what it should do by creating the default config and the good news is bind has just one main conflict file even though you might see some other tutorials that use even more complicated conflicts but we just need to create one simple file that is called the named.conf and here we can add all the general options and Zone specific settings I've just placed this into our config folder on the remote server and added the main options section and first to have a functional DNS server that can resolve DNS queries we need to configure one or more four Waters where outgoing queries are Central because if you're asking your DNS server hey what is the IP address of youtube.com your DNS server does know the answer so it needs to ask another DNS server and this DNS server might also have to ask another one so that's going on and on until their responsible DNS server which has this entry likely the one of Google's DNS servers is responding youtube.com is running on this IP address and that's then sent back all the way to your PC that is how a recursive DNS lookup is working and that's how all IP addresses on the internet are resolved by the way so there are millions of DNS servers running all across the world all have huge lists of names and appear addresses and the DNS protocol is created to ask around all these DNS servers to find out which one is responsible for a particular domain and that's where the IP address is ultimately coming from so for all the queries that need to be resolved which won't be specified in a Zone file on this particular server you can add one or more forwarding DNS servers for example I've configured the cloudflare's primary and secondary DNS servers IP addressed to the config because I've made the experience that either cloudflare or also the Google's DNS server say they have a great latency and they are able to resolve IP addresses pretty quickly however you can of course also add your isp's DNS server for example if you're using Vodafone or I don't know which other providers you have in the US or somewhere else you probably will get an IP address for the DNS servers of your ISP so you can also use these servers for resolving or you can use other services that are around like quad 9 is a pretty great service or also cloudflare's Family Protection addresses these are based on the cloudflare's DNS servers but they already contain some kind of malware and adult content blocking that's a pretty interesting option to increase the security in your entire network without configuring anything on a client or on a server but just using DNS or another option you can even add a pie hole DNS so it's not that you need to replace everything with bind you can also add your own chain of DNS resolvings yeah maybe you first send all your queries to a bind server for internal resolving and then it's is going to your pie hole or ad card for ad blocking before it's then finally sent out to cloudflare or Google and also don't worry too much here about latency DNS is a pretty efficient protocol and also every DNS server in the chain would also cache all these queries for a specific time so you have tons and tons of options here and I just mentioned a few of them of course it's completely up to you how you will manage the resolving Chain by the way later at the end of this video I will also show you how I'm doing it my home lab and what my DNS server lookup chain will look like there's just one more thing I wanted to tell you about this year because by default bind will answer queries coming from all IP addresses and what you can or what you should do is you should maintain a custom Access Control list for your internal DNS resolving for example here I have created one Access Control list that I call internal and this contains all IP networks in my home lab you could even think about excluding or including just specific IP addresses in here here but just make sure that your DNS server won't serve lookups for every Network automatically because that could be a problem somehow I mean if you are running this behind a net firewall or a router don't worry too much because usually this DNS server shouldn't be accessible from the public internet by default but just in case you have a situation where you'd like to make it accessible somehow don't make the mistake of not protecting it because that's also called an open DNS resolver I saw a server that is willing to resolve recursive DNS lookups for anyone on the internet and that's likely going to be abused in just a few minutes yeah your server will be flooded by millions of DNS requests and it will probably break your server so don't expose the port 53 on the public internet or when you really need to do it make sure you have an access control list that's of course also protecting your internal networks from any of these attacks so it's really important that you somehow Define such a control list to put all the internal IP addresses or networks in there and then just if fine with the a low query statement in the option section which objects should be permitted to send DNS requests to bind here you can also nip addresses of course but because we just defined the internal ACL the axis control list we simply can put the name in here and yeah that's how you have a better control over who is allowed to use this DNS server in your network okay so that's not really much but it's basically all you need to configure a recursive DNS server in bind and let's quickly do a test and see if that's working before we create our Zone file for internal domains I'm just running this on my remote server with a Docker compose up command and see if it throws any errors and yeah okay you can see I got an error here that will likely happen on your server as well when you installed it on Ubuntu because Ubuntu and that might be the case for other Linux distros as well it already has a DNS server running that's used for internal DNS resolving on the server itself and because this DNS server is already using the port 53 we can't start the bind container but there's a pretty simple fix on Ubuntu for that you just need to add a specific file in the ETC systemd that's called the resolve.conf and here you need to find a line which is called DNS stop listener just uncomment this line and change the value to no this will disable the listening on Port 53 for the resolved service on Ubuntu so it's free again and then we can use it to run bind to make this setting active we just need to restart the servers with the systemctl restart systemd resolved and that's it so let's now try to run the bind container again and that now should work fine so once the bind service has started up correctly and you didn't get any other errors you can then make a DNS query by using the NS lookup tool in your terminal that by the way should work on Linux Mac OS and also Windows let's for example try try to resolve the IP address for the name youtube.com and also make sure that you add the IP address of your remote Linux server where bind is running at the end of the command because otherwise nslookup will just resolve the name by using your default DNS server that's configured on the operating system and that's of course not what we want of course we want to test what actually happens if we ask our own bind DNS server and as you can see my DNS server gives us the IP address of youtube.com so the recursive DNS lookup is already working and now we can just use this as our primary DNS server in the entire network but that's of course just the first part so what I also wanted to do is maintain a zone of my public domain which I fill in with names and IP addresses of my internal services and that's done by adding a Zone config in the named dot conf file and here I'm going to add a new Zone that I call demo.cl creative.de so that is a subdomain of my public domain which I registered on cloudfare just to mention you could also Define a fake domain in here so for example something like serial creative.com but then again you would not be able to issue trusted SSL certificate from let's encrypt for this domain later so I can just recommend it getting a public domain if you haven't already done it I'm not going to recommend a special provider or service where you can buy a domain I am sure you you will quickly find thousands of providers where you can buy and register a domain just compare the pricing and see which one is free what you shouldn't do by no means is using a public domain that you don't own yourself so something that is already registered by somebody else or another pretty common mistake that people sometimes do is they use a DOT local domain which sounds like it would be a fake domain but it is in fact a public domain that is used for a specific multicast DNS purpose so my recommendation is either use a real public domain that you own or you use a fake domain something that is dot home at the end but when you define your domain that you want to use from now on in your local network by the way in bind you can of course also Define multiple DNS zones once you have done that you can configure a bind to be the master for this zone so that basically says hey you don't need to forward a query that's coming to that domain you're the one who is responsible for it and for the DNS entries we need to configure a file where you store them as a plain text this is by the way not really defined so how the file name needs to be it's actually up to you by the way I just need to mention here these semicolons are absolutely treacherous so don't forget you need to put a semicolon after every single command statement or object that you opened with brackets it's really annoying I know but that's really often the case when your DNS Server doesn't come up and you are wondering what the hell is going on take a look at the docker locks if you see something like name.conf is invalid you should check out the missing semicolons in the config file I of just forget to put it there and of course we also have to create this Zone file in the config folder that contains our actual DNS records before we can do that and we start adding our DNS records for our services and hosts we should configure a few settings as well so first you have to define the time to live value this is just the time that you find how long the DNS entries should be kept in Cache mostly I set this to two days or so and we should also Define the origin so that's the name of the DNS Zone that we want to configure because when we set this origin variable we later can Define the newer DNS entries in that list here just with the host name and we don't need to add the fully qualified domain name all the time when we need to create a new a record for example so that makes the configuration a bit cleaner now below this section here we can add all these DNS records but there are two entries that you will always need in a new DNS Zone and the first one is the SOA DNS entry so that's the start of our 40 record and it contains administrative information about the Zone this has to be a specific format like all the other DNS entries are following in this config file here as well it starts with a hostname so in case of the SOA you can just use an ad which represents the current DNS or name and the type should be always in for in in it and then the DNS record type this is an SOA record and then we also need to define the name of our SOI DNS server I just picked a hostname NS for name server and then dot The Zone name the next entry here is the email address of the administrator for this Zone and that shouldn't be confused with the DNS name actually it follows the same formatting as a DNS name but it is an email address so you just need to replace the first dot with an add symbol in your head so in my case I'm using the info add so I type a DOT and then see a creative.de which is my primary email address for any inquiries and then in the brackets there are also some other values that you need to Define starting with a serial number which is another thing that completely confused me first but there is just a 10 digit number that you need to increase once you update your config I'm going to use the current date when I'm recording this video and that's I I guess how most of the people are doing it and the next values I'm just fitting in with default values from my template file so the first is the refresh time the next is the retry time then the expiry time and the minimum time to live by the way if you really want to have a detailed list of all these parameters and what they actually stand for there is a great documentation of bind that's hosted on read the docs I'll link you that in the video description so if anything is unclear or if you're looking for something specific that's not really covered in this tutorial you will find it in the documentation but that's it about the SRA records so far their second record is a bit easier to Define and that's also needed because it's the name server record so because the SOA record there we just defined some general information about this domain but the name server is the record that tells everybody which server is responsible for containing all records in that zone for this record we actually don't need a hostname so we directly start with the type which is high-end for internet again followed by the record type which is NS for name server and then we specify the hostname which you can pick whatever you want yeah I just like to keep it simple so I've chosen NS followed by my domain name so dot demo.cocreative.e and because we just defined who is the name server we should also tell everybody which IP address it has and that is done by adding another record an a record that starts with the hostname that's NS then it goes on with in for internet again and the type is now an A record and after that simply type in the IP address of your name server so in this case we of course want to set it to the IP address of the Linux server where our bind DNS server is running okay so these are all the DNS entries that you necessarily need to create a functional DNS Zone in bind below this you can now just add all your DNS records that you need the most common DNS record would be the a record that we've just used for the name server and it simply resolves a name to an iprs so whenever you want to give your servers a DNS name just another hostname followed by in the type a record and then the IP address and when you query your DNS server for that name it just gives you the IP address very simple but of course there are many other DNS records that have specific functionalities and a different syntax that you might want to Define in your home lab just take a look at the official DNS records that are published by the internet assigned numbers of 40. in here we have the a record a DNS record for name server that's what we've just defined before also some other ones like the Legacy records mdmf these aren't used anymore a cname record that is also so pretty commonly used that it's an alias for example if you want to Define an additional name for the same a record you can use a c name the SOA record we also covered that one maybe the MX record which is important for male servers would also be interesting but you can see there are many many different DNS records in here and honestly I haven't used half of them mostly I just Define a records so a name that just resolves to an IP address and that's it but it's good to know that you can use and Define whatever you need as I said bind it isn't just a simple static a record to IP address you can do all sorts of configurations for DNS records it's really great to play around and test certain things with it and speaking about testing why not test my new configuration yeah as you can see I've added a couple of other DNS records in here these are just a records that resolve to IP addresses of my demo and production servers I also added a wildcard record which wasn't possible with my own setup so anything that you put in front of this SRV demo 2 will be resolved to the same IP address and once you updated the config it needs a quick reload or restart I simply just restart the container with a Docker restart or a Docker compose stop and start it up in the background mode so now if we go into the terminal I'd like to see whether it resolves to an internal Name by asking bind for the demo server for example followed by the domain name and at the end again put the IP address of bind and then you can see that it works great and when I put any name in front of this domain for example I can just use the wildcard DNS record that should resolve to the demo server here yeah it will also work so this is how I'm managing all my DNS records for my web apps by the way I've just created wildcard DNS entries for all the production servers of where my apps are running and then I can use whatever host name I want to use for an app and they all resolve to the same IP address where usually the load balancer traffic is running or when it's a signal server it just picks up whatever is running there on the server and then it just forwards it to the actual application by the way I've explained this part in more detail in my videos about traffic or nginx proxy managers I will link you these videos in the description below as well so you can check it out but this is how I'm managing the DNS records in my network for these apps and I think this is much better now than using static DNS entry somewhere in a firewall or using effect domain where I would need to add every single app with a separate entry and I hope that was interesting there's just one more thing at the end that I wanted to cover how to use your bind DNS server because well we have no tested it with a simple NS lookup and then added the IP address of the server at the end but how do you tell all your devices all your PCS your mobile phones whatever is running to use your DNS server and this information is usually coming from your dijcp server so if you haven't configured your DNS server statically somewhere in your network config your DHCP server that assigns a new IP address to New devices will also tell every device what is the primary and secondary DNS server for that Network depending on your router or firewall which one you're using it needs to be configured there so in my network for example as I said I'm running the surface XG firewall as my DHCP server and in the DHCP server options there is a new setting to configure the IP address of the bind server and distribute it to all new devices that get IP addresses and following this Logic the DNS chain on my network would be the following yeah the PC asks the DNS server that is the bind IP address and bind will answer all queries for the internal domains and for all other websites it will forward the query to the DNS servers that are configured in the forwarders section however I didn't want to do it this way simply because when my Buy DNS server is downed for whatever reason maybe I'm restarting it or I'm doing maintenance updates and so on all my PCS wouldn't be able to connect to website anymore because bind would be the single point of failure in my network and what I've done is I've configured the software XG firewall to keep it as the primary DNS server in my network so all PCS and all devices are still asking the surface XG first but I've created a request route for the internal domain home.clave.de or in our case demo.c creative.te to be sent to the bind DNS server so that means my PC will first ask the firewall as a primary DNS server but the internal queries are forwarded to the bind server while the externals are forwarded to cloudflare Google whatever DNS server I have configured on the firewall just like I said it's completely up to you how you configure it because it depends on which other components you have in your network and what you want to use as your DNS resolver as I said you could also use things like pie hole or ad guard in this chain um this is just the way how I'm doing it in my network and honestly I believe this is such a huge step forward for my home labia running my own DNS server to be able to resolve internal DNS queries makes it much easier and simpler for me to manage it some ideas I also have for the future are I want to automate that somehow so maybe with ansible or terraform when I deploy a new virtual machine on your server automatically I'd like to create a DNS entry in the same process on the bind server that would be so cool but maybe you also have some other nice ideas for Topics in the future that could also somehow use the DNS server or maybe add a pie hole in here whatever just tell me in the comments if you like this episode and what are your thoughts I hope that was a great start for the year 2023 and as always thanks everybody for watching I will catch you in the next video take care bye bye
Info
Channel: Christian Lempa
Views: 245,115
Rating: undefined out of 5
Keywords:
Id: syzwLwE3Xq4
Channel Id: undefined
Length: 32min 31sec (1951 seconds)
Published: Tue Jan 03 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.