网络工具全解
第7章:Linux 网络工具全解
网络是现代 Linux 系统的命脉。本章系统梳理 Linux 网络工具链:从 ip 系列命令替代已弃用的 ifconfig,到 ss/lsof 查看套接字状态,再到 curl/wget 的 HTTP 调试艺术、tcpdump 的抓包分析、SSH 进阶配置,以及 dig/nc 等诊断利器。掌握这些工具,你将能在任何网络问题前从容不迫。
7.1 网络接口管理:ip 命令族
ip 命令来自 iproute2 工具包,是 ifconfig、route、arp 等传统工具的现代替代。ifconfig 在大多数发行版中已标记为弃用(deprecated),生产环境应优先使用 ip。
# === ip addr — 管理 IP 地址 ===
ip addr show # 显示所有接口的 IP 地址(简写:ip a)
ip addr show eth0 # 只显示 eth0 接口
ip addr add 192.168.1.100/24 dev eth0 # 添加 IP 地址
ip addr del 192.168.1.100/24 dev eth0 # 删除 IP 地址
# === ip link — 管理网络接口 ===
ip link show # 列出所有接口(简写:ip l)
ip link set eth0 up # 启用接口
ip link set eth0 down # 禁用接口
ip link set eth0 mtu 9000 # 设置 MTU(巨帧)
ip link set eth0 promisc on # 开启混杂模式(抓包用)
# === ip route — 路由表管理 ===
ip route show # 查看路由表(简写:ip r)
ip route add default via 192.168.1.1 # 添加默认网关
ip route add 10.0.0.0/8 via 192.168.1.254 # 添加静态路由
ip route del 10.0.0.0/8 # 删除路由
ip route get 8.8.8.8 # 查询特定目标的路由路径
# === ip neigh — ARP 表(替代 arp 命令)===
ip neigh show # 查看 ARP/NDP 邻居表
ip neigh flush dev eth0 # 清空接口的 ARP 缓存
# === 对比:旧命令 vs 新命令 ===
# ifconfig eth0 → ip addr show eth0
# ifconfig eth0 up → ip link set eth0 up
# route -n → ip route show
# arp -n → ip neigh show
# netstat -rn → ip route show
为什么抛弃 ifconfig?
ifconfig来自net-tools包,自 2001 年起停止维护,不支持现代 Linux 网络特性(如 VRF、网络命名空间、多路由表)。iproute2的ip命令由内核团队维护,始终与内核网络栈保持同步。Ubuntu 18.04 之后net-tools已不再预装。
7.2 端口与连接:ss / lsof
ss(Socket Statistics)是 netstat 的现代替代,直接读取内核的 socket 结构,速度更快、信息更全面。
# === ss — Socket 统计 ===
ss -tulnp # 最常用:TCP+UDP 监听端口,不解析域名,显示进程
# -t TCP -u UDP -l listening -n numeric -p process
ss -s # 显示汇总统计(各状态 socket 数量)
ss -an # 所有连接(包含非监听状态)
ss -tnp state established # 只显示已建立的 TCP 连接
ss -tnp dst 10.0.0.1 # 过滤目标地址
ss -tnp sport = :80 # 过滤本地端口 80
# 输出示例解读:
# Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
# tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1234,fd=3))
# ↑协议 ↑状态 ↑接收队列 ↑发送队列 ↑本地地址:端口 ↑对端地址:端口 ↑进程信息
# === lsof -i — 通过文件查进程(网络版)===
lsof -i :8080 # 谁在占用 8080 端口
lsof -i tcp # 所有 TCP 连接
lsof -i -nP # -n 不解析主机名,-P 不解析端口名
lsof -i tcp:80 -n # 谁在监听 TCP 80 端口
# === netstat 兼容命令(已弃用,但部分系统仍有)===
netstat -tulnp # 等同 ss -tulnp
netstat -rn # 等同 ip route show
7.3 curl 完整指南
curl 是 Linux 下最强大的 HTTP 客户端工具,支持 HTTP/HTTPS/FTP/SFTP 等数十种协议。它是 API 调试、文件下载、自动化脚本的利器。
# === 基本 HTTP 方法 ===
curl https://api.example.com/users # GET 请求
curl -X POST https://api.example.com/users # POST 请求
curl -X PUT https://api.example.com/users/1 # PUT 请求
curl -X DELETE https://api.example.com/users/1 # DELETE 请求
# === 请求头与请求体 ===
curl -H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"name":"Alice","age":30}' \
-X POST https://api.example.com/users
# -d 发送 JSON/表单数据(application/x-www-form-urlencoded)
curl -d "username=alice&password=secret" https://example.com/login
# -F 发送 multipart/form-data(文件上传)
curl -F "file=@/path/to/photo.jpg" -F "title=My Photo" https://api.example.com/upload
# === 输出控制 ===
curl -o output.html https://example.com # 保存到文件
curl -O https://example.com/file.tar.gz # 用服务器文件名保存
curl -L https://short.url/abc # -L 跟随 301/302 重定向
curl -v https://example.com # -v 显示完整请求/响应头
curl -I https://example.com # 只获取响应头(HEAD 请求)
curl -s https://example.com # -s 静默模式(不显示进度)
curl -w "\nHTTP Status: %{http_code}\nTime: %{time_total}s\n" -o /dev/null \
https://example.com # 自定义输出格式
# === 认证 ===
curl -u admin:password https://example.com/api # Basic Auth
curl -H "Authorization: Bearer token123" https://api.example.com/data
# === TLS/SSL ===
curl --cacert /path/to/ca.crt https://internal.corp/api # 指定 CA 证书
curl --cert client.crt --key client.key https://api/mtls # 双向 TLS
curl --insecure https://self-signed.example.com # 忽略证书错误(仅测试!)
# === 结合 jq 处理 JSON ===
curl -s https://api.github.com/repos/torvalds/linux \
| jq '.stargazers_count' # 提取字段
curl -s https://api.example.com/users \
| jq '.[] | {id, name}' # 遍历数组
# === 断点续传 ===
curl -C - -O https://example.com/large-file.iso # -C - 从断点继续下载
# === 限速 ===
curl --limit-rate 1M -O https://example.com/file.iso # 限制下载速度 1MB/s
# === 并发(使用 xargs)===
cat urls.txt | xargs -P 4 -I{} curl -s -O {} # 4 并发下载
7.4 wget:递归下载与镜像网站
# 基本下载
wget https://example.com/file.tar.gz
# 断点续传(-c continue)
wget -c https://example.com/large-file.iso
# 后台下载(-b background,日志写入 wget-log)
wget -b https://example.com/file.iso
# 递归下载整个目录
wget -r -np -nH --cut-dirs=2 https://example.com/files/
# 镜像网站(保留目录结构、转换链接为本地路径)
wget --mirror --convert-links --page-requisites \
--no-parent https://example.com/
# 限速与重试
wget --limit-rate=500k --tries=3 --wait=2 https://example.com/file.iso
# 安静模式(不显示进度条)
wget -q -O /dev/null https://example.com/
# 显示进度条(非交互模式下)
wget --progress=bar:force https://example.com/file.iso
# 指定 User-Agent
wget --user-agent="Mozilla/5.0" https://example.com/
curl vs wget 选哪个? curl 更适合 API 调试、脚本中处理 HTTP 响应、需要细粒度控制请求头/方法的场景。wget 更适合单纯的文件下载、递归镜像网站、后台批量下载。两者都支持断点续传,curl 通过
-C -,wget 通过-c。
7.5 tcpdump:抓包分析利器
tcpdump 是 Linux 下的命令行抓包工具,能实时捕获网络数据包并显示其内容,是网络故障排查和协议分析的核心工具。
# 基本用法
sudo tcpdump -i eth0 # 抓 eth0 上的所有包
sudo tcpdump -i any # 抓所有接口
sudo tcpdump -i eth0 -n # -n 不解析 IP/端口为域名(速度更快)
sudo tcpdump -i eth0 -v # -v 更详细输出(-vv/-vvv 更多)
sudo tcpdump -i eth0 -c 100 # 只捕获 100 个包后退出
# 保存到文件(.pcap 格式,可用 Wireshark 打开)
sudo tcpdump -i eth0 -w capture.pcap
sudo tcpdump -i eth0 -w capture.pcap -G 3600 -W 24 # 每小时轮转,保留24个文件
# 读取 pcap 文件
sudo tcpdump -r capture.pcap
sudo tcpdump -r capture.pcap -n host 10.0.0.1
# 过滤表达式(BPF 语法)
sudo tcpdump -i eth0 host 192.168.1.100 # 过滤主机
sudo tcpdump -i eth0 src host 192.168.1.100 # 只看源地址
sudo tcpdump -i eth0 dst host 192.168.1.100 # 只看目标地址
sudo tcpdump -i eth0 port 80 # 过滤端口
sudo tcpdump -i eth0 tcp # 只看 TCP
sudo tcpdump -i eth0 udp # 只看 UDP
sudo tcpdump -i eth0 tcp and port 443 # 组合过滤(and/or/not)
sudo tcpdump -i eth0 'tcp and (port 80 or port 443)'
sudo tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0' # 只看 SYN 包(连接建立)
# 实用组合:HTTP 请求头
sudo tcpdump -i eth0 -n -A 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)>2)) != 0)'
tcpdump 过滤表达式速查表
| 过滤表达式 | 含义 | 示例 |
|---|---|---|
| host X | 匹配源或目标地址 | host 10.0.0.1 |
| src host X | 只匹配源地址 | src host 10.0.0.1 |
| dst host X | 只匹配目标地址 | dst host 8.8.8.8 |
| net X/mask | 匹配网段 | net 192.168.0.0/16 |
| port N | 匹配端口(源或目标) | port 443 |
| portrange N-M | 匹配端口范围 | portrange 8000-9000 |
| tcp / udp / icmp | 按协议过滤 | icmp |
| and / or / not | 逻辑组合 | tcp and not port 22 |
| greater N | 包大于 N 字节 | greater 1000 |
| less N | 包小于 N 字节 | less 64 |
7.6 SSH 进阶:密钥管理与 ProxyJump
密钥生成与部署
# === 生成 SSH 密钥对 ===
# Ed25519(推荐,更安全、更快)
ssh-keygen -t ed25519 -C "[email protected]"
# RSA 4096(兼容旧系统)
ssh-keygen -t rsa -b 4096 -C "[email protected]"
# 指定文件名(同时管理多对密钥时有用)
ssh-keygen -t ed25519 -f ~/.ssh/id_work -C "[email protected]"
# === 部署公钥到服务器 ===
ssh-copy-id [email protected]
ssh-copy-id -i ~/.ssh/id_work.pub [email protected] # 指定密钥
# 手动部署(当 ssh-copy-id 不可用时)
cat ~/.ssh/id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
# === ssh-agent:避免重复输入密码短语 ===
eval "$(ssh-agent -s)" # 启动 ssh-agent
ssh-add ~/.ssh/id_ed25519 # 添加私钥到 agent
ssh-add ~/.ssh/id_work # 添加工作密钥
ssh-add -l # 列出 agent 中的密钥
ssh-add -D # 清空 agent 中的所有密钥
# === 端口转发 ===
# 本地端口转发:将本地 8080 转发到远程服务器的 localhost:3306(访问远端 MySQL)
ssh -L 8080:localhost:3306 [email protected]
# 远程端口转发:将服务器 9090 转发回本地 localhost:8080(内网穿透)
ssh -R 9090:localhost:8080 [email protected]
# 动态端口转发(SOCKS5 代理)
ssh -D 1080 [email protected]
# === sshfs — 挂载远程目录 ===
sudo apt install sshfs
mkdir ~/remote-work
sshfs [email protected]:/var/www ~/remote-work
fusermount -u ~/remote-work # 卸载
~/.ssh/config 配置文件
~/.ssh/config 是 SSH 的客户端配置文件,可以为不同主机设置别名、密钥、用户名、跳板机等,大幅减少输入。
# ~/.ssh/config 完整示例
# 全局默认设置
Host *
ServerAliveInterval 60 # 每 60 秒发送心跳(防止超时断连)
ServerAliveCountMax 3 # 3 次无响应后断开
AddKeysToAgent yes # 自动将密钥添加到 ssh-agent
IdentityFile ~/.ssh/id_ed25519 # 默认密钥
# 工作服务器(直接访问)
Host work-web
HostName 203.0.113.10
User deploy
Port 2222
IdentityFile ~/.ssh/id_work
# 使用:ssh work-web
# 内网服务器(通过跳板机 ProxyJump)
Host internal-db
HostName 10.10.0.50
User dbadmin
ProxyJump work-web # 先连 work-web,再跳转到 internal-db
# 旧写法:ProxyCommand ssh -W %h:%p work-web
# 使用:ssh internal-db
# GitHub(多账号管理)
Host github-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_personal
# 使用:git clone git@github-personal:username/repo.git
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_work
# 使用:git clone git@github-work:org/repo.git
# 文件权限要求:
# chmod 600 ~/.ssh/config
# chmod 700 ~/.ssh/
ProxyJump 的威力:
ProxyJump支持多级跳转(如ProxyJump jump1,jump2),每一跳都可以有独立的密钥和用户名配置。与旧的ProxyCommand相比,ProxyJump(SSH 7.3+)更安全,因为它不会将私钥暴露给跳板机。
7.7 nc/netcat 与 socat 网络调试
# === nc(netcat)— "网络界的瑞士军刀" ===
# 端口扫描(-z 扫描模式,-v 详细,-w 超时)
nc -zv 192.168.1.1 22 # 检测单个端口是否开放
nc -zv 192.168.1.1 20-80 # 扫描端口范围
# 简单 TCP 服务器(监听 9999 端口)
nc -l 9999 # 监听并等待连接
nc -lk 9999 # -k 持续监听(每次连接后不退出)
# 连接到服务器
nc 192.168.1.1 9999
# 传输文件(发送方)
nc -l 9999 > received_file.txt # 接收端
nc 192.168.1.1 9999 /tmp/pipe
# === socat — nc 的进化版 ===
# 安装
sudo apt install socat
# 端口转发(将本地 8080 转发到 example.com:80)
socat TCP-LISTEN:8080,fork TCP:example.com:80
# TLS 测试
socat STDIO OPENSSL:example.com:443
# Unix socket 转 TCP
socat TCP-LISTEN:9999,fork UNIX-CONNECT:/var/run/docker.sock
# 文件传输(更快,无需多步骤)
socat -u FILE:file.tar.gz TCP-LISTEN:9999 # 发送端
socat -u TCP:192.168.1.1:9999 FILE:out.tar.gz # 接收端
7.8 DNS 工具:dig / nslookup / host
# === dig — DNS 查询主力工具 ===
dig example.com # 查询 A 记录(默认)
dig example.com A # 明确查询 A 记录(IPv4)
dig example.com AAAA # 查询 AAAA 记录(IPv6)
dig example.com MX # 查询邮件交换记录
dig example.com NS # 查询权威域名服务器
dig example.com CNAME # 查询别名记录
dig example.com TXT # 查询 TXT 记录(SPF/DKIM 等)
dig example.com SOA # 查询授权信息
# 指定 DNS 服务器(绕过系统 /etc/resolv.conf)
dig @8.8.8.8 example.com # 使用 Google DNS
dig @1.1.1.1 example.com # 使用 Cloudflare DNS
dig @192.168.1.1 example.com # 使用内网 DNS
# 简洁输出(+short 只显示结果)
dig +short example.com
dig +short example.com MX
# 追踪完整解析链(+trace 从根 DNS 开始)
dig +trace example.com
# 反向 DNS 查询(IP → 域名)
dig -x 8.8.8.8
# === nslookup — 交互式 DNS 工具 ===
nslookup example.com
nslookup example.com 8.8.8.8 # 指定 DNS 服务器
nslookup -type=MX example.com # 查询特定记录类型
# === host — 简洁查询 ===
host example.com
host -t MX example.com
host 8.8.8.8 # 反向查询
# === 本地 DNS 配置文件 ===
# /etc/hosts — 本地静态解析(优先级高于 DNS)
cat /etc/hosts
# 127.0.0.1 localhost
# 192.168.1.10 internal-server db.local
# /etc/resolv.conf — DNS 服务器配置
cat /etc/resolv.conf
# nameserver 8.8.8.8
# nameserver 8.8.4.4
# search example.com # 默认搜索域
# 刷新 DNS 缓存
sudo systemd-resolve --flush-caches # systemd-resolved
sudo resolvectl flush-caches # 新版语法
sudo service nscd restart # nscd 缓存
7.9 网络诊断:ping / traceroute / mtr
# === ping ===
ping example.com # 持续 ping
ping -c 4 example.com # 只 ping 4 次
ping -i 0.5 example.com # 每 0.5 秒发一次
ping6 2001:4860:4860::8888 # IPv6 ping
# === traceroute — 路由跟踪 ===
traceroute example.com
traceroute -n example.com # -n 不解析主机名(更快)
traceroute -T -p 80 example.com # 使用 TCP(穿越部分防火墙)
# === mtr — ping + traceroute 的实时结合(推荐)===
sudo apt install mtr
mtr example.com # 实时动态视图
mtr -n --report example.com # 非交互,报告模式(可用于记录)
mtr --report-cycles 20 example.com # 发 20 次后输出报告
连接失败排查检查清单
- 物理/链路层:
ip link show— 接口是否 UP?ethtool eth0— 是否有链路信号? - IP 地址:
ip addr show— 是否有正确的 IP 地址?子网掩码是否正确? - 网关路由:
ip route show— 是否有默认网关?ping网关 IP 是否可达? - DNS:
dig +short example.com @8.8.8.8— 绕过本地 DNS 测试。cat /etc/resolv.conf检查配置。 - 目标端口:
nc -zv target 80— 目标端口是否开放?ss -tulnp— 本地是否在监听? - 防火墙:
sudo iptables -L -n或sudo ufw status— 是否有规则阻断连接? - 抓包确认:
sudo tcpdump -i eth0 host target -n— 数据包是否到达/离开本机?
7.10 iptables / ufw 防火墙基础
# === ufw(Ubuntu 防火墙,iptables 的友好前端)===
sudo ufw status verbose # 查看状态和规则
sudo ufw enable # 启用防火墙
sudo ufw disable # 禁用防火墙
sudo ufw allow 22 # 允许 SSH(端口 22)
sudo ufw allow 80/tcp # 允许 HTTP
sudo ufw allow 443 # 允许 HTTPS
sudo ufw deny 23 # 拒绝 Telnet
sudo ufw allow from 192.168.1.0/24 # 允许来自特定子网
sudo ufw delete allow 80/tcp # 删除规则
sudo ufw reset # 重置所有规则
# === iptables — 底层规则(需要 root)===
sudo iptables -L -n -v # 列出所有规则(-n 不解析,-v 显示计数)
sudo iptables -L INPUT -n --line-numbers # 显示行号
# 基本规则示例
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 允许 SSH
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT # 允许 HTTP
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # 允许已建立连接
sudo iptables -A INPUT -j DROP # 默认拒绝所有
# 保存规则(Ubuntu)
sudo iptables-save > /etc/iptables/rules.v4
sudo ip6tables-save > /etc/iptables/rules.v6
# 查看 nftables(现代防火墙,替代 iptables)
sudo nft list ruleset
远程操作防火墙注意: 通过 SSH 修改 iptables 规则时,务必先添加
ACCEPT规则再添加DROP规则,且确保 SSH 端口(22)始终在 ACCEPT 列表中。一条错误的规则可能导致你被永久锁定在服务器外。建议在修改前设置一个定时任务自动恢复规则:echo "iptables -F" | at now + 5 min。
章节总结: 本章覆盖了 Linux 网络工具的全景:
ip命令族管理接口和路由,ss查看 socket 状态,curl调试 HTTP/API,tcpdump抓包分析,SSH 进阶配置让远程工作更高效,nc/socat用于快速网络测试,dig排查 DNS 问题,以及系统化的连接失败排查流程。下一章将深入 Linux 存储与磁盘管理。
上一章
← 第6章:权限与用户管理
下一章
第8章:存储与磁盘 →