Linux命令-netstat(查看Linux中网络系统状态信息)

netstat 是 Linux 中一个显示网络连接、路由表、接口统计等网络相关信息的经典工具。它提供了系统网络状态的全面视图,是网络故障排查和性能分析的重要工具。

📖 基本语法

bash 复制代码
netstat [选项]

重要特性

  • 显示网络连接状态
  • 显示路由表信息
  • 显示接口统计信息
  • 显示多播组成员
  • 显示网络协议统计

🎯 常用选项

选项 说明
-a, --all 显示所有连接和监听端口。
-t, --tcp 仅显示 TCP 连接。
-u, --udp 仅显示 UDP 连接。
-n, --numeric 以数字形式显示地址和端口,不解析主机名和服务名。
-l, --listening 仅显示监听状态的套接字。
-p, --program 显示每个连接所属的进程 ID 和程序名。
-r, --route 显示路由表。
-i, --interfaces 显示网络接口统计信息。
-s, --statistics 显示每个协议的统计信息。
-c, --continuous 连续输出,每隔一秒刷新一次。
-e, --extend 显示扩展信息。
-o, --timers 显示计时器信息。
-g, --groups 显示多播组成员信息。
-4, --inet 仅显示 IPv4 连接。
-6, --inet6 仅显示 IPv6 连接。
-C, --cache 显示路由缓存。
-F, --fib 显示转发信息库。
-W, --wide 不截断 IP 地址。
-h, --help 显示帮助信息。
-V, --version 显示版本信息。

💡 核心用法示例

1. 显示所有连接
bash 复制代码
# 显示所有连接(包括监听和非监听)
netstat -a

# 显示所有 TCP 连接
netstat -at

# 显示所有 UDP 连接
netstat -au

# 显示所有连接(数字形式)
netstat -an

# 显示所有连接,包含进程信息
netstat -ap

# 显示所有 IPv4 连接
netstat -4a

# 显示所有 IPv6 连接
netstat -6a
2. 显示监听端口
bash 复制代码
# 显示所有监听端口
netstat -l

# 显示 TCP 监听端口
netstat -lt

# 显示 UDP 监听端口
netstat -lu

# 显示监听端口(数字形式)
netstat -ln

# 显示监听端口,包含进程信息
netstat -lp

# 显示 IPv4 监听端口
netstat -4l

# 显示 IPv6 监听端口
netstat -6l
3. 显示路由表
bash 复制代码
# 显示路由表
netstat -r

# 显示路由表(数字形式)
netstat -rn

# 显示路由缓存
netstat -C

# 显示内核路由表
netstat -e

# 显示详细路由信息
netstat --verbose -r
4. 显示接口统计
bash 复制代码
# 显示所有接口统计
netstat -i

# 显示扩展接口统计
netstat -ie

# 显示接口统计(数字形式)
netstat -in

# 显示特定接口统计
netstat -i eth0

# 显示接口统计,包含错误信息
netstat -s -i
5. 显示协议统计
bash 复制代码
# 显示所有协议统计
netstat -s

# 显示 TCP 协议统计
netstat -st

# 显示 UDP 协议统计
netstat -su

# 显示 ICMP 协议统计
netstat -si

# 显示 IP 协议统计
netstat -sp ip

# 显示详细协议统计
netstat --statistics --verbose
6. 实用组合命令
bash 复制代码
# 最常用的组合:显示所有 TCP 连接,包含进程信息,数字形式
netstat -tunap

# 显示所有监听端口,包含进程信息
netstat -tunlp

# 显示所有 ESTABLISHED 连接
netstat -tunap | grep ESTABLISHED

# 显示所有 TIME_WAIT 连接
netstat -tunap | grep TIME_WAIT

# 显示所有 LISTEN 连接
netstat -tunap | grep LISTEN

# 显示特定端口的连接
netstat -tunap | grep :80

# 显示特定进程的连接
netstat -tunap | grep nginx

# 显示特定用户的连接
netstat -tunap | grep username

# 显示连接数统计
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

# 实时监控网络连接
watch -n 1 'netstat -tunap'

📊 输出字段解释

连接信息字段
复制代码
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
  • Proto:协议类型(tcp、udp、raw)
  • Recv-Q:接收队列大小(字节)
  • Send-Q:发送队列大小(字节)
  • Local Address:本地地址和端口
  • Foreign Address:远程地址和端口
  • State:连接状态
  • PID/Program name:进程 ID 和程序名
