百度已收录

版本一

重点监控某些 IP 地址的多次失败登录尝试,并针对特定 IP 发送告警,该脚本会监控并告警那些尝试登录次数超过阈值的 IP 地址

#!/bin/bash

# 设置钉钉 webhook URL  改为自己的钉钉机器人webhook
WEBHOOK_URL="https://oapi.dingtalk.com/robot/send?access_token=your_access_token"

# 设置日志文件路径,默认是 /var/log/auth.log(具体路径根据你的系统调整)
LOG_FILE="/var/log/auth.log"

# 设置匹配的异常登录模式,例如:多个错误登录尝试或 IP 地址
# 这里假设我们匹配 "Failed password" 登录尝试
PATTERN="Failed password"

# 设置阈值,超过此次数的 IP 会触发告警
THRESHOLD=5

# 获取当前时间,格式化为 YYYY-MM-DD HH:MM:SS
CURRENT_TIME=$(date "+%Y-%m-%d %H:%M:%S")

# 提取失败登录的 IP 地址,并统计每个 IP 的尝试次数
IP_ATTEMPTS=$(grep "$PATTERN" $LOG_FILE | grep -oP 'from \K(\S+)' | sort | uniq -c | sort -nr)

# 检查每个 IP 是否超过阈值,若超过则触发告警
ALERT_IPS=""
while read -r count ip; do
    if [ "$count" -gt "$THRESHOLD" ]; then
        ALERT_IPS="$ALERT_IPS\nIP 地址 $ip 尝试登录次数:$count 次"
    fi
done <<< "$IP_ATTEMPTS"

# 如果有 IP 地址超过阈值,则发送钉钉告警
if [ -n "$ALERT_IPS" ]; then
    # 构造告警内容
    MESSAGE="警告:检测到以下 IP 地址的 SSH 异常登录尝试。\n当前时间:$CURRENT_TIME\n$ALERT_IPS"

    # 发送钉钉告警
    curl -X POST $WEBHOOK_URL \
        -H "Content-Type: application/json" \
        -d '{
              "msgtype": "text",
              "text": {
                "content": "'"$MESSAGE"'"
              }
            }'
fi

版本二

为了避免频繁的告警,新增加一个机制,确保只有当出现 新的异常攻击 IP 地址 时才触发告警。具体思路是:

  • 记录上次已经告警过的 IP 地址:可以通过保存一个文件,记录上次已经触发告警的 IP 地址
  • 检查新增的攻击 IP 地址:在每次运行时,比较当前的异常登录 IP 地址和上次记录的 IP 地址,只有新增的 IP 地址才会触发告警
  • 更新已告警的 IP 地址列表:告警后,将新增的 IP 地址加入到记录文件中,避免重复告警
#!/bin/bash

# 设置钉钉 webhook URL
WEBHOOK_URL="https://oapi.dingtalk.com/robot/send?access_token=your_access_token"

# 设置日志文件路径,默认是 /var/log/auth.log(具体路径根据你的系统调整)
LOG_FILE="/var/log/auth.log"

# 设置匹配的异常登录模式,例如:多个错误登录尝试或 IP 地址
PATTERN="Failed password"

# 设置阈值,超过此次数的 IP 会触发告警
THRESHOLD=5

# 获取当前时间,格式化为 YYYY-MM-DD HH:MM:SS
CURRENT_TIME=$(date "+%Y-%m-%d %H:%M:%S")

# 提取失败登录的 IP 地址,并统计每个 IP 的尝试次数
IP_ATTEMPTS=$(grep "$PATTERN" $LOG_FILE | grep -oP 'from \K(\S+)' | sort | uniq -c | sort -nr)

# 临时存储上次告警过的 IP 地址
LAST_ALERT_FILE="/tmp/last_alert_ips.txt"

# 读取上次告警过的 IP 地址列表
if [ -f "$LAST_ALERT_FILE" ]; then
    LAST_ALERT_IPS=$(cat "$LAST_ALERT_FILE")
else
    LAST_ALERT_IPS=""
fi

# 检查每个 IP 是否超过阈值,若超过则触发告警
ALERT_IPS=""
NEW_ALERT_IPS=""
while read -r count ip; do
    if [ "$count" -gt "$THRESHOLD" ]; then
        if [[ ! "$LAST_ALERT_IPS" =~ "$ip" ]]; then
            # 记录新增的攻击 IP 地址
            NEW_ALERT_IPS="$NEW_ALERT_IPS\n*IP 地址* [**$ip**] 尝试登录次数:$count 次"
        fi
    fi
