TCP Wrappers 不支持 MAC 地址匹配,因其工作在传输层,仅处理 IP 和端口信息;/etc/hosts.allow 和 hosts.deny 语法中无 MAC 相关关键字,所有尝试如 sshd:00:11:22:33:44:55 均被忽略;需用 iptables -m mac 或 802.1X 等数据链路层机制实现物理地址控制。

Linux 上 TCP Wrappers 无法控制“物理地址”(即 MAC 地址)访问 —— 它只工作在传输层(TCP),不解析数据链路层帧头,libwrap.so 根本没有读取或匹配 MAC 地址的能力。
为什么 tcpd / hosts.allow 不支持 MAC 地址匹配
TCP Wrappers 的设计定位就是基于主机(IP 或域名)的粗粒度访问控制。它依赖内核交付给用户空间的 socket 连接请求,此时原始以太网帧早已被剥离,只剩 IP+端口信息。所有文档、源码和 man page(man 5 hosts_access)中均无任何关于 MAC、ether、hwaddr 等关键词的语法支持。
常见误操作包括:
- 在
/etc/hosts.allow里写sshd:00:11:22:33:44:55→ 规则被完全忽略,tcpdmatch返回no match - 用
arp -n | grep提前查 IP-MAC 对再写进配置 → IP 可伪造、ARP 可欺骗,且规则本身不生效 - 混淆
iptables的-m mac模块 → 那是 netfilter 在内核态做的事,和 TCP Wrappers 完全无关
真正能限制 MAC 地址的替代方案
如果业务场景确实需要绑定物理地址(例如固定终端设备接入 SSH),必须绕过 TCP Wrappers,改用底层机制:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
-
iptables -A INPUT -p tcp --dport 22 -m mac ! --mac-source 00:11:22:33:44:55 -j DROP:在INPUT链拦截非白名单 MAC 的 SSH 连接请求(注意:仅对直连同一二层网络的客户端有效,跨路由无效) - 结合
arpwatch+ipset动态维护 IP-MAC 映射表,再用iptables -m set匹配 → 适合小型局域网,但需额外运维 - 改用 802.1X 认证(如
hostapd+freeradius):在交换机或 AP 层强制 MAC 绑定,这才是符合网络分层逻辑的做法
别把 hosts.allow 当万能 ACL 引擎
很多人试图用 EXCEPT、spawn 或自定义脚本“曲线救国”,比如在 hosts.deny 里写:sshd: ALL : spawn /usr/local/bin/check-mac.sh %a。这看似可行,但实际会出问题:
-
%a是客户端 IP,不是 MAC;脚本里调arp -n | grep $IP查到的 MAC 可能已过期或被污染 -
spawn是同步阻塞执行,SSH 连接建立前要等脚本返回,延迟高且易超时 - 脚本失败(如权限、PATH、ARP 缓存为空)会导致默认放行,反而引入安全盲区
更关键的是:这种做法违背了 TCP Wrappers 的轻量设计初衷,也失去了规则可审计、可预测的优势。
真正要控 MAC,就得下到数据链路层;想用 hosts.allow,就老老实实填 IP 或域名。混用两套语义完全不同的控制平面,最后只会让排查变得更痛苦。










