安全加固要回答的不是“这台机器装了多少安全工具”,而是:谁能进入、进入后能做什么、哪些行为留下证据,以及配置出错后怎样恢复。默认安装通常追求通用性,而生产主机只承担有限职责。把不需要的入口关闭,把必要的权限缩小,把变更变成可以验证的步骤,才是本课的主线。
1 Linux 安全加固要覆盖的控制面
设想 1 台供运维登录的 Linux 跳板机。它有 SSH 服务、几个管理账号、访问内部主机的网络路径,以及保存脚本和日志的文件系统。即使业务程序没有部署在这里,它仍然很重要:攻击者得到登录权限后,可能读取凭据、改写脚本、尝试连接其他主机。加固必须围绕实际职责展开,不能只检查是否安装了某个软件包。
可以把控制面分成入口、身份、执行、数据和证据。入口包括监听端口、允许通过的网络路径和远程管理接口;身份包括本地账号、组、SSH 密钥与 sudo 授权;执行包括服务进程的权限、可执行文件及启动配置;数据包括目录权限、挂载点、备份和敏感配置;证据包括认证记录、审计事件、时间同步及日志留存。这些控制面互相补位,却不能互相替代。防火墙允许 SSH 通过,并不说明 SSH 账号授权合理。

先写主机职责,再写允许项。例如,“只允许管理网进入 TCP 22;普通运维账号通过密钥登录;服务以专用账号运行;系统配置变更可追溯”。这比“提高安全等级”更容易执行。每个允许项都应有负责人和理由;发现未知监听时,先查所属进程和用途,再决定关闭。直接停止未知服务可能同时切断监控、备份或远程恢复通道。
加固还包含维护周期。安装时安全的主机,经过账号增加、临时调试、软件升级后,可能重新暴露入口。基线是持续比较的参照,不是验收时拍下的照片。应记录预期状态、检查方法、偏差处理方式和例外到期时间。对于不能立即移除的旧服务,可以先限制来源地址与账号权限,再安排替换,避免“等彻底改好再说”使风险长期无人负责。
所有动手步骤都应先在测试主机练习。远程修改 SSH 或网络规则前,准备控制台访问与回滚办法,并保留当前会话。当前会话不断开,只能说明旧连接仍在,不能证明新连接能够成功建立。另开会话完成真实登录,才是入口变更的重要验收条件。
2 权限、能力与强制访问控制
Linux 的常规文件访问先从身份和权限理解。进程带着用户与组身份访问路径,目录上的执行权限影响能否穿越,文件上的读写权限影响内容操作。id 查看当前身份,ls -ld /srv/ops 查看目录权限,namei -l /srv/ops/run.sh 帮助逐层检查路径。只看脚本自身的权限不够:父目录若允许其他账号写入,脚本仍可能被替换,之后由高权限任务执行。
服务应尽量使用专用账号,避免让互不相关的进程共用身份。共享账号会把文件访问范围混在一起,也使日志难以区分责任人。管理员通过 sudo 执行必要任务时,应使用个人账号并保留调用记录。用 sudo -l 查看本人被授予的命令范围,用 visudo 编辑 sudoers 配置,利用它的语法检查减少配置损坏。命令白名单也需要审查命令本身是否能够启动 shell、加载任意配置或写入系统文件,不能只看名称是否“像运维命令”。
root 权限很宽,Linux capabilities 则把部分特权拆成较小的能力。例如某些程序只需要绑定低端口,不应因此获得完整 root 身份。getcap /path/to/program 可以查看文件能力;发现不熟悉的能力时,应核对软件用途与来源。能力仍然是特权:允许某类操作不代表只能操作某个业务对象。不要把“使用了 capability”直接当成安全结论,更不要随意给解释器或通用工具增加能力。
常规权限之外,强制访问控制可进一步限制进程能访问哪些资源。SELinux 常用安全上下文与策略约束访问,AppArmor 常用程序配置文件约束行为,具体可用机制取决于发行版。入门时先理解关系:普通权限通过后,强制访问控制仍可能拒绝;普通权限已经拒绝,修改策略也不会自动补齐文件权限。排查时分别检查身份、路径权限和策略证据,避免在不同层之间盲目试改。
在使用 SELinux 的主机上,getenforce 查看模式,ls -Z /srv/app 查看标签。复制文件、从备份恢复或把服务数据放到新目录,都可能让标签与预期不符。应该先确认程序确实需要该路径,再通过发行版提供的持久标签配置与 restorecon 恢复预期状态。容器、用户命名空间等进一步隔离机制有自己的边界,本课不展开;当前先把账号、文件权限、能力和强制策略这几层关系讲清楚。
3 审计、完整性与漏洞面收敛
权限控制用于阻止不被允许的操作,审计用于留下关键行为的证据。二者不能互相代替:记录了越权尝试不等于阻止了它,拒绝了访问也不保证事后能解释原因。首先确认日志确实产生、时间可对齐、保存周期足够。timedatectl status 可查看本机时间与同步状态;集中日志还需要考虑传输失败、本地缓冲和磁盘容量,不能把“已经配置转发”当成日志一定送达。
在使用 systemd 的系统中,journalctl -u sshd --since '1 hour ago' 可查看指定服务近期日志;某些发行版的服务名是 ssh。认证记录也可能进入独立文件,路径和轮转策略应按实际系统确认。日志可能包含用户名、地址或命令参数,因此读取权限和集中存储权限也要受控。不要为了方便排障,把日志目录开放给所有用户,或把密钥、令牌直接打印进脚本输出。
Linux Audit 可以记录配置变更、权限调整等选定事件。auditctl -s 查看审计状态,auditctl -l 查看当前规则。规则应从少量关键对象开始,例如身份配置、授权配置和重要服务配置;“记录所有文件读写”往往导致大量噪声、存储压力与查找困难。审计规则本身也需要持久化配置、变更审查和效果验证。检查丢失事件计数与采集链路,才能知道证据是否完整到足以支撑判断。
完整性检查关注文件是否偏离预期。包管理器可帮助校验已安装软件的文件,例如 RPM 系统使用 rpm -V,支持相应功能的 Debian 系统可使用 dpkg -V。输出中的差异可能来自合法配置变更,应结合基线解释。对自行部署的脚本,可以保存受保护的散列清单并复核,但清单若与脚本一起被攻击者修改,本地比较就失去了可信参照。完整性异常是调查线索,不是单独证明入侵的结论。
漏洞面收敛包括卸载不需要的软件、禁用无用途的服务,以及维护仍然需要的软件。停止服务、禁止开机启动、卸载软件包是不同操作;某些服务还会被 socket 或依赖关系激活。补丁处理应核对发行版公告、安装状态和运行状态,不能只凭版本字符串判断,因为维护方可能回补修复。更新内核或长期运行的进程后,还需安排重启或服务重启,确认实际运行实例已使用修复版本。

