1. 为什么你的服务器总被“踩点”?从Traceroute和ICMP timestamp说起
最近有好几个朋友跑来问我,说自己的云服务器或者内网设备,明明没开什么服务,怎么安全扫描报告上老是亮红灯,提示什么“Traceroute探测漏洞”和“ICMP timestamp请求响应漏洞”。他们一头雾水:这俩是啥?严重吗?不就是一个用来查网络路径的命令和一个不起眼的ICMP消息吗,怎么就成“漏洞”了?
我刚开始接触安全运维的时候,也有过同样的困惑。后来踩过几次坑才明白,安全这事儿,很多时候防的就是那些“不起眼”的地方。攻击者在真正发动攻击前,总得先“踩点”吧?就像小偷不会直接砸门,而是先看看你家窗户牢不牢、有没有装防盗网。Traceroute和ICMP timestamp,恰恰就是攻击者手里非常好用的“侦察工具”。
Traceroute 这玩意儿,咱们平时用来排查“从我家到某个网站为什么这么卡”非常顺手。它通过发送一系列带有特殊TTL(生存时间)的数据包,利用沿途路由器返回的“超时”或“端口不可达”消息,一步步画出网络路径图。但问题来了,如果你的服务器老老实实地回应这些“超时”或“不可达”消息,就等于把自己的网络位置和拓扑信息拱手送人。攻击者拿到这张“地图”,就能分析出你的服务器前面有没有防火墙、大概在哪个网络区域,甚至推断出内网结构。
而 ICMP timestamp 请求/响应,是一个更古老的协议功能,初衷是为了同步时间。你的服务器如果回应了这种请求,就会在回复包里带上自己的系统时间戳。这看起来没啥,但实际上泄露了服务器的系统时间信息。在某些特定场景下,攻击者可以利用时间差进行攻击,或者仅仅是通过时间戳来确认主机的存活状态和操作系统类型,为后续攻击做铺垫。
所以,这两个“漏洞”的本质,不是让你服务器宕机或数据被盗的“直接攻击”,而是“信息泄露”。在安全领域,减少不必要的信息暴露,是加固防线最基本、也最重要的一步。今天,我就手把手带你用Linux系统里最常见的防火墙管理工具 firewall-cmd,把这两个“侦察通道”给堵上。操作不难,但效果立竿见影。
2. 实战准备:理解firewall-cmd与我们的防御策略
在开始敲命令之前,咱们先花几分钟把“武器”和“战术”搞清楚。我知道很多朋友一看到命令行就头大,但别怕,firewall-cmd 其实是CentOS 7、RHEL 7及更新版本(包括Fedora)上对防火墙配置的一个非常友好的“翻译官”。它背后是强大的 nftables(或老系统的 iptables)防火墙子系统,但firewall-cmd用“区域”、“服务”这些概念,让配置变得直观多了。
核心概念一:区域(Zone) 你可以把“区域”理解成一套预设的防火墙规则模板,根据网络环境切换。比如:
- public(公共):默认区域,适用于连接公共场所的Wi-Fi,规则最严格。
- trusted(信任):允许所有连接,用于完全信任的网络(如内网)。
- home(家庭)、internal(内部):比public宽松一些,允许部分服务。
我们的服务器通常就运行在 public 区域。今天的所有操作,也主要针对这个区域。
核心概念二:直接规则(Direct Rules)
firewall-cmd 虽然方便,但并非能100%覆盖所有高级、底层的防火墙规则。这时候就需要“直接规则”出场了。它允许我们绕过firewall-cmd的抽象层,直接向底层的防火墙框架(如 nftables)插入规则。阻断Traceroute探测,就需要用到这个“大招”。
我们的防御战术蓝图:
- 针对Traceroute探测:它的原理是接收我们发出的探测包(如UDP高端口包或ICMP Echo请求)后,沿途路由器或目标主机返回ICMP错误消息(类型3-目的不可达、类型11-超时)。因此,我们要在服务器的出站(OUTPUT) 链上,丢弃(DROP) 由本机生成的、用于回应Traceroute的ICMP type 0(回显应答)、type 3(目的不可达)和type 11(超时)包。注意,是出站!因为我们是要阻止本机发出这些回应。
- 针对ICMP timestamp漏洞:这个就简单直接了。我们直接在防火墙的ICMP类型过滤中,屏蔽(block) 掉
timestamp-request(时间戳请求)和timestamp-reply(时间戳应答)这两种类型的ICMP包。这样,无论外头怎么发请求,我们的服务器都当作没看见。
好了,理论铺垫完毕。接下来,请打开你的终端,切换到root用户(sudo -i 或 su -),咱们进入真枪实弹的配置环节。
3. 手把手关闭Traceroute探测信息泄露
首先来处理Traceroute。正如前面所说,我们要阻止服务器发出特定的ICMP应答包。这里必须使用 --direct 参数来添加直接规则。
3.1 添加三条核心防火墙规则
我们将依次添加三条规则,分别丢弃ICMP type 0, 3, 11。一条一条来,看清楚每个参数的意义:
firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 0 -p icmp --icmp-type 0 -j DROP
逐条拆解,让你彻底明白:
--permanent: 让规则永久生效,否则重启防火墙就没了。--direct: 告诉firewall-cmd,我要加的是直接规则。--add-rule: 添加规则。ipv4 filter OUTPUT 0: 这是规则的具体位置。ipv4指IPv4协议栈;filter是用于包过滤的表;OUTPUT链,处理本机发出的包;0是优先级,数字越小优先级越高,放在链的最前面。-p icmp: 指定协议为ICMP。--icmp-type 0: 匹配ICMP类型为0(Echo Reply,回显应答)。当别人ping你,你本可以回一个“我在这”,但现在我们不让它回。-j DROP: 匹配到上述条件的包,执行丢弃动作。
接下来是另外两条,原理一模一样,只是类型号不同:
firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 0 -p icmp --icmp-type 3 -j DROP
这条规则丢弃ICMP类型3(Destination Unreachable,目的不可达)的包。当Traceroute发送的UDP包到达目标端口(通常是未开放的),目标主机可能会返回这个包。
firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 0 -p icmp --icmp-type 11 -j DROP
这条规则丢弃ICMP类型11(Time Exceeded,超时)的包。这是Traceroute工作的核心,当数据包TTL减到0时,路由器会返回这个包。
一个非常重要的提醒和避坑指南:
在原始文章的示例命令中,包含了 -m comment --comment "deny traceroute" 参数,这是为了给规则添加一个注释,方便日后管理。这本身非常好。但是,在实际操作中,我遇到过在一些特定的系统或firewall-cmd版本上,使用 -m comment 模块可能会导致规则添加失败,报错提示模块找不到。 如果你也遇到了类似问题,别慌,直接去掉 -m comment --comment "deny traceroute" 这部分,只保留核心规则即可。规则的功能不受影响,只是少了个人类可读的标签。所以,上面我给出的命令是精简后的稳定版本。如果你想加注释且系统支持,可以加回去。
3.2 让规则生效并确认
三条规则添加完成后,它们还只是写在了配置文件里,需要重新加载防火墙才能激活。
firewall-cmd --reload
这个命令会重新加载所有永久生效的规则,包括我们刚加的。执行时可能会有一瞬间的网络中断(对于生产环境,请在维护窗口操作),但通常很快。
怎么确认我们的规则已经加上了呢?用这个命令查看所有直接规则:
firewall-cmd --direct --get-all-rules
你应该会看到类似下面的输出,列出了我们刚刚添加的三条规则:
ipv4 filter OUTPUT 0 -p icmp --icmp-type 0 -j DROP
ipv4 filter OUTPUT 0 -p icmp --icmp-type 3 -j DROP
ipv4 filter OUTPUT 0 -p icmp --icmp-type 11 -j DROP
看到它们,心里就踏实了。现在,你的服务器已经不会再主动回应那些会泄露路径信息的ICMP错误消息了。我们可以简单测试一下:从另一台机器对你的服务器执行一次Traceroute,你会发现路径显示可能在一跳之后就变成了连续的 * * *(超时),或者最终无法到达目标,这就是规则在起作用。
4. 快速封堵ICMP timestamp漏洞
处理完Traceroute,我们再来解决ICMP timestamp这个“老古董”漏洞。这个操作相对简单,因为firewall-cmd已经为我们内置了对ICMP类型的过滤功能,不需要写复杂的直接规则。
4.1 屏蔽timestamp请求与应答
我们只需要两条命令,分别屏蔽请求和应答:
firewall-cmd --permanent --zone=public --add-icmp-block=timestamp-request
firewall-cmd --permanent --zone=public --add-icmp-block=timestamp-reply
命令解读:
--zone=public: 指定规则作用于public区域。如果你的服务器不在默认的public区域,需要替换成你的实际区域名(可以用firewall-cmd --get-default-zone查看)。--add-icmp-block=...: 这是关键参数,意思是“添加一个ICMP阻塞规则”。timestamp-request对应ICMP类型13(时间戳请求),timestamp-reply对应ICMP类型14(时间戳应答)。
这两条命令执行后,防火墙会阻止发往本机的timestamp请求包,同时也会阻止本机发出timestamp应答包(虽然正常情况下我们不会主动发,但这是双重保险)。
4.2 重载与验证配置
同样,添加永久规则后需要重载:
firewall-cmd --reload
验证规则是否添加成功,我们可以查看public区域的完整配置:
firewall-cmd --list-all --zone=public
在输出的信息中,找到 icmp-blocks 这一行。你会看到它后面列出了被屏蔽的ICMP类型,其中应该包含了 timestamp-request 和 timestamp-reply。
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: ssh dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks: timestamp-request timestamp-reply
rich rules:
看到这个,就说明配置成功了。现在,任何向你的服务器发送ICMP timestamp请求的行为,都会像石沉大海,得不到任何回应。
5. 进阶思考与注意事项:安全没有银弹
配置做完,漏洞扫描报告上的这两个问题应该就消失了。但我想说的是,安全加固从来不是打几个勾、执行几条命令就一劳永逸的事情。这里有几个我踩过坑后总结的要点,分享给你:
第一,理解规则的副作用。
我们阻断的ICMP type 3和type 11,不仅仅是影响Traceroute。在某些网络环境下,它们也用于正常的路径MTU发现(PMTUD)或通信错误反馈。极端情况下,可能会影响某些特定应用的网络连通性。比如,如果服务器完全禁止发出“目的不可达”消息,当客户端尝试连接一个服务器未监听的端口时,可能会一直等待而不是快速失败。因此,在生产环境部署前,最好在测试环境充分验证你的关键应用是否受影响。 我们的规则是 DROP(静默丢弃),而不是 REJECT(明确拒绝),这在一定程度上减少了信息泄露,但也使得调试网络问题变得更困难。
第二,防火墙规则的管理。
我们使用了 --permanent 参数,规则会保存到配置文件中(通常是 /etc/firewalld/ 下的xml文件)。如果你想临时添加一个规则做测试,可以不加 --permanent,这样 firewall-cmd --reload 后规则就消失了。另外,所有通过 --direct 添加的规则,用 firewall-cmd --direct --get-all-rules 查看和管理还算方便,但如果你想删除某条规则,需要使用 --remove-rule 并原样指定规则参数,稍微有点麻烦。建议做好配置变更记录。
第三,这只是网络层的基础防护。
堵住Traceroute和ICMP timestamp,好比给房子装了厚窗帘,外面的人看不清里面的情况了。但这并不代表房子就固若金汤。真正的安全是一个体系,还包括:及时的系统更新、最小化的服务开放(用 firewall-cmd --add-service 精细控制)、强密码与密钥认证、应用程序自身的安全配置等等。今天讲的内容,是这个安全体系中网络边界防护的一小部分,但却是非常扎实的一步。
最后,如果你在执行命令过程中遇到任何问题,一个非常有用的调试命令是查看防火墙的详细日志。你可以通过配置富规则(rich rules)来记录被丢弃的包,或者直接查看系统日志(如 journalctl -u firewalld)来获取线索。网络安全的世界就是这样,一边学习原理,一边动手实践,遇到问题就查资料、做实验,慢慢的,你就能建立起属于自己的安全防线了。
449



被折叠的 条评论
为什么被折叠?



