掌握 Linux Netstat 命令:从基础到高级网络监控

LightNode
By LightNode ·

介绍

netstat(网络统计)命令是 Linux 系统管理员工具包中最基本的网络工具之一。这个多功能的命令行实用程序提供了网络连接、路由表、接口统计信息以及其他重要的网络相关信息的全面视图。

什么是 netstat?

netstat 是一个命令行网络实用程序,用于显示各种网络相关信息,包括:

  • 网络连接(包括传入和传出)
  • 路由表
  • 网络接口统计信息
  • 伪装连接
  • 多播成员资格
  • 协议统计信息

为什么它很重要

系统管理员和网络工程师依赖 netstat 完成几个关键任务:

  1. 故障排除网络问题 - 快速识别连接问题和网络瓶颈
  2. 安全监控 - 检测未经授权的网络连接和可疑活动
  3. 性能分析 - 监控网络流量模式和接口统计信息
  4. 系统审计 - 审查活动服务和开放端口

简要历史

netstat 命令自 Unix 系统早期以来就是 TCP/IP 网络工具包的一部分。虽然它起源于 BSD Unix,但它已经发展成为各种类 Unix 操作系统的标准工具,包括 Linux。尽管被认为是“弃用”的,因更现代的工具如 ss 的出现,netstat 仍然因其:

  • 在系统管理员中广泛使用
  • 在不同类 Unix 系统中的广泛可用性
  • 丰富的功能集和详细的输出选项
  • 广泛的文档和社区支持而被广泛使用

基本语法和用法

命令格式

netstat 命令的基本语法是:

netstat [选项]

该命令可以与各种选项一起使用,以根据您的需要自定义输出。没有任何选项时,netstat 将显示打开的套接字列表。

常用选项和标志

以下是最常用的选项:

选项描述
-a显示所有监听端口和活动连接
-t显示 TCP 连接
-u显示 UDP 连接
-n显示数字地址,而不是解析主机和端口
-l仅显示监听套接字
-p显示 PID 和程序名称
-r显示路由表
-i显示网络接口统计信息
-s显示协议统计信息

基本示例

  1. 查看所有活动连接
netstat -a
  1. 显示所有 TCP 连接
netstat -at
  1. 显示带有程序信息的监听端口
sudo netstat -tulnp

这个常用组合显示:

  • -t: TCP 连接
  • -u: UDP 连接
  • -l: 仅监听端口
  • -n: 数字地址
  • -p: 程序信息
  1. 检查路由表
netstat -r
  1. 查看接口统计信息
netstat -i

理解输出

典型的 netstat 输出包括几个列:

  • Proto: 协议(TCP、UDP)
  • Recv-Q: 接收队列中的数据
  • Send-Q: 发送队列中的数据
  • Local Address: 连接的本地端点
  • Foreign Address: 连接的远程端点
  • State: 连接状态(LISTEN、ESTABLISHED 等)

使用 netstat -tan 时的示例输出:

Proto Recv-Q Send-Q Local Address          Foreign Address        State
tcp        0      0 0.0.0.0:22            0.0.0.0:*             LISTEN
tcp        0      0 127.0.0.1:631         0.0.0.0:*             LISTEN
tcp        0      0 192.168.1.5:22        192.168.1.100:52614   ESTABLISHED

关键特性和选项

显示选项

列出所有连接

netstat 命令提供了多种方式来列出网络连接,具体取决于您的需求:

  1. 显示所有协议的数字地址
netstat -an
  1. 显示扩展信息
netstat -ae

这将添加额外的信息,如用户和 inode

  1. 显示计时器信息
netstat -o

添加有助于故障排除的计时信息

协议特定显示

  1. 仅 TCP
# 显示所有 TCP 连接,包括监听端口
netstat -at

# 仅显示监听 TCP 端口
netstat -lt
  1. 仅 UDP
# 显示所有 UDP 连接
netstat -au

# 仅显示监听 UDP 端口
netstat -lu
  1. Unix 域套接字
# 显示 Unix 域套接字
netstat -x

输出格式选项

数字显示

# 完全数字输出(不进行名称解析)
netstat -n

# 与其他选项结合
netstat -ant  # 带有数字地址的 TCP 连接

数字显示的好处:

  • 更快的执行
  • 无需 DNS 查找
  • 在 DNS 问题情况下更可靠

扩展信息视图

# 显示进程信息
sudo netstat -p

# 显示用户和进程信息
sudo netstat -ep

# 显示带有扩展信息的网络接口统计信息
netstat -ie

