Fail2ban快速安装和检测

miao7 发布于 2026-03-06 150 次阅读


下面这个脚本按 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谨慎操作