本文简述用 Nginx 代理 DoH (DNS Over HTTPS)的实现方式.
先说说碰到的坑.
配置 upstream, 用于 keepalive.
http {
# ... 省略设置
upstream doh-google {
zone doh-google 64k;
server 8.8.8.8:443;
server 8.8.4.4:443;
# keepalive 的数量不需要多, 建议为 CPU 数*2
keepalive 16;
}
upstream doh-cloudflare {
zone doh-cloudflare 64k;
server 1.1.1.1:443;
server 1.1.1.1:443;
keepalive 16;
}
server {
# ... 省略设置
grpc_socket_keepalive on;
# 与 grpcs ssl 的协议, 如果远端不支持, 注释该行
grpc_ssl_protocols TLSv1.3;
location /dns-query {
# grpcs 代表远端是 ssl 连接, 如果不是, 则使用 grpc
grpc_pass grpcs://doh-cloudflare;
# 用 upstream 时, http 头中的 Host 会有问题, 一些服务商例如 cloudflare 需要依赖 Host, 所以要强制指定.
# 同样, 有些服务器商需要指定 SNI, 则需要设置 grpc_ssl_name 和 grpc_ssl_server_name. 详情参看 nginx 文档.
grpc_set_header Host cloudflare-dns.com;
}
location /dns-query2 {
# 两端 URI 不一致, 需要 rewrite
rewrite / /dns-query break;
grpc_pass grpcs://doh-google;
}
# 该范例转发至不加密的 h2 DoH
location /dns-query3 {
rewrite / /dns-query break;
grpc_pass grpc://127.0.0.1:8053;
}
}
}