容器化Bind9通过Nginx反向代理部署DoH服务故障排查求助
容器化Bind9通过Nginx反向代理部署DoH服务故障排查求助
看起来你在容器化Bind9搭配Nginx反向代理部署DoH(DNS over HTTPS)服务时遇到了TLS错误和HTTP协议异常的问题,我结合你提供的配置文件,梳理几个关键排查方向和修改建议:
一、先排查Bind9的DoH基础配置是否生效
你当前的Bind9配置里,listen-on port 80 tls none http default { any; };可能存在小问题:
tls none确实是告诉Bind9不启用TLS(因为我们让Nginx做HTLS终止),但http default的写法可能不如直接用http { any; };明确,而且建议显式指定DoH的请求路径。- 修改
/etc/bind/named.conf.options的相关配置:
directory "/var/cache/bind"; recursion yes; allow-recursion { any; }; listen-on port 53 { any; }; listen-on-v6 port 53 { any; }; # 启用HTTP协议的DoH服务,监听80端口 listen-on port 80 http { any; }; listen-on-v6 port 80 http { any; }; # 显式指定DoH的标准请求路径 http-path "/dns-query"; dnssec-validation auto; };
- 然后检查Bind9容器是否真的监听了80端口:进入Bind9容器执行
ss -tulpn | grep named,确认有0.0.0.0:80的监听记录;同时查看容器日志(你启动命令加了-d1,日志会输出调试信息),确认没有http模块启动失败的报错。
二、优化Nginx反向代理的适配配置
你的Nginx配置里有几个可能影响DoH的点:
- 指定DoH专属路径:DoH的标准请求路径是
/dns-query,没必要让所有路径都反向代理到Bind9,单独配置这个路径更合理。 - HTTP版本和头部调整:DoH基于HTTP/1.1或HTTP/2,需要确保Nginx传递正确的协议版本和头部,避免出现HTTP/0.9的异常响应。
修改后的/etc/nginx/conf.d/bind9.conf:
listen 80; listen [::]:80; server_name $BASE_URL; return 301 https://$host$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name $BASE_URL; ssl_certificate /etc/letsencrypt/live/$BASE_URL/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/$BASE_URL/privkey.pem; # 仅针对DoH标准路径做反向代理 location /dns-query { proxy_pass http://bind9:80/dns-query; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 强制使用HTTP/1.1协议,避免协议兼容问题 proxy_http_version 1.1; proxy_set_header Connection "keep-alive"; proxy_redirect off; } # 其他路径返回404,避免无效请求 location / { return 404; } }
三、分步测试连通性,定位故障点
按以下顺序测试,能快速定位是哪一层出了问题:
- Bind9容器内部测试:
执行curl -v http://localhost:80/dns-query?name=gnu.org&type=A,如果返回JSON格式的DoH响应,说明Bind9的DoH服务本身是正常的。 - Nginx容器内部测试:
执行curl -v http://bind9:80/dns-query?name=gnu.org&type=A,如果能得到正确响应,说明容器间网络连通性没问题。 - 宿主机测试HTTPs请求:
执行curl -v https://$BASE_URL/dns-query?name=gnu.org&type=A,如果返回正确的JSON,说明Nginx的HTLS终止和反向代理都正常。 - 最后测试dig的DoH命令:
使用标准格式的dig命令:dig +https @$BASE_URL gnu.org -p 443,如果还是有TLS错误,加-d参数查看详细调试信息,确认是证书不被信任还是握手失败。
四、额外注意点
- 确保你的
$BASE_URL能被正确解析到Nginx容器的公网IP,dig命令需要先解析这个域名才能发起DoH请求。 - 检查Bind9容器的权限:你在Dockerfile里设置了
chown -R bind:bind /etc/bind/ /var/cache/bind/,确保named进程能读取配置文件和写入缓存。
备注:内容来源于stack exchange,提问作者ange




