目录#
[[toc]]
背景: 国内服务器使用 doh 的时候,需要 https 协议,这个时候又不想备案,并且不想使用 udp 以及 tcp(容易被 q),所以这里采取了 给 ip 地址生成自签的 ca 证书,并且本地跳过证书验证,这样满足了加密的需求。
生成证书#
python
sudo mkdir -p /etc/nginx/ip-ssl
cd /etc/nginx/ip-ssl
sudo openssl req -x509 -nodes -newkey rsa:2048 -days 365 \
-keyout ip.key \
-out ip.crt \
-subj "/CN=your-ip" \
-addext "subjectAltName=IP:your-ip"
| 参数 | 作用 |
|---|---|
| req -x509 | 生成自签名(self-signed)证书,而不是仅生成 CSR 请求。 |
| -nodes | 生成的私钥不加密(不设置密码),方便 nginx 直接读取。 |
| -newkey rsa:2048 | 生成一个 2048 位 RSA 私钥和证书。 |
| -days 365 | 证书有效期 365 天。 |
| -keyout ip.key | 保存私钥文件。 |
| -out ip.crt | 保存证书文件。 |
| -subj "/CN=your-ip" | 证书主题(Subject)里的 Common Name,这里直接填 IP。 |
| -addext "subjectAltName=IP:your-ip" | 关键扩展:证书的 Subject Alternative Name,明确声明证书适用于这个 IP 地址。 |
| 自签 | 受信 CA |
|---|---|
| 自己就是根证书颁发者 | 由受信任的 CA(如 Let’s Encrypt)签发 |
| 免费,快速生成 | 需要域名验证,通常必须有域名 |
| 默认不被浏览器信任,访问时需要 --insecure 或手动信任 | 自动被主流操作系统/浏览器信任 |
| 适合内部测试、内网服务或你自己能控制客户端 | 适合公网正式生产环境 |
配置nginx#
python
server {
listen 49443 ssl http2; # 用你想开放的端口
server_name your-ip;
ssl_certificate /etc/nginx/ip-ssl/ip.crt;
ssl_certificate_key /etc/nginx/ip-ssl/ip.key;
location /dns-query {
proxy_pass https://127.0.0.1:59443/dns-query;
proxy_ssl_verify off;
# 强制使用 1.1,避免出现 EOF问题
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
# 传递真实客户端 IP
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 如果 AdGuardHome 的 DoH 监听在本地 3000 端口,则直接写这个
# 如果你只开了 tcp://59537(DoT),则改成对应的 DoH 端口或开启 DoH 服务
}
}
- 外层 listen … ssl http2
- 客户端(curl、浏览器或系统 DoH 解析器)与 nginx 建立的是 HTTP/2 连接。
- HTTP/2 支持多路复用,多个请求可以复用同一个 TLS 连接,减少握手和连接建立的开销。
- 内层 proxy_http_version 1.1
- nginx 与后端 AdGuardHome 通信时强制使用 HTTP/1.1。
- 这是为了避免 AdGuardHome 对 HTTP/2 的兼容性或 Keep-Alive 行为导致的 EOF / TLS handshake error。
- 同时 proxy_set_header Connection "" 可以让 nginx 不再插入 Connection: keep-alive 或 Connection: close,进一步避免后端因为连接管理不同步而提前断开。
测试:
python
curl -vk https://your-ip:49443/dns-query
配置 adguardhome#
编辑 AdGuardHome.yaml(路径一般是 /opt/AdGuardHome/AdGuardHome.yaml 或容器挂载目录),在 http: 段落里增加或确认:
python
http:
x_forwarded_for: true
然后重启 AdGuard Home:
这样,AdGuard Home 就会优先显示 X-Forwarded-For 中的真实外部 IP,而不是 127.0.0.1。
评论
还没有评论,来发第一个吧