Nginx - Pihole cluster load balancing
Trong bài viết này mình sẽ cùng bạn dựng DNS server với pihole và dùng nginx để làm load balancing.
Tổng quát luồng xử lý như sau:
- (1)
nginx
nhận request cổng53
cho phân giải DNS và cổng8080
cho HTTP request - (2)
nginx
phân bổ request về 2 pihole chạy trên docker, lần lượt nghe ở các port:531, 532, 8081, 8082
# DNS
DNS request :53 --> nginx :53 --> pihole_1 :531
--> pihole_2 :532
# HTTP
Admin user :8080 --> nginx :8080 --> pihole_1 :8081
--> pihole_2 :8082
Môi trường
Server đã cài đặt sẵn các ứng dụng và dịch vụ như sau:
- Hệ điều hành: Ubuntu 20.04 Srv
- Docker version: 20.10.9
- Docker Compose version: 1.29.2
- Nginx version: 1.18.0
Cài đặt Pihole Cluster
Tạo file docker-compose.yml
nội dung như bên dưới, cluster gồm 2 docker, share chung data, thư mục mount tạo tự động ở cùng cấp với file docker-compose.yml
version: "3"
# More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/
services:
pihole1:
container_name: pihole1
image: pihole/pihole:latest
ports:
- "531:53/tcp"
- "531:53/udp"
- "671:67/udp"
- "8081:80/tcp"
environment:
TZ: 'Asia/Ho_Chi_Minh'
# WEBPASSWORD: 'set a secure password here or it will be random'
# Volumes store your data between container upgrades
volumes:
- './etc-pihole/:/etc/pihole/'
- './etc-dnsmasq.d/:/etc/dnsmasq.d/'
# Recommended but not required (DHCP needs NET_ADMIN)
# https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
cap_add:
- NET_ADMIN
restart: unless-stopped
pihole2:
container_name: pihole2
image: pihole/pihole:latest
ports:
- "532:53/tcp"
- "532:53/udp"
- "672:67/udp"
- "8082:80/tcp"
environment:
TZ: 'Asia/Ho_Chi_Minh'
# WEBPASSWORD: 'set a secure password here or it will be random'
# Volumes store your data between container upgrades
volumes:
- './etc-pihole/:/etc/pihole/'
- './etc-dnsmasq.d/:/etc/dnsmasq.d/'
# Recommended but not required (DHCP needs NET_ADMIN)
# https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
cap_add:
- NET_ADMIN
restart: unless-stopped
Lưu file.
Tạo container: docker-conpose up -d
Kiểm tra các container với docker ps
hoặc docker stats
ta có như minh họa sau:
Cấu hình Nginx
nginx làm reverse proxy cho DNS request TCP/UDP port 53
Cầu hình này yêu cầu cần nằm ngang cấp với thẻ http
của nginx, edit file /etc/nginx/nginx.conf
thêm vào nội dung:
stream {
upstream dns_servers {
server 127.0.0.1:531 fail_timeout=5s;
server 127.0.0.1:532 fail_timeout=5s;
}
server {
listen 53 udp;
listen 53; #tcp
proxy_pass dns_servers;
error_log /var/log/nginx/dns.log info;
proxy_responses 1;
proxy_timeout 1s;
}
}
nginx làm load-balancer cho pihole web UI
Tạo 1 file pihole_cluster_ui.conf
trong /etc/nginx/sites-available
, nội dung:
upstream pihole_ui {
server 127.0.0.1:8081;
server 127.0.0.1:8082;
}
server {
listen 8080;
location / {
proxy_pass http://pihole_ui;
proxy_set_header Host $host;
}
}
Enable file cấu hình trên:
cd /etc/nginx/sites-enabled/
# tạo symbolic link
ln -s ../etc/nginx/sites-available/pihole_cluster_ui.conf pihole_cluster_ui.conf
Kiểm tra cấu hình với: nginx -t
(hoặc nginx -T
)
Ngoài ra, cổng 53
trên Ubuntu thường đã được sử dụng, tham khảo hướng dẫn sau để giải phóng cổng này, tóm tắt:
- Edit file
/etc/systemd/resolved.conf
- Un-comment dòng
DNSStubListener
và set giá trị thànhno
- Reboot
Đến đây, các thay đổi trên chưa được nginx sử dụng, áp dụng cấu hình mới với lệnh: service nginx reload
Sử dụng
- Trỏ DNS máy tính của bạn về IP của nginx test phân giải với
nslookup
- Thử truy cập
http://thay-bang-ip-address-nginx:8080
để vào giao diện web của pihole - Hãy thử ngưng lần lượt từng pihole container để kiểm tra xem việc phân giải DNS có bình thường
Lưu ý
Với cấu hình hiện tại, khi bạn xem truy cập trong trang Pihole Web Admin, sẽ thấy server không nhận được IP chính xác của client đang request, thay vậy, sẽ là IP của Nginx server (hoặc docker gateway), nếu cần cho pihole nhận biết chính xác IP của client, xem thêm tài liệu sau: IP Transparency and Direct Server Return with NGINX and NGINX Plus as Transparent Proxy