4 动手:列出一台主机的暴露面清单
本练习先做只读盘点,不修改系统。选择有授权的测试主机,记录采集时间、系统用途和操作者。命令输出可能包含内部地址与账号,保存结果时使用受控目录。若缺少权限而看不到进程信息,在清单里注明“未确认”,不要把空白解释为不存在。不同发行版的服务名、包管理器和日志布局不同,命令输出需要结合环境判断。
先确认系统与身份:cat /etc/os-release 查看发行版信息,uname -r 查看运行内核,id 查看当前身份,getent passwd 查看通过当前名称服务能查询到的账号。账号清单不能只靠登录 shell 判断风险,还要检查服务用途、授权密钥与 sudo 范围。记录管理员账号时,应核对实际组成员和授权配置,而不是假设某个固定组在所有系统中都具有相同权限。
再看网络:ip -br addr 显示接口地址,ip route 显示路由,ss -lntup 列出 TCP、UDP 监听及可见的进程信息。需要时通过受控 sudo 补齐进程信息。监听在 127.0.0.1 与监听在 0.0.0.0 的暴露范围不同,IPv6 的 :: 也要检查;实际可达性还受到主机防火墙、上游网络策略和路由影响。查看地址不是连通性验证,外部探测必须在明确授权范围内进行。
服务与进程可以结合 systemctl --type=service --state=running、systemctl list-sockets 和 ps -eo user,pid,ppid,args 查看。重点问 3 件事:谁启动它、以谁的身份运行、为什么必须存在。进程参数可能包含敏感值,不要把完整输出随意贴进工单。对每个监听,关联到 PID、服务单元、配置位置和负责人;若进程已退出或 PID 已复用,需要重新确认,避免用过时截图解释当前状态。
文件系统可用 findmnt 和 df -h 查看挂载布局与容量,再对关键路径执行 ls -ld、namei -l。关注服务数据是否与系统目录合理分离、日志空间是否有容量保障、脚本目录是否被非维护者写入。noexec、nodev、nosuid 等挂载选项可限制部分行为,但需要验证应用兼容性,也不能当作完整隔离。例如 noexec 不能保证脚本内容无法被已有解释器读取并执行。
把证据整理成清单,而不是堆叠终端截图:
| 对象 | 当前证据 | 预期状态 | 偏差与处理 |
|---|---|---|---|
| SSH 入口 | 监听地址、有效配置、来源限制 | 仅管理路径可达 | 确认防火墙实际规则与新登录 |
| 运维账号 | 身份、组、sudo 范围 | 个人账号、按需授权 | 清理无负责人授权 |
| 服务脚本 | 路径权限、属主、启动引用 | 仅维护者可修改 | 修复可替换的父目录 |
| 审计链路 | 状态、规则、近期事件 | 关键事件可查询 | 补齐持久规则与留存 |
清单完成后,先选 1 个可回滚的小偏差,在测试主机执行修复并验证功能。例如限制某个脚本目录的写权限后,既要确认普通用户无法改写,也要确认部署账号仍能按流程更新。盘点的价值是把未知变成待确认事项,把偏差变成有证据的行动,不是让所有项目立即显示“通过”。

