用户工具

站点工具


xnix:nginx_doh

这是本文档旧的修订版!


使用 Nginx 搭建 DNS over HTTPS (DoH)

参考文档及源代码

为 Nginx 增加 njs 功能模块

对于 FreeBSD, ports安装时, 选上 NJS 模块即可, 如果选了 DSO, 则配置文件需要加载 njs 的 stream 模块. 另外 stream 模块都需要加上

load_module /usr/local/libexec/nginx/ndk_http_module.so;
load_module /usr/local/libexec/nginx/ngx_stream_js_module.so;
load_module /usr/local/libexec/nginx/ngx_stream_module.so;

对于 Linux, 如果直接安装已编译好的包, 可参考上面文档 #4. 如果是手动编译, 则需要下载源代码并且编译nginx时添加参数. 例如

--add-module=/path/njs-src/nginx

njs 的 最新源代码

配置 Nginx

以下是简明配置, 详细的参考上面的文档 #1 和 #2 先从 #2 下载 nginx-dns js 全部代码, 本地目录 /path/nginx_dns

如果上游DNS服务器使用DNS over TLS(DoT),一般是853端口, 则 stream 配置需要启用 proxy_ssl

如果上游DNS服务器是普通形式, 一般是53端口, 则 stream 配置需要启用 proxy_ssl

http {
	....省略....
	ssl_protocols			TLSv1.2 TLSv1.3;
	ssl_ciphers			"TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256";
	ssl_prefer_server_ciphers	on;
	ssl_session_cache		shared:SSL:50m;
	ssl_session_timeout		1d;
	ssl_dhparam			/path/dh4096.pem;
	ssl_early_data			on;
	upstream dohloop {
		zone		dohloop 64k;
		server		127.0.0.1:8053;
		keepalive	10;
	}
	server {
		server_name		hshh.org;
		listen			443 ssl http2;
		listen			[::]:443 ssl http2;
		ssl_certificate		/path/fullchain.pem;
		ssl_certificate_key	/path/privkey.pem;
		ssl_stapling		on;
		ssl_stapling_verify	on;
		add_header		Strict-Transport-Security max-age=31536000;
		location /dns-query {
			proxy_http_version	1.1;
			proxy_set_header	Connection "";
			proxy_pass		http://dohloop;
		}
	}
}

stream {
	ssl_protocols			TLSv1.2 TLSv1.3;
	ssl_ciphers			"TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256";
	ssl_prefer_server_ciphers	on;
	#ssl_session_cache		shared:SSL:50m;
	ssl_session_timeout		1d;
	ssl_dhparam			/path/dh4096.pem;
	tcp_nodelay			on;
	js_import			/path/nginx_dns/nginx_stream.js;
	upstream dot {
		zone	dot 64k;
		server	8.8.8.8:853;
		server	8.8.4.4:853;
	}
	server {
		listen		127.0.0.1:8053;
		js_filter	nginx_stream.dns_filter_doh_request;
		proxy_ssl	on; # 如果上面upstream dot内的DNS服务器不是DoT, 即是普通53端口, 则注释本行
		proxy_pass	dot;
	}
}

nginx_stream.js hack

在本次修改前, nginx_stream.js 还未适配最新的 njs, 需要手动添加以下至文件末尾

export default { glb_get_response, glb_process_request, glb_get_edns_subnet, dns_filter_doh_request, dns_preread_doh_request, dns_preread_dns_request, dns_get_qname, dns_get_response };

测试

使用 curl

curl -v --doh-url https://dnsserver/dns-query http://example.com

使用 doh

更新说明

  • 20211228, 新版的 njs, 需要 js 源代码输出 export, 为此 js_filter 也需要声明. 另外配置文件中的 js_include 已被废弃, 取而代之为 js_import. nginx_stream.js 也可能需要手动修改适配.
xnix/nginx_doh.1640702809.txt.gz · 最后更改: 2021/12/28 22:46 由 Hshh