bash脚本如何从日志提取匹配IP并通过ipset执行封禁?
日志特征匹配+ipset封禁IPv4地址实现方案
以下是可直接投入使用的完整bash脚本,全程完成特征匹配、ID校验、IP提取、合法性校验到封禁的全流程:
#!/bin/bash # 按实际情况修改以下两个变量 LOG_FILE="/path/to/your/target.log" IPSET_BLACKLIST="blacklist" # 若ipset黑名单不存在则先创建,可根据需求调整超时等参数 ipset create -exist "$IPSET_BLACKLIST" hash:ip awk -v lookback_lines=15 ' # 维护循环队列存储最近15行日志 { line_buffer[NR % lookback_lines] = $0 } # 匹配目标特征行 /sky is blue/ { # 提取当前行的纯数字clientID,严格匹配[数字]格式 if (match($0, /\[([0-9]+)\]/, id_res)) { target_id = id_res[1] # 回溯前15行查找同ID的连接建立记录 for (i = 1; i <= lookback_lines; i++) { current_line = line_buffer[(NR - i) % lookback_lines] # 双重校验:clientID完全匹配 + 是con_accept连接行 if (current_line ~ "\\[" target_id "\\]" && current_line ~ /con_accept:.*connection from/) { # 提取IPv4地址 if (match(current_line, /connection from ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+):/, ip_res)) { print ip_res[1] } break } } } } ' "$LOG_FILE" | sort -u | while read -r ip; do # 二次校验IPv4格式合法性,避免无效命令执行 if [[ $ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then # !参数代表IP已存在则直接跳过,不会抛出重复添加报错 ipset add "$IPSET_BLACKLIST" "$ip"! fi done
关键逻辑说明
- 滑窗存行:awk内部用循环队列存储最近15行日志,不需要输出中间内容做二次处理,执行效率更高
- ClientID精准匹配:提取和回溯时都严格匹配
[纯数字]格式,避免类似ID为75和759的部分匹配误判 - IP合法性双重校验:先从固定格式的
con_accept行提取IP,输出后再做一次正则格式校验,避免误提取异常字符串 - 去重处理:用
sort -u对提取到的IP去重,避免重复执行添加操作
内容的提问来源于stack exchange,提问作者Brian-reins
相关产品推荐
相关产品推荐

