服务器初始化安全脚本

一台刚开机的云服务器,默认状态往往"能跑但不够安全":root 可以直接 SSH 登录、密码登录开放、防火墙没开、缺少暴力破解防护。很多入侵事件就发生在服务器上线后的头几天。下面这份脚本把常见的初始化加固步骤串成一次执行,适合 Ubuntu 22.04/24.04 等 Debian 系系统。

为什么偏偏是"头几天"最危险?云厂商的扫描器会在新 IP 上线后几分钟内开始探测,自动化脚本对 22 端口做字典爆破几乎是常态。一台开放密码登录、root 直连的服务器,快则几小时就能被撞库成功。这不是危言耸听——部署一台蜜罐服务器,24 小时内收到几千次 SSH 爆破尝试是很常见的数据。所以加固的关键不是"以后慢慢改",而是"上线当天就做完"。下面这份脚本把创建用户、SSH 加固、防火墙、Fail2Ban、自动更新五件事串成一次执行,五分钟内完成。

完整的加固脚本

#!/bin/bash
# 服务器初始化安全配置

# 创建非 root 用户
adduser deploy
usermod -aG sudo deploy

# SSH 加固
sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart sshd

# 防火墙
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable

# 安装 Fail2Ban
apt install fail2ban -y
systemctl enable fail2ban
systemctl start fail2ban

# 自动更新
apt install unattended-upgrades -y
dpkg-reconfigure -plow unattended-upgrades

每一步在做什么

步骤 作用
创建非 root 用户 遵循最小权限原则,日常操作不用 root
关闭 root 登录 消除最常被暴力破解的目标账户
关闭密码登录 只允许密钥登录,从源头阻断撞库
UFW 防火墙 默认拒绝入站,只放行 SSH/HTTP/HTTPS
Fail2Ban 连续失败 3 次封锁来源 IP 一小时
自动更新 无人值守安装安全补丁

理解每步的意图,比背下脚本更重要。创建非 root 用户是基于最小权限原则:日常部署用 deploy 账户,只有需要系统级操作时才 sudo,这样即使某天 Web 应用被攻破,攻击者拿到的也不是 root。关闭 root 登录和密码登录是同一件事的两面:root 是字典攻击的第一目标,密码是可猜测的弱凭证,两者同时关掉,SSH 爆破基本就失效了。Fail2Ban 则是兜底——就算前面都做了,它还能在短时间内自动封锁暴力尝试的 IP。自动更新则解决"已知漏洞未打补丁"的问题,很多入侵是利用公开披露后未被修补的漏洞。

两个需要小心的坑

第一个坑是顺序:先复制好 SSH 公钥、确认能用密钥登录,再重启 sshd。如果密钥没配置好就关掉密码登录,服务器可能直接失联。第二个坑是端口:默认 22 端口是扫描器的最爱,可以改成高位端口(如 2222),但记得同步防火墙规则并通知团队成员。另外注意:改 SSH 端口不是安全措施,只是减少日志噪音——真正的安全来自密钥登录和 Fail2Ban,别指望换个端口就能挡住攻击者。

验证加固是否生效

# 查看 SSH 实际生效的配置
sshd -T | grep -E "permitrootlogin|passwordauthentication"

# 查看防火墙规则
ufw status verbose

# 查看 Fail2Ban 是否在监听
fail2ban-client status sshd

# 查看当前监听端口
ss -tlnp

加固做完要验证,而不是"执行完就当成功"。sshd -T 会输出 sshd 实际生效的配置,用来确认 PermitRootLogin noPasswordAuthentication no 真的写进去了;ss -tlnp 可以检查有没有意外暴露的端口——比如某个开发用的调试端口忘了关。一个实用的习惯是:加固完成后,从外部用 nc -vz <IP> 22 测一下端口连通性,确认预期内的端口才可达。

场景参考

如果是多台服务器组成的集群,建议把脚本沉淀到配置管理工具里统一执行,而不是逐台手工跑。以 Ansible 为例,把脚本拆成 playbook 的 task,配合 inventory 对所有机器批量执行,还能保证各台机器的配置一致,避免"这台加固了、那台没加固"的疏漏。更完整的加固基线可以参考SSH 加固指南和CIS 基准加固;日常巡检可配合服务器运维技巧定期复查。

常见问题

  • 临时测试机也要这么麻烦吗? 至少完成用户创建、防火墙和 SSH 加固三步,成本很低,还能保护共享的网关和资源。
  • 关掉密码登录后发现自己失联了怎么办? 通过云厂商控制台的 VNC 或串口登录,临时改回 PasswordAuthentication yes,把密钥配好后再关回去。
  • 只能在全新服务器上跑吗? Debian 系系统都适用,存量服务器可以挑相关段落维护窗口期执行。
  • 密钥文件丢了怎么办? 服务器上要保留一个备用登录方式(如 VNC 或第二把密钥),同时把私钥备份到加密的密码管理器里;丢了私钥而没有任何备用入口,就只能重装系统。

参考

参考:Ubuntu 服务器安全文档 https://ubuntu.com/server/docs/security-hardening
参考:OpenSSH 手册 https://man.openbsd.org/sshd_config