Debian/Ubuntu + Docker + Mox 搭建支持 DNSSEC/DANE 的 Unbound 递归 DNS
安装MOX参考: 使用Docker部署Mox Mail 邮局
在 Linux 上使用 Docker 部署 Mox 邮件服务器时,很多人会遇到下面的警告:
DANE is inactive because MX records are not DNSSEC-signed.
但实际上,问题通常并不在域名本身,而是:
Mox 所使用的 DNS 解析器(resolver)没有真正进行 DNSSEC 验证。
本文将完整介绍:
- DANE 与 DNSSEC 的关系
- 为什么 Docker 默认 DNS 不够
- 为什么推荐禁用 systemd-resolved
- 如何安装 Unbound
- 如何配置 DNSSEC 验证
- 如何避免开放公网 53 端口
- 如何让 Docker 中的 Mox 使用 Unbound
- 如何验证 DNSSEC 是否真正生效
适用环境:
Debian / Ubuntu
Docker
Mox Mail Server
Unbound
一、为什么会出现 DANE inactive
Mox 的 DANE 工作流程:
- 查询:
MX example.com
- 查询:
_25._tcp.mail.example.com TLSA
- 验证:
- MX 是否经过 DNSSEC 签名
- TLSA 是否经过 DNSSEC 签名
- TLS 证书是否匹配 TLSA
只有 DNSSEC 验证成功,DANE 才会启用。
二、为什么 Docker 默认 DNS 不行
Docker 默认会给容器分配:
127.0.0.11
作为 DNS。
这是 Docker 内部 DNS 转发器:
- 不进行 DNSSEC 验证
- 不提供 authenticated data
- 不适合 DANE
因此即使你的域名已经开启 DNSSEC,Mox 仍可能提示:
DANE is inactive because MX records are not DNSSEC-signed.
三、systemd-resolved 为什么会影响 DNSSEC
Debian/Ubuntu 默认启用:
systemd-resolved
它通常会监听:
127.0.0.53:53
并自动管理:
/etc/resolv.conf
例如:
cat /etc/resolv.conf
可能看到:
nameserver 127.0.0.53
这意味着:
系统 DNS
↓
systemd-resolved
↓
上游 DNS
这会导致几个问题:
- Unbound 无法绑定 53 端口
- Docker 继承错误 DNS
- DNS 链条变复杂
- DNSSEC 验证可能失效
ad标志丢失- DANE 失败
四、推荐架构
推荐:
Internet
↓
Unbound(宿主机递归 DNS)
↓
Docker Mox
不要:
Docker DNS
↓
8.8.8.8
也不推荐:
systemd-resolved
↓
Docker DNS
五、禁用 systemd-resolved(推荐)
1. 停止服务
systemctl stop systemd-resolved
2. 禁止开机启动
systemctl disable systemd-resolved
3. 删除旧 resolv.conf
先查看:
ls -l /etc/resolv.conf
通常会看到:
/etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
备份:
mv /etc/resolv.conf /etc/resolv.conf.bak
4. 创建新的 resolv.conf
nano /etc/resolv.conf
写入:
nameserver 127.0.0.1
表示:
系统 DNS
↓
Unbound
六、安装 Unbound
Ubuntu / Debian:
apt update
apt install -y unbound unbound-anchor dnsutils
查看版本:
unbound -V
应看到:
validator iterator
说明支持 DNSSEC。
七、检查 trust anchor
现代 Debian/Ubuntu 通常会自动生成:
ls -l /var/lib/unbound/root.key
如果文件存在:
/var/lib/unbound/root.key
说明 trust anchor 已初始化。
不存在则执行
unbound-anchor -a /var/lib/unbound/root.key
文件内容类似开头:
; autotrust trust anchor file
即可。
八、配置 Unbound
创建配置文件:
nano /etc/unbound/unbound.conf.d/mox.conf
推荐配置:
server:
interface: 0.0.0.0
port: 53
do-ip4: yes
do-ip6: yes
do-udp: yes
do-tcp: yes
prefer-ip6: no
harden-dnssec-stripped: yes
harden-glue: yes
harden-large-queries: yes
qname-minimisation: yes
hide-identity: yes
hide-version: yes
cache-max-ttl: 86400
cache-min-ttl: 300
num-threads: 2
so-reuseport: yes
verbosity: 1
access-control: 127.0.0.0/8 allow
access-control: 172.16.0.0/12 allow
access-control: 0.0.0.0/0 refuse
这里的 interface 因该设置为 127.0.0.1,但考虑是docker部署的mox,为了避免后续麻烦,设置了 0.0.0.0 ,然后用
access-control设置了白名单。
九、检查配置
unbound-checkconf
如果返回:
no errors
说明配置正常。
十、启动 Unbound
systemctl enable unbound
systemctl restart unbound
检查状态:
systemctl status unbound
十一、确认 Unbound 已接管 53
查看:
ss -lntup | grep :53
应该看到监听对应进程为:
unbound
而不是:
systemd-resolved
十二、测试 DNSSEC
普通解析
dig google.com @127.0.0.1
DNSSEC 验证
dig +dnssec cloudflare.com @127.0.0.1
返回中必须包含:
ad
例如:
flags: qr rd ra ad
其中:
ad = Authenticated Data
说明 DNSSEC 验证成功。
十三、最关键测试
测试一个故意损坏 DNSSEC 的域名:
dig dnssec-failed.org @127.0.0.1
正确结果:
SERVFAIL
如果还能解析出 IP:
说明 DNSSEC 实际没有生效。
十四、让 Docker 中的 Mox 使用 Unbound
docker-compose:
services:
mox:
dns:
- 172.17.0.1
这样:
Mox
↓
Unbound
↓
递归 DNS
十五、域名侧还必须完成
仅安装 Unbound 不够。
还需要:
1. 域名开启 DNSSEC
在 DNS 提供商:
- Cloudflare
- HE
- Route53
- 阿里云
- 腾讯云
- PowerDNS
等开启 DNSSEC。
2. 注册商添加 DS 记录
没有 DS:
DNSSEC 实际无效
3. 配置 TLSA
Mox 会生成:
_25._tcp.mail.example.com
的 TLSA 记录。
十六、推荐检测工具
本地:
delv example.com MX
delv _25._tcp.mail.example.com TLSA
在线:
总结
DANE 是否真正工作,关键并不只是:
域名有没有开启 DNSSEC
更重要的是:
邮件服务器所使用的 DNS 解析器
是否真正进行 DNSSEC 验证。
因此:
- Docker 默认 DNS 不够
- 推荐禁用 systemd-resolved
- 必须使用支持 DNSSEC 的 resolver
- Unbound 是最推荐方案
- 同时要避免开放公网 53 端口
- 并正确配置 DS 与 TLSA
完成这些后, Mox 邮件系统就可以支持:
DNSSEC + DANE