先讲人话:它在干啥
一句话——把一台新服务器从"谁都能进"改成"只有你知道的钥匙能从指定地方进,而且进来干啥都被盯着"。
脚本按这个顺序来(老柴清单):
1. 备份先行:动 sshd / firewalld / sysctl / PAM / selinux 之前,全 cp 一份到 /root/security-backup-日期。翻车能回滚,这是保命第一步。
2. 建专用运维账号 + sudo:日常不碰 root,root 只留给系统自己。
3. 密码复杂度 + 登录失败锁定:pwquality 强制 12 位、四类字符;pam_faillock 失败 5 次锁 900 秒,连 root 一起锁。
4. SSH 加固:换端口、禁 root 直登、禁密码、只认密钥、限定来源 IP。
5. 防火墙:firewalld 默认区只留 http/https + 自定义 SSH 端口,内网段划 trusted 全放行。
6. fail2ban 防爆破 + ClamAV 杀毒:爆破 IP 自动封 24 小时;定时更新病毒库、扫 Web 目录。
7. AIDE 文件完整性监控:给 /etc/usr/bin 等建基线,谁改了系统文件邮件告警。
8. SELinux enforcing + 内核安全参数:syncookies 防 SYN 洪水、禁 IP 源路由、反向路径过滤、开 ASLR。
核心代码:SSH 加固这段直接抄
这是整份脚本里最该抄的一段——sshd_config.d 下放独立 conf,不碰主配置,改坏了删文件就回滚:
# /etc/ssh/sshd_config.d/00-hardening.confPort 2222 # 别用默认 22AddressFamily inetProtocol 2PermitRootLogin no # root 禁止直登PasswordAuthentication no # 密码登录关闭,只认密钥PubkeyAuthentication yesPermitEmptyPasswords noChallengeResponseAuthentication noKerberosAuthentication noGSSAPIAuthentication noMaxAuthTries 3 # 试错上限压到 3MaxSessions 5LoginGraceTime 60ClientAliveInterval 300ClientAliveCountMax 2X11Forwarding noPrintMotd noTCPKeepAlive noCompression no# 仅允许指定用户从指定来源登录AllowUsers cjd@27.185.229.62
老柴提醒:sshd -t 先校验语法,过了才 systemctl reload sshd。永远先在另一个会话确认能登进去,再关掉旧连接——这是脚本唯一没自动兜底、得你自己盯死的地方。
三个真坑(照抄前必看)
脚本整体是好的,但这三处是"能让你半夜被叫醒"级别的真坑。
坑一:/16 当单 IP 用,把整段公网划进 trusted
脚本里 ALLOWED_NETWORK="27.185.229.62/16",firewalld 一句:
firewall-cmd --permanent --zone=trusted --add-source="27.185.229.62/16"
/16 是 65536 个地址。这一句把整个公网段划进 trusted 区,等于对这 6 万多个 IP 防火墙全放行、形同虚设。而且 27.185.x 是公网段不是内网——本意大概是"只允许这台跳板机",结果把一整段公网放进了来。
更坑的是 AllowUsers 那行拼接:${ALLOWED_NETWORK%/*}.* 把 /16 剥掉得到 27.185.229.62,再拼成 cjd@27.185.229.62.*。SSH 的 host 部分匹配的是客户端主机名/反向解析,不是裸 IP——27.185.229.62.* 要求后面还得有个点,而真实来源 IP 27.185.229.62 没有,结果你自己都被挡在门外。
正确做法:单 IP 就干脆去掉 /16;要放行一段就给最小掩码(比如 /32 单台、/28 一小撮),并且 fail2ban 的 ignoreip 一定要包含你的真实出口段,不然自己输错三次密码就被 ban 了。
坑二:NOPASSWD: ALL 自相矛盾
脚本前面辛辛苦苦禁了 root 直登、上了密钥,转头给运维账号写死:
echo "cjd ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/cjd
这是免密 root 等价。一旦 SSH 私钥泄漏(再叠加坑一的 trusted 整段放行),攻击者在那段公网里直接 sudo 提权到 root,前面所有加固约等于零。
正确做法:按需授权具体命令,别给 NOPASSWD: ALL。运维日常要的也就是重启服务、看日志那几个,写白名单比一把梭安全十倍。
坑三:ip_forward=0 一刀切 + ClamAV 全量扫盘
net.ipv4.ip_forward = 0 # 内核参数里这一句clamscan -r -i / --log=/var/log/clamav-full.log # 杀毒全量扫根
ip_forward=0 对纯应用服务器没问题,但只要是 Docker / K8s / 转发网关主机,这一句下去容器网络直接断、集群失联,你加固完反而把业务搞挂了。
ClamAV 的 clamscan -r -i / 全量扫根,在线上服务器会把磁盘 IO 打满、业务卡死。这两处都得按机器角色留开关,别无脑套模板。
老柴的底线
加固不是"跑一遍脚本就安全了",是一条条对着自己的机器角色过。脚本是拐杖不是脑子:
- sudo 别给
NOPASSWD: ALL,私钥泄露就是全局沦陷; - 改完 SSH、防火墙,先开第二个会话验能登录,再断旧连接;
- 凡
ip_forward、全量扫盘这类"全局副作用",先问自己"这台机器跑不跑容器/转发"。
你上线前会先跑哪一步?评论区告诉我,老柴帮你排雷。
下期预告 PART16:怎么让发布不背锅——CI/CD 与灰度那些事。