持续显示

# 每 2 秒更新一次
netstat -c

# 与其他选项结合进行持续监控
netstat -ct  # 持续 TCP 监控

统计显示

  1. 协议统计
# 显示所有协议的摘要统计
netstat -s

# 仅显示 TCP 统计
netstat -st

# 仅显示 UDP 统计
netstat -su
  1. 接口统计
# 显示接口统计信息
netstat -i

# 显示扩展接口信息
netstat -ie

接口统计信息的示例输出:

Iface    MTU   RX-OK RX-ERR RX-DRP RX-OVR   TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0    1500  158426      0      0      0   88573      0      0      0 BMRU
lo     65536   24846      0      0      0   24846      0      0      0 LRU

其中:

  • RX: 接收统计
  • TX: 发送统计
  • OK: 成功的数据包
  • ERR: 错误计数
  • DRP: 丢弃的数据包
  • OVR: 溢出事件

常见用例

网络故障排除

检查开放端口

  1. 查找系统上的所有开放端口
sudo netstat -tulpn | grep LISTEN

此命令有助于识别:

  • 正在运行的服务
  • 它们使用的端口
  • 拥有这些端口的进程
  1. 检查特定端口是否正在使用
sudo netstat -tulpn | grep ":80"    # 检查 Web 服务器
sudo netstat -tulpn | grep ":3306"  # 检查 MySQL

识别活动连接

  1. 监控当前连接
# 显示所有已建立的连接
netstat -nat | grep ESTABLISHED

# 统计每个 IP 地址的连接数
netstat -nat | grep ESTABLISHED | awk '{print $5}' | cut -d: -f1 | sort | uniq -c
  1. 跟踪连接状态
# 查看连接状态分布
netstat -ant | awk '{print $6}' | sort | uniq -c

监控网络流量

  1. 接口流量分析
# 实时监控接口统计信息
netstat -i
watch -n 1 "netstat -i"
  1. 协议特定监控
# 监控 TCP 流量统计
netstat -st

# 监控 UDP 流量统计
netstat -su

安全分析

查找可疑连接

  1. 检测异常端口
# 列出所有非标准监听端口
sudo netstat -tulpn | grep -v ":22\|:80\|:443"
  1. 检查可疑连接模式
# 查找来自意外 IP 的连接
netstat -ant | grep ESTABLISHED | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn

端口扫描检测

# 查找多个连接尝试
netstat -ant | grep SYN_RECV | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr

系统审计

  1. 服务验证
# 检查哪些进程在监听哪些端口
sudo netstat -tulpn | grep LISTEN | sort -k 4
  1. 连接日志
# 创建一个简单的连接日志
while true; do
    date >> connection_log.txt
    netstat -ant >> connection_log.txt
    sleep 60
done
  1. 资源使用监控
# 监控每个服务的连接计数
netstat -ant | grep ESTABLISHED | awk '{print $4}' | cut -d: -f2 | sort | uniq -c

常见故障排除场景

  1. Web 服务器问题
# 检查 Web 服务器连接
sudo netstat -ant | grep ":80\|:443" | awk '{print $6}' | sort | uniq -c
  1. 数据库连接问题
# 监控数据库连接(MySQL 示例)
sudo netstat -ant | grep :3306 | awk '{print $6}' | sort | uniq -c
  1. 邮件服务器分析
# 检查邮件服务器连接
sudo netstat -ant | grep ":25\|:465\|:587" | awk '{print $6}' | sort | uniq -c

高级用法

与其他命令结合使用

使用 grep 和 awk

  1. 复杂过滤和分析
# 按状态和端口统计连接
netstat -ant | awk '{print $6, $4}' | sort | uniq -c | sort -rn

# 监控特定服务连接的变化
watch -n 1 'netstat -ant | grep ":80" | wc -l'
  1. 高级连接分析
# 创建连接摘要
netstat -ant | \
awk '{ip[$5]++} END {for (i in ip) print ip[i],i}' | \
sort -nr | head -n 10

管道到其他工具

# 使用 tee 进行日志记录
netstat -ant | tee network_status.log

# 使用 xargs 进行进程管理
netstat -tulpn | grep LISTEN | awk '{print $7}' | cut -d/ -f1 | xargs ps -f

脚本和自动化

基本监控脚本

#!/bin/bash

LOG_FILE="/var/log/network_monitor.log"

