1. 项目概述:为什么我们需要一个“等保三级加固脚本”?
在运维和安全的圈子里,但凡涉及到政府、金融、能源这类对安全有硬性要求的行业,“等保三级”这四个字就是绕不开的坎。它不是一句口号,而是一套由国家制定的、非常具体的安全基线要求。很多朋友,尤其是刚接触这块的运维工程师,一听到“等保测评”就头疼,感觉要配置的东西又多又杂,像PAM、Auditd这些名词听起来就让人望而生畏,更别提去一条条手动配置了,既怕漏项,又怕配错导致业务出问题。
这就是我写这个脚本,以及这篇深度解析文章的初衷。我见过太多团队在等保合规上耗费大量人力,重复劳动,甚至因为配置不一致导致测评不通过。一个成熟的、经过实战检验的加固脚本,其价值远不止是“一键执行”。它更是一个标准化的安全配置知识库,把散落在各处的安全最佳实践、测评要求、以及我们踩过的无数个坑,都固化成了可重复、可审计的代码。今天,我们不只讲脚本怎么用,更要拆开脚本的每一个模块,把PAM、Auditd、SSH加固、文件权限这些“黑盒子”一个个打开,讲清楚它们背后的安全逻辑、等保要求的具体映射,以及那些手册里不会写的“避坑点”。无论你是想快速通过测评,还是想深入理解Linux主机安全,这篇文章都能给你一份清晰的“作战地图”。
2. 脚本整体架构与设计哲学
在动手写任何一行代码之前,明确设计思路至关重要。一个鲁棒的等保加固脚本,绝不是命令的简单堆砌,它需要平衡安全性、可用性、可维护性三大核心。
2.1 核心设计原则
我的脚本设计遵循以下几个核心原则:
- 幂等性(Idempotent):这是最重要的原则。脚本必须支持反复、安全地执行。无论系统当前状态如何,执行一次和执行N次的结果应该是一致的,不会因为重复执行导致配置错误或服务异常。这意味着所有操作都需要先做状态检查。
- 模块化与可配置:将不同的安全领域(如身份鉴别、访问控制、安全审计)拆分为独立的模块或函数。每个模块负责一类配置,并且关键参数(如密码策略复杂度、失败锁定次数)应该设计成可配置的变量,方便不同环境调整。
- 交互式与无人值守:提供两种模式。交互模式会提示用户确认每一项重大修改(如修改SSH端口、禁用root远程登录),并给出明确说明。无人值守模式则允许通过传入参数自动执行,适用于自动化部署流水线。
- 预检查与回滚(尽可能):在执行任何修改前,对系统状态进行检查和备份。对于关键配置文件(如
/etc/ssh/sshd_config,/etc/pam.d/system-auth),脚本必须先行备份。对于无法完美回滚的操作(如内核参数调整),则提供明确的警告和手动回滚指引。 - 日志与审计追踪:脚本自身的行为必须被完整记录。谁、在什么时候、执行了脚本、修改了哪些文件、结果如何,这些信息需要记录到独立的日志文件中,这本身也是满足等保审计要求的一部分。
2.2 脚本主要模块划分
基于等保2.0三级对Linux主机的要求,我将脚本划分为以下核心模块,这也是本文后续详细拆解的顺序:
| 模块名称 | 对应等保要求项 | 核心组件/技术 | 输出/影响 |
|---|---|---|---|
| 身份鉴别加固模块 | 身份鉴别 (a, b, c, d) | PAM (pam_cracklib/pam_pwquality),/etc/login.defs, SSH | 密码策略、登录失败处理、SSH协议强化 |
| 访问控制加固模块 | 访问控制 (a, b, c, d, e, f) | 文件权限 (chmod/chown), 用户账户管理,sudoers, SELinux/AppArmor | 最小权限、默认账户处理、权限分离 |
| 安全审计加固模块 | 安全审计 (a, b, c, d) | Auditd (auditd服务),rsyslog/systemd-journald | 关键行为审计、日志集中与保护 |
| 入侵防范加固模块 | 入侵防范 (a, b, c, e) | 服务管理 (systemd), 防火墙 (firewalld/iptables), 内核参数 (sysctl), 漏洞管理 | 最小化服务、端口限制、系统加固 |
| 其他与基线核查模块 | 恶意代码防范、剩余信息保护等 | 基线检查脚本、合规性报告生成 | 提供系统合规状态快照 |
这个架构确保了每一项等保要求都有对应的技术实现点,并且模块之间相对独立,便于调试和维护。
3. 身份鉴别模块深度解析:PAM是核心引擎
身份鉴别是安全的第一道大门,等保三级对此有细致要求。而Linux系统上,负责这道大门验证规则的“总控制器”,就是PAM(Pluggable Authentication Modules,可插拔认证模块)。
3.1 PAM工作机制与配置文件
PAM不是一个命令,而是一套框架。它的精髓在于“可插拔”——认证过程像流水线,每个环节(检查密码、限制登录次数、设置环境等)都由独立的、可配置的模块(.so文件)完成。这些模块的调用规则,定义在/etc/pam.d/目录下的各个配置文件中,例如system-auth、password-auth、sshd等。
一个典型的PAM配置行包含四个字段:
module_type control_flag module_path [arguments]例如,在system-auth中控制密码复杂度的行:
password requisite pam_pwquality.so try_first_pass retry=3 minlen=12 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=-1 enforce_for_rootpassword: 模块类型,表示这条规则用于“修改密码”这个管理动作。requisite: 控制标志,表示此模块必须成功通过。如果失败,立即返回失败,不再执行后续同类型模块。pam_pwquality.so: 模块路径,这就是实现密码复杂度检查的模块(在CentOS 7+上,它替代了旧的pam_cracklib)。retry=3 minlen=12 ...: 模块参数,定义了具体策略。
避坑点1:理解
system-auth和password-auth的区别这是最容易混淆的地方。通常,system-auth是“主”配置文件,被其他服务(如sshd、login)通过@include指令包含。而password-auth常用于非本地登录(如SSH)。在编写脚本时,我们必须同时修改这两个文件,或者修改一个,然后让另一个软链接到它,以确保策略全局生效。我的脚本通常采用备份后统一替换的策略。
3.2 密码复杂度策略实现
等保要求密码具备复杂度并定期更换。这主要涉及两个文件:PAM配置和/etc/login.defs。
在PAM中 (pam_pwquality.so),我们关注这些关键参数:
minlen=12: 密码最小长度。等保三级建议至少8位,但从安全实践出发,12位是更稳妥的基线。dcredit=-1: 要求至少1个数字。-1表示“至少1个”,-2表示“至少2个”,以此类推。ucredit=-1: 要求至少1个大写字母。lcredit=-1: 要求至少1个小写字母。ocredit=-1: 要求至少1个特殊字符(如!@#$%)。retry=3: 设置密码时,允许重试的次数。enforce_for_root:至关重要!强制root用户也必须遵守此策略。很多默认配置缺少这一项,导致root密码可以设为简单密码,成为巨大隐患。
在/etc/login.defs中,我们设置:
PASS_MAX_DAYS 90: 密码最长使用天数90天,强制定期更换。PASS_MIN_DAYS 7: 密码最短使用天数7天,防止用户频繁改回旧密码。PASS_WARN_AGE 14: 密码过期前14天开始警告。
脚本操作时,不能直接覆盖login.defs,因为里面还有其他配置。正确做法是用sed命令精准修改这几行。
3.3 登录失败处理与账户锁定
等保要求“限制非法登录次数”。这通过PAM的pam_tally2.so(或较新系统的pam_faillock.so)模块实现。
配置示例(在system-auth的auth部分):
auth required pam_tally2.so onerr=fail deny=5 unlock_time=900 even_deny_root root_unlock_time=1800deny=5: 连续失败5次后锁定账户。unlock_time=900: 普通账户锁定900秒(15分钟)后自动解锁。even_deny_root: root账户也受此规则限制。root_unlock_time=1800: root账户锁定1800秒(30分钟)。通常root的锁定时间更长。
避坑点2:pam_tally2与pam_faillock的选择与状态重置
- CentOS 7/RHEL 7 常用
pam_tally2,而 CentOS 8/RHEL 8 及更新版本转向pam_faillock。脚本需要先检测系统版本再决定配置哪个模块。 - 账户被锁定后,管理员可以使用
pam_tally2 --user <username> --reset命令手动解锁。务必在脚本注释或日志中提醒这一点,否则一线支持人员可能不知道如何解救被锁定的账户。 - 这个锁定是基于**终端(tty)**的。SSH登录和本地控制台登录的失败计数是分开的。这符合安全逻辑,但需要向团队解释清楚。
3.4 SSH服务深度加固
SSH是远程管理的命脉,也是攻击的主要入口。等保要求防止鉴别信息被窃听(使用SSH协议本身已满足),但我们还需要进一步收紧。
脚本中SSH加固 (/etc/ssh/sshd_config) 的关键配置包括:
- 禁止Root直接登录:
PermitRootLogin no。这是铁律。所有管理操作应通过普通用户登录后sudo提权。 - 修改默认端口:
Port 2222。将端口从22改为一个非公认端口,能减少99%的自动化扫描和撞库攻击。但这也是最大的坑!脚本必须:- 在修改前检查新端口是否被占用。
- 修改后,立即且仅重启SSH服务(
systemctl restart sshd),而不是重启机器。 - 在重启前,务必在当前已建立的SSH会话中,用
ss -tlnp | grep 2222验证新端口是否已监听。并开启另一个新终端尝试用新端口连接,确认成功后再退出当前旧会话。否则你可能把自己关在门外。
- 禁用密码认证,启用密钥认证:
PasswordAuthentication no和PubkeyAuthentication yes。这是比复杂密码更安全的方案。但脚本实现必须极其谨慎:- 必须先检查登录用户的家目录下是否存在
~/.ssh/authorized_keys文件且包含有效的公钥。 - 可以设计一个交互式选项,让用户确认已部署公钥,或者由脚本自动从指定位置导入公钥。
- 对于批量运维,密钥管理本身又是一个大课题,脚本可以留出接口。
- 必须先检查登录用户的家目录下是否存在
- 其他重要参数:
Protocol 2: 只使用SSH协议第2版。MaxAuthTries 3: 每次连接最大认证尝试次数,配合PAM的失败锁定。ClientAliveInterval 300和ClientAliveCountMax 2: 设置300秒无活动则发送心跳包,最多发送2次,总计10分钟后断开空闲连接,满足“连接超时自动退出”的要求。AllowUsers user1 user2@192.168.1.0/24: 限制允许登录的用户和来源IP,实现网络层访问控制。
4. 访问控制模块:贯彻最小权限原则
访问控制的核心是“谁,能对什么资源,进行何种操作”。等保要求删除默认账户、权限分离、权限最小化。
4.1 账户管理与默认账户处理
脚本需要自动化处理以下任务:
- 识别并锁定/删除无用账户:检查
/etc/passwd,识别像games、ftp、nobody(如果业务不用)等系统账户。通常我们选择锁定而非删除,使用usermod -L <username>或passwd -l <username>。对于halt、shutdown这类可能带来风险的账户,可以考虑删除 (userdel -r),但需绝对确认与业务无关。 - 检查UID为0的非Root账户:任何UID为0的用户都拥有root权限。使用
awk -F: '($3 == 0) { print $1 }' /etc/passwd命令检查,除了root,不应该有别的结果。这是一个高危项。 - 设置正确的默认umask:在
/etc/profile或/etc/bashrc中设置umask 027。这样普通用户创建的文件默认权限是750(目录)和640(文件),组外用户无权限。
4.2 文件系统权限扫描与修复
等保要求配置文件权限不大于644,可执行文件不大于755。脚本需要实现一个安全基线扫描功能。
# 示例:查找权限过大的配置文件(全局可写是严重风险) find /etc -type f -perm /o=w -exec ls -la {} \; # 查找SUID/SGID文件(这些文件执行时会以文件所有者权限运行,需严格审查) find / -type f \( -perm -4000 -o -perm -2000 \) -exec ls -la {} \; 2>/dev/null脚本不应盲目修改所有找到的文件,因为某些应用(如Oracle)可能需要特定的权限。正确的做法是:
- 生成一份问题文件报告。
- 提供一个“修复模式”,根据一个预定义的安全文件权限白名单(例如,已知的
/etc/shadow必须是600,/etc/passwd是644)进行自动修复。 - 对于白名单之外的文件,提示管理员手动审查。
4.3 Sudo权限精细化配置
/etc/sudoers文件是权限分离的关键。等保要求实现最小权限。脚本可以做的不是直接修改sudoers(因为语法严格,易出错),而是推荐最佳实践并在sudoers.d/目录下创建清晰的规则片段。
避坑点3:sudoers语法与visudo永远不要直接用vi编辑/etc/sudoers!必须使用visudo命令,它会在保存时进行语法检查,防止配置错误导致所有sudo权限失效(那将是一场灾难)。脚本如果非要自动化修改,也应该调用visudo -c -f <new_file>来检查语法。
一个良好的sudo规则示例:
# 在 /etc/sudoers.d/ 下创建文件,例如 `10-admins` # 用户组 `sysadmins` 可以在所有主机上运行所有命令,但需要密码 %sysadmins ALL=(ALL) ALL # 用户 `appuser` 可以以 `www-data` 用户身份重启nginx,且无需密码(用于自动化脚本) appuser ALL=(www-data) NOPASSWD: /usr/bin/systemctl restart nginx脚本可以提供一个模板,引导管理员根据实际角色创建这样的精细化规则。
4.4 SELinux:强制访问控制的考量
等保要求“访问控制粒度应达到主体为用户级或进程级,客体为文件级”,并提到了强制访问控制(MAC)。SELinux是Linux上最主要的MAC实现。
然而,在大多数生产环境中,SELinux常常被设置为Permissive或Disabled。原因很简单:它对应用程序行为有极其严格的限制,很多非标准部署的应用会因此报错,运维人员往往缺乏深度调试SELinux策略的能力。
脚本中的策略:
- 检查状态:
getenforce和/etc/selinux/config。 - 建议:如果业务应用明确支持SELinux,则将其设置为
Enforcing模式,并安装必要的策略模块(如setroubleshoot,policycoreutils-python用于审计日志分析)。这是合规的加分项。 - 务实操作:如果环境复杂或团队不熟悉,可以将其设置为
Permissive模式。在此模式下,SELinux会记录违规行为但不阻止,既能收集审计日志满足部分要求,又不会影响业务。脚本可以提供切换模式的选项,并给出明确的风险说明。
5. 安全审计模块:让Auditd成为你的“黑匣子”
等保三级对审计的要求非常严格:要覆盖每个用户,记录关键事件,并保护审计记录。auditd是Linux内核自带的审计子系统守护进程,功能强大,是满足这一要求的核心工具。
5.1 Auditd基础与规则配置
auditd的配置分为两部分:守护进程配置 (/etc/audit/auditd.conf) 和审计规则 (/etc/audit/rules.d/audit.rules或auditctl命令)。
首先,确保服务启用并配置日志: 在auditd.conf中,关键参数是max_log_file(单个日志文件大小,如50MB)和num_logs(保留的日志文件数量,如10)。这意味着审计日志最多占用50 * 10 = 500MB空间。space_left和space_left_action参数用于在磁盘空间不足时触发告警或动作,脚本应合理设置这些值。
核心在于审计规则。规则定义了“审计什么”。规则语法主要分两类:
- 文件/目录监视:
-w /etc/passwd -p wa -k identity-w: 监视路径。-p: 触发权限,r读,w写,x执行,a属性更改。-k: 给事件打上一个“关键词”标签,便于在海量日志中搜索。identity表示这是与身份文件相关的事件。
- 系统调用监视:
-a always,exit -F arch=b64 -S openat -S open -F success=1 -F dir=/etc -F perm=wa -k config_change- 这条规则更复杂,它监控所有在
/etc目录下,成功 (success=1) 进行写或属性更改 (perm=wa) 的open和openat系统调用。-F arch=b64指定64位系统。
- 这条规则更复杂,它监控所有在
5.2 等保关键审计项实现
脚本需要添加的规则,必须覆盖等保要求的“重要的用户行为和重要安全事件”:
- 用户身份相关:
-w /etc/passwd -p wa -k identity -w /etc/group -p wa -k identity -w /etc/shadow -p wa -k identity -w /etc/sudoers -p wa -k privilege_escalation -w /etc/sudoers.d/ -p wa -k privilege_escalation - 系统配置与网络相关:
-w /etc/ssh/sshd_config -p wa -k ssh_config -w /etc/hosts -p wa -k network_mod -w /etc/hosts.allow -p wa -k network_mod -w /etc/hosts.deny -p wa -k network_mod -w /etc/firewalld/ -p wa -k firewall_mod -w /etc/audit/ -p wa -k audit_config # 审计配置自身也要被审计 - 特权命令执行:监控
su、sudo、passwd等命令的使用。-a always,exit -F path=/usr/bin/su -F perm=x -k privileged_cmd -a always,exit -F path=/usr/bin/sudo -F perm=x -k privileged_cmd -a always,exit -F path=/usr/bin/passwd -F perm=x -k identity_cmd - 文件删除与时间篡改:
-a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F success=1 -k delete -a always,exit -F arch=b64 -S adjtimex -S settimeofday -S clock_settime -k time_change
避坑点4:审计规则性能与日志量不加选择地添加大量规则,尤其是监控频繁的系统调用(如open、read),会显著影响系统性能并产生海量日志,迅速撑满磁盘。脚本中的规则应该是精炼的、关键的。优先使用-w监视特定关键文件,而非宽泛的系统调用。部署后,必须监控/var/log/audit/audit.log的增长速度和系统负载。
5.3 审计日志的查询、分析与保护
配置了规则,还要会用。常用命令:
ausearch -k identity: 搜索所有带identity标签的审计事件。aureport -l: 生成可登录事件的报告。auditctl -l: 列出当前活动的审计规则。
日志保护:等保要求防止审计记录被未预期删除或覆盖。
- 文件权限:确保
/var/log/audit/目录权限为700,日志文件权限为600,所有者是root。 - 日志轮转与归档:
auditd自身会根据max_log_file和num_logs配置进行轮转。但脚本还应配置logrotate或通过其他方式,将旧的audit.log.*文件压缩并归档到其他安全位置(如集中日志服务器),保留至少6个月。 - 防止服务被中断:普通用户无法停止
auditd服务 (systemctl stop auditd需要root权限)。这本身已提供一定保护。更严格的话,可以通过chattr +i /usr/sbin/auditd给审计守护进程二进制文件加上不可更改属性(需极端谨慎)。
6. 入侵防范与系统加固模块
这个模块范围很广,目标是减少攻击面,提升系统自身抵抗力。
6.1 服务与端口最小化
脚本应自动化执行“关停并转”:
- 列出所有启用服务:
systemctl list-unit-files --state=enabled。 - 定义“白名单”:根据服务器角色(Web、DB、中间件),定义一个基础服务白名单(如
sshd,auditd,rsyslog,crond,network,firewalld)。 - 禁用非必要服务:遍历启用服务列表,不在白名单内的,使用
systemctl disable --now <service_name>禁用并停止。对于不熟悉的服务,务必先查清用途!脚本可以设置为交互式确认,或生成待处理列表由管理员审核。 - 端口扫描与防火墙:使用
ss -tulnp或netstat -tulnp查看监听端口。结合firewalld或iptables配置,只开放业务必需的端口。脚本可以配置防火墙默认区域为drop,然后只添加允许的端口和源IP规则。
6.2 内核参数加固(sysctl)
Linux内核通过网络和系统参数暴露了很多可调节项。通过/etc/sysctl.conf或/etc/sysctl.d/下的文件进行加固,能有效防范多种网络攻击和资源滥用。
脚本应配置的关键参数示例:
# 禁止ICMP重定向(防止中间人攻击) net.ipv4.conf.all.accept_redirects = 0 net.ipv6.conf.all.accept_redirects = 0 # 禁止发送ICMP重定向(除非是路由器) net.ipv4.conf.all.send_redirects = 0 # 开启SYN Cookie防御SYN Flood攻击 net.ipv4.tcp_syncookies = 1 # 忽略ICMP广播,避免Smurf攻击 net.ipv4.icmp_echo_ignore_broadcasts = 1 # 忽略虚假的ICMP响应 net.ipv4.icmp_ignore_bogus_error_responses = 1 # 开启反向路径过滤,防止IP欺骗 net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 # 不响应ICMP时间戳请求 net.ipv4.icmp_echo_ignore_all = 0 # 通常设为0以允许ping,安全要求高可设为1 # 限制系统级核心转储(防止敏感信息泄露) fs.suid_dumpable = 0 # 控制核心转储文件的命名和位置 kernel.core_pattern = |/bin/false # 或者指向一个安全脚本 # 禁止非特权用户使用dmesg查看内核日志 kernel.dmesg_restrict = 1修改后执行sysctl -p使配置生效。避坑点5:网络参数的影响。某些参数(如net.ipv4.tcp_tw_recycle)在NAT环境下可能导致连接问题,需根据实际网络环境调整。脚本最好提供注释说明每个参数的作用。
6.3 漏洞管理与补丁
脚本无法自动打补丁(因为这涉及业务兼容性测试),但可以自动化完成以下工作:
- 系统信息收集:
uname -a,cat /etc/os-release。 - 列出已安装包及更新:
yum list installed或apt list --installed,以及yum check-update/apt list --upgradable。 - 生成报告:列出所有可用的安全更新,并标记出关键/高危漏洞的补丁(通常可以通过
yum --security check-update或使用apt-get upgrade --dry-run结合安全源来判断)。 - 提供一键更新建议:给出更新命令,但强烈建议在测试环境验证后再在生产环境执行。
7. 常见问题、排查技巧与脚本使用实录
即使有了脚本,在实际运行中也会遇到各种问题。这里记录一些典型场景和解决方法。
7.1 脚本执行前后的验证清单
执行前:
- [ ]备份!备份!备份!确认脚本有备份关键配置文件的功能,并且备份目录 (
/tmp或自定义目录) 有足够空间。 - [ ]建立救援通道:确保你有通过控制台或带外管理(如iDRAC, iLO)访问服务器的途径。如果SSH配置出错被关在外面,这是唯一的救命稻草。
- [ ]快照或克隆:如果是在虚拟化环境中,先为虚拟机创建一个快照。
- [ ]分模块测试:不要一次性运行整个脚本。可以先在测试机运行“身份鉴别”模块,验证登录和密码策略;再运行“SSH加固”模块,用新端口测试连接。
执行后:
- [ ]SSH连接验证:这是第一步也是最重要的一步。用新端口、新策略(如密钥)登录测试。
- [ ]关键服务状态:
systemctl status sshd auditd rsyslog firewalld确保核心服务正常运行。 - [ ]审计日志生成:执行
ausearch -m SYSCALL -ts recent或直接tail -f /var/log/audit/audit.log,然后尝试修改一个被监控的文件(如touch /etc/test_audit),看是否有审计事件产生。 - [ ]sudo权限测试:用普通用户测试配置的sudo规则是否生效且符合预期。
7.2 典型故障与排查
问题1:执行脚本后,所有用户(包括root)都无法登录。
- 可能原因:PAM配置错误,导致认证流程崩溃。例如,
pam_tally2.so模块路径错误或参数错误。 - 排查:通过控制台登录。检查
/var/log/secure或/var/log/auth.log,里面通常有PAM报错的详细信息。恢复备份的PAM配置文件。 - 脚本设计教训:PAM修改部分,脚本应使用
pam-config或authselect(如果系统支持)这类更安全的高级工具,或者至少要在修改后立即用pam_tally2 --user root --reset之类的命令测试一下认证流程。
问题2:SSH修改端口后,防火墙未放行,导致无法连接。
- 可能原因:脚本只修改了
sshd_config,忘了在firewalld或iptables中添加新端口的规则。 - 排查:在服务器本地
ss -tlnp | grep <新端口>确认监听。在客户端telnet <服务器IP> <新端口>测试连通性。在服务器上查看防火墙规则firewall-cmd --list-all或iptables -L -n。 - 脚本设计教训:修改SSH端口的函数必须与防火墙配置联动。先检查防火墙状态和当前规则,再添加新端口规则,并永久生效(
--permanent或保存到规则文件)。
问题3:Auditd日志暴涨,磁盘被迅速占满。
- 可能原因:审计规则过于宽泛,例如监控了
/var/log目录的写操作,而业务日志正好写在这里。 - 排查:使用
aureport --summary查看事件最多的规则关键词。使用ausearch -k <关键词> --start recent分析具体事件内容。 - 脚本设计教训:规则要精准。提供“宽松”和“严格”两套审计规则模板供选择。在脚本中设置
auditd.conf的max_log_file和num_logs参数,并提示管理员监控日志增长。可以增加一个日志清理的定时任务建议。
问题4:应用报错“权限不够”,但SELinux是Permissive模式。
- 可能原因:即使SELinux不阻止,文件系统的基础权限(
rwx)也可能被脚本收紧。例如,将某个应用运行时需要写入的目录权限从775改成了755。 - 排查:检查应用日志。使用
ls -laZ <文件/目录>查看SELinux上下文和传统权限。对比脚本执行前后的权限变化。 - 脚本设计教训:文件权限修复功能必须非常谨慎。最好采用“报告-确认-修复”的模式,而不是全自动修复。对于已知的常见应用目录(如
/var/www/html/,/usr/local/tomcat/webapps/),应在白名单中排除或设置特定权限。
7.3 脚本的扩展与维护
一个脚本不是一劳永逸的。等保要求会演进,系统版本会更新,新的漏洞和最佳实践会出现。因此,脚本本身应该是易于维护和扩展的。
- 版本化与变更日志:使用Git管理脚本,为每次更新编写清晰的commit message。在脚本开头维护一个版本历史和变更日志。
- 参数外部化:将所有可配置的参数(密码长度、失败次数、SSH端口、审计规则关键词等)提取到脚本开头的一个变量区域,或者一个独立的配置文件(如
config.ini或vars.sh)中。 - 支持多发行版:通过检测
/etc/os-release来区分 CentOS/RHEL、Ubuntu/Debian、OpenSUSE 等,对包管理器命令(yumvsapt)、服务管理命令(systemctlvsservice)、配置文件路径的差异进行适配。 - 生成合规报告:脚本执行完毕后,可以自动运行一系列检查命令(如
grep PASS_MAX_DAYS /etc/login.defs,auditctl -l,systemctl is-enabled sshd),将结果与等保要求条目对比,生成一个简单的HTML或Markdown格式的合规性报告,直观展示哪些项已符合,哪些项需要手动处理。
最后,我想强调的是,自动化脚本是提升效率、保证一致性的利器,但它不能替代运维人员对系统和安全原理的深入理解。这个脚本更像是一个“严师”,它强制我们按照既定的安全规范去操作,但在遇到边界情况时,依然需要你凭借知识和经验去判断和决策。希望这份详细的拆解,能让你不仅会用脚本,更能读懂脚本背后的每一行安全逻辑,在未来的运维和安全工作中更加游刃有余。