“瑞士军刀” netstat 和 ss 命令详解:网络连接排查利器

157 阅读6分钟

1. 引言

在网络管理和故障排查中,能够快速准确地查看和分析网络连接状态是至关重要的技能。Linux 系统提供了两个强大的网络诊断工具:netstat 和 ss。这两个命令被誉为网络管理员的"瑞士军刀",能够帮助您深入了解系统的网络连接状况、端口使用情况以及各种网络统计信息。

2. netstat 命令详解

2.1 netstat 基础介绍

netstat(network statistics)是一个传统的网络工具,用于显示网络连接、路由表、接口统计等信息。虽然在新系统中逐渐被 ss 命令取代,但它仍然是许多管理员的首选工具。

2.2 netstat 安装与基本语法

安装 netstat:

# Ubuntu/Debian 系统
sudo apt update
sudo apt install net-tools

# CentOS/RHEL 系统
sudo yum install net-tools

# 验证安装
netstat --version

基本语法结构:

netstat [选项]

2.3 netstat 常用参数详解

# 显示所有连接
netstat -a

# 显示 TCP 连接
netstat -t

# 显示 UDP 连接  
netstat -u

# 显示监听端口
netstat -l

# 显示数字格式的地址和端口
netstat -n

# 显示进程 ID 和程序名称
netstat -p

# 组合使用示例
netstat -tunlp

2.4 netstat 实战应用

查看所有网络连接:

# 显示所有活动的网络连接
netstat -a

# 显示详细信息示例
netstat -tunap

分析输出结果:

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1234/sshd
tcp        0      0 192.168.1.100:22        192.168.1.50:54321      ESTABLISHED 5678/sshd: user
tcp6       0      0 :::80                   :::*                    LISTEN      9012/apache2

解释各列含义:

  • Proto:协议类型(TCP/UDP)
  • Recv-Q:接收队列大小
  • Send-Q:发送队列大小
  • Local Address:本地地址和端口
  • Foreign Address:远程地址和端口
  • State:连接状态
  • PID/Program name:进程ID和程序名称

2.5 netstat 高级用法

按协议筛选连接:

# 只显示 TCP 连接
netstat -at

# 只显示 UDP 连接
netstat -au

# 显示 UNIX 域套接字
netstat -ax

查看网络接口统计:

# 显示网络接口统计信息
netstat -i

# 持续显示接口统计
netstat -ic

查看路由表:

# 显示内核路由表
netstat -r

# 显示数字格式的路由表
netstat -rn

3. ss 命令详解

3.1 ss 命令介绍

ss(socket statistics)是 iproute2 工具包的一部分,比 netstat 更快速、更高效,特别是在处理大量连接时表现更出色。

3.2 ss 基本语法和安装

ss 通常随系统预装,验证方法:

ss --version

基本语法:

ss [选项] [过滤表达式]

3.3 ss 核心参数详解

# 显示所有套接字
ss -a

# 显示 TCP 套接字
ss -t

# 显示 UDP 套接字
ss -u

# 显示监听套接字
ss -l

# 显示进程信息
ss -p

# 显示数字格式
ss -n

# 显示计时器信息
ss -o

# 显示详细的套接字信息
ss -e

# 显示内部 TCP 信息
ss -i

3.4 ss 命令实战应用

查看所有连接:

# 显示所有连接
ss -a

# 显示详细信息
ss -tunp

分析连接状态:

# 按状态筛选连接
ss -t state established
ss -t state listening
ss -t state time-wait

常用状态类型:

  • established:已建立的连接
  • syn-sent:SYN 已发送
  • syn-recv:SYN 已接收
  • fin-wait-1:FIN 等待1
  • fin-wait-2:FIN 等待2
  • time-wait:时间等待
  • closed:已关闭
  • close-wait:关闭等待
  • last-ack:最后确认
  • listening:监听状态
  • closing:正在关闭

3.5 ss 高级过滤功能

按端口过滤:

# 查看特定端口的连接
ss -t sport = :80
ss -t dport = :443

# 查看端口范围
ss -t sport gt :1024
ss -t dport le :10000

按 IP 地址过滤:

# 查看特定 IP 的连接
ss -t dst 192.168.1.100
ss -t src 10.0.0.50

# 查看 IP 段的连接
ss -t src 192.168.1.0/24

组合过滤条件:

# 复杂的过滤条件
ss -t '( dport = :80 or dport = :443 )'
ss -t state established '( sport = :22 or sport = :23 )'

4. netstat 与 ss 对比分析

4.1 性能对比

# 测试 netstat 性能
time netstat -tun

# 测试 ss 性能  
time ss -tun