monitor_connections() {
    echo "=== 网络状态报告 ===" >> $LOG_FILE
    date >> $LOG_FILE
    echo "活动连接:" >> $LOG_FILE
    netstat -ant | grep ESTABLISHED | wc -l >> $LOG_FILE
    echo "监听端口:" >> $LOG_FILE
    netstat -tulpn | grep LISTEN >> $LOG_FILE
    echo "=========================" >> $LOG_FILE
}

# 每 5 分钟运行一次
while true; do
    monitor_connections
    sleep 300
done

高级分析脚本

#!/bin/bash

analyze_network() {
    echo "=== 网络分析 ==="
    
    echo -e "\n前 10 个 IP 连接:"
    netstat -ant | grep ESTABLISHED | \
    awk '{print $5}' | cut -d: -f1 | \
    sort | uniq -c | sort -rn | head -n 10
    
    echo -e "\n连接状态:"
    netstat -ant | awk '{print $6}' | \
    sort | uniq -c | sort -rn
    
    echo -e "\n端口使用情况:"
    netstat -ant | awk '{print $4}' | \
    cut -d: -f2 | sort | uniq -c | sort -rn | head -n 10
}

# 保存到带时间戳的文件
analyze_network | tee -a "network_analysis_$(date +%Y%m%d_%H%M%S).log"

性能监控

资源使用跟踪

  1. CPU 和内存影响
# 监控 netstat 自身的资源使用
while true; do
    ps aux | grep netstat | grep -v grep
    sleep 1
done
  1. 网络接口性能
#!/bin/bash
# 监控接口吞吐量
INTERVAL=1
INTERFACE="eth0"

while true; do
    R1=$(cat /sys/class/net/$INTERFACE/statistics/rx_bytes)
    T1=$(cat /sys/class/net/$INTERFACE/statistics/tx_bytes)
    sleep $INTERVAL
    R2=$(cat /sys/class/net/$INTERFACE/statistics/rx_bytes)
    T2=$(cat /sys/class/net/$INTERFACE/statistics/tx_bytes)
    
    RBPS=$(( ($R2 - $R1) / $INTERVAL ))
    TBPS=$(( ($T2 - $T1) / $INTERVAL ))
    
    echo "接口 $INTERFACE:"
    echo "接收:$(($RBPS/1024)) KB/s"
    echo "发送:$(($TBPS/1024)) KB/s"
    echo "------------------------"
done

长期监控解决方案

#!/bin/bash
# 创建每小时的网络统计报告

LOGDIR="/var/log/netstat_reports"
mkdir -p $LOGDIR

generate_report() {
    TIMESTAMP=$(date +%Y%m%d_%H)
    REPORT="$LOGDIR/netstat_report_$TIMESTAMP.log"
    
    echo "网络报告 - $(date)" > $REPORT
    echo "=========================" >> $REPORT
    
    echo "连接摘要:" >> $REPORT
    netstat -s >> $REPORT
    
    echo "接口统计信息:" >> $REPORT
    netstat -i >> $REPORT
    
    echo "当前连接:" >> $REPORT
    netstat -ant >> $REPORT
}

# 运行报告生成
generate_report

集成提示

  1. 与系统监控结合
# 添加到系统监控脚本
if [ $(netstat -ant | grep ESTABLISHED | wc -l) -gt 100 ]; then
    echo "检测到高连接数" | mail -s "网络警报" [email protected]
fi
  1. 自定义报告功能
network_summary() {
    local port="$1"
    echo "端口 $port 的连接:"
    netstat -ant | grep ":$port" | awk '{print $6}' | sort | uniq -c
}

# 用法:network_summary 80

netstat 的替代品

ss 命令

ss(套接字统计)是 Linux 系统中 netstat 的现代替代品。它通常比 netstat 更快,功能更丰富。

ss 的主要优点

  • 更快的执行,尤其是在连接较多的系统上
  • 更详细的套接字信息
  • 更好的新协议支持
  • 更低的系统资源使用

与 netstat 的比较

# netstat 命令与 ss 等效

# 列出所有连接
netstat -a
ss

# 显示监听 TCP 端口
netstat -tln
ss -tln

# 显示进程信息
netstat -p
ss -p

# 显示统计信息
netstat -s
ss -s

ss 的示例用法

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

# 显示计时器信息
ss -o

# 显示内存使用情况
ss -m

# 按状态过滤
ss state established

# 按端口过滤
ss sport = :80

现代替代品

lsof(列出打开的文件)

# 显示网络连接
lsof -i

# 显示监听端口
lsof -i -P -n | grep LISTEN

