ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

集群安全加固实战:从边界防护到东西向流量管控

集群安全加固实战:从边界防护到东西向流量管控

给计算机集群加一道安全屏障,这事听起来很宏大,但落到实操上,往往就是一组组规则、一条条策略、几次配置调整。我服务过不少业务集群,从十几台节点的中小规模,到上百台节点的分布式系统都接触过,最大的感受是:集群安全不是玄学,而是非常具体的工程管理。不管你的集群跑的是数据分析、后端服务还是容器化平台,安全屏障的核心诉求都一样——让不该进来的人进不来,让不该出去的数据出不去,让正常业务完全不受打扰。

这篇文章我会从设计思路、核心细节、实操流程和问题排查四个方面展开,把我在实际加固过程中踩过的坑、验证过的方案、总结出的经验一次性讲清楚。适合正在维护集群的运维工程师、后端开发以及刚接手集群管理工作的朋友参考,即使你现在还不需要做全套加固,也可以把其中一些思路用在单机防护上。

1. 集群安全屏障的设计思路拆解

1.1 安全屏障到底在防什么:四个威胁维度

动手配置之前,必须先把防护对象搞清楚。集群环境的安全威胁和单机完全不一样,单机主要防外部扫描、防入侵,集群除了这些,还要防内网横向渗透、防异常流量在节点间扩散。我把常见的威胁拆成了四个维度,这也是后面所有配置的主线。

第一是边界维度。集群对外提供的服务端口,比如 Web 端口、API 端口,是攻击者第一个瞄准的目标。端口扫描、暴力破解、漏洞探测,全都从这里进来。这个维度要解决的是"谁可以访问集群的入口"。

第二是主机维度。单台节点被攻破后,攻击者拿到的是这台机器的权限,如果主机层面没有加固,他可以直接登录、提权、留后门,甚至通过这台机器访问集群内部的其他节点。这个维度要解决的是"即使有人进来了,他能做什么"。

第三是流量维度。集群内部节点之间的通信,默认往往是完全信任的。业务 API、数据库连接、缓存读写都裸奔在内网。一旦某一台节点被控制,攻击者就可以顺着内网流量摸到数据库、摸到核心服务。这个维度要解决的是"内网流量是否也需要管控"。

第四是身份维度。谁在登录你的集群?是哪个账号?密钥是否还在有效期内?有没有人用离职员工的旧密钥登录?这听起来是管理问题,但在实际事故中,因为账号管理松散导致的集群沦陷,我见过不止一次。

这四个维度不是互相独立的,边界防线被突破之后,主机维度就是第二道防线,流量维度是第三道,身份维度则是贯穿始终的底线。我做的所有安全屏障配置,都是沿着这条链路逐层加固的。

1.2 为什么优先做边界防护

很多团队一上来就折腾复杂的微服务加密、容器网络隔离,结果边界端口大开,等于把金银财宝摆在门口只锁了卧室门。我的建议是:先从边界防护开始,因为它是投入产出比最高的环节。

理由很简单,集群的攻击面绝大多数暴露在网络入口。你开放一个 22 端口,全互联网的扫描器都会来试;你开放一个应用端口,各种漏洞利用脚本就会蜂拥而至。边界防护做得好,能把绝大多数无效攻击挡在第一道门外,为其他维度的加固争取时间。

边界防护的核心思路可以概括成八个字:默认拒绝,按需放行。也就是说,所有端口的默认状态都是关闭的,只有明确需要对外开放的端口才打开,而且只对需要的来源放行。这个思路看起来简单,做起来却需要非常细致的规划,每一台节点、每一个端口都要梳理清楚。

一个常见误区是"反正内网有防火墙,外网访问不到"。我在实际工作中见过不少集群部署在云内网或办公内网,团队觉得内网就安全了,于是把数据库端口、缓存端口全部暴露在内网网段。结果内网一台不太相关的机器被攻破之后,攻击者用它做跳板,直接连到了数据库。内网不等于信任域,边界防护的位置可以变化,但"默认拒绝"的原则不能变。

1.3 安全屏障的合理分层与最小权限原则

