TCP连接数监控与异常检测
监控服务器TCP连接状态,统计各状态连接数,检测异常连接(如SYN_RECV过多可能是DDOS攻击),支持按IP统计连接数并告警
详细内容
#!/bin/bash
# ==========================================
# TCP连接数监控与异常检测脚本
# 用途:监控TCP连接状态,检测异常连接和潜在攻击
# 使用方法:bash tcp_conn_monitor.sh --once (单次检测)
# bash tcp_conn_monitor.sh (持续监控)
# ==========================================
# ========== 配置 ==========
WARN_TOTAL=1000 # 总连接数告警阈值
WARN_SYN_RECV=50 # SYN_RECV状态告警阈值(可能是SYN洪水攻击)
WARN_TIME_WAIT=5000 # TIME_WAIT告警阈值
WARN_PER_IP=100 # 单个IP连接数告警阈值
CHECK_INTERVAL=60 # 检测间隔(秒)
LOG_FILE="/var/log/tcp_conn_monitor.log"
ALERT_EMAIL=""
WECOM_WEBHOOK=""
# ==========================
mkdir -p "$(dirname "$LOG_FILE")"
log_msg() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
send_alert() {
local title="$1"
local content="$2"
log_msg "【告警】$title: $content"
if [ -n "$ALERT_EMAIL" ]; then
echo -e "$content" | mail -s "【网络告警】$title" "$ALERT_EMAIL" 2>/dev/null
fi
if [ -n "$WECOM_WEBHOOK" ]; then
curl -s "$WECOM_WEBHOOK" -H "Content-Type: application/json" -d "{
"msgtype": "text",
"text": {"content": "【网络告警】$title\n$content\n主机: $(hostname)"}
}" >/dev/null 2>&1
fi
}
check_connections() {
log_msg "===== TCP连接状态检测 ====="
# 统计各状态连接数
declare -A STATES
while read -r state; do
STATES[$state]=$((${STATES[$state]:-0} + 1))
done < <(ss -tan 2>/dev/null | awk 'NR>1{print $1}' || netstat -tan 2>/dev/null | awk 'NR>2{print $6}')
TOTAL=0
for state in "${!STATES[@]}"; do
count=${STATES[$state]}
TOTAL=$((TOTAL + count))
log_msg " $state: $count"
done
log_msg " 总计: $TOTAL"
# 总连接数告警
if [ "$TOTAL" -gt "$WARN_TOTAL" ]; then
send_alert "TCP总连接数过高" "当前总连接数: $TOTAL (阈值: $WARN_TOTAL)\n可能存在异常流量或攻击"
fi
# SYN_RECV告警(可能是SYN洪水攻击)
SYN_RECV=${STATES[SYN-RECV]:-${STATES[SYN_RECV]:-0}}
if [ "$SYN_RECV" -gt "$WARN_SYN_RECV" ]; then
TOP_IPS=$(ss -tan 2>/dev/null | grep SYN-RECV | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head -5)
send_alert "SYN_RECV连接数异常" "SYN_RECV: $SYN_RECV (阈值: $WARN_SYN_RECV)\n可能遭受SYN洪水攻击!\nTop攻击IP:\n$TOP_IPS"
fi
# TIME_WAIT告警
TIME_WAIT=${STATES[TIME-WAIT]:-${STATES[TIME_WAIT]:-0}}
if [ "$TIME_WAIT" -gt "$WARN_TIME_WAIT" ]; then
send_alert "TIME_WAIT连接数过高" "TIME_WAIT: $TIME_WAIT (阈值: $WARN_TIME_WAIT)\n建议优化内核参数: net.ipv4.tcp_tw_reuse=1"
fi
# 按IP统计连接数,检测异常IP
log_msg " Top 10 IP连接数:"
TOP_IPS=$(ss -tan 2>/dev/null | awk 'NR>1{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head -10)
echo "$TOP_IPS" | while read count ip; do
[ -z "$ip" ] && continue
log_msg " $ip: $count"
if [ "$count" -gt "$WARN_PER_IP" ] && [ "$ip" != "127.0.0.1" ] && [ "$ip" != "::1" ]; then
send_alert "单个IP连接数异常" "IP: $ip 连接数: $count (阈值: $WARN_PER_IP)\n可能是异常连接或攻击"
fi
done
# 监听端口列表
log_msg " 监听端口:"
ss -tlnp 2>/dev/null | awk 'NR>1{print " "$4" ("$6")"}' | head -20
}
if [ "$1" = "--once" ]; then
check_connections
exit 0
fi
log_msg "===== TCP连接监控启动,间隔${CHECK_INTERVAL}秒 ====="
while true; do
check_connections
sleep "$CHECK_INTERVAL"
done
适配环境
适配系统:CentOS 7+,Ubuntu 18.04+,Debian 10+
依赖环境:bash 4.0+
参数说明
[{"name": "WARN_TOTAL", "label": "\u603b\u8fde\u63a5\u6570\u544a\u8b66\u9608\u503c", "default": "1000"}, {"name": "WARN_SYN_RECV", "label": "SYN_RECV\u544a\u8b66\u9608\u503c", "default": "50"}, {"name": "WARN_PER_IP", "label": "\u5355IP\u8fde\u63a5\u6570\u544a\u8b66\u9608\u503c", "default": "100"}, {"name": "ALERT_EMAIL", "label": "\u544a\u8b66\u90ae\u7bb1(\u53ef\u9009)", "default": ""}]