Setting up a CoreDNS Server for Local Custom Domain Management on Ubuntu Using Docker
Tags: coredns, ubuntu, docker, beginners
Published: 2024-03-19 03:16:55

I recently embarked on a journey to set up a CoreDNS server as an authoritative nameserver on my Ubuntu machine to manage a local custom domain, `mich0w0h.house`, within my home network. This post is one part of building a local DNS service using docker-compose and I'll write other remaining parts later.

## Directory Structure

Before diving in, let's take a quick look at the directory structure:

```
internal-dns
│
└── authoritative
    │
    ├── Corefile
    └── zone
        └── mich0w0h.house.db
```

## Prerequisites

Make sure Docker is installed and running on your Ubuntu server.

## Creating the Corefile

The Corefile is where we define our CoreDNS configuration. Here's what mine looks like:

```corefile
mich0w0h.house {
    file /etc/coredns/zone/mich0w0h.house.db
    log
}
```
- The first line defines zone for this server  (default DNS port is 53).
- file /path/to/your/mich0w0h.house.db tells CoreDNS to load the zone file for your domain.
- log enables logging
## Creating the Zone File

Now, let's create the zone file `mich0w0h.house.db` with our DNS records. Here's a snippet of what mine looks like:

```mich0w0h.house.db
$TTL 2d
$ORIGIN mich0w0h.house.

@       IN    SOA      ns1.mich0w0h.house. mail.mich0w0h.house. (
                       2024031801  
                       3600       
                       600        
                       86400      
                       3600       
                       )
; Name server resource record for the domain
          IN     NS      ns1.mich0w0h.house.
  
; Domain hosts includes NS records defined above
ns1     IN     A       192.168.1.102
www     IN     A       192.168.1.103
```
## Creating a Docker network
Create a Docker network to enable the container to be accessed by a static IP address.
```sh
sudo docker network create --subnet=192.168.1.0/24 internal-dns
```

## Running the CoreDNS Container

Now, let's fire up the CoreDNS container (run this command in `internal-dns` directory):

```sh
sudo docker container run --rm -d --name authoritative -v $(pwd)/authoritative:/etc/coredns --network internal-dns --ip 192.168.1.102 coredns/coredns -conf /etc/coredns/Corefile
```

command explanations
- `--rm`: remove container when it stops
- `-d`: Runs the container in detached mode (background).
- `--name authoritative`: Assigns a name to the container for easier management.
- `-v $(pwd)/authoritative:/etc/coredns`: Mounts the directory containing your Corefile into the /etc/coredns directory inside the container. This allows CoreDNS to access your configuration files.
- `-network internal-dns`: Specifies the Docker network created at the preliminary step.
- `--ip 192.168.1.102`: Set a static IP address for this container. This should be inside of the subnet of specified Docker network
- `coredns/coredns`: Specifies the Docker image to use. 
- `-conf /etc/coredns/Corefile`: let CoreDNS read `/etc/coredns/Corefile`

## Testing with Dig
Finally, let's test our setup using `dig` on the host ubuntu server:

```sh
dig +nocookie @192.168.1.102 ns1.mich0w0h.house 
```

Now I can see these outputs and it shows the configurations work correctly.
```sh
; <<>> DiG 9.18.18-0ubuntu0.22.04.2-Ubuntu <<>> +nocookie @192.168.1.102 ns1.mich0w0h.house
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58701
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;ns1.mich0w0h.house.		IN	A

;; ANSWER SECTION:
ns1.mich0w0h.house.	172800	IN	A	192.168.1.102

;; AUTHORITY SECTION:
mich0w0h.house.		172800	IN	NS	ns1.mich0w0h.house.

;; Query time: 3 msec
;; SERVER: 192.168.1.102#53(192.168.1.102) (UDP)
;; WHEN: Tue Mar 19 10:08:10 JST 2024
;; MSG SIZE  rcvd: 127
```

## What's next
I'll try to create a recursive resolver container and then build a local internal DNS service using docker-compose.

## References
- [DNSがよくわかる教科書 | SBクリエイティブ](https://www.sbcr.jp/product/4797394481/)
- [開発系エンジニアのためのDocker絵とき入門 - 秀和システム あなたの学びをサポート！](https://www.shuwasystem.co.jp/book/9784798071503.html)
- [Corefile Explained](https://coredns.io/2017/07/23/corefile-explained/)
- [Docker+DNS入門　その1：CoreDNSを用いた権威DNSサーバ構築 #Docker - Qiita](https://qiita.com/miwamoto/items/2a8befac7135bd21e08a)