Unbound + doh‑proxy 的简易 DoH 实现
本文最后更新于 45 天前,其中的信息可能已经有所发展或是发生改变。

1. 安装 Unbound 递归DNS服务

关闭系统自带的systemd‑resolved避免占用53端口:

apt update
apt install -y unbound
systemctl stop systemd-resolved
systemctl disable systemd-resolved

编写unbound配置文件 /etc/unbound/unbound.conf.d/local-recursor.conf

server:
  # 仅本地回环给doh‑proxy调用,不对外暴露53端口
  interface: 127.0.0.1
  interface: ::1
​
  access-control: 127.0.0.0/8 allow
  access-control: ::1 allow
  access-control: 0.0.0.0/0 refuse
​
  # DNSSEC 验证开启
  auto-trust-anchor-file: "/var/lib/unbound/root.key"
  val-log-level: 1
​
  hide-identity: yes
  hide-version: yes
​
  # 缓存调优
  msg-cache-size: 16m
  rrset-cache-size: 32m
  cache-max-ttl: 86400
  cache-min-ttl: 60
​
  edns-buffer-size: 1232
  prefetch: yes
  prefetch-key: yes

生成DNSSEC根信任锚文件:

unbound-anchor -a /var/lib/unbound/root.key
chown unbound:unbound /var/lib/unbound/root.key

校验配置语法,启动unbound:

unbound-checkconf
systemctl enable --now unbound
systemctl status unbound

测试unbound本地解析是否正常:

dig @127.0.0.1 example.com A

正常返回A记录代表递归解析工作正常。

2. 安装 doh‑proxy deb包

下载官方发布deb包并安装:

wget https://github.com/DNSCrypt/doh-server/releases/download/0.9.16/doh-proxy_0.9.16-1_amd64.deb
apt install ./doh-proxy_0.9.16-1_amd64.deb

确认版本:

doh-proxy --version
# 输出 doh-proxy 0.9.16

3. 编写 doh‑proxy TOML配置

配置文件路径固定:/etc/doh-proxy/doh-proxy.toml

# doh-proxy.toml
listen_address = "127.0.0.1:3000"
server_address = "udp:127.0.0.1:53"
​
max_clients = 1024
min_ttl = 10
max_ttl = 86400
err_ttl = 5
disable_keepalive = false
allow_odoh_post = true
log_level = "info"

参数说明

  • listen_address = "127.0.0.1:3000":仅本机回环监听,由反向代理转发请求;多机部署场景改为0.0.0.0:3000,并配置trusted_proxies信任前端代理IP。
  • server_address = "udp:127.0.0.1:53":上游指向本机unbound,必须带udp:前缀,缺少会启动崩溃。
  • allow_odoh_post = true:开启ODoH支持。

4. 创建 systemd 服务单元

创建文件 /etc/systemd/system/doh-proxy.service

[Unit]
Description=DoH‑Proxy 0.9.16 (DNSCrypt doh‑server)
After=network.target unbound.service
Requires=unbound.service
​
[Service]
Type=simple
User=nobody
Group=nogroup
ExecStart=/usr/bin/doh-proxy
Restart=on-failure
RestartSec=3
PrivateTmp=true
NoNewPrivileges=true
​
[Install]
WantedBy=multi-user.target

重载systemd,设置开机自启并启动服务:

systemctl daemon-reload
systemctl enable --now doh-proxy
systemctl status doh-proxy

本地裸HTTP测试doh‑proxy

curl -H "Accept: application/dns-json" 'http://127.0.0.1:3000/dns-query?name=example.com&type=A'

正常返回JSON格式DNS应答,代表 doh‑proxy ↔ unbound 链路工作正常。

5. 配置HTTPS反向代理(二选一)

doh‑proxy本身不处理TLS,必须依靠Nginx/Caddy完成443端口SSL终止。DoH访问端点:https://你的域名/dns-query

方案A:Caddy(推荐,自动申请Let’s Encrypt证书)

Caddyfile示例

doh.example.com {
  reverse_proxy 127.0.0.1:3000
}

重启caddy:

systemctl restart caddy

方案B:Nginx + Let’s Encrypt证书

server {
  listen 443 ssl http2;
  server_name doh.example.com;
​
  ssl_certificate /etc/letsencrypt/live/doh.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/doh.example.com/privkey.pem;
​
  location / {
      proxy_pass http://127.0.0.1:3000;
      proxy_set_header Host $host;
      proxy_set_header X‑Real‑IP $remote_addr;
      proxy_set_header X‑Forwarded‑For $proxy_add_x_forwarded_for;
      proxy_http_version 1.1;
      proxy_read_timeout 15s;
      proxy_connect_timeout 10s;
  }
}

校验并重载nginx:

nginx -t
systemctl reload nginx

6. 公网完整功能测试

curl -H "Accept: application/dns-json" 'https://doh.example.com/dns-query?name=example.com&type=A'

常用排错命令

# 查看doh‑proxy运行状态
systemctl status doh-proxy
# 实时日志
journalctl -u doh-proxy -f
# 查看端口监听
ss -tulpn | grep 3000
# 前台直接运行doh‑proxy看配置解析报错
doh-proxy
# unbound日志
journalctl -u unbound -f
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
Bmoji
热词系列
TVmoji
小电视
2233娘
那兔
洛天依
红小豆
上一篇