tcp wrapper主机名控制生效需服务链接libwrap.so或由tcpd接管,且须启用dns解析(如sshd -t | grep use_dns返回yes),同时正向与反向dns记录严格一致,否则known/unknown宏不触发。

只有服务本身链接了 libwrap.so,或者由 tcpd 接管启动,基于主机名的控制才真正生效;否则写再多 hosts.allow 规则也完全被忽略。
确认目标服务是否真的支持 TCP Wrapper 主机名匹配
主机名解析依赖服务进程主动调用 libwrap 的反向 DNS 查找逻辑,不是系统自动“翻译”IP 为名字。很多服务(如新版 sshd)虽链接 libwrap.so,但默认禁用主机名检查以提升性能或规避 DNS 延迟。
- 先验证是否链接库:
ldd $(which sshd) | grep libwrap—— 有输出才继续 - 再查是否启用主机名匹配:
sshd -T | grep use_dns,若返回use_dns yes才可能触发KNOWN/UNKNOWN宏匹配 - 静态编译服务(如某些定制
vsftpd)需用strings $(which vsftpd) | grep -i 'hosts\.allow'确认硬编码支持 - 注意:
xinetd管理的服务(如in.telnetd)由tcpd统一处理,主机名解析由tcpd完成,不依赖子服务自身配置
hosts.allow 中写主机名的几条硬约束
规则看似简单,但格式错一个字符就失效。TCP Wrapper 对空格、标点、大小写极其敏感,且不报错。
Linux AI 服务器 — 将 Linux 服务器转换为本地 AI 推理集群。使用 systemd、NVIDIA CUDA 实现无头 Linux AI,零 GUI 开销。
- 必须用英文冒号
:分隔服务名和客户端列表,前后不能有空格:sshd:www.example.com✅,sshd : www.example.com❌ - FQDN 必须完整,
example.com不匹配www.example.com;通配符只支持前导点:.example.com匹配所有子域 - IPv6 地址必须加方括号:
sshd: [2001:db8::1],写成sshd: 2001:db8::1直接跳过匹配 - 文件末尾必须有换行符 ——
echo "sshd:.trusted.org" >> /etc/hosts.allow后没回车,最后一行会被内核静默丢弃
为什么 KNOWN 和 UNKNOWN 宏常不按预期工作
这两个宏不是“查 DNS 就行”,而是要求正向(A/AAAA 记录)与反向(PTR 记录)解析严格一致,且无超时。线上环境多数失败源于 DNS 配置不闭环。
-
KNOWN:必须同时满足nslookup 192.168.1.100返回host.trusted.org,且nslookup host.trusted.org返回192.168.1.100 -
UNKNOWN:PTR 记录不存在,或解析超时(tcpd默认超时 30 秒,期间连接挂起) -
PARANOID:正向与反向记录存在但不对应(例如host.bad.org → 192.168.1.100,但192.168.1.100 → host.other.org) - 调试建议:临时在
/etc/hosts.deny加ALL: ALL : spawn /bin/echo "%a %h %d" >> /var/log/tcpwrap-debug.log,看日志里%h字段是否为空或错误
实际部署中最容易被忽略的 DNS 依赖点
TCP Wrapper 不走 /etc/nsswitch.conf,它直接调用 gethostbyaddr() 和 gethostbyname(),因此:
- 必须确保系统级 DNS 可用(
systemd-resolved或dnsmasq正常运行),/etc/resolv.conf不能是空或仅含127.0.0.1却无本地 DNS 服务 - 禁止使用
systemd-networkd自动配置的127.0.0.53作为唯一 nameserver ——tcpd无法与该 socket 通信 - 若用私有 DNS,请在
/etc/hosts中静态定义关键主机名(如192.168.1.10 admin.internal),绕过 DNS 查询 - 主机名规则生效后,
telnet或ssh -v连接时观察 debug 输出中是否有reverse mapping checking字样,这是匹配触发的关键信号