实际落地的时候,我不会只做一层防护,而是按照"最小权限原则"做分层。最小权限原则的意思,就是每个主体(用户、进程、服务)只拥有完成任务所需的最小权限,不多给一分。

在集群安全里,这个原则体现在三处。第一处是网络端口,只开放业务必需的端口,管理端口只对管理网段开放。第二处是系统账户,每个账户只具备完成工作所需的能力,不需要 root 的就不给 root。第三处是集群内部的服务调用,某个业务服务只能访问它依赖的数据库,不能访问其他业务的数据。

分层是为了防止"一破全破"。如果所有节点、所有服务都处于同一个安全等级,攻破任何一台就等于攻破整个集群。分层之后,即使边界被突破,攻击者面对的是一个一个独立加固的主机,横向移动的成本会急剧上升,这会给安全团队争取到关键的响应时间。

2. 核心细节解析与实操要点

2.1 网络层过滤:从 iptables 到安全组的配置逻辑

网络层过滤是边界防护的主力,具体实现方式取决于你的集群部署在什么环境。物理机房里的集群通常用 iptables 或 nftables;虚拟化或容器环境通常用安全组;容器网络则用网络策略。虽然工具不同,底层逻辑完全一致:匹配流量来源、目的地、端口,然后决定放行还是拒绝。

我在物理集群上最常用的还是 iptables,原因是它足够通用、足够稳定。下面是一组常用的规则模板:

# 清空默认规则,设置默认策略为拒绝所有入站流量 iptables -F iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT # 允许本机回环接口流量 iptables -A INPUT -i lo -j ACCEPT # 允许已建立的连接及其相关连接回包 iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # 按需放行特定端口,例如 web 服务端口 80/443 对所有来源开放 iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -j ACCEPT # 管理端口 22 只对管理网段 192.0.2.0/24 开放 iptables -A INPUT -p tcp --dport 22 -s 192.0.2.0/24 -j ACCEPT

注意我把 OUTPUT 策略保留为 ACCEPT,这是实际运维中的常见选择。很多业务场景下,集群需要主动访问外部服务(比如拉取镜像、调用外部 API),如果 OUTPUT 默认拒绝,会遇到大量莫名其妙的连接超时问题。安全是层层递进的,不必在出方向一开始就卡死,先把入方向管住了,再考虑出方向的精细化。

安全组的配置逻辑也是一样。在云环境里,我给安全组规则定的铁律是:先写拒绝所有,再逐条放行。很多默认安全组规则是"放行所有端口",新创建的实例必须第一时间改掉这个默认规则。曾经有个业务团队因为懒省事,把数据库实例放进了"放行所有"的安全组,结果数据库端口被全网扫描,所幸没有造成数据损失,但那一次之后,我再也没允许任何集群资源使用默认安全组。

一个容易被忽略的细节是规则顺序。iptables 按顺序匹配,第一条匹配的规则生效。所以宽泛规则要写后面,精确规则写前面。比如先写"允许管理网段访问 22 端口",再写"拒绝所有来源访问 22 端口";顺序反了,拒绝规则会在允许规则之前匹配,管理网段也被挡在外面。这种顺序问题排查起来非常头疼,最好写规则的时候就养成"从精确到宽泛"的习惯。

2.2 主机层加固:SSH、账户与登录策略

网络层挡住的是外部流量,主机层要解决的是"如果有人到达了登录入口,他能不能进得来"。SSH 是集群管理的生命线,也是攻击者最常尝试的突破口,所以我总是把 SSH 加固放在主机加固的第一位。

SSH 加固的第一步是禁止密码登录,只允许密钥认证。密码可以爆破,密钥在正确配置的前提下几乎无法被暴力破解。具体做法是修改 /etc/ssh/sshd_config:

# 禁止密码登录 PasswordAuthentication no # 禁止空密码账户登录 PermitEmptyPasswords no # 禁止 root 直接登录,管理员先登录普通用户再切换 PermitRootLogin no # 限制 SSH 监听的地址,如果管理网段固定,可以只监听内网地址 # ListenAddress 192.0.2.10