# 显示已建立的连接
lsof -i | grep ESTABLISHED

nmap

# 扫描开放端口
nmap localhost

# 详细端口扫描
nmap -sV localhost

iptraf-ng

  • 实时 IP 流量监控
  • 详细的协议统计
  • 接口统计
  • LAN 站点监控

何时使用什么

使用 netstat 当:

  • 在旧系统上工作
  • 需要跨平台兼容性
  • 遵循已建立的文档
  • 运行简单的网络诊断

使用 ss 当:

  • 在现代 Linux 系统上工作
  • 需要更快的执行
  • 处理许多连接
  • 需要详细的套接字信息

使用 lsof 当:

  • 需要查看文件描述符信息
  • 想要将网络连接与进程关联
  • 故障排除应用程序问题

使用 nmap 当:

  • 执行安全审计
  • 需要详细的端口扫描
  • 分析网络服务

迁移指南

从 netstat 迁移到 ss

netstat 命令ss 等效描述
netstat -tss -t显示 TCP 连接
netstat -uss -u显示 UDP 连接
netstat -lss -l显示监听套接字
netstat -pss -p显示进程信息
netstat -nss -n不解析名称
netstat -ass显示所有套接字
netstat -rip route显示路由表

脚本迁移示例

# 旧的 netstat 脚本
#!/bin/bash
netstat -tulpn | grep LISTEN > listening_ports.log

# 新的 ss 等效
#!/bin/bash
ss -tulpn | grep LISTEN > listening_ports.log

工具选择提示

  1. 性能考虑
  • 对于大规模系统:使用 ss
  • 对于基本检查:任一工具均可
  • 对于详细分析:结合多种工具
  1. 兼容性问题
# 检查 ss 是否可用
if command -v ss >/dev/null 2>&1; then
    ss -tulpn
else
    netstat -tulpn
fi
  1. 功能需求
  • 基本监控:netstat/ss
  • 安全分析:nmap
  • 进程关联:lsof
  • 实时监控:iptraf-ng

最佳实践和提示

性能考虑

优化命令使用

  1. 尽可能使用数字输出
# 较慢(进行 DNS 解析)
netstat -ta

# 更快(不进行 DNS 解析)
netstat -tan
  1. 限制输出大小
# 而不是显示所有连接
netstat -a

# 过滤特定信息
netstat -an | grep ':80'
  1. 避免持续轮询
# 不推荐在繁忙系统上使用
netstat -c

# 更好的方法是控制间隔
while true; do
    netstat -an | grep ESTABLISHED
    sleep 5
done

常见陷阱

资源使用问题

  • 问题:在名称解析期间过度使用 CPU
# 有问题的命令
watch -n 1 'netstat -ta'

# 更好的替代
watch -n 1 'netstat -tan'

权限问题

  • 问题:缺少进程信息
# 将显示不完整的信息
netstat -p

# 正确用法
sudo netstat -p

输出解释

  • 问题:误解连接状态
# 常见的误解 TIME_WAIT
netstat -ant | grep TIME_WAIT

# 更好的分析上下文
netstat -ant | awk '{print $6}' | sort | uniq -c

每日使用提示

创建有用的别名

# 添加到 ~/.bashrc
alias ns='netstat -tulpn'
alias nsc='netstat -ant | grep ESTABLISHED'
alias nsl='sudo netstat -tulpn | grep LISTEN'

快速安全检查

# 检查异常监听端口
check_ports() {
    echo "已知端口:"
    sudo netstat -tulpn | grep -E ':22|:80|:443'
    echo -e "\n未知端口:"
    sudo netstat -tulpn | grep -vE ':22|:80|:443'
}

监控模板

# 连接监控模板
monitor_connections() {
    local port=$1
    local threshold=$2
    
    count=$(netstat -an | grep ":$port" | grep ESTABLISHED | wc -l)
    if [ $count -gt $threshold ]; then
        echo "警报:端口 $port 上的连接数 $count 超过阈值 $threshold"
    fi
}

# 用法:monitor_connections 80 100

文档和日志记录

创建有用的日志

#!/bin/bash
# 网络状态记录器

log_network_status() {
    local logfile="/var/log/network_status.log"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    
    {
        echo "=== 网络状态于 $timestamp ==="
        echo "监听端口:"
        netstat -tulpn | grep LISTEN
        echo "当前连接:"
        netstat -ant | awk '{print $6}' | sort | uniq -c
        echo "=================================="
    } >> "$logfile"
}

标准操作程序

