# 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: ![](https://i.imgur.com/CGFGiKy.jpg) 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 ``` ![](https://i.imgur.com/euhoaa6.jpg) 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 ``` ![](https://i.imgur.com/8NXI7vg.jpg) ## 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`. ![](https://i.imgur.com/euhoaa6.jpg) 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 ``` ![](https://i.imgur.com/gdJ9mPN.jpg) 3. After self-testing, you can reset the DNS setting to obtain automatically. ``` netsh interface ip set dns "Wi-Fi" dhcp ```