掌握 Linux Netstat 命令:从基础到高级网络监控
介绍
netstat
(网络统计)命令是 Linux 系统管理员工具包中最基本的网络工具之一。这个多功能的命令行实用程序提供了网络连接、路由表、接口统计信息以及其他重要的网络相关信息的全面视图。
什么是 netstat?
netstat
是一个命令行网络实用程序,用于显示各种网络相关信息,包括:
- 网络连接(包括传入和传出)
- 路由表
- 网络接口统计信息
- 伪装连接
- 多播成员资格
- 协议统计信息
为什么它很重要
系统管理员和网络工程师依赖 netstat
完成几个关键任务:
- 故障排除网络问题 - 快速识别连接问题和网络瓶颈
- 安全监控 - 检测未经授权的网络连接和可疑活动
- 性能分析 - 监控网络流量模式和接口统计信息
- 系统审计 - 审查活动服务和开放端口
简要历史
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 | 显示协议统计信息 |
基本示例
- 查看所有活动连接
netstat -a
- 显示所有 TCP 连接
netstat -at
- 显示带有程序信息的监听端口
sudo netstat -tulnp
这个常用组合显示:
-t
: TCP 连接-u
: UDP 连接-l
: 仅监听端口-n
: 数字地址-p
: 程序信息
- 检查路由表
netstat -r
- 查看接口统计信息
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 命令提供了多种方式来列出网络连接,具体取决于您的需求:
- 显示所有协议的数字地址
netstat -an
- 显示扩展信息
netstat -ae
这将添加额外的信息,如用户和 inode
- 显示计时器信息
netstat -o
添加有助于故障排除的计时信息
协议特定显示
- 仅 TCP
# 显示所有 TCP 连接,包括监听端口
netstat -at
# 仅显示监听 TCP 端口
netstat -lt
- 仅 UDP
# 显示所有 UDP 连接
netstat -au
# 仅显示监听 UDP 端口
netstat -lu
- 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 监控
统计显示
- 协议统计
# 显示所有协议的摘要统计
netstat -s
# 仅显示 TCP 统计
netstat -st
# 仅显示 UDP 统计
netstat -su
- 接口统计
# 显示接口统计信息
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: 溢出事件
常见用例
网络故障排除
检查开放端口
- 查找系统上的所有开放端口
sudo netstat -tulpn | grep LISTEN
此命令有助于识别:
- 正在运行的服务
- 它们使用的端口
- 拥有这些端口的进程
- 检查特定端口是否正在使用
sudo netstat -tulpn | grep ":80" # 检查 Web 服务器
sudo netstat -tulpn | grep ":3306" # 检查 MySQL
识别活动连接
- 监控当前连接
# 显示所有已建立的连接
netstat -nat | grep ESTABLISHED
# 统计每个 IP 地址的连接数
netstat -nat | grep ESTABLISHED | awk '{print $5}' | cut -d: -f1 | sort | uniq -c
- 跟踪连接状态
# 查看连接状态分布
netstat -ant | awk '{print $6}' | sort | uniq -c
监控网络流量
- 接口流量分析
# 实时监控接口统计信息
netstat -i
watch -n 1 "netstat -i"
- 协议特定监控
# 监控 TCP 流量统计
netstat -st
# 监控 UDP 流量统计
netstat -su
安全分析
查找可疑连接
- 检测异常端口
# 列出所有非标准监听端口
sudo netstat -tulpn | grep -v ":22\|:80\|:443"
- 检查可疑连接模式
# 查找来自意外 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
系统审计
- 服务验证
# 检查哪些进程在监听哪些端口
sudo netstat -tulpn | grep LISTEN | sort -k 4
- 连接日志
# 创建一个简单的连接日志
while true; do
date >> connection_log.txt
netstat -ant >> connection_log.txt
sleep 60
done
- 资源使用监控
# 监控每个服务的连接计数
netstat -ant | grep ESTABLISHED | awk '{print $4}' | cut -d: -f2 | sort | uniq -c
常见故障排除场景
- Web 服务器问题
# 检查 Web 服务器连接
sudo netstat -ant | grep ":80\|:443" | awk '{print $6}' | sort | uniq -c
- 数据库连接问题
# 监控数据库连接(MySQL 示例)
sudo netstat -ant | grep :3306 | awk '{print $6}' | sort | uniq -c
- 邮件服务器分析
# 检查邮件服务器连接
sudo netstat -ant | grep ":25\|:465\|:587" | awk '{print $6}' | sort | uniq -c
高级用法
与其他命令结合使用
使用 grep 和 awk
- 复杂过滤和分析
# 按状态和端口统计连接
netstat -ant | awk '{print $6, $4}' | sort | uniq -c | sort -rn
# 监控特定服务连接的变化
watch -n 1 'netstat -ant | grep ":80" | wc -l'
- 高级连接分析
# 创建连接摘要
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"
性能监控
资源使用跟踪
- CPU 和内存影响
# 监控 netstat 自身的资源使用
while true; do
ps aux | grep netstat | grep -v grep
sleep 1
done
- 网络接口性能
#!/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
集成提示
- 与系统监控结合
# 添加到系统监控脚本
if [ $(netstat -ant | grep ESTABLISHED | wc -l) -gt 100 ]; then
echo "检测到高连接数" | mail -s "网络警报" [email protected]
fi
- 自定义报告功能
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 -t | ss -t | 显示 TCP 连接 |
netstat -u | ss -u | 显示 UDP 连接 |
netstat -l | ss -l | 显示监听套接字 |
netstat -p | ss -p | 显示进程信息 |
netstat -n | ss -n | 不解析名称 |
netstat -a | ss | 显示所有套接字 |
netstat -r | ip route | 显示路由表 |
脚本迁移示例
# 旧的 netstat 脚本
#!/bin/bash
netstat -tulpn | grep LISTEN > listening_ports.log
# 新的 ss 等效
#!/bin/bash
ss -tulpn | grep LISTEN > listening_ports.log
工具选择提示
- 性能考虑
- 对于大规模系统:使用
ss
- 对于基本检查:任一工具均可
- 对于详细分析:结合多种工具
- 兼容性问题
# 检查 ss 是否可用
if command -v ss >/dev/null 2>&1; then
ss -tulpn
else
netstat -tulpn
fi
- 功能需求
- 基本监控:netstat/ss
- 安全分析:nmap
- 进程关联:lsof
- 实时监控:iptraf-ng
最佳实践和提示
性能考虑
优化命令使用
- 尽可能使用数字输出
# 较慢(进行 DNS 解析)
netstat -ta
# 更快(不进行 DNS 解析)
netstat -tan
- 限制输出大小
# 而不是显示所有连接
netstat -a
# 过滤特定信息
netstat -an | grep ':80'
- 避免持续轮询
# 不推荐在繁忙系统上使用
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
}
故障排除指南
- 连接问题
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
}
- 系统资源监控
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