能用systemctl管控、yum/apt安装、配置文件生效的项适合进脚本;涉及内核模块、SELinux重编译、业务端口确认的须交互或跳过,核心判断标准是“是否可逆”和“是否影响业务连通性”。

直接上结论:能用 systemctl 管控的服务、能用 yum 或 apt 安装的组件、能通过修改配置文件生效的安全策略,都适合放进一键脚本;但涉及内核模块加载、SELinux策略重编译、或需人工确认业务端口的环节,必须加交互或跳过——硬编码反而埋雷。
怎么判断哪些加固项该进脚本,哪些该人工介入
核心逻辑是看「是否可逆」和「是否影响业务连通性」。比如关闭 telnet、禁用 root 远程登录、设置 MaxAuthTries,这些操作重启服务即生效、失败也能快速回滚;但像调整 net.ipv4.tcp_syncookies 这类内核参数,如果值设错可能直接断 SSH 连接,就必须先 sysctl -n 检查当前值,再做增量变更。
- 推荐进脚本的:防火墙规则(
firewalld或ufw)、SSH 配置(/etc/ssh/sshd_config)、密码策略(/etc/pam.d/system-auth)、日志轮转(/etc/logrotate.d/) - 必须人工确认的:开放哪些非标准端口(如业务用的 8080、9001)、是否启用 SELinux enforcing 模式、是否关闭 IPv6(某些旧中间件不兼容)
- 建议跳过或仅检测的:内核版本升级(
kernel-ml类更新需重启,不能自动化)、auditd规则深度定制(规则冲突难调试)
SSH 安全配置为什么不能只改 PermitRootLogin
只改 PermitRootLogin no 是最低限度,生产环境真正卡住入口的其实是三件事:密钥认证强制化、密码登录彻底禁用、登录失败锁定。漏掉任意一项,脚本就等于没加固。
- 必须同步关闭
PasswordAuthentication no和ChallengeResponseAuthentication no,否则PermitRootLogin no形同虚设 - 要配
MaxAuthTries 3+LockoutDuration 600(需pam_faillock.so支持),防暴力扫号 -
UseDNS no和GSSAPIAuthentication no必须加上,否则新连接会卡顿甚至超时,运维误以为服务挂了 - 改完必须跑
systemctl restart sshd,且得用ss -tlnp | grep :22验证端口是否还在监听——有些发行版(如 CentOS Stream)改错配置会导致sshd启动失败而静默退出
firewalld 开放端口时最容易踩的坑
很多人用 firewall-cmd --add-port=80/tcp 加完就以为完了,其实这条命令只生效于当前 runtime,机器一重启规则就丢。真正要持久化,必须带 --permanent,而且得重载两次。
- 正确顺序是:
firewall-cmd --permanent --add-port=22/tcp→firewall-cmd --permanent --add-service=ssh→firewall-cmd --reload - 别信
firewall-cmd --list-all的输出——它默认显示 runtime,得加--permanent参数才看持久化配置:firewall-cmd --permanent --list-all - CentOS 7 默认 zone 是
public,但有些脚本会误切到trusted,导致后续规则不生效;建议开头就固定:firewall-cmd --set-default-zone=public - 如果机器已跑 Docker,
firewalld和dockerd会抢 iptables 链,必须关掉 docker 的 iptables 管理:echo '{ "iptables": false }' > /etc/docker/daemon.json && systemctl restart docker
最常被忽略的一点:脚本末尾一定要写自我校验逻辑。比如检查 sshd_config 里 PasswordAuthentication 是否真为 no,而不是只管写入;检查 firewalld 是否确实在监听 22 端口,而不是只调了 firewall-cmd 命令。没有验证的加固,等于没加固。


















