脚本能自动封禁SSH攻击IP吗?

wen 实用脚本 3

是的,可以通过脚本自动封禁SSH攻击IP,以下是几种常见的实现方法:

脚本能自动封禁SSH攻击IP吗?

基于日志分析的Shell脚本

#!/bin/bash
# 分析SSH日志,封禁多次失败的IP
# 阈值设置
MAX_ATTEMPTS=5
LOG_FILE="/var/log/auth.log"
# 或使用 /var/log/secure (CentOS/RHEL)
# 获取失败次数超过阈值的IP
FAILED_IPS=$(grep "Failed password" $LOG_FILE | \
    awk '{print $(NF-3)}' | \
    sort | uniq -c | \
    awk -v limit=$MAX_ATTEMPTS '$1 > limit {print $2}')
# 封禁IP
for IP in $FAILED_IPS; do
    # 检查是否已封禁
    if ! iptables -L INPUT -n | grep -q "$IP"; then
        iptables -A INPUT -s $IP -j DROP
        echo "[$(date)] 封禁IP: $IP" >> /var/log/autoblock.log
    fi
done

使用fail2ban(推荐)

# fail2ban配置文件 /etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
bantime = 3600
findtime = 600

实时监控脚本(含解封机制)

#!/bin/bash
# 实时监控并自动封禁/解封
while true; do
    # 封禁逻辑
    tail -n0 -F /var/log/auth.log | while read line; do
        if echo "$line" | grep -q "Failed password"; then
            IP=$(echo "$line" | grep -oP '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
            COUNT=$(grep "Failed password.*$IP" /var/log/auth.log | wc -l)
            if [ $COUNT -ge 5 ]; then
                iptables -C INPUT -s $IP -j DROP 2>/dev/null || \
                iptables -A INPUT -s $IP -j DROP
                echo "[$(date)] 自动封禁IP: $IP (失败$COUNT次)"
            fi
        fi
    done
    sleep 1
done

高级功能脚本

#!/usr/bin/env python3
"""
高级SSH攻击防护脚本
功能:自动封禁、解封、发送告警
"""
import re
import subprocess
import time
from collections import defaultdict
from datetime import datetime, timedelta
class SSHBlocker:
    def __init__(self, max_attempts=5, ban_time=3600):
        self.max_attempts = max_attempts
        self.ban_time = ban_time
        self.failed_attempts = defaultdict(list)
    def parse_logs(self):
        """解析SSH日志"""
        try:
            with open('/var/log/auth.log', 'r') as f:
                for line in f.readlines()[-1000:]:  # 只读取最后1000行
                    if 'Failed password' in line:
                        ip_match = re.search(r'\d+\.\d+\.\d+\.\d+', line)
                        if ip_match:
                            ip = ip_match.group()
                            self.failed_attempts[ip].append(datetime.now())
        except FileNotFoundError:
            # 尝试其他日志路径
            pass
    def block_ip(self, ip):
        """封禁IP"""
        try:
            subprocess.run(['iptables', '-A', 'INPUT', '-s', ip, '-j', 'DROP'], 
                         check=True)
            print(f"[{datetime.now()}] 封禁IP: {ip}")
            self.send_alert(f"SSH攻击防护: 已封禁IP {ip}")
        except Exception as e:
            print(f"封禁失败 {ip}: {e}")
    def unblock_ip(self, ip):
        """解封IP"""
        try:
            subprocess.run(['iptables', '-D', 'INPUT', '-s', ip, '-j', 'DROP'], 
                         check=True)
            print(f"[{datetime.now()}] 解封IP: {ip}")
        except:
            pass
    def send_alert(self, message):
        """发送告警(可替换为邮件、钉钉等)"""
        # 这里可以集成告警系统
        print(f"告警: {message}")
    def run_check(self):
        """执行安全检查"""
        self.parse_logs()
        now = datetime.now()
        for ip, attempts in list(self.failed_attempts.items()):
            # 清理过期记录
            valid_attempts = [t for t in attempts if now - t < timedelta(hours=1)]
            self.failed_attempts[ip] = valid_attempts
            if len(valid_attempts) >= self.max_attempts:
                self.block_ip(ip)
if __name__ == "__main__":
    blocker = SSHBlocker()
    # 每60秒检查一次
    while True:
        blocker.run_check()
        time.sleep(60)

使用方法

  1. 基本脚本
    chmod +x autoblock.sh
    ./autoblock.sh

添加到crontab定期执行

crontab -e /5 * /path/to/autoblock.sh


2. **fail2ban**(最推荐):
```bash
# Ubuntu/Debian
apt install fail2ban
systemctl enable fail2ban
systemctl start fail2ban
# CentOS/RHEL
yum install fail2ban
systemctl enable fail2ban
systemctl start fail2ban
  1. 高级脚本
    chmod +x ssh_blocker.py
    nohup python3 ssh_blocker.py &

注意事项

  1. 白名单设置:避免误封自己的IP
  2. 日志轮转:注意日志文件可能被切割
  3. 权限问题:需要root权限运行封禁命令
  4. 持久化:iptables规则重启后会丢失,建议保存规则
  5. 性能影响:避免频繁读取大日志文件

最佳实践

  • 优先使用fail2ban:成熟稳定,配置灵活
  • 设置合理阈值:5次失败/10分钟内比较合理
  • 永久封禁+自动解封:根据IP reputation动态调整
  • 多维度防护:结合geoiploc、黑名单库等

这些脚本可以有效防止SSH暴力破解攻击,建议在生产环境下使用fail2ban方案。

抱歉,评论功能暂时关闭!