Birds – Flying beyond the wall

DNS 53端口被占用怎么办?按系统定位并修复

更新于 2026-11-05 · birds.mom

简答:DNS 53端口被占用时,不要先强制结束进程。先分别检查UDP 53、TCP 53以及IPv6监听者,确认PID和所属服务,再选择停止冲突服务、修改监听地址或改用其他端口;修复后用ss、netstat、nslookup或dig复测。

定义:DNS 53端口冲突,是指两个服务尝试在同一台主机的相同IP、相同传输协议和相同端口上监听,导致其中一个服务启动失败。

先做这5步:确认谁占用了53端口

  1. 确认报错范围:记录是DNS服务启动失败、容器启动失败,还是客户端解析超时;不要把“端口被占用”和“防火墙阻断”混为一谈。
  2. 同时查UDP和TCP:DNS查询通常优先使用UDP 53,响应较大或需要回退时可能使用TCP 53,因此只查一种协议可能遗漏冲突。Microsoft对DNS端口和UDP/TCP回退的说明。
  3. 确认监听地址:重点查看0.0.0.0:53、[::]:53、127.0.0.53:53或指定网卡地址。绑定所有地址的服务,可能阻止另一个服务绑定单独网卡。
  4. 确认PID和服务归属:先记录进程名、PID、启动方式和配置文件,再决定是否停止;不要直接执行kill -9或结束未知系统进程。
  5. 修改后复测:再次检查端口,并用nslookup或dig向目标DNS地址发起查询,确认“能监听”不等于“能正常解析”。
场景先查什么优先处理方式
Windowsnetstat -ano、PowerShell根据PID确认服务,再停止或调整监听
Linux主机ss、lsof、systemd服务识别systemd-resolved、dnsmasq或named
Docker宿主机监听与端口映射释放宿主机53,或调整发布端口
仅IPv6冲突[::]:53调整IPv6监听范围或服务绑定地址

Windows:用PID定位占用进程

以管理员身份打开命令提示符,先查看所有监听端口和PID:

netstat -ano | findstr ":53"

netstat的-a参数可显示监听中的TCP和UDP端口,-n显示数字地址,-o显示PID;这些参数适用于Windows 10、Windows 11及相关Windows Server版本。Microsoft netstat命令说明。

看到PID后继续确认进程名称:

tasklist /FI "PID eq 1234"

也可以在PowerShell中分别查询TCP和UDP:

Get-NetTCPConnection -LocalPort 53 -State Listen

Get-NetUDPEndpoint -LocalPort 53

PowerShell结果中的OwningProcess对应进程PID,可再用任务管理器或Get-Process -Id 1234确认。Get-NetTCPConnection官方文档。

如果占用者是已安装的DNS服务,优先从“服务”控制台停止或修改其监听设置;如果是VPN、代理、虚拟化或安全软件,先确认它是否承担本机解析功能,再决定停用。停止前应记录原状态和启动类型,避免重启后网络解析失效。

Linux:重点排查systemd-resolved和其他DNS服务

先用以下命令查看UDP、TCP及IPv6监听:

sudo ss -lntup | grep ':53'

sudo lsof -nP -iTCP:53 -iUDP:53

ss用于查看套接字统计,-l筛选监听状态,-n避免名称解析,-t和-u分别对应TCP和UDP。Linux ss手册。

常见情况是systemd-resolved已经在本机回环地址提供DNS stub。官方说明显示,它可能在127.0.0.53和127.0.0.54提供本地DNS监听,因此自建DNS服务再绑定相同地址和53端口就会冲突。systemd-resolved官方说明。

先确认服务状态:

systemctl status systemd-resolved

resolvectl status

如果你需要保留systemd-resolved,优先让自建DNS只绑定未被占用的指定IP,或让它监听其他端口。若确实要关闭stub,应先准备恢复方案,再编辑/etc/systemd/resolved.conf中的[Resolve]配置,并确认/etc/resolv.conf最终指向可用的上游DNS;不要直接删除该文件。systemd文档建议使用配置覆盖文件,并说明DNS=可指定上游服务器和端口。resolved.conf配置说明。

修改后执行sudo systemctl restart systemd-resolved或重启对应DNS服务,再重新运行ss和dig @127.0.0.1 example.com验证。若端口已释放但查询超时,继续检查防火墙、监听地址和上游DNS。

Docker、Pi-hole或AdGuard Home:区分容器端口和宿主机端口

容器内部的53端口空闲,并不代表宿主机的53端口空闲。Docker发布端口时,会把宿主机端口映射到容器端口;例如同时发布TCP和UDP时,需要分别声明:

ports:、- "53:53/udp"、- "53:53/tcp"

Docker官方文档明确区分TCP和UDP端口映射,并说明发布端口默认可能对外可访问;因此DNS服务只应绑定必要的主机地址,并结合防火墙限制来源。Docker端口发布与映射文档。

排查顺序是:先在宿主机执行ss -lntup | grep ':53',再查看docker ps和docker port 容器名,最后检查Compose文件是否重复发布53端口。如果宿主机已有系统解析服务,不要只把容器内部端口改成其他数字;客户端访问的仍是宿主机发布端口,DNS客户端、转发器、防火墙和容器映射必须保持一致。

如果只是本机管理面板需要访问容器DNS,可考虑仅绑定127.0.0.1或局域网指定地址;如果要让局域网设备使用,则应明确开放范围,避免把递归DNS服务无意暴露到公网。

修复后验证:端口、服务、解析三层都要通过

  1. 端口层:Windows再次运行netstat -ano | findstr ":53";Linux运行sudo ss -lntup | grep ':53',确认目标服务占用预期的UDP、TCP和地址。
  2. 服务层:检查服务状态和日志。Linux可用systemctl status 服务名与journalctl -u 服务名 --since "10 minutes ago";Windows可查看应用、系统和DNS相关事件日志。
  3. 解析层:Windows使用nslookup example.com DNS服务器地址,Linux使用dig @DNS服务器地址 example.com。Microsoft建议使用指定DNS服务器地址的nslookup来判断服务器是否能响应查询。Microsoft DNS故障排查步骤。
  4. 客户端层:如果服务器本机能解析、其他设备不能解析,重点检查防火墙、安全组、路由器DNS设置以及UDP/TCP 53是否同时放行;如果所有设备都失败,再检查上游转发和DNS配置。

“端口不再报占用”只是第一关。只有监听状态正常、服务日志无启动错误、指定服务器能返回结果,才算完成一次有效修复。

常见问题

为什么只查TCP 53看不到占用,但DNS服务仍启动失败?

DNS服务通常需要同时处理UDP 53和TCP 53。只查询TCP可能漏掉UDP监听,也要检查IPv6的[::]:53以及具体回环地址。

可以直接关闭systemd-resolved吗?

不建议直接关闭。先确认它是否提供本机解析,再准备可恢复的resolv.conf和上游DNS配置;也可以优先让自建DNS绑定其他地址或端口。

把DNS服务改到5353就能解决吗?

只有在客户端、转发器、容器映射和防火墙都支持该非标准端口时才可行。普通DNS客户端默认查询53端口,改端口后必须同步调整访问路径。

Docker容器里的53端口没冲突,为什么仍然启动失败?

冲突可能发生在宿主机发布端口。检查Compose中的TCP和UDP映射,以及宿主机是否已有系统解析服务或其他容器发布53端口。

相关阅读

参考资料

  1. Microsoft Learn:Network Ports Used by DNS
  2. Microsoft Learn:对 DNS 服务器进行故障排除
  3. freedesktop.org:resolved.conf
  4. Linux manual page:ss(8)