TCP 连接状态
状态 说明
LISTEN 监听状态,等待连接请求。
SYN_SENT 已发送连接请求,等待确认。
SYN_RECV 收到连接请求,等待确认。
ESTABLISHED 连接已建立,数据传输中。
FIN_WAIT1 已发送关闭请求,等待确认。
FIN_WAIT2 收到关闭确认,等待对方关闭。
TIME_WAIT 等待足够时间确保远程 TCP 收到连接中断请求。
CLOSE_WAIT 收到关闭请求,等待本地关闭。
LAST_ACK 等待先前发送的关闭请求的确认。
CLOSING 双方同时尝试关闭连接。
CLOSED 连接已关闭。
路由表字段
复制代码
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.1.1     0.0.0.0         UG    100    0        0 eth0
192.168.1.0     0.0.0.0         255.255.255.0   U     100    0        0 eth0
  • Destination:目标网络或主机
  • Gateway:网关地址
  • Genmask:网络掩码
  • Flags :路由标志
    • U:路由是活动的
    • G:使用网关
    • H:目标是一台主机
    • D:由重定向创建
    • M:由重定向修改
  • Metric:路由距离
  • Ref:路由引用计数
  • Use:路由查找计数
  • Iface:网络接口
接口统计字段
复制代码
Iface      MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0      1500  1234567      0      0 0        987654      0      0      0 BMRU
lo       65536   123456      0      0 0         123456      0      0      0 LRU
  • Iface:接口名称
  • MTU:最大传输单元
  • RX-OK/TX-OK:成功接收/发送的数据包数
  • RX-ERR/TX-ERR:接收/发送错误的数据包数
  • RX-DRP/TX-DRP:接收/发送丢弃的数据包数
  • RX-OVR/TX-OVR:接收/发送溢出的数据包数
  • Flg :接口标志
    • B:广播地址已设置
    • L:回环接口
    • M:混杂模式
    • O:ARP 关闭
    • P:点对点链接
    • R:正在运行
    • U:接口已启动

🔧 实用场景示例

1. 查看端口占用情况
bash 复制代码
# 查看 80 端口被哪个进程占用
netstat -tunlp | grep :80

# 查看 22 端口(SSH)的连接情况
netstat -tunap | grep :22

# 查看所有监听端口
netstat -tunlp

# 查看特定进程占用的端口
netstat -tunlp | grep nginx
netstat -tunlp | grep apache
netstat -tunlp | grep mysql

# 查看端口范围占用情况
netstat -tunap | awk '$4 ~ /:80$/ || $4 ~ /:443$/ {print}'
2. 监控网络连接状态
bash 复制代码
# 查看所有 ESTABLISHED 连接
netstat -tunap | grep ESTABLISHED

# 查看所有 TIME_WAIT 连接
netstat -tunap | grep TIME_WAIT

# 查看连接数最多的 IP
netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n

# 查看连接状态统计
netstat -nt | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

# 实时监控连接状态
watch -n 1 'netstat -nt | awk '\''/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'\'''
3. 排查网络问题
bash 复制代码
# 查看是否有大量 TIME_WAIT 连接
netstat -nt | grep TIME_WAIT | wc -l

# 查看是否有大量 SYN_RECV 连接(可能遭受 SYN 攻击)
netstat -nt | grep SYN_RECV | wc -l

# 查看接收/发送错误
netstat -i

# 查看接口丢包情况
netstat -ie | grep -E "(Iface|errors|dropped)"

# 查看路由表,检查路由是否正确
netstat -rn

# 查看 ARP 表
arp -a
4. 服务监控
bash 复制代码
# 监控 Web 服务器连接
watch -n 1 'netstat -tunap | grep -E "(nginx|apache|httpd)"'

# 监控数据库连接
watch -n 1 'netstat -tunap | grep -E "(mysql|postgres|mongodb)"'

# 监控 SSH 连接
watch -n 1 'netstat -tunap | grep sshd'

# 监控 FTP 连接
watch -n 1 'netstat -tunap | grep -E "(ftp|vsftpd|proftpd)"'
5. 安全审计
bash 复制代码
# 查看所有外来连接
netstat -tunap | grep -v "127.0.0.1" | grep -v "::1"

