Trên dns.bibica.net, ở phiên bản v1 tôi dùng AdGuard Home (Caddy), v2 đổi sang dùng Mosdns-x (Caddy + Redis), hiệu năng tốt cả, vì DNS yêu cầu phần cứng rất nhẹ, có điều cảm giác cấu hình dài dòng, phức tạp quá mức cần thiết, vì Mosdns-x có thể hoạt động độc lập rất tốt
Mosdns-x Native sử dụng Mosdns-x PR, viết sửa 1 số tính năng so với mosdns-x gốc, cài thêm lego hỗ trợ tạo SSL, lego chỉ gọi khi tạo mới hoặc gia hạn SSL, không chạy ngầm, nên không tốn CPU và RAM
- Cập nhật Go và thư viện phụ thuộc lên phiên bản mới nhất
- Thêm các kiểm tra, làm sạch DNS và tùy chọn cho phép bật/tắt 1 số tính năng từ tầng server, giúp giảm overhead do không cần tạo context plugin, đây là thay đổi quan trọng, vì chỉ phải kiểm tra 1 lần từ đầu, các plugin viết thêm không cần kiểm tra nữa
- ANY luôn bị chặn, đúng 1 question, Opcode = QUERY, Qclass = INET, header phải là truy vấn thuần
- Tự động chuyển domain về chữ thường
- Chặn truy vấn IPv6 AAAA (nếu bật
block_aaaa) - Chặn truy vấn ngược PTR (nếu bật
block_ptr) - Chặn truy vấn HTTPS (nếu bật
block_https) - Chặn domain không có dot, ví dụ localhost (nếu bật
block_no_dot) - Xóa phần mở rộng EDNS (nếu bật
strip_edns0)
- Các giao thức TCP, UDP, DoH, DoH3, DoT và DoQ được điều chỉnh và tối ưu lại, tập trung sửa lỗi, nâng cao hiệu suất và độ ổn định
- Health check và redirect:
- Thêm
health_pathcung cấp endpoint kiểm tra tình trạng hoạt động - Thêm
redirect_urltự động chuyển hướng các request không phải DNS (ngoại trừhealth_pathvà/dns-query) tới URL tùy chỉnh
- Thêm
- Bảo mật và quyền riêng tư:
- Tắt hoàn toàn việc ghi nhật ký IP client để đảm bảo tính ẩn danh, kể cả khi bật logging
- SSL
- Tốc độ kết nối: cải thiện khả năng kết nối lại sau khi restart server, các khóa được lưu tại thư mục
keyđể hỗ trợ 0-RTT và TLS session resumption - Thuật toán mã hóa: sử dụng X25519 và ECDSA (P-256), tiêu tốn ít CPU hơn và tạo chứng chỉ nhỏ hơn so với Post-Quantum (ML-KEM/Kyber)
- Hỗ trợ nén certificate bằng brotli nếu client hỗ trợ (chỉ hoạt động trên DoH/DoT)
- Kiểm tra
certFile,keyFilekhi có renew lại chính xác hơn
- Tốc độ kết nối: cải thiện khả năng kết nối lại sau khi restart server, các khóa được lưu tại thư mục
- Nén gói tin DNS trước khi gửi tới client
msg_buf - Cache: thay đổi rất nhiều so với mosdns-x gốc, không dùng
cache_everythingmà quản lý theopipeline, ECS chỉ được xử lý tại vị trí đặt pluginecstrong fileyaml- Sử dụng GetMsgHash tạo key cache 8 byte (uint64 hashing) nhỏ và nhanh hơn
- Khi đạt giới hạn size, hệ thống tái sử dụng (reuse) phần tử cũ thay vì cấp phát mới, cơ chế này loại bỏ overhead từ GC và tránh tăng RAM đột biến khi traffic cao
- Lazy cache: viết lại đơn giản hơn, loại bỏ các xử lý dư thừa
- Thêm
cleaner_intervalcho phép tùy chỉnh thời gian dọn key cache - Hỗ trợ bộ nhớ đệm
NXDOMAIN - Tối ưu
concurrent_lru,listvàlru… giúp lưu và xóa cache hiệu quả hơn
- ECS
- Chuẩn hóa ECS: các IP trong cùng dải
1.2.3.4và1.2.3.5đều được quy về1.2.3.0/24, đảm bảo cache hoạt động chính xác
- Chuẩn hóa ECS: các IP trong cùng dải
- Upstream
- Khi có >=2 upstream, chạy song song (
parallel) - Sử dụng X25519 và ECDSA (P-256), tiêu tốn ít CPU hơn và tạo chứng chỉ nhỏ hơn so với Post-Quantum (ML-KEM/Kyber)
- Khi có >=2 upstream, chạy song song (
- Matcher
response_matchervàquery_matcherviết lại rất nhiều để tăng hiệu quả xử lý
- Plugin: hầu hết plugin đã loại bỏ validation do đã xử lý từ tầng server, giúp giảm độ trễ toàn hệ thống
redirect: loại bỏ CNAME nhưng giữ lại A/AAAA theo tên truy vấn gốc, đồng bộ với plugin_no_cnamelimit_ip: giới hạn tối đa 2 địa chỉ IP trong mỗi phản hồi DNSdynamic_domain_collector: tự động đọc và ghi domain vào filequery_summary: tắt ghi nhật ký IP client và hạn chế ghi các lỗi nhẹ ở mức info
Gần 95% file gốc của dự án mosdns-x gốc đều có sửa qua, 1 số thay đổi hiệu quả, còn lại ở mức rất nhỏ, cache là thứ viết lại nhiều nhất, từ sửa đơn giản, cho tới viết mới hoàn toàn, đều thấy không hiệu quả, bản cache hiện tại đang duy trì cân bằng mọi thứ, không thay đổi quá nhiều
Reinstall OS
- Trên 1 VPS mới nên reinstall bản mặc định, tránh mọi lỗi linh tinh phát sinh, phiên bản của bin456789 có sẵn chọn port, cài vào là coi như VPS đã tự đổi port SSH, đỡ 1 số thao tác thủ công
sudo -s cd ~ curl -O https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.sh bash reinstall.sh debian 13 # root with a default password 123@@@
Basic Optimization
- Cài đặt một số ứng dụng thiết yếu, tinh chỉnh cơ bản ban đầu, chú ý là bản script này xóa khá sạch các ứng dụng còn sót trên Debian 13, mặc định tắt logs hệ thống
apt install -y curl sudo && curl -fsSL go.bibica.net/vps | sudo bash -s -- -no-log -no-docker
- Xong xuôi
rebootlại VPS cho sạch sẽ
Cài đặt Mosdns-x Native và lego
Cá nhân duy trì cài đặt tất cả mọi thứ vào thư mục /home, nên làm bash script cài đặt Mosdns-x Native và lego tự động vào /home
wget -qO /home/setup-mosdns-x-native.sh https://go.bibica.net/mosdns-x && sudo bash /home/setup-mosdns-x-native.sh
- Nhập domain muốn dùng và thông tin Cloudflare API Token
Mặc định SSL tự động gia hạn mỗi ngày, cập nhập các bộ lọc quảng cáo và domain tlds cũng đã chạy tự động, không cần quan tâm thêm
Bash script xử lý cơ bản các lỗi khi tạo SSL, lưu key Cloudflare API Token, cài đặt lại hoặc đổi domain khác chỉ cần chạy lại setup-mosdns-x-native.sh
Nếu đổi VPS, copy toàn bộ dữ liệu từ /home, chép sang /home trên VPS mới, chạy setup-mosdns-x-native.sh chọn tùy chọn 2 Restore
- Mosdns-x Native tạo sẵn 1 số command, khi dùng gỡ phải gõ nhiều, nhớ duy nhất
dns -hlà đủ
MosDNS-X Commands: dns start - Start service dns stop - Stop service dns restart - Restart service dns status - Show status dns log - View logs dns update - Update to latest dns -v - Show version
Cá nhân hay dùng dns restart khi cập nhập cấu hình, thi thoảng chạy dns update để cập nhập Mosdns-x PR và lego lên bản mới nhất
Tùy chỉnh Geo Firewall v3 – cài đặt thủ công
Với các dịch vụ DNS public, nên cài firewall, hạn chế các kết nối rác từ các tool, bot khác
nano /home/setup-geo-firewall.sh
Mặc định cho phép user IP Việt Nam, Singapore, Japan, Hong Kong truy cập vào VPS qua TCP port 22 2224 53 443 853, UDP port 53 443 853
# Allowed countries (ISO 3166-1 alpha-2 codes)
ALLOW_COUNTRIES=("VN" "SG" "JP" "HK")
# Services to be protected (ports open to allowed countries)
ALLOW_TCP_PORTS=("53" "443" "853")
ALLOW_UDP_PORTS=("53" "443" "853")
NO_RATELIMIT_TCP_PORTS=("22" "2224") # GeoIP protected, but no rate-limit (e.g. SSH)
# Allow ICMP echo-request (ping) from allowed countries
ENABLE_PING=false
# RATE LIMIT (per IP, per port)
# If an IP sends more than RATE packets/sec (after BURST absorbed), it gets penalized.
# While penalized, only THROTTLE_RATE packets/sec are allowed for PENALTY_TIME seconds.
ENABLE_RATE_LIMIT=true
RATE_LIMIT_UDP=250 # Max packets/sec per IP (UDP)
RATE_LIMIT_TCP=500 # Max packets/sec per IP (TCP)
BURST_UDP=5000 # Allowed spike before rate-limit kicks in
BURST_TCP=5000 # Allowed spike before rate-limit kicks in
THROTTLE_RATE=5 # Packets/sec allowed while penalized
PENALTY_TIME=5 # Penalty duration (seconds, auto-refreshed if abuse continues)
Cần mở thêm port, thêm vào ALLOW_TCP_PORTS, ALLOW_UDP_PORTS, hoặc NO_RATELIMIT_TCP_PORTS các giá trị khác, dùng như mặc định là được
- Điều chỉnh xong chạy cài đặt firewall
/home/setup-geo-firewall.sh
DoH DoT DoQ DoH3 đã cấu hình mở port sẵn, nếu VPS chạy qua các dịch vụ cloud như Amazon, Google, Oralce, Tencent …. cần vào quản trị mở các port TCP 53 443 853 – UDP 53 443 853
watch -n 1 "for s in \$(ipset list -n | grep rl_pen); do count=\$(ipset list \$s | grep 'Number of entries' | awk '{print \$NF}'); if [ \$count -gt 0 ]; then echo \"--- \$s (\$count) ---\"; ipset list \$s | sed -n '/Members:/,\$p' | tail -n +2; fi; done"
Có thể chạy lệnh bên trên, kiểm tra IP nào đang bị Rate Limit chặn
Bản Geo Firewall v3 theo mình là đủ hiệu quả cho các nhu cầu sử dụng DNS thông thường, cũng gọi là nhà có khóa cửa 😀
Kiểm tra tỷ lệ cache và tốc độ các giao thức
Giai đoạn đầu sử dụng, có thể bật ghi log
- Sửa log level thành
info, bỏ comment ở dòng- _query_summarytrong/home/mosdns-x/config/config.yaml
log: level: info # Options: debug, info, error, warn file: "log/mosdns.log"
Chạy ít ngày, khi lượng log đủ nhiều, có thể kiểm tra tỷ lệ cache, tốc độ các giao thức bằng đoạn code bên dưới
awk -v exclude_str="dnscheck.tools check-dns.net leaktest.net bibica.net" '
BEGIN {
# Split the exclusion string into an array
n = split(exclude_str, ex_arr, " ")
}
# Match specific protocols
/"protocol": "(h2|h3|tls|quic)"/ {
# Extract domain name
match($0, /"qname": "([^"]+)"/); domain = substr($0, RSTART+10, RLENGTH-11)
# Check if domain contains any of the excluded strings
skip = 0
for (i=1; i<=n; i++) {
if (index(domain, ex_arr[i])) {
skip = 1
break
}
}
if (skip) next
# Extract protocol
match($0, /"protocol": "([^"]+)"/); proto = substr($0, RSTART+13, RLENGTH-14)
# Extract elapsed time string
match($0, /"elapsed": "([0-9.]+)(µs|ms)"/);
e = substr($0, RSTART, RLENGTH)
gsub(/"elapsed": "|"/, "", e)
# Convert time to microseconds
match(e, /[0-9.]+/); time = substr(e, RSTART, RLENGTH)
# Counter for domain frequency
domain_count[domain]++
if (index(e, "ms")) {
time *= 1000
nc[proto]++; nct[proto] += time
total_nc++; total_nct += time
} else {
c[proto]++; ct[proto] += time
total_c++; total_ct += time
}
tot[proto] += time; cnt[proto]++
print time "\t" proto "\t" domain > "/tmp/mosdns_slow.txt"
}
function fmt(us) { return us >= 1000 ? sprintf("%.2fms", us/1000) : sprintf("%.2fµs", us) }
END {
total = total_c + total_nc
if (total == 0) { print "No data found."; exit }
print "=== TOTAL ==="
printf "Cache: %s (%d, %.1f%%) | Non-cache: %s (%d, %.1f%%) | Total: %d\n\n",
fmt(total_ct/total_c), total_c, total_c*100/total,
fmt(total_nct/total_nc), total_nc, total_nc*100/total, total
print "=== PER PROTOCOL ==="
for (p in tot) {
ca = c[p] ? ct[p]/c[p] : 0; nca = nc[p] ? nct[p]/nc[p] : 0; t = c[p]+nc[p]
printf "%s: Cache=%s (%d, %.1f%%) | Non-cache=%s (%d, %.1f%%) | Total=%d\n",
p, fmt(ca), c[p], c[p]*100/t, fmt(nca), nc[p], nc[p]*100/t, t
cache[p] = ca; noncache[p] = nca
}
print "\n=== SUMMARY ==="
n1=0; for (p in cache) { cl[n1]=p; cv[n1]=cache[p]; n1++ }
for (i=0; i<n1; i++) for (j=i+1; j<n1; j++)
if (cv[i] > cv[j]) { t=cv[i]; cv[i]=cv[j]; cv[j]=t; t=cl[i]; cl[i]=cl[j]; cl[j]=t }
n2=0; for (p in noncache) { ncl[n2]=p; ncv[n2]=noncache[p]; n2++ }
for (i=0; i<n2; i++) for (j=i+1; j<n2; j++)
if (ncv[i] > ncv[j]) { t=ncv[i]; ncv[i]=ncv[j]; ncv[j]=t; t=ncl[i]; ncl[i]=ncl[j]; ncl[j]=t }
printf "Cache: "; for (i=0; i<n1; i++) printf "%s%s (%s)", i?" > ":"", cl[i], fmt(cv[i]); print ""
printf "Non-cache: "; for (i=0; i<n2; i++) printf "%s%s (%s)", i?" > ":"", ncl[i], fmt(ncv[i]); print ""
print "\n=== TOP 10 MOST FREQUENT ==="
for (d in domain_count) print domain_count[d] "\t" d > "/tmp/mosdns_freq.txt"
close("/tmp/mosdns_freq.txt")
system("sort -rn /tmp/mosdns_freq.txt | head -10 | awk '\''{printf \"%2d. %-5d hits - %s\\n\", NR, $1, $2}'\''")
system("rm -f /tmp/mosdns_freq.txt")
print "\n=== TOP 10 SLOWEST ==="
close("/tmp/mosdns_slow.txt")
system("sort -rn /tmp/mosdns_slow.txt | head -10 | awk '\''function f(u){return u>=1000?sprintf(\"%.2fms\",u/1000):sprintf(\"%.2fµs\",u)} {printf \"%2d. %-8s - %-5s - %s\\n\", NR, f($1), $2, $3}'\''")
system("rm -f /tmp/mosdns_slow.txt")
}' /home/mosdns-x/log/mosdns.log
Lượng log lưu lại càng nhiều, sẽ ít sai số hơn, thường sau khi DNS server của bạn, chạy vài ngày, cache HIT > 90% thì không cần quan tâm tới giao thức DoH hay DoQ gì nữa, vì load từ cache, thường < 100µs, tức là < 0.1ms, mà 1000ms mới bằng …. 1 giây 😀 giao thức nào cũng na ná nhau cả
Kiểm tra các log lỗi
awk '/"resp_rcode": [1-9]/ || /"resp_rcode": [0-9][0-9]+/' /home/mosdns-x/log/mosdns.log > /home/mosdns-x/log/error.txt
Nó sẽ tạo ra file /home/mosdns-x/log/error.txt, ghi lại các resp_rcode khác 0, kiểm tra xem các domain này gặp vấn đề gì để có hướng sử lý
Chạy theo dõi ít hôm, thấy ổn định rồi thì tắt log đi cho nhẹ
Kết luận
Cá nhân vẫn thích dùng Caddy và chạy mọi thứ qua Docker, quản lý quen thuộc hơn, còn dùng trần như bản v3 thì được cái đơn giản, mosdns-x sập hay lỗi, kết luận ngay do mosdns-x, đỡ phải tìm hiểu nguyên nhân do ứng dụng nào
Mosdns-x Native chặn khá nhiều request không cần thiết (PTR ANY HTTPS) kiểm tra domain đầu vào, nên giảm khá nhiều request rác, thường sau 1 ngày sử dụng, các domain được cache đầy đủ, hiệu năng gần như kịch trần
Theo tác giải thì Mosdns-x có thể đáp ứng 1000 user cùng sử dụng mà dùng loanh quanh 5% CPU trên các VPS cấu hình thấp, thèng dns.bibica.net trung bình 50 user, load average < 1%, nói chung trừ khi bạn có 10.000 user cùng dùng, cần theo dõi thêm, còn dưới mức này VPS cấu hình thấp nhất, giá rẻ nhất dùng vẫn thừa
Chính sách bình luận: Chúng tôi rất trân trọng các bình luận của bạn và cảm ơn thời gian bạn dành để chia sẻ ý tưởng và phản hồi.
Ghi chú: Những bình luận được xác định là spam hoặc chỉ mang tính quảng cáo sẽ bị xóa.
• Để cải thiện trải nghiệm bình luận, chúng tôi khuyến khích bạn tạo một tài khoản Gravatar. Thêm avatar vào tài khoản Gravatar sẽ giúp bình luận của bạn dễ nhận diện hơn đối với các thành viên khác.
• ✂️ Sao chép và 📋 Dán Emoji 💪 giúp bình luận thêm sinh động và thú vị!