服务器初始化配置脚本
新买的服务器不是开箱即用的。默认情况下 root 用户可以密码登录、防火墙是关闭的、系统软件停留在镜像出厂的版本——任何一个疏漏都可能成为被爆破的入口。把初始化的每一步固化成脚本,好处不只是省时间:你可以在新服务器、新环境上重复执行同一套配置,结果可预期、可审计,不会漏步骤。下面这份脚本适用于 Ubuntu 22.04 / 24.04,覆盖安全加固、用户创建、防火墙、基础软件安装等关键环节。
参考:Ubuntu 安全加固文档 https://ubuntu.com/server/docs/security-hardening
一键初始化脚本
#!/bin/bash
# server-init.sh — 新服务器初始化配置
# 适用于 Ubuntu 22.04 / 24.04
set -euo pipefail
# === 配置变量 ===
NEW_USER="deploy"
SSH_PORT="22" # 建议改为非标准端口
TIMEZONE="Asia/Shanghai"
# === 1. 系统更新 ===
echo ">>> Updating system packages..."
apt update && apt upgrade -y
apt autoremove -y
# === 2. 创建部署用户 ===
echo ">>> Creating deploy user..."
if ! id "$NEW_USER" &>/dev/null; then
useradd -m -s /bin/bash "$NEW_USER"
usermod -aG sudo "$NEW_USER"
fi
# === 3. 配置 SSH 密钥登录 ===
echo ">>> Configuring SSH keys..."
mkdir -p /home/$NEW_USER/.ssh
cp ~/.ssh/authorized_keys /home/$NEW_USER/.ssh/ 2>/dev/null || true
chown -R $NEW_USER:$NEW_USER /home/$NEW_USER/.ssh
chmod 700 /home/$NEW_USER/.ssh
chmod 600 /home/$NEW_USER/.ssh/authorized_keys
# === 4. 强化 SSH 配置 ===
echo ">>> Hardening SSH configuration..."
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/#Port 22/Port '"$SSH_PORT"'/' /etc/ssh/sshd_config
systemctl restart sshd
# === 5. 配置防火墙 ===
echo ">>> Configuring firewall..."
ufw allow $SSH_PORT/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable
# === 6. 配置时区和 NTP ===
echo ">>> Configuring timezone..."
timedatectl set-timezone $TIMEZONE
apt install -y chrony
systemctl enable --now chrony
# === 7. 安装基础软件 ===
echo ">>> Installing essential packages..."
apt install -y curl wget git ufw fail2ban htop nginx docker.io docker-compose-plugin certbot python3-certbot-nginx
# === 8. 配置 fail2ban ===
echo ">>> Configuring fail2ban..."
cat > /etc/fail2ban/jail.local << 'EOF'
[sshd]
enabled = true
port = $SSH_PORT
maxretry = 3
bantime = 3600
EOF
systemctl enable --now fail2ban
# === 9. 配置 Swap ===
echo ">>> Configuring swap..."
if [ ! -f /swapfile ]; then
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
fi
# === 10. 完成 ===
echo ""
echo "=== Server initialization complete! ==="
echo "Created user: $NEW_USER"
echo "SSH port: $SSH_PORT"
echo "Please logout and test SSH with new user before closing this session."
脚本开头 set -euo pipefail 保证任何一步出错就立刻停止,不会带着半成品配置继续往下跑。开头集中定义变量(用户、SSH 端口、时区),换一台机器只需要改这几行。
每一步在做什么
| 步骤 | 作用 | 说明 |
|---|---|---|
| 系统更新 | apt update & upgrade | 确保系统包为最新版本 |
| 创建用户 | 创建 deploy 用户 | 禁止 root 直接登录 |
| SSH 密钥 | 拷贝并设置权限 | 仅允许密钥认证 |
| SSH 加固 | 禁用密码+root登录 | 密钥登录唯一入口 |
| 防火墙 | UFW | 仅开放 SSH/HTTP/HTTPS |
| 时区与 NTP | chrony 时间同步 | 日志时间一致,证书校验正常 |
| Fail2ban | 暴力破解防护 | SSH 3 次失败封禁 1 小时 |
| Swap | 内存交换 | 2GB Swap 防止 OOM |
几个容易被忽略的细节:chmod 700 与 chmod 600 的权限设置如果少了,OpenSSH 会直接拒绝使用该密钥文件;时区不统一会导致多台服务器日志时间对不上,排障时非常痛苦;2GB swap 对 2GB 内存以下的小机器几乎是必需品,否则内存跑满后 OOM Killer 可能杀掉数据库进程。
使用流程
# 1. 上传脚本到服务器
scp server-init.sh root@your-server:~/
# 2. 登录服务器执行
ssh root@your-server
chmod +x server-init.sh
sudo ./server-init.sh
脚本执行完成后,务必先开一个新的 SSH 会话用 deploy 用户登录验证,确认能连上再关闭当前 root 会话——这是防止把自己锁在服务器外面的最后一道保险。如果发现密钥登录有问题,趁 root 会话还没关,立刻回滚修改。
执行完后还可以快速自检:ss -tlnp | grep -E ':(22|80|443)' 查看端口监听,ufw status 确认防火墙规则,fail2ban-client status sshd 确认防暴力破解已启用。
一个真实场景
给客户部署一套 WordPress 站群时,三台 2C4G 的轻量云主机用了同一份脚本初始化,从下单到全部加固完成不到十五分钟。之后的运维只通过 deploy 用户 + 密钥进行,公网 SSH 端口改为 22022。三个月后查看 fail2ban 日志,累计拦截了 40 多次针对 SSH 的暴力尝试——而其中任何一次成功,都意味着整台机器沦陷。
常见问题
- 脚本可以直接跑在 Debian 上吗? 大部分命令通用,但软件包名可能不同,建议先在测试机上完整跑一遍再上生产。
- 跑完发现 SSH 登录失败怎么办? 保持当前 root 会话不要关,检查
sshd_config里的端口和密码认证设置,恢复后重试。 set -euo pipefail会不会太激进? 初始化阶段宁可失败也不要带病运行;如果确实要容忍某条命令失败,可以显式加|| true。- 防火墙误伤怎么办? UFW 默认拒绝未放行端口,务必先放行你的 SSH 端口再启用,否则可能把自己关在门外。
安全建议
- 修改 SSH 端口:将 SSH_PORT 改为 2222 或其他非标准端口,配合 fail2ban 能把绝大多数自动化扫描挡在门外
- 更换 SSH 密钥:不要使用服务器生成的默认密钥,用自己本地生成的密钥对
- 配置自动更新:
apt install unattended-upgrades启用安全更新自动安装 - 定期检查日志:
journalctl -xe和tail -f /var/log/auth.log - 限制 sudo:
visudo中为 deploy 用户添加 NOPASSWD 时注意授权范围,不要放开所有命令 - 备份关键配置:初始化完成后把
/etc/ssh/sshd_config等关键配置备份一份,方便日后比对或回滚
16IDC 观察
安全加固没有"差不多就行",一台被入侵的服务器可能成为攻击下游用户的跳板。初始化脚本把安全基线变成可重复的默认动作——每台新服务器都执行一遍,就不用每次手工重复同一套设置,也少一个忘记加固的角落。配置即代码的意义在于,一次验证通过的脚本,可以放心地复制到所有同类机器上,让集群的安全基线保持一致。一台干净、加固到位的服务器,是后续所有业务稳定运行的地基。