- Kubernetes CoreDNS - Mon, Dec 4 2023
- Update container images with Copa - Mon, Nov 27 2023
- Deploying stateful applications with Kubernetes StatefulSets - Wed, Nov 1 2023
I will use a Bind9 docker image maintained by Canonical. Please note that this post does not cover the basics of DNS or security best practices.
Prerequisites
For this guide, I will use Docker running in an Ubuntu 22.04 VM.
I also recommend that you read my previous article, MacVLAN network driver: Assign MAC address to Docker containers.
Since we will be using MacVLAN, make sure you enable interface promiscuity with the following commands:
sudo ip -detail -color link show enp0s3 sudo ip link set dev enp0s3 promisc on
This command is needed to enable communication between the Docker container and your internal network devices.
Create a macvlan network
First, we need a new macvlan network to connect our private DNS server container. You could use a bridge network and publish DNS ports (TCP/UDP 53) to the Docker host, but I like working with a macvlan network for various reasons that are discussed in my previous post. To create a macvlan network, run the following command:
sudo docker network create \ --driver macvlan \ --subnet 192.168.0.0/24 \ --gateway 192.168.0.1 \ --ip-range 192.168.0.80/28 \ --aux-address 'host=192.168.0.80' \ --opt parent=enp0s3 \ dns_net
I discussed this command in my previous post, so I will not discuss it in detail. In a nutshell, this command creates a new Docker network using a macvlan driver.
Prepare DNS configuration files
Since our DNS server will be running in a Docker container, the DNS (bind) configuration files will reset every time the container is restarted. To have a persistent and consistent configuration, we will store the configuration files in a directory on the Docker host and then mount the directory to the container.
As you can see in the screenshot, I created a dns directory with a config subdirectory to store the configuration file and zone files. Use a text editor to create the main configuration file, named.conf, under the ~/dns/config/ directory, and paste the following lines of code:
acl bogus_networks { 0.0.0.0/8; 224.0.0.0/3; 10.0.0.0/8; 172.16.0.0/12; }; acl private_networks { 192.168.0.0/24; }; options { forwarders { 8.8.8.8; 1.1.1.1; }; allow-query { private_networks; }; allow-recursion { private_networks; }; blackhole { bogus_networks; }; }; zone "techtuts.local" IN { type master; file "/etc/bind/techtuts.local.zone"; allow-query { any; }; };
At the top, we defined two ACLs with network subnets to block and allow. The allow-query and allow-recursion options allow requests from our private networks, whereas the blackhole option completely rejects requests from unwanted networks.
At the end, we defined the zone information for our domain with a path to the actual zone file (/etc/bind/techtuts.local.zone). Of course, you can change these values and extend them as required.
Similarly, create a zone file named techtuts.local.zone under the ~/dns/config/ directory with the following information:
; ; BIND data file for techtuts.local zone ; $TTL 604800 $ORIGIN techtuts.local. @ IN SOA ns.techtuts.local. root.techtuts.local. ( 1 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ;name server records IN NS ns.techtuts.local. ;name server host records ns IN A 192.168.0.40 ;host records for other devices srv1 IN A 192.168.0.40 web101 IN A 192.168.0.82 web102 IN A 192.168.0.83 db101 IN A 192.168.0.92 db102 IN A 192.168.0.93
I have added several records to this zone file. Of course, you can add other records, such as CNAME, MX, and TXT.
Once you have both files ready, you are all set to launch a Docker container using a Bind9 image.
Launch a DNS server in a Docker container
To launch a Docker container with a Bind9 DNS server, use the following command:
sudo docker run --detach \ --network dns_net \ --ip 192.168.0.41 \ --name ns1 \ --env TZ=Asia/Kolkata \ --env BIND9_USER=root \ --volume /home/surender/dns/config:/etc/bind \ --restart=always \ ubuntu/bind9
This command pulls the Bind9 Docker image on the fly and launches a container with the specified options. The restart=always option is important, as it will automatically restart your Docker container when your Docker host is restarted. Once the Docker container is launched, you can view the logs with the following command:
sudo docker logs -f ns1
If you have any error in your configuration or zone file, you will be able to view that error with this command. In my case, the zone was loaded successfully.
Verify DNS server functionality
Our DNS server is now ready to perform the name resolutions. To test whether the DNS server is working as expected, use the host or nslookup commands, as shown below:
host srv1.techtuts.local 192.168.0.41 host 4sysops.com 192.168.0.41
Similarly, we can use nslookup to query the IP address for any internal network device using our new DNS server running in Docker.
Subscribe to 4sysops newsletter!
nslookup web101.techtuts.local 192.168.0.41 nslookup db101.techtuts.local 192.168.0.41 nslookup techtutsonline.com 192.168.0.41
Once you verify that the DNS server is working as expected, you can configure your client devices to use this DNS server. But please remember, as I said earlier, this post covers a really simple DNS server setup; it doesn't use the best practices for running a production-ready DNS server. In a production environment, you might also want to create a secondary DNS server for failover if your primary DNS server is unavailable to avoid service disruption. For security considerations, I recommend checking out the official Bind9 documentation.
Read the latest IT news and community updates!
Join our IT community and read articles without ads!
Do you want to write for 4sysops? We are looking for new authors.