tcp-wrappers通过libwrap.so在应用层前置拦截连接,需验证服务是否链接该库(如ldd $(which sshd) | grep libwrap),规则按顺序逐行匹配、不支持cidr原生写法,须配合hosts.deny实现白名单隔离,并用tcpdmatch调试验证。

Tcp-Wrappers 在应用层实现访问控制,本质是让服务进程在接收连接前,先经 libwrap.so 拦截并校验规则。它不是网络层防火墙,也不修改包,而是通过“前置拦截”机制,在连接进入服务主逻辑前就决定放行或拒绝。要真正用好 /etc/hosts.allow 做隔离,关键不在文件怎么写,而在于确保整个链路可靠生效。
确认服务是否真的走 Tcp-Wrappers 路径
不是所有监听 22、21 端口的服务都会被控制。必须验证该服务二进制是否链接了 libwrap.so:
- 运行
ldd $(which sshd) | grep libwrap - 有输出(如
libwrap.so.0 => /lib64/libwrap.so.0)才说明支持 - 若无输出,改
hosts.allow完全无效。常见不支持服务:nginx、httpd、redis、dockerd、systemd socket-activated 的 sshd(如sshd.socket)
规则必须按精确格式写进 hosts.allow,且顺序即策略
Tcp-Wrappers 不是“先查 allow 再查 deny”的布尔叠加,而是逐行扫描,匹配第一行就立即执行并终止匹配。所以:
- 允许规则要写在
hosts.allow开头,越具体越靠前 -
sshd:192.168.5.0/24是无效写法 —— Tcp-Wrappers 不原生识别 CIDR,应写成sshd:192.168.5.或sshd:192.168.5.0/255.255.255.0 - 冒号必须是英文半角,前后不能有空格:
sshd:192.168.5.*✅,sshd : 192.168.5.*❌ - 文件末尾必须有换行符,否则最后一行被 POSIX 忽略
搭配 hosts.deny 实现白名单式隔离
高安全场景下,hosts.allow 单独不够,需配合 hosts.deny 构建默认拒绝边界:
- 在
/etc/hosts.deny中写入ALL: ALL—— 拒绝所有服务的所有来源 - 在
/etc/hosts.allow中只写明确允许的条目,例如:sshd:192.168.10.100vsftpd:172.16.0.0/255.255.0.0ALL: LOCAL(允许本地回环和本机启动的连接)
这样,未显式列入hosts.allow的任何请求,都会被hosts.deny的ALL: ALL拦下
调试要靠 tcpdmatch,别靠盲试
改完配置别急着连,用 tcpdmatch 模拟判断:
-
tcpdmatch sshd 192.168.10.5→ 显示access granted via /etc/hosts.allow或access denied via /etc/hosts.deny - 若提示
no such process,说明系统没装tcp_wrappers包(CentOS 用yum install tcp_wrappers,Debian/Ubuntu 用apt install tcpd) - 注意:
tcpdmatch不触发 DNS 反查,但足以验证 IP/掩码/服务名三级匹配是否成立
不复杂但容易忽略