5 加固强度与运维成本的取舍
加固会改变操作方式。缩短凭据有效期会增加轮换工作,收紧网络来源会影响临时排障,扩大审计范围会增加日志容量与分析负担。正确的取舍不是安全越严越好,也不是只要影响工作就取消控制,而是依据主机职责、暴露范围和故障后果选择约束,并把维护成本写进方案。面向公网的管理入口和隔离测试环境,不能照搬同一份允许列表。
可以按影响分批推进:先清理无负责人账号、无用途监听和明显过宽权限,再逐步收紧服务身份、策略与审计。每批变更都定义成功条件和回滚触发条件。例如限制 SSH 来源后,成功条件包含新建管理会话、自动化任务可用和拒绝事件符合预期;若授权管理路径被阻断,应按事先准备的控制台流程恢复。不要在连接即将中断时才寻找规则备份。
交互中的分值用于比较控制组合,不是计算真实入侵概率。真实风险还受到漏洞、凭据质量、人员流程和网络环境影响。通过滑块可以看到:把所有控制推到最严格时,运维负担可能快速增加,而收益取决于是否保护了真正重要的入口。优先处理能解释清楚的风险,比追求抽象总分更可靠。
例外需要明确边界。某个旧程序暂时必须使用更宽权限时,应记录业务原因、受影响资产、补偿控制、负责人和到期日期。补偿控制可能是限制来源、隔离运行或加强关键行为审计,但不能声称已经消除了原风险。到期复查既要检查替代方案是否完成,也要检查例外是否被复制到其他主机。没有期限的临时配置往往会变成下一轮基线中的隐患。
还要区分检测与强制。新规则可以先在测试环境或受支持的观察模式中收集证据,明确正常行为后再执行拒绝。观察期需要结束条件,否则风险只被记录而没有收敛。策略上线后持续监测失败率、告警量和工单量,寻找不必要的阻断与遗漏;不能为了让仪表盘好看而直接丢弃失败事件。
6 常见坑:关掉 SELinux 换短期方便
服务迁移到 /srv/report 后读不到文件,普通权限看起来也正确,于是有人关闭 SELinux,服务恢复。这个现象只能说明强制策略可能参与了拒绝,不能说明关闭它是合理修复。全局关闭会同时放宽其他受策略保护的进程,而原问题可能只是新路径标签不正确,或应用访问了本不该访问的位置。
排查应先复现失败并记录时间、服务名、目标路径和错误信息。检查 systemctl status 与服务日志,再核对进程身份、父目录权限和标签。在启用 Audit 且有权限的系统上,可用 ausearch -m AVC,USER_AVC -ts recent 查找近期拒绝事件。日志中的进程、对象和请求动作需要与刚才的失败对应;看到 1 条 AVC 并不能断定所有故障都来自 SELinux。

