# Set up DNS server with Docker
[TOC]
## Preparation for self-testing (Optional)
1. Change the DNS server to `127.0.0.1`.
```
netsh interface ip set dns "<interface_name>" static 127.0.0.1
```
For examaple:

In this case, the `<interface_name>` will be `Wi-Fi`.
Therefore, the command should be:
```
netsh interface ip set dns "Wi-Fi" static 127.0.0.1
```

After changeing the DNS server to `127.0.0.1`, try to resolve `www.google.com` and `my.domain`. The expect result is that the address can't be resolved.
```
nslookup www.googe.com
nslookup my.domain
```

## Set up a DNS server with Docker
:warning: Our goal is set up a DNS server which can resolve the private domain name`my.domain` to `10.0.2.15` and also be able to resolve other public domain name.
### Background knowledges
1. Docker: Know how to pull image and run container.
2. Docker Compose: Know what the docker compose is and the dockercompose file format and how to trigger a service.
3. [Bind9](https://www.isc.org/bind/): Just need to know it's DNS server is good enough.
4. [Bind9 in docker](https://hub.docker.com/r/internetsystemsconsortium/bind9)
5. Config Bind9: At least go through this video
{%youtube DuVNclBfykw %}
### Prepare needed configuration files
1. Create a folder named `my_dns`.
2. Create another folder named `config` under `my_dns`.
3. Create a file named `named.conf.options` with the contenet below:
```
options {
directory "/var/cache/bind";
// If there is a firewall between you and nameservers you want
// to talk to, you may need to fix the firewall to allow multiple
// ports to talk. See http://www.kb.cert.org/vuls/id/800113
// If your ISP provided one or more IP addresses for stable
// nameservers, you probably want to use them as forwarders.
// Uncomment the following block, and insert the addresses replacing
// the all-0's placeholder.
forwarders {
8.8.8.8;
8.8.4.4;
};
//========================================================================
// If BIND logs error messages about the root key being expired,
// you will need to update your keys. See https://www.isc.org/bind-keys
//========================================================================
dnssec-validation auto;
listen-on-v6 { any; };
};
```
4. Create a file named `named.conf.local` with the contenet below:
```
//
// Do any local configuration here
//
// Consider adding the 1918 zones here, if they are not used in your
// organization
//include "/etc/bind/zones.rfc1918";
zone "my.domain" {
type master;
file "/etc/bind/db.my.domain";
};
```
5. Create a file named `db.my.domain` with the contenet below:
```
; BIND reverse data file for empty rfc1918 zone
;
; DO NOT EDIT THIS FILE - it is used for multiple zones.
; Instead, copy it, edit named.conf, and use that copy.
;
$TTL 86400
@ IN SOA localhost. root.localhost. (
1 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
86400 ) ; Negative Cache TTL
;
IN A 10.0.2.15
@ IN NS localhost.
```
### Trigger the DNS service
#### Docker Compose
1. Under the `my_dns` create a file named `docker-compose.yml`.
```yaml
version: '3'
services:
bind9:
container_name: my-dns
image: internetsystemsconsortium/bind9:9.18
ports:
- "53:53/tcp"
- "53:53/udp"
- "127.0.0.1:953:953/tcp"
volumes:
- ./config/named.conf.options:/etc/bind/named.conf.options
- ./config/named.conf.local:/etc/bind/named.conf.local
- ./config/db.my.domain:/etc/bind/db.my.domain
restart: unless-stopped
```
2. Under `my_dns` execute
```
docker-compose up
```
If you don't want to see the log use:
```
docker-compose up -d
```
#### Docker (Under WSL)
1. Under the `my_dns` execute
```
docker run \
--name=my-dns \
--restart=unless-stopped \
--publish 53:53/udp \
--publish 53:53/tcp \
--publish 127.0.0.1:953:953/tcp \
--volume `pwd`/config/named.conf.options:/etc/bind/named.conf.options \
--volume `pwd`/config/named.conf.local:/etc/bind/named.conf.local \
--volume `pwd`/config/db.my.domain:/etc/bind/db.my.domain \
internetsystemsconsortium/bind9:9.18
```
or
```
docker run \
--name=my-dns \
--restart=unless-stopped \
-p 53:53/udp \
-p 53:53/tcp \
-p 127.0.0.1:953:953/tcp \
-v `pwd`/config/named.conf.options:/etc/bind/named.conf.options \
-v `pwd`/config/named.conf.local:/etc/bind/named.conf.local \
-v `pwd`/config/db.my.domain:/etc/bind/db.my.domain \
internetsystemsconsortium/bind9:9.18
```
If you don't want to see the log use:
```
docker run \
--detach \
--name=my-dns \
--restart=unless-stopped \
--publish 53:53/udp \
--publish 53:53/tcp \
--publish 127.0.0.1:953:953/tcp \
--volume `pwd`/config/named.conf.options:/etc/bind/named.conf.options \
--volume `pwd`/config/named.conf.local:/etc/bind/named.conf.local \
--volume `pwd`/config/db.my.domain:/etc/bind/db.my.domain \
internetsystemsconsortium/bind9:9.18
```
or
```
docker run \
-d \
--name=my-dns \
--restart=unless-stopped \
-p 53:53/udp \
-p 53:53/tcp \
-p 127.0.0.1:953:953/tcp \
-v `pwd`/config/named.conf.options:/etc/bind/named.conf.options \
-v `pwd`/config/named.conf.local:/etc/bind/named.conf.local \
-v `pwd`/config/db.my.domain:/etc/bind/db.my.domain \
internetsystemsconsortium/bind9:9.18
```
## Self-testing (Optional)
1. Make sure the DNS server is set to `127.0.0.1`.

2. Try to resolve `www.google.com` and `my.domain`. The expect result is that the address can be resolved.
```
nslookup www.googe.com
nslookup my.domain
```

3. After self-testing, you can reset the DNS setting to obtain automatically.
```
netsh interface ip set dns "Wi-Fi" dhcp
```