# 对比输出行数
netstat -tun | wc -l
ss -tun | wc -l

4.2 功能特性对比

特性netstatss
速度较慢快速
内存使用较高较低
信息详细程度基础详细
过滤功能有限强大
系统资源消耗多消耗少

4.3 使用场景推荐

推荐使用 netstat 的场景:

  • 老版本系统兼容性要求
  • 简单的连接查看
  • 路由表信息查看

推荐使用 ss 的场景:

  • 高性能要求的场景
  • 复杂的连接过滤
  • 详细的连接信息分析
  • 大量连接的处理

5. 网络连接排查实战流程

以下是通过 netstat 和 ss 进行网络连接排查的完整流程:

graph TD
    A[开始网络排查] --> B{选择排查工具};
    B --> C[使用ss命令];
    B --> D[使用netstat命令];
    
    C --> E[查看所有连接 ss -tunap];
    D --> F[查看所有连接 netstat -tunap];
    
    E --> G[分析连接状态];
    F --> G;
    
    G --> H{发现问题连接?};
    H -->|是| I[详细分析问题连接];
    H -->|否| J[排查结束];
    
    I --> K[使用过滤条件精确定位];
    K --> L[分析进程和状态];
    L --> M[制定解决方案];
    M --> N[实施修复措施];
    N --> O[验证修复结果];
    O --> P[问题解决];
    
    style A fill:#2ecc71,stroke:#27ae60,stroke-width:2px,color:white
    style P fill:#2ecc71,stroke:#27ae60,stroke-width:2px,color:white
    style I fill:#e74c3c,stroke:#c0392b,stroke-width:2px,color:white
    style M fill:#3498db,stroke:#2980b9,stroke-width:2px,color:white
    style E fill:#9b59b6,stroke:#8e44ad,stroke-width:2px,color:white
    style G fill:#f39c12,stroke:#e67e22,stroke-width:2px,color:white
    
    style B fill:#34495e,stroke:#2c3e50,stroke-width:2px,color:white
    style C fill:#34495e,stroke:#2c3e50,stroke-width:2px,color:white
    style D fill:#34495e,stroke:#2c3e50,stroke-width:2px,color:white
    style F fill:#34495e,stroke:#2c3e50,stroke-width:2px,color:white
    style H fill:#34495e,stroke:#2c3e50,stroke-width:2px,color:white
    style K fill:#34495e,stroke:#2c3e50,stroke-width:2px,color:white
    style L fill:#34495e,stroke:#2c3e50,stroke-width:2px,color:white
    style N fill:#34495e,stroke:#2c3e50,stroke-width:2px,color:white
    style O fill:#34495e,stroke:#2c3e50,stroke-width:2px,color:white
    style J fill:#95a5a6,stroke:#7f8c8d,stroke-width:2px,color:white

5.1 完整的排查脚本示例

#!/bin/bash

# 网络连接排查脚本
echo "=== 网络连接全面排查报告 ==="
echo "生成时间: $(date)"
echo ""

echo "1. 系统基本信息"
echo "主机名: $(hostname)"
echo "IP 地址: $(hostname -I)"
echo ""

echo "2. 使用 ss 命令查看所有 TCP 连接"
echo "----------------------------------------"
ss -tunp
echo ""

echo "3. 查看监听端口"
echo "----------------------------------------"
ss -tunlp
echo ""

echo "4. 按状态统计连接数"
echo "----------------------------------------"
echo "ESTABLISHED: $(ss -t state established | wc -l)"
echo "LISTEN: $(ss -t state listening | wc -l)" 
echo "TIME-WAIT: $(ss -t state time-wait | wc -l)"
echo ""

echo "5. 查看特定服务连接"
echo "----------------------------------------"
echo "SSH 连接:"
ss -t sport = :22
echo ""
echo "HTTP 连接:"
ss -t sport = :80
echo ""

echo "6. 网络接口统计"
echo "----------------------------------------"
netstat -i
echo ""

echo "7. 路由表信息"
echo "----------------------------------------"
netstat -rn
echo ""

echo "排查完成"

5.2 常见问题排查案例

案例 1:端口占用问题

# 查找占用 8080 端口的进程
ss -tunlp | grep :8080
# 或者使用 netstat
netstat -tunlp | grep :8080

# 如果找到占用进程,可以进一步分析
ps aux | grep [PID]

案例 2:连接数过多问题

# 统计每个 IP 的连接数
ss -tun | grep ESTAB | awk '{print $6}' | cut -d: -f1 | sort | uniq -c | sort -nr

# 查看连接数最多的前10个IP
ss -tun | grep ESTAB | awk '{print $6}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -10

