服务器突然变得异常卡顿,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的告警会比任何人工巡检都更快地发出通知。这套方案的核心价值在于将网络层的异常可视化、可量化、可告警化,让运维团队从被动响应转向主动发现。