下面这个脚本按 Debian VPS + OpenSSH + systemd + Fail2Ban 来写,并考虑了几个容易把自己锁在 VPS 外面的坑:
- 自动安装 Fail2Ban
- SSH 端口改为 2222
- 修改前自动备份 SSH 配置
- 先执行
sshd -t检查配置,配置有问题不会重启 SSH - 启用 Fail2Ban 的 sshd Jail
- 如果启用了 UFW,自动放行 2222/tcp
- 启动并设置 Fail2Ban 开机自启
- 最后检查 SSH 是否监听 2222、Fail2Ban 是否正常
- 不会直接关闭当前 SSH 会话
脚本执行完后,你应该先开一个新的 SSH 窗口测试 2222,确认能登录后再关闭旧连接。
脚本为 sh 脚本:
#!/bin/sh
set -u
SSH_PORT="2222"
BACKUP_DIR="/root/ssh-fail2ban-backup-$(date +%Y%m%d-%H%M%S)"
echo "======================================"
echo " SSH 端口修改 + Fail2Ban 配置"
echo " 新 SSH 端口:$SSH_PORT"
echo "======================================"
# 必须 root
if [ "$(id -u)" != "0" ]; then
echo "错误:请使用 root 执行此脚本"
exit 1
fi
# Debian 检查
if [ ! -f /etc/debian_version ]; then
echo "警告:当前系统不是标准 Debian,脚本停止执行"
exit 1
fi
echo
echo "[1/8] 检查 SSH 服务"
if command -v sshd >/dev/null 2>&1; then
SSHD="$(command -v sshd)"
elif [ -x /usr/sbin/sshd ]; then
SSHD="/usr/sbin/sshd"
else
echo "错误:未找到 sshd"
exit 1
fi
if systemctl list-unit-files 2>/dev/null | grep -q '^ssh.service'; then
SSH_SERVICE="ssh"
elif systemctl list-unit-files 2>/dev/null | grep -q '^sshd.service'; then
SSH_SERVICE="sshd"
else
echo "错误:未找到 SSH systemd 服务"
exit 1
fi
echo "SSH 程序:$SSHD"
echo "SSH 服务:$SSH_SERVICE"
echo
echo "[2/8] 创建备份"
mkdir -p "$BACKUP_DIR"
cp -a /etc/ssh "$BACKUP_DIR/ssh"
if [ -f /etc/fail2ban/jail.local ]; then
cp -a /etc/fail2ban/jail.local "$BACKUP_DIR/jail.local"
fi
echo "备份位置:$BACKUP_DIR"
echo
echo "[3/8] 安装 Fail2Ban"
if ! command -v fail2ban-client >/dev/null 2>&1; then
echo "未安装 Fail2Ban,开始安装..."
apt-get update
apt-get install -y fail2ban
if ! command -v fail2ban-client >/dev/null 2>&1; then
echo "错误:Fail2Ban 安装失败"
exit 1
fi
else
echo "Fail2Ban 已安装"
fi
echo
echo "[4/8] 配置 SSH 端口"
mkdir -p /etc/ssh/sshd_config.d
cat > /etc/ssh/sshd_config.d/99-custom-port.conf <<EOF
# Managed by SSH + Fail2Ban setup script
Port $SSH_PORT
EOF
echo "设置 SSH 端口:$SSH_PORT"
echo
echo "[5/8] 检查 SSH 配置"
if ! "$SSHD" -t; then
echo
echo "错误:SSH 配置检查失败!"
echo "正在恢复刚才创建的配置..."
rm -f /etc/ssh/sshd_config.d/99-custom-port.conf
echo "原配置未被破坏。"
exit 1
fi
echo "✓ SSH 配置检查通过"
echo
echo "[6/8] 配置 Fail2Ban"
cat > /etc/fail2ban/jail.local <<EOF
[DEFAULT]
# 默认封禁时间:1小时
bantime = 1h
# 登录失败次数
maxretry = 5
# 统计失败的时间窗口
findtime = 10m
# SSH
[sshd]
enabled = true
port = $SSH_PORT
backend = systemd
EOF
echo "Fail2Ban sshd Jail 已配置"
echo
echo "[7/8] 配置防火墙"
# 只有 UFW 正在使用时才自动放行
if command -v ufw >/dev/null 2>&1; then
UFW_STATUS="$(ufw status 2>/dev/null | head -n 1)"
if echo "$UFW_STATUS" | grep -q "Status: active"; then
echo "检测到 UFW 已启用,放行 $SSH_PORT/tcp"
if ! ufw allow "$SSH_PORT/tcp"; then
echo "错误:UFW 放行失败"
echo "为避免锁死 SSH,停止执行"
exit 1
fi
else
echo "UFW 未启用,不修改 UFW"
fi
else
echo "未安装 UFW,不修改防火墙"
fi
echo
echo "[8/8] 启动 SSH 和 Fail2Ban"
systemctl daemon-reload
if ! systemctl reload "$SSH_SERVICE"; then
echo "SSH reload 失败,尝试 restart..."
if ! systemctl restart "$SSH_SERVICE"; then
echo
echo "错误:SSH 重启失败!"
echo
echo "请检查:"
echo " systemctl status $SSH_SERVICE"
echo " journalctl -u $SSH_SERVICE -n 50"
exit 1
fi
fi
systemctl enable fail2ban
systemctl restart fail2ban
sleep 2
echo
echo "======================================"
echo " 最终检查"
echo "======================================"
echo
echo "[SSH 服务]"
systemctl is-active "$SSH_SERVICE"
echo
echo "[SSH 监听端口]"
if ss -lntp 2>/dev/null | grep -E "[:.]$SSH_PORT[[:space:]]"; then
echo "✓ SSH 正在监听 $SSH_PORT"
else
echo "✗ 未检测到 SSH 监听 $SSH_PORT"
fi
echo
echo "[Fail2Ban]"
systemctl is-active fail2ban
echo
echo "[Fail2Ban Jail]"
fail2ban-client status
echo
echo "[SSH Jail]"
fail2ban-client status sshd
echo
echo "======================================"
echo " 配置完成"
echo "======================================"
echo
echo "SSH 新端口:$SSH_PORT"
echo "备份目录:$BACKUP_DIR"
echo
echo "请不要立即关闭当前 SSH 窗口!"
echo
echo "请新开一个终端测试:"
echo
echo "ssh -p $SSH_PORT root@你的VPS_IP"
echo
echo "确认 2222 可以正常登录后,再关闭旧 SSH 连接。"
echo
注:Vps没VNC谨慎操作

Comments NOTHING