# 定期检查的模板
daily_network_check() {
    echo "1. 检查监听端口..."
    sudo netstat -tulpn | grep LISTEN
    
    echo "2. 检查已建立的连接..."
    netstat -ant | grep ESTABLISHED | wc -l
    
    echo "3. 检查连接状态..."
    netstat -ant | awk '{print $6}' | sort | uniq -c
    
    echo "4. 检查接口统计信息..."
    netstat -i
}

故障排除指南

  1. 连接问题
connection_troubleshoot() {
    local port=$1
    echo "=== 端口 $port 故障排除 ==="
    echo "1. 检查端口是否在监听:"
    sudo netstat -tulpn | grep ":$port"
    
    echo "2. 检查活动连接:"
    netstat -ant | grep ":$port" | awk '{print $6}' | sort | uniq -c
    
    echo "3. 检查连接状态:"
    netstat -ant | grep ":$port" | awk '{print $6}' | sort | uniq -c
}
  1. 系统资源监控
resource_check() {
    echo "=== 系统资源检查 ==="
    echo "1. 总连接数:"
    netstat -ant | wc -l
    
    echo "2. 每个 IP 的连接数:"
    netstat -ant | grep ESTABLISHED | \
    awk '{print $5}' | cut -d: -f1 | \
    sort | uniq -c | sort -nr | head -5
    
    echo "3. 网络进程的内存使用情况:"
    ps aux | grep -E 'netstat|ss' | grep -v grep
}

常见问题解答 (FAQ)

问:为什么我看不到进程信息(PID)?

答:这通常是由于权限问题。使用 sudo 运行命令:
sudo netstat -tulpn

-p 选项需要 root 权限才能显示进程信息。

问:LISTEN 和 ESTABLISHED 状态有什么区别?

答:
- LISTEN:表示服务正在监听该端口,等待连接
- ESTABLISHED:表示一个活动的、当前连接的会话

问:如何检查特定端口的连接?

答:您可以使用 grep 过滤特定端口的连接:

# 检查端口 80 上的所有连接
netstat -an | grep ":80"

# 仅检查监听端口
netstat -tunl | grep ":80"

问:为什么我的 netstat 命令运行缓慢?

答:主要有两个原因:
1. DNS 解析 - 使用 -n 选项以避免名称解析
2. 连接过多 - 使用过滤或考虑切换到 ss

# 更快的命令示例
netstat -tan | grep ESTABLISHED

问:netstat 会影响系统性能吗?

答:频繁轮询可能会影响性能。最佳实践:
1. 增加轮询间隔
2. 使用过滤以减少输出
3. 对于大规模系统考虑使用 ss
4. 在繁忙系统上避免使用持续模式(-c)

问:如何识别哪个应用程序正在使用特定端口?

答:使用以下命令:
# 显示使用端口 80 的进程
sudo netstat -tulpn | grep ":80"

# 使用 lsof 的替代方法
sudo lsof -i :80

问:如何监控连接状态?

答:几种方法:

# 按状态统计连接
netstat -ant | awk '{print $6}' | sort | uniq -c

# 监控已建立的连接
watch -n 1 'netstat -ant | grep ESTABLISHED | wc -l'

问:如何检查可疑连接?

答:查找:
1. 异常端口:
netstat -tulpn | grep -vE ':22|:80|:443'

2. 单个 IP 的连接数过高:
netstat -ant | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn

问:如何检测端口扫描尝试?

答:监控 SYN_RECV 连接:
netstat -ant | grep SYN_RECV | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr

问:-t 和 -u 选项有什么区别?

答:
-t : 仅显示 TCP 连接
-u : 仅显示 UDP 连接

您可以结合使用:
netstat -tu : 显示 TCP 和 UDP

问:如何将 netstat 输出保存到文件?

答:几种方法:

# 基本输出到文件
netstat -ant > network_status.log

# 带时间戳
(date; netstat -ant) > network_status.log

# 持续日志记录
while true; do
    netstat -ant >> network_log.txt
    sleep 300
done

问:什么是“地址已在使用”在 netstat 输出中?

答:这表示某个端口已被另一个进程使用。要找到它:
sudo netstat -tulpn | grep "<port_number>"

问:为什么我看到很多 TIME_WAIT 连接?

答:TIME_WAIT 是连接关闭后正常的。然而,过多可能表示:
1. 高连接周转
2. 可能的网络问题
3. 应用程序未重用连接

使用以下命令监控:
netstat -ant | grep TIME_WAIT | wc -l