# 查看异常连接
netstat -tunap | grep -E "(SYN_SENT|SYN_RECV|FIN_WAIT|CLOSE_WAIT|LAST_ACK)"

# 查看可疑的监听端口
netstat -tunlp | grep -vE "(127.0.0.1|::1|0.0.0.0)" | grep LISTEN

# 查看 root 用户的网络连接
netstat -tunap | grep root

# 查看非标准端口的监听
netstat -tunlp | grep LISTEN | grep -vE ":($(echo {20..23} {25} {53} {67..69} {80} {110} {123} {137..139} {143} {161..162} {389} {443} {445} {465} {514} {587} {636} {993} {995} {1080} {1194} {1433} {1521} {1723} {2049} {2082..2083} {2222} {3128} {3306} {3389} {3690} {4333} {4444} {5432} {5900..5901} {6000..6001} {6379} {6665..6669} {8000} {8008..8009} {8080..8081} {8443} {8888} {9000} {9090} {9200} {9300} {10000} {11211} {27017} {28017} {50000} | tr ' ' '|'))\s"

🛠️ 实用脚本

1. 网络连接监控脚本
bash 复制代码
#!/bin/bash
# 网络连接监控脚本

LOG_FILE="/var/log/network_connections.log"
INTERVAL=60  # 检查间隔(秒)
ALERT_THRESHOLD=100  # 连接数警报阈值
ALERT_EMAIL="admin@example.com"

echo "开始网络连接监控 $(date)" >> "$LOG_FILE"
echo "检查间隔: ${INTERVAL}秒" >> "$LOG_FILE"
echo "警报阈值: ${ALERT_THRESHOLD} 个连接" >> "$LOG_FILE"
echo "======================================" >> "$LOG_FILE"

monitor_connections() {
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    
    # 获取连接统计
    local total_conn=$(netstat -nt | wc -l)
    local established=$(netstat -nt | grep ESTABLISHED | wc -l)
    local time_wait=$(netstat -nt | grep TIME_WAIT | wc -l)
    local close_wait=$(netstat -nt | grep CLOSE_WAIT | wc -l)
    local syn_recv=$(netstat -nt | grep SYN_RECV | wc -l)
    
    # 记录到日志
    echo "[$timestamp] 连接统计:" >> "$LOG_FILE"
    echo "  总连接数: $total_conn" >> "$LOG_FILE"
    echo "  ESTABLISHED: $established" >> "$LOG_FILE"
    echo "  TIME_WAIT: $time_wait" >> "$LOG_FILE"
    echo "  CLOSE_WAIT: $close_wait" >> "$LOG_FILE"
    echo "  SYN_RECV: $syn_recv" >> "$LOG_FILE"
    
    # 检查警报条件
    if [[ $total_conn -gt $ALERT_THRESHOLD ]]; then
        echo "[警报] 连接数超过阈值: $total_conn" >> "$LOG_FILE"
        echo "网络连接数异常: $total_conn (阈值: $ALERT_THRESHOLD)" | \
            mail -s "网络连接警报 - $timestamp" "$ALERT_EMAIL"
    fi
    
    if [[ $syn_recv -gt 10 ]]; then
        echo "[警报] SYN_RECV 连接过多: $syn_recv" >> "$LOG_FILE"
        echo "可能的 SYN 攻击: SYN_RECV=$syn_recv" | \
            mail -s "SYN 攻击警报 - $timestamp" "$ALERT_EMAIL"
    fi
    
    # 显示前10个连接最多的IP
    echo "  连接最多的IP:" >> "$LOG_FILE"
    netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -10 >> "$LOG_FILE"
    
    echo "--------------------------------------" >> "$LOG_FILE"
}

# 主循环
while true; do
    monitor_connections
    sleep "$INTERVAL"
done
2. 端口扫描检测脚本
bash 复制代码
#!/bin/bash
# 端口扫描检测脚本

LOG_FILE="/var/log/port_scan.log"
INTERVAL=10  # 检查间隔(秒)
SCAN_THRESHOLD=20  # 端口扫描阈值(同一IP的连接尝试次数)
BLOCK_TIME=3600  # 屏蔽时间(秒)
BLOCK_LIST="/tmp/blocked_ips.txt"