修改完配置文件后,记得执行 systemctl restart sshd 前先测试一下配置语法,ssh -t 检查密钥能否正常登录,确认无误再重启。不然密钥配置有问题的话,重启之后你可能被锁在集群外面,这我踩过一次,教训深刻。

账户管理也很有讲究。集群上的账户不是越多越好,每一个账户都意味着一个攻击面。我通常会定期清理长期不活跃的账户,删掉离职员工的账号,同时对必须保留的账户做最小权限限制。能用普通账户 + sudo 切到管理权限的,就不直接给 root。

口令策略也要设置。即使禁用了密码登录,系统账户的密码策略仍然不能放松,因为总有些服务会用系统账户做认证。通过 PAM 模块配置复杂度策略、密码定期轮换、登录失败锁定,这些在集群环境下应该作为标准配置。设置登录失败锁定时要小心,我在某次配置中把连续失败 3 次就锁定 30 分钟的策略加到了所有账户上,结果一个自动化脚本因为凭据过期连续失败,把所有相关账户都锁了,业务直接停摆。后来的做法是:自动化服务账户单独配置策略,人工管理账户才启用锁定。

2.3 流量层面与应用层防护的取舍

网络层过滤之后,还有一层是应用层防护。这类防护不是每个集群都必须上,但如果集群对外开放业务服务,我强烈建议认真考虑。

最常见的手段是在集群入口加 Web 应用防火墙(WAF)能力,用来过滤 SQL 注入、跨站脚本、恶意爬虫等应用层攻击。这类攻击在 TCP 层看起来完全正常,网络层过滤根本分辨不出来,必须到应用层才能拦截。

不过,WAF 类方案也有代价:会增加请求延迟,规则配得不好还会误伤正常业务。我见过一个团队配置了过于严格的 WAF 规则,把正常用户请求当攻击拦掉了,业务方半夜打电话投诉,最后不得不紧急回滚规则。在集群场景中,我的建议是:外层用网络层过滤挡掉大量的扫描和探测,内层再按业务风险决定是否加应用层防护。不要一上来就全量铺开,先做最小范围的试点。

流量层面的另一个重点是限流。集群入口的带宽和连接数是有限的,如果不做限制,一场流量突增就可能把集群拖垮。限流有两种维度:连接数限制和带宽限制。前者通过限制单 IP 并发连接数来防止连接耗尽,后者通过限制速率来保护带宽。实际操作中,连接数限制比较容易实现且效果明显,我一般会在集群入口的负载均衡器上配置单 IP 连接数上限。

3. 实操过程与核心环节实现

3.1 一次完整的集群边界加固实操流程

现在我把一次完整的边界加固流程走一遍,这套流程我在多个集群上验证过,按步骤执行基本不会出大问题。

第一步,资产梳理和端口盘点。在动任何规则之前,先摸清楚每台节点上跑着什么服务,监听哪些端口。这一步可以借助 ss 命令完成:

ss -tlnp

输出里每一行是一个监听端口,对应进程一目了然。把结果整理成表格,标明每个端口的用途、是否需要对外开放、允许哪些来源访问。这张表就是后续防火墙规则的依据。我曾经接手过一个集群,直到做完端口腔盘点,才发现某个旧服务残留进程一直在监听一个高危端口,而该服务早该下线了。

第二步,编写基线规则。按照第一步的端口表,把"默认拒绝、按需放行"的规则落到 iptables 或安全组上。这里给出一份生产环境常用的开放端口清单作为参考:

端口用途默认开放范围
22SSH 管理管理网段
80HTTP 服务全来源或特定来源
443HTTPS 服务全来源或特定来源
8080应用服务端口内网或负载均衡来源
3306数据库端口仅允许应用节点网段访问
6379缓存服务端口仅允许应用节点网段访问
9090监控面板端口管理网段或办公网段

第三步,逐台节点应用规则。在规模较小的集群里,可以手动在各节点执行;规模大了之后,一定要借助批量分发工具,避免人工遗漏。我见过有些集群一半节点加固了、一半没有加固,攻击者专挑没加固的节点下手,这种半吊子的安全策略比完全不加固更危险。要么全部做,要么别开始。

