Ở bài trước mình đã hướng dẫn các bạn triển khai 1 DNS Server bằng phương pháp cài gói, ở bài này mình sẽ hướng dẫn các bạn chạy 1 DNS Server bằng Container nhé.
Đầu tiên các bạn tạo 1 thư mục chứa các file cấu hình của chúng ta và phân quyền cho nó.
sudo mkdir -p /home/bind
sudo chmod -R 755 /home/bind
cd /home/bind
Tạo file bash và khai báo biến môi trường cho nó, hãy thay đổi thông tin phù hợp với server của bạn.
cat > /home/bind/environment.sh << 'EOF'
export container_dns_server_ipaddr='172.16.1.1'
export container_subnet_server='172.16.1.0/24'
export container_gateway='172.16.1.254'
export reverse_ip_dns='1.16.172'
export root_dns='hoanghd.com'
EOF
Khởi chạy biến môi trường bằng file vừa tạo.
source /home/bind/environment.sh
Mình sẽ tự tạo 1 image Bind9 bằng cách tạo Dockerfile nội dung như dưới hoặc bạn có thể sử dụng image có sẵn trong Docker Hub như internetsystemsconsortium/bind9:9.16 tuỳ theo các nhân của bạn.
echo '''FROM ubuntu:18.04
RUN apt update
RUN apt upgrade -y
RUN apt install -y vim iputils-ping bind9 bind9utils bind9-doc -y
WORKDIR /etc/bind/
EXPOSE 53
RUN chmod -R 755 /etc/bind
RUN chown -R bind:bind /etc/bind
#ENTRYPOINT ["/etc/init.d/bind9", "start"]''' > /home/bind/Dockerfile
Chạy lệnh build 1 container chứa Bind9 mới từ file Dockerfile vừa mới tạo ở trên.
docker build -t bind9:1.0.1 --force-rm -f Dockerfile .
Sau đó tiến hành sửa file /home/bind/named.conf.options, để nhanh họn bạn hãy chạy lệnh dưới.
echo '''acl goodclients {
192.168.1.1/32;
localhost;
localnets;
};
options {
directory "/var/cache/bind";
recursion yes;
allow-query { goodclients; };
forwarders {
8.8.8.8;
8.8.4.4;
};
forward only;
dnssec-enable yes;
dnssec-validation no;
auth-nxdomain no; # conform to RFC1035
listen-on-v6 { any; };
};''' > /home/bind/named.conf.options
Tạo file /home/bind/named.conf, chạy lệnh dưới để tạo file nhanh.
echo '''include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";''' > /home/bind/named.conf
Tiếp tục chạy lệnh dưới để tạo file /home/bind/named.conf.local
echo """zone \"$root_dns\" {
type master;
file \"/etc/bind/forward.$root_dns\";
};
zone \"$reverse_ip_dns.in-addr.arpa\" {
type master;
file \"/etc/bind/reverse.$root_dns\";
};""" > /home/bind/named.conf.local
Tiếp tục chạy lệnh dưới để tạo file /home/bind/forward.hoanghd.com
echo """\$TTL 604800
@ IN SOA $root_dns. root.$root_dns. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
@ IN NS $root_dns.
@ IN A $container_dns_server_ipaddr
wiki IN A 192.168.13.207
resume IN A 192.168.13.208""" > /home/bind/forward.$root_dns
Tiếp tục chạy lệnh dưới để tạo file /home/bind/reverse.hoanghd.com
echo """\$TTL 604800
@ IN SOA $root_dns. root.$root_dns. (
1
604800
86400
2419200
604800 )
@ IN NS $root_dns.
@ IN A $container_dns_server_ipaddr
wiki IN A 192.168.13.207
resume IN A 192.168.13.208
102 IN PTR wiki.$root_dns.
103 IN PTR resume.$root_dns.""" > /home/bind/reverse.$root_dns
Tạo file /home/bind/resolv.conf trỏ DNS Server về ip của container để mount cho nó.
echo """search $root_dns
nameserver $container_dns_server_ipaddr""" > /home/bind/resolv.conf
Tạo file Docker Compose như dưới, file này có tên /home/bind/bind9.yaml
echo """services:
bind9:
image: bind9:1.0.1
container_name: bind9
restart: unless-stopped
ports:
- \"53:53/udp\"
- \"53:53/tcp\"
stdin_open: true
tty: true
# entrypoint: [\"/etc/init.d/bind9\", \"start\"]
privileged: true
volumes:
- /home/bind/resolv.conf:/etc/resolv.conf
- /home/bind/reverse.$root_dns:/etc/bind/reverse.$root_dns
- /home/bind/forward.$root_dns:/etc/bind/forward.$root_dns
- /home/bind/named.conf.local:/etc/bind/named.conf.local
- /home/bind/named.conf:/etc/bind/named.conf
- /home/bind/named.conf.options:/etc/bind/named.conf.options
networks:
vpcbr:
ipv4_address: $container_dns_server_ipaddr
networks:
vpcbr:
driver: bridge
ipam:
config:
- subnet: $container_subnet_server
gateway: $container_gateway""" > /home/bind/bind9.yaml
Port 53 được sử dụng cho các dịch vụ phân giải tên miền. Nếu bạn có ý định vận hành một ứng dụng dạng này ví dụ như Bind9 thì bạn sẽ cần đến nó. Tuy vậy, trên server Ubuntu, port này được chiếm dụng bởi dịch vụ systemd-resolve, nếu bạn cố gắng bind port 53, bạn sẽ nhận được thông báo listen tcp 0.0.0.0:53: bind: address already in use.
$ netstat -tulnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 846/systemd-resolve
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1323/sshd
tcp6 0 0 :::22 :::* LISTEN 1323/sshd
udp 0 0 127.0.0.53:53 0.0.0.0:* 846/systemd-resolve
Hãy huỷ nó bằng cách chạy các lệnh dưới.
sed -i 's/#DNSStubListener=*.*/DNSStubListener=no/' /etc/systemd/resolved.conf
sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
systemctl restart systemd-resolved
Kiểm tra lại ta thấy port 53 đã mất.
$ netstat -tulnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1317/sshd
tcp6 0 0 :::22 :::* LISTEN 1317/sshd
Chạy lệnh dưới để run container đã khai báo trong file /home/bind/bind9.yaml
docker-compose -f /home/bind/bind9.yaml up -d
Xác minh lại kết quả run.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9484eb519a67 bind9:1.0.1 "bash" 7 seconds ago Up 5 seconds 0.0.0.0:8053->53/tcp, 0.0.0.0:8053->53/udp, :::8053->53/tcp, :::8053->53/udp bind9
Chạy lệnh dưới để run dịch vụ bind9.
$ docker exec bind9 /etc/init.d/bind9 start
* Starting domain name service... bind9
...done.
Bạn có thể verify lại xem bind9 đã chạy chưa bằng bằng lệnh dưới.
$ docker exec bind9 /etc/init.d/bind9 status
* bind9 is running
Bạn có thể sử dụng lệnh này để clear cache DNS nhé.
sudo systemd-resolve --flush-caches
- Kiểm tra trên máy host (máy chủ chạy container Bind9)
Trên máy host hãy chỉnh sửa DNS Server của bạn, mình đang sử dụng netplan của Ubuntu nên mình sẽ chỉnh sửa thông tin DNS trong file /etc/netplan/50-cloud-init.yaml
echo """network:
ethernets:
ens192:
addresses:
- 192.168.13.207/23
dhcp4: false
gateway4: 192.168.12.5
nameservers:
addresses:
- $container_dns_server_ipaddr
search:
- $root_dns
version: 2""" > /etc/netplan/50-cloud-init.yaml
Đừng quên apply nó nhé.
netplan apply
Hoặc bạn có thể trỏ trong file /etc/resolv.conf
echo """search $root_dns
nameserver $container_dns_server_ipaddr""" > /etc/resolv.conf
Hãy kiểm tra kết quả phân giải trên client và bạn sẽ có kết quả như dưới.
$ ifconfig ens192
ens192: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.13.207 netmask 255.255.254.0 broadcast 192.168.13.255
inet6 fe80::250:56ff:fead:c307 prefixlen 64 scopeid 0x20<link>
ether 00:50:56:ad:c3:07 txqueuelen 1000 (Ethernet)
RX packets 66657 bytes 87399926 (87.3 MB)
RX errors 0 dropped 15 overruns 0 frame 0
TX packets 21215 bytes 1674565 (1.6 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
$ nslookup hoanghd.com
Server: 172.16.1.1
Address: 172.16.1.1#53
Name: hoanghd.com
Address: 172.16.1.1
$ ping wiki.hoanghd.com
PING wiki.hoanghd.com (192.168.13.207) 56(84) bytes of data.
64 bytes from 192.168.13.207 (192.168.13.207): icmp_seq=1 ttl=64 time=0.044 ms
64 bytes from 192.168.13.207 (192.168.13.207): icmp_seq=2 ttl=64 time=0.079 ms
64 bytes from 192.168.13.207 (192.168.13.207): icmp_seq=3 ttl=64 time=0.079 ms
64 bytes from 192.168.13.207 (192.168.13.207): icmp_seq=4 ttl=64 time=0.087 ms
--- wiki.hoanghd.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3036ms
rtt min/avg/max/mdev = 0.044/0.072/0.087/0.017 ms
Như vậy là container DNS Server đã có thể sẵn sàng để sử dụng.