# 初始化屏蔽列表
touch "$BLOCK_LIST"

echo "开始端口扫描检测 $(date)" >> "$LOG_FILE"
echo "检查间隔: ${INTERVAL}秒" >> "$LOG_FILE"
echo "扫描阈值: ${SCAN_THRESHOLD} 次连接尝试" >> "$LOG_FILE"
echo "======================================" >> "$LOG_FILE"

detect_port_scan() {
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    
    # 分析 SYN_RECV 状态的连接
    netstat -nt | grep SYN_RECV | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | \
    while read -r count ip; do
        if [[ $count -gt $SCAN_THRESHOLD ]]; then
            # 检查是否已在屏蔽列表中
            if ! grep -q "^$ip$" "$BLOCK_LIST"; then
                echo "[$timestamp] 检测到端口扫描: IP=$ip, 尝试次数=$count" >> "$LOG_FILE"
                
                # 添加到屏蔽列表
                echo "$ip" >> "$BLOCK_LIST"
                
                # 使用 iptables 屏蔽
                if command -v iptables >/dev/null 2>&1; then
                    iptables -A INPUT -s "$ip" -j DROP
                    echo "  已使用 iptables 屏蔽 IP: $ip" >> "$LOG_FILE"
                fi
                
                # 发送警报
                echo "检测到端口扫描攻击" >> "$LOG_FILE"
                echo "攻击IP: $ip" >> "$LOG_FILE"
                echo "尝试次数: $count" >> "$LOG_FILE"
                echo "时间: $timestamp" >> "$LOG_FILE"
            fi
        fi
    done
    
    # 清理过期的屏蔽记录
    if [[ -f "$BLOCK_LIST" ]]; then
        # 这里简化处理,实际应该记录时间
        # 可以使用更复杂的时间管理
        echo "当前屏蔽的IP:" >> "$LOG_FILE"
        cat "$BLOCK_LIST" >> "$LOG_FILE"
    fi
}

# 主循环
while true; do
    detect_port_scan
    sleep "$INTERVAL"
done
3. 服务健康检查脚本
bash 复制代码
#!/bin/bash
# 服务健康检查脚本

SERVICES=(
    "ssh:22:tcp"
    "http:80:tcp"
    "https:443:tcp"
    "mysql:3306:tcp"
    "redis:6379:tcp"
    "mongodb:27017:tcp"
)

CHECK_INTERVAL=300  # 检查间隔(秒)
LOG_FILE="/var/log/service_health.log"
ALERT_EMAIL="admin@example.com"

echo "开始服务健康检查 $(date)" >> "$LOG_FILE"
echo "检查间隔: ${CHECK_INTERVAL}秒" >> "$LOG_FILE"
echo "======================================" >> "$LOG_FILE"

check_service() {
    local service_name="$1"
    local port="$2"
    local protocol="$3"
    
    # 检查端口是否在监听
    if [[ "$protocol" == "tcp" ]]; then
        netstat -ltn | grep -q ":$port "
        status=$?
    elif [[ "$protocol" == "udp" ]]; then
        netstat -lun | grep -q ":$port "
        status=$?
    else
        netstat -lan | grep -q ":$port "
        status=$?
    fi
    
    if [[ $status -eq 0 ]]; then
        echo "  ✓ $service_name ($port/$protocol): 正常" >> "$LOG_FILE"
        return 0
    else
        echo "  ✗ $service_name ($port/$protocol): 异常" >> "$LOG_FILE"
        return 1
    fi
}