第四步,验证连通性和业务可用性。规则应用后,从外部测试对外开放的端口是否正常,从内部测试业务依赖的端口是否互通。很多加固事故都是这一步没做就匆忙上线,结果业务端口被自己误伤。我的习惯是准备一个测试清单,把核心业务接口、数据库连接、缓存读写都测一遍,没问题才算完成。

3.2 集群内部东西向访问控制:用好网络策略与命名空间

边界加固完成之后,下一步是内部流量的管控,也就是所谓的东西向访问控制。这一步最容易被忽略,但恰恰是防止横向渗透扩散的关键。

在传统物理集群里,内部流量管控通常通过 VLAN 或子网划分来实现。把管理网段、业务网段、数据网段分开,网段之间用防火墙规则控制互访权限。比如应用节点可以访问数据库节点的 3306 端口,但反过来数据库节点不能主动连接应用节点的任意端口,这样即使数据库节点被攻破,攻击者也不能轻易以它为跳板攻击应用层。

在容器化集群里,管控方式变成了网络策略。Kubernetes 环境里的 NetworkPolicy 本质上是给 Pod 之间的流量加规则。默认情况下,Kubernetes 集群的 Pod 之间是可以互相访问的,这非常危险。我在部署业务时必做的一件事是:给每个命名空间配置默认拒绝所有流量的网络策略,然后按业务依赖关系逐条放行。

一个典型的网络策略配置思路如下:

  • 拒绝所有命名空间之间的默认访问。
  • 允许网关命名空间访问业务命名空间的指定端口。
  • 允许业务命名空间访问数据命名空间的数据库端口。
  • 允许监控命名空间访问所有命名空间的监控端口。

这套策略实施起来需要业务部门配合梳理服务依赖关系,工作量不小,但安全价值极大。我在某个集群上实施之后,再出现容器被攻破的事件时,攻击者只能访问到这一个容器的能力,无法扩散到其他服务,响应时间从小时级缩短到了分钟级。

3.3 身份认证与密钥管理的实际落地

最后一块,也是最容易被拖延的一块,是身份认证和密钥管理。很多集群长期使用同一个管理密钥,所有管理员共享 root 或 sudo 账户,出了问题根本查不到是谁操作的,更谈不上最小权限。

我推荐的落地方式,是搭建集中的认证体系。所有管理员使用统一的账户系统登录集群,账户权限按角色划分:运维工程师有节点管理权限,开发人员只有日志查看和部署权限,数据库管理员单独一套权限。这样既能追溯操作记录,又能在人员变动时快速调整权限。

密钥管理上,我有几个实际操作中的经验。第一,密钥文件必须设置严格的权限,私钥文件权限建议为 600,公钥为 644,权限过松会带来私钥泄露风险。第二,密钥建议设置有效期,定期轮换,不要让一把密钥用三五年。第三,禁止将私有密钥存放在代码仓库中,这个错误在开发团队里极其常见,一旦仓库泄露,整个集群的访问权限都会暴露。

审计日志也要长期保存。我建议至少保留 180 天以上的登录记录和关键操作记录,最好把日志同步到独立的日志存储节点,防止攻击者登录后删除本地日志销毁痕迹。磁盘空间有限的话,可以用日志轮转策略压缩保存,但优先级一定不能低于业务日志。

4. 常见问题与排查技巧实录

4.1 加固后服务不可用:状态机制放行顺序是头号嫌疑

第 3.1 节的流程走完之后,最常见的故障是"加固完了,业务挂了"。这种问题百分之七八十出在三个地方:默认策略设错了、回包没放行、规则顺序写反了。

默认策略设错,指的是把 INPUT 策略设置成 DROP 之后,忘了允许已建立的连接回包。TCP 连接是双向的,客户端发来 SYN,服务端要回 SYN-ACK,客户端的 ACK 还要再进来。如果只放行了入站的 80 端口,没有放行 ESTABLISHED,RELATED 状态的回包,客户端的连接握手就无法完成。所以那两行 conntrack 规则我会看得很重,缺了它们,几乎所有对外服务都会挂。

