服务器初始化配置脚本

新买的服务器不是开箱即用的。默认情况下 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 700chmod 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 端口再启用,否则可能把自己关在门外。

安全建议

  1. 修改 SSH 端口:将 SSH_PORT 改为 2222 或其他非标准端口,配合 fail2ban 能把绝大多数自动化扫描挡在门外
  2. 更换 SSH 密钥:不要使用服务器生成的默认密钥,用自己本地生成的密钥对
  3. 配置自动更新apt install unattended-upgrades 启用安全更新自动安装
  4. 定期检查日志journalctl -xetail -f /var/log/auth.log
  5. 限制 sudovisudo 中为 deploy 用户添加 NOPASSWD 时注意授权范围,不要放开所有命令
  6. 备份关键配置:初始化完成后把 /etc/ssh/sshd_config 等关键配置备份一份,方便日后比对或回滚

16IDC 观察

安全加固没有"差不多就行",一台被入侵的服务器可能成为攻击下游用户的跳板。初始化脚本把安全基线变成可重复的默认动作——每台新服务器都执行一遍,就不用每次手工重复同一套设置,也少一个忘记加固的角落。配置即代码的意义在于,一次验证通过的脚本,可以放心地复制到所有同类机器上,让集群的安全基线保持一致。一台干净、加固到位的服务器,是后续所有业务稳定运行的地基。