案例 3:网络服务故障

# 检查服务是否在监听
ss -tunl | grep :80
if [ $? -ne 0 ]; then
    echo "HTTP 服务未在监听状态"
    # 进一步检查服务状态
    systemctl status apache2 || systemctl status nginx
fi

6. 高级技巧和自动化脚本

6.1 监控网络连接的脚本

#!/bin/bash

# 网络连接监控脚本
INTERVAL=5  # 监控间隔(秒)
LOG_FILE="/var/log/network_connections.log"

echo "开始网络连接监控,间隔: ${INTERVAL}秒" | tee -a $LOG_FILE

while true; do
    TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
    echo "=== 时间: $TIMESTAMP ===" | tee -a $LOG_FILE
    
    # 记录总连接数
    TOTAL_CONN=$(ss -tun | wc -l)
    ESTABLISHED=$(ss -t state established | wc -l)
    LISTENING=$(ss -t state listening | wc -l)
    
    echo "总连接数: $TOTAL_CONN" | tee -a $LOG_FILE
    echo "已建立连接: $ESTABLISHED" | tee -a $LOG_FILE  
    echo "监听端口: $LISTENING" | tee -a $LOG_FILE
    
    # 如果有异常连接数增加,记录详细信息
    if [ $TOTAL_CONN -gt 1000 ]; then
        echo "警告: 连接数异常增加!" | tee -a $LOG_FILE
        ss -tunp >> $LOG_FILE
    fi
    
    echo "----------------------------------------" | tee -a $LOG_FILE
    sleep $INTERVAL
done

6.2 网络连接分析报告生成

#!/bin/bash

# 生成网络连接分析报告
REPORT_FILE="/tmp/network_analysis_$(date +%Y%m%d_%H%M%S).txt"

{
echo "网络连接分析报告"
echo "生成时间: $(date)"
echo "========================================"

echo "一、系统概览"
echo "----------------------------------------"
echo "主机名: $(hostname)"
echo "运行时间: $(uptime)"
echo "IP 地址: $(hostname -I)"
echo ""

echo "二、连接统计"
echo "----------------------------------------"
echo "TCP 连接统计:"
ss -t | awk 'NR>1 {count[$2]++} END {for(state in count) print state ": " count[state]}'
echo ""

echo "三、监听服务"
echo "----------------------------------------"
echo "TCP 监听服务:"
ss -tuln | grep LISTEN | while read line; do
    PROTO=$(echo $line | awk '{print $1}')
    LOCAL=$(echo $line | awk '{print $5}')
    PID=$(echo $line | awk '{print $7}' | cut -d, -f2)
    echo "$PROTO $LOCAL -> PID: $PID"
done
echo ""

echo "四、连接数最多的IP"
echo "----------------------------------------"
ss -tun | awk '{print $6}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -10 | \
while read count ip; do
    if [ "$ip" != "*" ] && [ -n "$ip" ]; then
        echo "$count 连接来自 $ip"
    fi
done
echo ""

echo "五、异常连接检测"
echo "----------------------------------------"
# 检测 TIME-WAIT 状态过多的连接
TIME_WAIT_COUNT=$(ss -t state time-wait | wc -l)
if [ $TIME_WAIT_COUNT -gt 100 ]; then
    echo "警告: TIME-WAIT 状态连接过多: $TIME_WAIT_COUNT"
fi

# 检测 CLOSE-WAIT 状态连接
CLOSE_WAIT_COUNT=$(ss -t state close-wait | wc -l)
if [ $CLOSE_WAIT_COUNT -gt 10 ]; then
    echo "警告: CLOSE-WAIT 状态连接: $CLOSE_WAIT_COUNT"
fi

echo ""
echo "报告生成完成"

} > $REPORT_FILE

echo "分析报告已保存至: $REPORT_FILE"

7. 总结

netstat 和 ss 命令是 Linux 系统网络排查中不可或缺的工具。通过本教程的学习,您应该能够:

  1. 熟练使用 netstat 查看网络连接、路由表和接口统计
  2. 掌握 ss 命令的高效用法和强大过滤功能
  3. 理解两个命令的优缺点和适用场景
  4. 建立完整的网络连接排查流程
  5. 编写自动化脚本来监控和分析网络状态

在实际工作中,建议优先使用 ss 命令进行网络连接分析,特别是在处理大量连接时。而对于简单的查看或老系统兼容性要求时,可以使用 netstat 命令。

记住,熟练使用这些工具需要不断的实践和经验积累。建议在日常工作中多使用这些命令,逐步培养对网络连接状态的敏感度和分析能力。