00

身为一个半路出家的前端,本来让我写后端已经够高估我了,磕磕绊绊总算写完上线
完了还得部署上去,服务器这块玩的是真的少
然后没两天,阿里云就连接数报警了,直接几万个连接
然后服务器看着又一切正常,nginx日志看着也没毛病
问鸡皮提 top netstat ss 啥的都没有异常
反正找了半天没找到

01

最后总算是发现了,用的conntrack
conntrack -L | awk '{print $5}' | cut -d= -f2 | cut -d' ' -f1 | sort | uniq -c | sort -nr | head
直接列出了ip 和 连接数
那就好办了,直接iptables封禁
iptables -I INPUT -s 192.168.1.1 -j DROP
iptables -I FORWARD -s 192.168.1.1 -j DROP
然后断开链接
conntrack -D -s 192.168.1.1
保存下iptables
iptables-save > /etc/sysconfig/iptables

02

能自动的事绝不手动,这必然是要上脚本的
然后继续问鸡皮提,没学过,磕磕绊绊搞了很久
最后手动执行可以了,定时执行又不行了
最后发现是没有设置path

03

记录下脚本备用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/bin/bash
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
export SHELL=/bin/bash

# ===== 配置部分 =====
THRESHOLD=100 # 触发封禁的连接数阈值
WHITELIST=("127.0.0.1" "172.17.0.5") # 白名单IP
LOGFILE="/var/log/iptables_syn_block.log" # 日志路径
IPTABLES_SAVE_FILE="/etc/sysconfig/iptables" # CentOS规则保存路径

# ===== 初始化 =====
mkdir -p "$(dirname "$LOGFILE")"
touch "$LOGFILE"
echo "====== $(date) 脚本启动 ======" >> "$LOGFILE"

# ===== 已验证的IP统计方法(调试增强版) =====
get_conn_stats() {

echo "----- 调试:处理后IP列表 -----" >> "$LOGFILE"
conntrack -L 2>/dev/null | awk '{
for(i=1;i<=NF;i++) {
if($i=="src") {print $(i+1)}
else if($i~"src=") {print substr($i,5)}
}
}' | sort | uniq -c | sort -nr | head -n 20 #| tee -a "$LOGFILE"
}

# 函数:保存iptables规则
save_iptables_rules() {
echo "$(date): 保存iptables规则到 $IPTABLES_SAVE_FILE" >> "$LOGFILE"
iptables-save > "$IPTABLES_SAVE_FILE"
}


# ===== 增强封禁函数 =====
ban_ip() {
local IP=$1
local COUNT=$2

# 封禁INPUT链(如果未封禁)
if ! iptables -nL INPUT | grep -q "$IP"; then
iptables -I INPUT 1 -s "$IP" -j DROP && \
echo "$(date): [成功] INPUT封禁 $IP (连接数: $COUNT)" >> "$LOGFILE" || \
echo "$(date): [失败] INPUT封禁 $IP 失败" >> "$LOGFILE"
fi

# 封禁FORWARD链(如果未封禁)
if ! iptables -nL FORWARD | grep -q "$IP"; then
iptables -I FORWARD 1 -s "$IP" -j DROP && \
echo "$(date): [成功] FORWARD封禁 $IP (连接数: $COUNT)" >> "$LOGFILE" || \
echo "$(date): [失败] FORWARD封禁 $IP 失败" >> "$LOGFILE"
fi

# 清除现有连接
conntrack -D -s "$IP" &>/dev/null && \
echo "$(date): 已清除 $IP 的连接追踪" >> "$LOGFILE" || \
echo "$(date): 清除 $IP 连接失败" >> "$LOGFILE"
}

# ===== 主程序 =====
echo "当前连接统计:" | tee -a "$LOGFILE"
STATS=$(get_conn_stats)
echo "$STATS" | tee -a "$LOGFILE"

# 封禁处理
echo "$STATS" | while read COUNT IP; do
[[ -z "$IP" ]] && continue

# 跳过 172.16.0.0/12 私有网段
if [[ "$IP" =~ ^172\.1[6-9]\. || "$IP" =~ ^172\.2[0-9]\. || "$IP" =~ ^172\.3[0-1]\. ]]; then
echo "$(date): 跳过内网IP $IP" >> "$LOGFILE"
continue
fi

# 严格白名单检查
SKIP=false
for WIP in "${WHITELIST[@]}"; do
[[ "$IP" == "$WIP" ]] && SKIP=true && break
done
$SKIP && continue

if (( COUNT > THRESHOLD )); then
echo "正在封禁 $IP (连接数: $COUNT)" | tee -a "$LOGFILE"
ban_ip "$IP" "$COUNT"
fi
done

# 确保最后保存一次规则
save_iptables_rules

echo "====== $(date) 执行结束 ======" >> "$LOGFILE"

保存文件 给权限
chmod +x /usr/local/bin/auto_block_syn.sh
创建定时任务 每分钟走一次
crontab -e
* * * * * /usr/local/bin/auto_block_syn.sh
然后看日志应就有记录了

04

可气的是,我写完了,他不来了,可恶啊