
核心要点(TL;DR)
- 安全基线应先用脚本批量下发,再用开源面板做统一纳管与巡检,避免逐台手工配置。
- SSH加固优先做四件事:禁root直登、改端口、限来源IP、强制密钥登录。
- 基线落地必须配巡检:用脚本定期比对配置,防止变更漂移。
- 最小暴露原则:默认拒绝入站,仅按业务放行端口并记录审计日志。
很多运维和站长第一次接手云主机时,安全配置是「装完系统就上线」:root 密码能直登、22 端口对全网开放、数据库跟着公网 IP 一起暴露。单台机器还能靠记忆逐项改,一旦到十几台、几十台,手工配置必然出现遗漏和漂移。本文给出一套可复用的做法:用脚本把云主机安全基线批量下发,用开源面板做统一纳管与巡检,并附上可直接执行的命令和上线检查清单。
一、云主机安全基线到底包含什么
安全基线不是一张无限长的清单,而是一组「默认安全」的配置事实。对 Linux 云主机,最小可用集合可以归为六类:
- 远程访问:SSH 禁 root 直登、强制密钥、限制来源 IP。
- 账号权限:清理无用账号、sudo 最小授权、密码策略与失败锁定。
- 网络暴露面:防火墙默认拒绝入站,仅按业务放行。
- 服务与端口:关闭不必要服务,数据库等中间件不对公网监听。
- 审计与日志:开启 auditd 或等效审计,保留登录与提权记录。
- 补丁与更新:系统与关键组件定期更新,建立版本台账。
这六类覆盖了绝大多数自动化扫描和爆破的入口。先全部落地,再按业务补充细项,比一上来追求大而全更有效。
二、先建配置事实源,再谈批量
批量落地的前提是「配置有唯一来源」。推荐用 Ansible 或纯 Shell 脚本维护一份基线仓库,目录结构如下:
baseline/ inventory.ini # 主机清单 ssh_hardening.sh # SSH 加固 firewall_setup.sh # 防火墙规则 account_audit.sh # 账号与 sudo 检查 check_baseline.sh # 巡检断言脚本
所有脚本必须幂等:重复执行不产生副作用。例如写 sshd 配置时先备份、再用 sed 精确替换,而不是无脑追加:
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F) sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config sshd -t && systemctl reload sshd
注意用 reload 而不是 restart,并提前确认密钥可登录、新会话验证通过后再退出当前会话,避免把自己锁在门外。
三、SSH 与账号权限:最高优先级的加固
SSH 是云主机最常见的失陷入口,优先做四件事:禁 root 直登、改非默认端口、限制来源 IP、强制密钥。改端口时要在安全组和主机防火墙同时放行新端口,验证后再关旧端口。
账号侧重点检查三处:
- 清理
/etc/passwd中 UID 为 0 的非 root 账号; - 检查
/etc/sudoers与/etc/sudoers.d/是否存在 NOPASSWD 过度授权; - 开启失败锁定,例如在
/etc/security/faillock.conf设置deny = 5、unlock_time = 900。
快速排查命令:
awk -F: '==0 {print }' /etc/passwd
grep -r "NOPASSWD" /etc/sudoers /etc/sudoers.d/ 2>/dev/null
lastb | head -20四、网络暴露面与审计:默认拒绝,留下证据
防火墙策略遵循「默认拒绝入站、按需放行」。以 firewalld 为例:
firewall-cmd --permanent --set-default-zone=drop firewall-cmd --permanent --zone=drop --add-service=ssh firewall-cmd --permanent --zone=drop --add-port=443/tcp firewall-cmd --reload firewall-cmd --list-all
同时确认数据库等中间件只监听内网地址,例如 MySQL 配置 bind-address = 127.0.0.1 或内网网卡 IP,而不是 0.0.0.0。审计方面,确保 auditd 运行并保留 SSH 登录、sudo 提权记录,日志外送到独立存储,避免本机被清后无据可查。
| 基线项 | 手工逐台 | 脚本批量 | 面板纳管 |
|---|---|---|---|
| SSH 加固 | 易漏、易漂移 | 幂等、可复跑 | 可视化查看状态 |
| 防火墙规则 | 规则不一致 | 统一下发 | 集中看板告警 |
| 巡检验证 | 靠记忆 | 断言输出清单 | 定时任务与报表 |
五、用开源面板统一纳管与巡检
脚本解决「下发」,面板解决「看得见」。选择支持多主机纳管、基线巡检与告警的开源面板(如 Cockpit 加巡检插件,或轻量运维面板),把主机批量接入后,重点用三个能力:集中查看 SSH 与防火墙状态、定时执行巡检脚本并汇总结果、对异常变更发告警。原则是面板只做展示与巡检入口,配置仍以脚本仓库为事实源,避免在面板里手工改配置造成与脚本不一致。
巡检脚本的核心是逐项断言并输出通过/失败,例如:
grep -q '^PermitRootLogin no' /etc/ssh/sshd_config && echo "PASS ssh-root" || echo "FAIL ssh-root" systemctl is-active --quiet auditd && echo "PASS auditd" || echo "FAIL auditd"
把结果接入 cron 或面板定时任务,形成配置漂移告警。若团队缺少自建巡检与告警的精力,也可以借助 AegisX 这类平台的主机基线核查与集中告警能力,把脚本产出与平台看板结合使用。
六、上线检查清单与行动建议
- SSH:禁 root 直登、禁密码登录、限制来源、改端口并双端放行。
- 账号:无 UID 0 冗余账号、sudo 无过度 NOPASSWD、失败锁定已开启。
- 网络:防火墙默认拒绝、仅放行业务端口、数据库不对公网监听。
- 审计:auditd 运行、登录与提权日志外送、保留周期明确。
- 更新:安全更新策略与组件版本台账建立。
- 验证:巡检脚本全项 PASS,并已加入定时任务。
行动建议:今天先在一台非核心机器上跑通脚本与巡检,确认不会锁死登录;明天扩到全部主机;本周把巡检接入定时任务并配置告警。基线不是一次性任务,而是一条「脚本下发—面板巡检—漂移告警」的闭环,跑起来之后,新增机器只需接入清单即可继承全部配置。
常见问题(FAQ)
云主机安全基线到底要配哪些项,有没有最小集合?
有。最小集合包括:SSH禁止root直登并强制密钥、账号与sudo权限收敛、防火墙默认拒绝入站、关闭不必要服务与端口、开启审计日志与登录失败锁定、系统与软件定期更新。这六类覆盖了绝大多数入侵入口,先全部落地再按业务补充,比追求大而全的清单更有效。
几十台云主机,用开源面板还是纯脚本更合适?
两者配合最好。脚本负责批量下发与幂等执行,适合初始化与周期性巡检;开源面板负责可视化纳管、集中看板与告警,适合日常运维。建议用Ansible或Shell做配置事实源,面板只做展示与巡检入口,避免在面板里手工改配置导致与脚本不一致。
改了SSH端口或禁用密码登录,会不会把自己锁在门外?
会,所以必须按顺序操作:先确认密钥可登录,再新开一个会话验证,最后才改配置并reload而非restart。改端口时先在安全组和防火墙同时放行新端口,验证通过后再关闭旧端口。生产环境建议保留一个带超时的备用会话窗口,确认无误再退出。
基线配置完成后,怎么证明它真的生效了?
用可重复的检查脚本验证,而不是靠记忆。常见做法是写巡检脚本逐项断言:sshd_config关键参数、firewalld/ufw规则、sudoers权限、auditd状态、失败登录锁定策略,输出通过/失败清单并接入定时任务。每次变更后跑一遍,形成配置漂移告警。
没有等保需求的小站点,也需要做完整基线吗?
需要做精简版。小站点最常见的失陷原因是弱口令SSH、暴露的数据库端口和过期的Web组件。把SSH密钥化、防火墙默认拒绝、关闭公网数据库端口、开启自动安全更新这四项做到,成本很低但能挡掉大部分自动化扫描与爆破。