如果新目录应当使用某个既有服务标签,先查本机策略文档或已知正常目录,确认类型适合该用途,再使用 semanage fcontext 建立持久路径规则,并由 restorecon 应用。不要从网上复制未知类型,也不要只用临时改标签的方法应付迁移,否则重新标记或重建主机时可能丢失。若策略提供与业务语义相符的布尔开关,也要先理解它放宽了哪些操作,再决定是否启用。
另一个坑是把拒绝日志直接转换成允许策略。日志描述的是曾经尝试的访问,其中可能包含应用错误、越权动作或攻击行为。自动生成的规则只能作为审查材料,不能自动成为需求。应该先问“程序为什么需要这个访问”,能通过修改路径或配置解决的,就不扩大策略。确实需要自定义规则时,应进入专门评审,本课不展开策略语言。
修复后验证需要同时覆盖允许与拒绝:服务能访问所需数据,仍不能读取无关敏感路径,SELinux 保持预期模式,重启后配置仍有效。setenforce 0 会让整个系统进入 permissive 模式,在故障定位中即使使用,也必须受控、限时并记录恢复;不能把它加入启动脚本当作永久解决办法。对不使用 SELinux 的发行版,应检查其实际采用的控制机制,不能把“没有这个命令”解释为主机没有访问约束。
7 案例:未加固跳板机成为突破口
某团队把 1 台通用 Linux 主机作为跳板机,长期保留离职人员账号,SSH 对过大的网络范围开放。运维脚本放在共享可写目录,自动任务又以 root 身份调用这些脚本。团队认为“没有业务数据”就风险较低,没有持续核对账号、脚本权限与内部访问范围。这些条件共同形成了从登录到高权限执行的路径。
攻击者获得其中 1 个仍有效的凭据后成功登录。普通账号本来不应具有管理员权限,但它能够修改共享目录中的脚本;定时任务随后执行了被替换的内容。跳板机又能访问多台内部主机,且目录里遗留了用途不明的凭据文件。这里的关键不是某个复杂内核漏洞,而是入口、文件写权限、任务执行身份和网络范围彼此叠加。
复盘必须区分已证实事实与推测。认证日志可以支持某个账号从某个来源建立会话,任务日志可支持某个时间发生执行,文件差异可证明当前内容偏离可信基线;但若缺少当时的写入审计,就不能只凭文件时间断言具体是谁修改。时间戳还可能被改变。证据不足应标注,而不是补成看似完整的故事。调查还需要遵守现场保全与事件响应流程。
处置时先按授权流程限制受影响主机的网络能力、保留必要证据,再从可信环境撤销相关凭据并检查关联资产。单纯删除可疑脚本不能恢复对主机的信任;若高权限环境已被控制,通常需要按响应方案从可信镜像重建。恢复登录服务前,应补齐账号清理、脚本权限、自动任务身份和访问范围控制,避免重建后复制原有缺陷。
把这条失败路径逐段切开,就能得到有针对性的基线:离职账号及时失效,个人凭据不共享,管理入口限制来源,自动任务不执行低权限用户可改写的内容,内部访问按职责授权,关键配置变更留下日志。任何 1 个措施都不能保证绝对安全,但每个措施都能阻断或暴露某个明确环节。这个案例也提醒我们:没有直接存放业务数据的运维主机,仍然可能承载高价值的信任关系。
8 把加固基线写进主机镜像方案
镜像适合固化软件包、服务默认状态、目录权限和通用策略,让新主机从可解释的状态开始。基线应拆成通用部分与角色部分:通用部分规定日志、时间同步、账号原则和更新来源;跳板机角色规定管理入口与运维工具;应用角色规定服务账号、数据目录和所需端口。把所有角色都塞进同一镜像,会让每台主机继承大量无关服务和权限。
不要把私钥、真实口令或所有实例共用的主机身份烘焙进镜像。实例需要的身份材料应在受控初始化流程中生成或分发,并验证权限、轮换和撤销方式。清理构建缓存与临时配置时,也要检查命令历史、构建日志和测试文件是否留下敏感值。镜像版本必须能关联构建来源、基线版本和补丁状态,出现异常时才能知道哪些实例需要处理。
基线规则应能转换成检查。例如,“禁止普通用户写系统任务调用的脚本”需要列出脚本路径、父目录与属主要求;“关闭无用服务”需要列出该角色的允许服务以及 socket 激活情况。仅记录 systemctl disable 的执行成功不够,还要验证当前运行状态和重启后的状态。网络规则同样要验证允许连接与应被拒绝的连接,且测试来源必须符合预期路径。
镜像发布前执行小规模启动验收:初始化成功、管理通道可用、关键服务以预期身份运行、审计事件能送达、强制策略保持预期模式。再用代表性工作负载检查功能,逐步扩大部署。回滚不仅是选择旧镜像,还要考虑数据格式、实例身份和配置兼容性。若旧镜像包含已知风险,回滚只能作为限时恢复措施,并配套隔离或访问限制。
部署之后继续检测漂移。临时放开的端口、手工增加的 sudo 授权、错误恢复的标签,都可能使实际状态偏离镜像基线。发现漂移后先确定是否属于批准变更,再选择恢复配置或更新基线;直接覆盖可能中断合法业务,直接接受则会把错误永久化。镜像解决起点一致性,配置管理与巡检维持运行中的一致性,二者共同承担加固的生命周期。
9 从安全加固走向 SSD 内部原理(H28)
主机权限控制决定谁能通过操作系统接口访问数据,却不能替代对存储介质的理解。管理员删除 1 个敏感文件后,路径不再可见,并不意味着数据已在介质所有位置消失。备份、快照、日志副本和仍打开文件的进程,都可能保留相关内容。加固清单中的“数据清理”因此必须写清对象和验证边界,不能只写执行了 rm。
在 Linux 中,可以用 lsblk -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINTS 观察块设备与挂载关系,用 findmnt 把业务路径关联到文件系统。它们帮助回答“这份数据由哪个挂载点承载”,却不能直接告诉我们 SSD 内部如何安排实际存储位置。虚拟机里看到的设备还可能经过虚拟化与存储服务,不能仅凭设备名判断底层介质。
SSD 的逻辑地址与实际存储位置之间存在内部管理,删除、覆盖与介质处置的关系需要专门学习。下一课 H28 将建立这些基础直觉,本课先保留结论边界:不要用反复覆盖某个文件就声称 SSD 已被彻底清除,也不要在生产设备上随意尝试擦除或维护命令。介质退役应遵循适用于设备、加密状态和组织要求的验证流程。
这也连接到加密密钥管理。磁盘加密可以缓解介质遗失带来的部分风险,但已解锁的运行系统仍依赖账号、进程权限和策略保护。密钥遗失会影响恢复,密钥泄露会削弱保密性,因此密钥备份、访问授权和撤销同样属于方案。学习存储内部原理之后,我们才能更准确地区分运行中的访问控制、文件删除、空间回收与设备退役,把不同问题交给合适的控制措施。
放进方案里
为跳板机编写方案时,先写清主机职责、管理入口和负责人:仅允许批准的管理路径访问 SSH,运维使用个人账号与独立凭据,管理员操作通过受控 sudo 留痕。列出必须运行的服务、监听地址、服务身份和内部访问目标,把其余项目作为待关闭或待确认项。每个允许项都附带业务理由,避免后续复制镜像时扩大权限。
镜像部分记录发行版、补丁与基线版本,固化服务默认状态、关键目录权限、强制访问控制和日志配置。实例身份与密钥由初始化流程处理,不写入通用镜像。对脚本及自动任务逐项确认执行身份、文件属主与父目录权限,保证低权限账号不能改写随后被高权限执行的内容。关键配置的可信参照放在受控位置。
验收部分同时写功能与安全结果:批准来源能新建登录,非批准路径不能进入;服务能访问必要数据,不能越界读取敏感路径;关键变更产生可查询事件,日志时间能对齐;重启后规则、标签和服务状态仍符合预期。用实际证据记录结论,对权限不足或范围外对象标注未确认,不能用空输出代替通过。
变更部分安排测试、分批上线、控制台恢复与回滚触发条件,避免入口收紧后失去维护能力。例外记录原因、补偿控制、负责人和到期日期。运行阶段定期检查账号、监听、补丁、授权与配置漂移,发现偏差后判断是恢复配置还是修订基线。发生疑似高权限失陷时,按响应流程保全证据、撤销凭据并评估可信重建。
最后把存储边界补进资产退出流程:文件删除不作为介质清除证明,备份与快照同步纳入范围,设备退役采用适用且可验证的方法。方案应明确哪些结论由主机检查支持,哪些仍依赖网络、身份或存储团队提供证据,让每项控制都有执行者、检查点和失败后的处理路径。
10 小结:下一步 SSD 内部原理(H28)
Linux 安全加固从主机职责出发,持续收敛入口、身份、执行权限和软件暴露面,并用审计与完整性检查保留证据。常规权限、capabilities 与强制访问控制各有边界;服务失败时应沿证据定位,避免用全局关闭策略掩盖局部配置问题。镜像提供一致起点,运行中的漂移检查维持基线。
自测时尝试解释 3 个问题:为什么只看监听端口不足以判断外部可达?为什么普通用户可写的脚本被 root 任务执行很危险?为什么删除文件不能直接证明 SSD 上的数据已经消失?下一步进入 SSD 内部原理(H28),把文件系统看到的逻辑操作与存储介质的行为联系起来。