规则顺序写反的情况前面提到过,精确规则宽泛规则顺序颠倒,导致所有流量都被宽泛的拒绝规则拦截。排查这种问题最简单的方法是按顺序检查规则列表,iptables -L -n --line-numbers 会把每行规则按匹配顺序编号,一眼就能看出顺序问题。

4.2 高并发场景下的性能取舍

防火墙规则在高并发场景下会不会拖慢集群?这个问题的答案是"会,但要看怎么配"。

iptables 的匹配流程是线性的,规则数量越多,每条流量经过时需要检查的规则就越多,性能自然下降。在每秒数万连接的高并发场景,成百上千条规则会带来明显的 CPU 开销。解决办法有两个方向。

第一个方向是让规则更精简。把多个端口、多个来源合并成一条规则,减少匹配次数。比如同一来源段访问连续的端口范围,可以用端口范围表示法,而不是逐个端口写规则。第二个方向是充分利用连接跟踪机制,让已经建立连接的流量走 conntrack 快速路径,而不是每次从头匹配所有规则,这也是 state 模块的底层逻辑。

我还遇到过一种情况:安全组规则太多太复杂,云平台底层转发性能下降。这种情况下,应该把经常变动的复杂策略下沉到集群内部防火墙,安全组只保留稳定的粗粒度策略。把静态和动态策略分开管理,性能问题会好很多。

4.3 常见问题速查表与巡检建议

把我在集群加固过程中遇到的高频问题整理成了一张速查表,方便你排查时对照。

问题现象可能原因排查方法
某个外部端口不通iptables 规则未放行或顺序错误执行 iptables -L -n --line-numbers 检查规则
外部能连上但业务超时回包规则缺失,conntrack 未放行检查 ESTABLISHED,RELATED 规则是否存在
内网节点之间无法互访安全组或网络策略未放行对应网段端口检查安全组入站规则和 NetworkPolicy 配置
SSH 登录卡住或超时反向 DNS 解析导致延迟sshd_config 中设置 UseDNS no
连接被频繁断开连接数限制策略过严调整单 IP 连接数上限,确认业务正常峰值连接数
规则配置正确但容器网络不通网络策略默认拒绝规则覆盖了新服务检查网络策略的 podSelector 和新服务标签是否匹配

日常巡检我习惯三条命令加一份清单。三条命令分别是:查看当前监听端口、检查防火墙规则统计、查看登录日志。登录日志里如果有大量来自陌生来源的失败尝试,说明有人正在尝试入侵你的集群,别忽视这些信号。

巡检清单则包括:是否有新的未知端口在监听、防火墙规则是否有意外变更、是否有新账户创建、密钥文件权限是否被篡改、审计日志是否完整。这些检查听起来琐碎,但在集群被攻击时,它们往往是最先暴露异常的线索。

4.4 一场典型的集群应急响应实录

讲一个我处理过的应急响应案例。某天下午,监控系统发来告警,说某个业务节点的外网流量异常飙升。我登上去查看时,发现该节点正在向外大量发包,显然被植入了恶意程序。幸运的是,加固工作不久前刚好做完,节点上的 SSH 禁用了密码登录,审计日志也在正常记录。

我第一件事是把该节点的所有入站和出站流量全部切断,再通过管理网段登录查看进程和网络连接。查到一个可疑进程在持续外联,终端是通过某个漏洞打进来的。整个过程从发现到隔离不到十分钟,因为策略已经预置好了,不需要现想应对方案。后来复盘时,最大的教训是:如果当时没有做节点隔离的预案,凭现场手忙脚乱地找命令封禁流量,攻击者可能早就把数据传完了。

这也印证了我反复跟同行强调的观点:安全加固的意义不只是"挡住攻击",更重要的是"攻击发生时,你有多少反应时间"。一道好的安全屏障,让运维人员在事件中拿到的是主动权,而不是被动挨打。

我个人在实际操作中体会最深的一点是:集群安全是一个持续迭代的过程,不是做完一次加固就万事大吉。每次业务变更、每次架构调整、每次人员变动,都需要重新审视安全策略。把安全当成运维流程的一部分去维护,而不是当成一次性项目去交付,这个心态比任何具体技术都重要。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进