# 主循环
while true; do
    timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] 服务状态检查:" >> "$LOG_FILE"
    
    failed_services=()
    
    for service in "${SERVICES[@]}"; do
        IFS=':' read -r name port protocol <<< "$service"
        
        if ! check_service "$name" "$port" "$protocol"; then
            failed_services+=("$name($port/$protocol)")
        fi
    done
    
    # 如果有服务异常,发送警报
    if [[ ${#failed_services[@]} -gt 0 ]]; then
        echo "  异常服务: ${failed_services[*]}" >> "$LOG_FILE"
        
        # 发送邮件警报
        echo "以下服务异常: ${failed_services[*]}" | \
            mail -s "服务健康检查警报 - $timestamp" "$ALERT_EMAIL"
    fi
    
    echo "--------------------------------------" >> "$LOG_FILE"
    sleep "$CHECK_INTERVAL"
done

🔄 与 ss 命令对比

ss(socket statistics)是 netstat 的现代替代品,速度更快,功能更强大。

特性 netstat ss
速度 较慢(读取 /proc/net/ 文件) 较快(直接从内核获取)
功能 基本功能 更多高级功能
输出格式 传统格式 更清晰的格式
过滤能力 有限 强大的过滤功能
协议支持 基本协议 更多协议支持
系统资源 占用较多 占用较少
ss 命令示例
bash 复制代码
# 显示所有 TCP 连接
ss -t

# 显示所有 UDP 连接
ss -u

# 显示所有监听端口
ss -l

# 显示进程信息
ss -p

# 显示数字格式
ss -n

# 显示所有连接
ss -a

# 组合使用
ss -tunap

# 过滤功能
ss -t state established
ss -t state listening
ss -t '( dport = :80 or sport = :80 )'
ss -t dst 192.168.1.100
ss -t src 192.168.1.50

⚠️ 注意事项

  1. 性能影响 :在连接数很多的系统上,netstat 可能较慢,建议使用 ss
  2. 权限要求:查看进程信息需要 root 权限。
  3. 过时警告 :一些新系统推荐使用 ss 替代 netstat
  4. 输出解析 :不同 Linux 发行版的 netstat 输出格式可能略有不同。
  5. IPv6 支持:确保系统支持 IPv6 才能看到 IPv6 连接。

📌 最佳实践

  1. 使用 ss 替代 :在新系统中,优先使用 ss 命令。
  2. 结合使用netstat 查看整体状态,ss 查看详细信息。
  3. 定期监控:使用脚本定期监控网络连接状态。
  4. 安全审计:定期检查异常连接和监听端口。
  5. 性能优化:关注 TIME_WAIT 和 CLOSE_WAIT 状态连接数量。

🎯 快速参考卡

复制代码
基本查看:
  netstat -tunap                    # 查看所有连接
  netstat -tunlp                    # 查看监听端口
  netstat -rn                       # 查看路由表
  netstat -i                        # 查看接口统计
  netstat -s                        # 查看协议统计

状态过滤:
  netstat -tunap | grep ESTABLISHED # 已建立连接
  netstat -tunap | grep LISTEN      # 监听端口
  netstat -tunap | grep TIME_WAIT   # TIME_WAIT 连接
  netstat -tunap | grep SYN_RECV    # SYN_RECV 连接

端口检查:
  netstat -tunlp | grep :80         # 检查80端口
  netstat -tunlp | grep nginx       # 检查nginx进程
  netstat -tunap | grep 192.168.1.1 # 检查特定IP

统计信息:
  netstat -s                        # 所有协议统计
  netstat -st                       # TCP统计
  netstat -su                       # UDP统计
  netstat -nt | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

实时监控:
  watch -n 1 'netstat -tunap'       # 每秒刷新
  netstat -c                        # 连续输出

netstat 是 Linux 网络管理的基础工具,虽然在新系统中逐渐被 ss 替代,但它仍然是排查网络问题的有力工具。掌握 netstat 的使用方法对于系统管理员和网络工程师来说非常重要。

相关推荐
_Emma_2 小时前
【Raspberry PI】Raspberry Pi HEVC (H.265) 硬件解码器
linux·驱动开发·视频编解码
Hello.Reader2 小时前
双卡 A100 + Ollama 生产部署从安装、踩坑、调优到最终可上线方案
linux·人工智能·算法
SPC的存折2 小时前
1、MySQL数据库基础
linux·运维·数据库·mysql
无忧.芙桃2 小时前
进程之环境变量
linux·运维·服务器
Wanliang Li2 小时前
Linux驱动——input子系统
linux·驱动开发·input
feng_you_ying_li2 小时前
liunx之make/makefile的使用
linux
默|笙2 小时前
【Linux】线程概念与控制(4)_线程封装
linux
仍然探索未知中3 小时前
【Linux内核源码分析】内核数据结构
linux·数据结构
chxii3 小时前
linux 下用 acme.sh 搞定 Nginx 免费 SSL 证书自动续期(下) 对于acme.sh命令安装详解
linux·运维·服务器