done <<< "$IP_ATTEMPTS"

# 如果有新增 IP 地址,发送钉钉告警
if [ -n "$NEW_ALERT_IPS" ]; then
    # 构造告警内容
    MESSAGE="警告:检测到以下 IP 地址的 SSH 异常登录尝试。\n当前时间:$CURRENT_TIME\n$NEW_ALERT_IPS"

    # 发送钉钉告警
    curl -X POST $WEBHOOK_URL \
        -H "Content-Type: application/json" \
        -d '{
              "msgtype": "text",
              "text": {
                "content": "'"$MESSAGE"'"
              }
            }'

    # 更新已告警的 IP 地址记录
    echo -e "$LAST_ALERT_IPS\n$NEW_ALERT_IPS" | grep -oP 'from \K(\S+)' | sort | uniq > "$LAST_ALERT_FILE"
fi

版本三

要在脚本中新增将异常 IP 地址拉入黑名单的功能,可以在发现异常 IP 地址时,自动执行相关的封禁操作,将这些 IP 地址拉入黑名单,防止其继续尝试登录。
以下是修改后的脚本,使用 iptables 来封禁异常的 IP 地址

#!/bin/bash

# 设置钉钉 webhook URL
WEBHOOK_URL="https://oapi.dingtalk.com/robot/send?access_token=your_access_token"

# 设置日志文件路径,默认是 /var/log/auth.log(具体路径根据你的系统调整)
LOG_FILE="/var/log/auth.log"

# 设置匹配的异常登录模式,例如:多个错误登录尝试或 IP 地址
PATTERN="Failed password"

# 设置阈值,超过此次数的 IP 会触发告警
THRESHOLD=5

# 获取当前时间,格式化为 YYYY-MM-DD HH:MM:SS
CURRENT_TIME=$(date "+%Y-%m-%d %H:%M:%S")

# 提取失败登录的 IP 地址,并统计每个 IP 的尝试次数
IP_ATTEMPTS=$(grep "$PATTERN" $LOG_FILE | grep -oP 'from \K(\S+)' | sort | uniq -c | sort -nr)

# 临时存储上次告警过的 IP 地址
LAST_ALERT_FILE="/tmp/last_alert_ips.txt"

# 读取上次告警过的 IP 地址列表
if [ -f "$LAST_ALERT_FILE" ]; then
    LAST_ALERT_IPS=$(cat "$LAST_ALERT_FILE")
else
    LAST_ALERT_IPS=""
fi

# 检查每个 IP 是否超过阈值,若超过则触发告警
ALERT_IPS=""
NEW_ALERT_IPS=""
BLACKLIST_IPS=""
while read -r count ip; do
    if [ "$count" -gt "$THRESHOLD" ]; then
        if [[ ! "$LAST_ALERT_IPS" =~ "$ip" ]]; then
            # 记录新增的攻击 IP 地址
            NEW_ALERT_IPS="$NEW_ALERT_IPS\n*IP 地址* [**$ip**] 尝试登录次数:$count 次"

            # 将此 IP 地址加入黑名单
            BLACKLIST_IPS="$BLACKLIST_IPS\n$ip"

            # 使用 iptables 封禁该 IP
            iptables -A INPUT -s "$ip" -j DROP
            echo "IP 地址 $ip 已被添加到黑名单并封禁。"
        fi
    fi
done <<< "$IP_ATTEMPTS"

# 如果有新增 IP 地址,发送钉钉告警
if [ -n "$NEW_ALERT_IPS" ]; then
    # 构造告警内容
    MESSAGE="警告:检测到以下 IP 地址的 SSH 异常登录尝试。\n当前时间:$CURRENT_TIME\n$NEW_ALERT_IPS"

    # 发送钉钉告警
    curl -X POST $WEBHOOK_URL \
        -H "Content-Type: application/json" \
        -d '{
              "msgtype": "text",
              "text": {
                "content": "'"$MESSAGE"'"
              }
            }'

    # 更新已告警的 IP 地址记录
    echo -e "$LAST_ALERT_IPS\n$NEW_ALERT_IPS" | grep -oP 'from \K(\S+)' | sort | uniq > "$LAST_ALERT_FILE"
fi

# 如果有 IP 被加入黑名单,打印日志
if [ -n "$BLACKLIST_IPS" ]; then
    echo -e "以下 IP 地址已被添加到黑名单并封禁:$BLACKLIST_IPS" >> /var/log/ssh_blacklist.log
fi

最后编写一个crontab任务即可