服务器突然变得异常卡顿,SSH登录响应极慢,Web服务几乎不可用,但登录后台查看CPU和内存占用率却并不高。这种场景十有八九是网络层面的问题,要么是服务器主动对外发起了大量异常连接(比如被植入了挖矿木马或僵尸网络客户端),要么是正在遭受DDoS攻击的前兆。传统的Zabbix或Nagios在监控网络连接数方面并非强项,而Prometheus配合Node Exporter,可以非常精准地捕捉到这些异常信号。
为什么连接数指标是发现入侵和攻击的关键绝大多数Linux服务器在正常运行状态下,TCP连接数相对稳定。一台Web服务器可能维持在几百到几千个连接,一台数据库服务器可能只有几十到几百个连接。当这个数字在短时间内飙升到数万甚至数十万时,一定出了问题。常见的原因包括:服务器被攻破后成为扫描源或DDoS攻击源,对外发起大量SYN请求;应用层出现死循环或逻辑漏洞,导致连接池耗尽;遭受SYN Flood、CC攻击等DDoS攻击;恶意软件回连C2服务器产生大量长连接。这些异常都会直接反映在系统的连接追踪表或Socket状态中,而Prometheus可以轻松采集并告警。
Node Exporter采集网络指标的原理Prometheus生态中的Node Exporter默认会开启netstat模块,采集/proc/net/sockstat和/proc/net/netstat中的信息。其中最重要的几个指标包括:node_sockstat_TCP_tw,表示处于TIME_WAIT状态的TCP连接数;node_sockstat_TCP_alloc,表示已分配的TCP Socket数量;node_sockstat_TCP_inuse,表示正在使用的TCP连接数;node_netstat_Tcp_CurrEstab,表示当前已建立的TCP连接数。通过这些指标的组合分析,就能精准判断服务器连接状态是否异常。
部署Node Exporter并开启网络指标采集首先需要在被监控的服务器上部署Node Exporter。下载最新版本的Node Exporter并解压,然后创建systemd服务文件来管理它。默认情况下,Node Exporter会监听9100端口,并且自动包含netstat采集器。启动后可以通过curl http://localhost:9100/metrics | grep sockstat来验证网络指标是否正常输出。如果看到类似node_sockstat_TCP_inuse 342这样的数据,说明采集已经生效。
# 下载Node Exporter wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz tar -xzf node_exporter-1.7.0.linux-amd64.tar.gz sudo mv node_exporter-1.7.0.linux-amd64/node_exporter /usr/local/bin/ # 创建systemd服务 sudo tee /etc/systemd/system/node_exporter.service <Prometheus配置与抓取规则 在Prometheus服务器的配置文件中添加对应的Job来抓取Node Exporter的数据。编辑prometheus.yml,在scrape_configs部分添加新的目标。如果监控的服务器数量较多,建议使用文件服务发现或Consul来动态管理目标列表。抓取间隔可以根据实际需求设置,对于连接数这种变化较快的指标,15秒到30秒的间隔比较合适。
scrape_configs: - job_name: 'node_network' scrape_interval: 15s static_configs: - targets: - '192.168.1.100:9100' - '192.168.1.101:9100' labels: env: 'production'核心PromQL查询语句解读掌握几条关键的PromQL查询语句,是发现异常的第一步。查看当前所有服务器的TCP已建立连接数,使用node_netstat_Tcp_CurrEstab。这个指标直接反映了服务器上活跃的TCP连接数量。查看TIME_WAIT状态的连接数,使用node_sockstat_TCP_tw。TIME_WAIT连接过多通常意味着服务器处理了大量短连接请求,可能是CC攻击的迹象。查看TCP总分配数,使用node_sockstat_TCP_alloc。如果这个数值远大于inuse,说明有大量连接处于CLOSE_WAIT或其他中间状态,可能是应用层没有正确关闭连接。
# 查询当前已建立的TCP连接数 node_netstat_Tcp_CurrEstab{instance="192.168.1.100:9100"} # 查询TIME_WAIT状态的连接数 node_sockstat_TCP_tw{instance="192.168.1.100:9100"} # 计算连接数变化速率(每分钟新增连接数) rate(node_netstat_Tcp_CurrEstab{instance="192.168.1.100:9100"}[1m]) * 60建立异常检测的告警规则有了数据采集和查询能力,接下来需要建立有效的告警规则。告警阈值不能拍脑袋设定,需要先观察服务器正常运行一周的历史数据,取峰值的1.5到2倍作为告警阈值。比如一台Web服务器正常高峰期TCP连接数在3000左右,那么告警阈值可以设置在5000到6000。对于连接数增长速率的告警更为重要,因为DDoS攻击往往在几十秒内就能让连接数翻倍。建议设置两个级别的告警:warning级别用于提醒运维人员关注,critical级别则需要立即响应。
groups: - name: tcp_connection_alerts interval: 30s rules: - alert: HighTCPConnections expr: node_netstat_Tcp_CurrEstab > 5000 for: 2m labels: severity: warning annotations: summary: "服务器 {{ $labels.instance }} TCP连接数过高" description: "当前TCP连接数为 {{ $value }},超过阈值5000,请检查是否存在异常流量或应用故障。" - alert: CriticalTCPConnections expr: node_netstat_Tcp_CurrEstab > 10000 for: 1m labels: severity: critical annotations: summary: "服务器 {{ $labels.instance }} TCP连接数严重异常" description: "当前TCP连接数为 {{ $value }},超过严重阈值10000,疑似DDoS攻击或恶意软件活动。" - alert: RapidConnectionGrowth expr: rate(node_netstat_Tcp_CurrEstab[1m]) * 60 > 1000 for: 30s labels: severity: critical annotations: summary: "服务器 {{ $labels.instance }} 连接数急剧增长" description: "每分钟新增连接数达到 {{ $value }},可能是DDoS攻击前兆,请立即处理。" - alert: HighTimeWaitConnections expr: node_sockstat_TCP_tw > 30000 for: 2m labels: severity: warning annotations: summary: "服务器 {{ $labels.instance }} TIME_WAIT连接数过高" description: "当前TIME_WAIT连接数为 {{ $value }},可能存在大量短连接请求,需关注是否为CC攻击。"区分正常流量突增与真实攻击并非所有连接数飙升都是攻击。电商大促、抢票活动、热点事件都可能导致流量正常增长。如何区分?关键在于多维度的交叉分析。将TCP连接数指标与应用层指标结合判断,比如同时观察HTTP请求数、带宽使用量、响应延迟等。如果连接数暴增但HTTP请求数没有同比例增长,说明可能是SYN Flood攻击,只建立连接不发送请求。如果连接数和请求数都暴增但带宽变化不大,可能是CC攻击或慢速攻击。如果三者同步增长,大概率是正常流量。Prometheus可以通过同时查询多个指标来实现这种交叉验证。
# 同时查询连接数和HTTP请求数,观察增长比例 node_netstat_Tcp_CurrEstab{instance="web-server:9100"} rate(nginx_http_requests_total{instance="web-server:9100"}[1m]) # 如果连接数增长远快于请求数增长,则可能是攻击 (node_netstat_Tcp_CurrEstab / rate(nginx_http_requests_total[1m])) > 10利用conntrack指标深入分析连接状态对于更精细化的监控,可以启用Node Exporter的conntrack采集器。Linux内核的连接追踪模块维护了所有网络连接的状态信息。通过conntrack指标,可以按协议、状态分类查看连接分布。比如监控SYN_SENT状态的连接数,如果短时间内出现大量SYN_SENT,说明服务器对外发起了大量连接请求,这通常是服务器被入侵后参与DDoS攻击的典型特征。同样,SYN_RECV状态连接数暴增则意味着服务器正在遭受SYN Flood攻击。
# 启用conntrack采集器 node_exporter --collector.netstat --collector.conntrack # 查询SYN_SENT状态连接数 node_nf_conntrack_entries{state="SYN_SENT"} # 查询SYN_RECV状态连接数 node_nf_conntrack_entries{state="SYN_RECV"}构建Grafana可视化监控面板告警规则能及时发现问题,而可视化面板则能帮助运维人员快速定位问题根源。在Grafana中创建一个专门的网络连接监控Dashboard。建议包含以下面板:TCP连接总数趋势图,使用折线图展示node_netstat_Tcp_CurrEstab随时间的变化;各状态连接分布图,使用堆叠图展示ESTABLISHED、TIME_WAIT、CLOSE_WAIT等状态的连接数;连接数变化速率图,使用rate函数计算每分钟新增连接数;Top连接数服务器排行,使用表格列出连接数最高的服务器;conntrack连接总数趋势,监控内核连接追踪表的使用情况。这些面板组合在一起,能在几秒内判断出异常的性质和影响范围。
应急响应与自动化处理策略当Prometheus触发critical级别告警时,运维人员需要立即采取行动。第一件事不是登录服务器,而是通过Prometheus的查询界面确认告警的真实性,查看连接数的具体数值和增长趋势。确认异常后,优先通过网络层面进行流量清洗,比如联系机房或云服务商启用黑洞路由或流量清洗服务。如果服务器已被入侵,需要立即隔离服务器,通过iptables限制出站连接,防止其继续对外发起攻击。同时保留内存快照和网络日志用于事后溯源。可以将这些应急步骤部分自动化,比如通过Alertmanager的webhook功能触发自动化脚本,当检测到连接数超过临界值时自动执行iptables规则限制单个IP的连接频率。
# 示例:限制单个IP的最大连接数 iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 50 -j DROP # 限制服务器对外发起的连接(防止成为攻击源) iptables -A OUTPUT -p tcp -m state --state NEW -m limit --limit 100/s -j ACCEPT iptables -A OUTPUT -p tcp -m state --state NEW -j DROP长期优化与基线建立监控的最终目的是建立稳定的安全基线。运行Prometheus一个月后,会积累大量的历史数据。利用这些数据可以计算出每台服务器在不同时段的连接数正常范围。比如某台API服务器在工作日上午10点的TCP连接数通常在2000到3500之间,凌晨3点则在100到300之间。基于这些历史数据,可以设置动态告警阈值,而不是一刀切的固定值。Prometheus的recording rules功能可以预计算这些统计指标,然后告警规则引用这些预计算结果。动态阈值能大幅降低误报率,让告警更加精准。
# recording rule计算过去一周同时段的连接数均值 groups: - name: tcp_baseline interval: 60s rules: - record: tcp_connections_weekly_avg expr: avg_over_time(node_netstat_Tcp_CurrEstab[1w] offset 1w) # 基于动态基线的告警 - alert: DeviationFromBaseline expr: node_netstat_Tcp_CurrEstab > tcp_connections_weekly_avg * 2 for: 5m labels: severity: warning annotations: summary: "服务器 {{ $labels.instance }} 连接数偏离历史基线"通过Prometheus监控服务器异常连接数,本质上是建立了一套低成本但高效率的网络层入侵检测系统。它不能替代专业的IDS或防火墙,但能在第一时间发现那些绕过传统安全设备的异常行为。当一台服务器突然开始对外发起数千个连接,或者短时间内接收了大量SYN包时,Prometheus的告警会比任何人工巡检都更快地发出通知。这套方案的核心价值在于将网络层的异常可视化、可量化、可告警化,让运维团队从被动响应转向主动发现。
