Linux 网络进阶
大约 12 分钟约 3685 字
Linux 网络进阶
简介
Linux 网络管理是运维工作中最核心的技能之一。无论是配置服务器 IP 地址、排查网络连接问题、管理防火墙规则,还是理解容器网络的底层原理,都离不开对 Linux 网络栈的深入理解。
现代 Linux 网络管理已经从传统的 ifconfig、route、netstat 等工具过渡到统一的 ip 命令族(iproute2 工具包)。同时,tcpdump 抓包分析、网络命名空间(Network Namespace)、链路聚合(Bond)等高级技能也是排查复杂网络问题所必需的。
本文将从网络接口配置、路由管理、网络诊断、抓包分析、网络命名空间、链路聚合等方面,全面介绍 Linux 网络进阶知识。
Linux 网络栈概览
┌─────────────────────────────────────┐
│ 用户空间应用 │
├─────────────────────────────────────┤
│ Socket API (BSD Socket) │
├─────────────────────────────────────┤
│ TCP / UDP / ICMP / IGMP (传输层) │
├─────────────────────────────────────┤
│ IP / IPv6 (网络层) │
├─────────────────────────────────────┤
│ 路由表 / 策略路由 / Netfilter │
├─────────────────────────────────────┤
│ ARP / ICMP / 网卡驱动 (链路层) │
├─────────────────────────────────────┤
│ 物理网卡 (NIC) │
└─────────────────────────────────────┘理解这个分层模型有助于定位网络问题发生在哪一层:DNS 解析问题在应用层,连接超时在传输层,路由不通在网络层,MAC 地址问题在链路层。
ip 命令族
ip 命令是现代 Linux 网络管理的核心工具,替代了已废弃的 ifconfig、route、netstat 等命令。
网络接口管理
# 查看所有网络接口
ip addr show
ip a # 简写
# 查看指定接口
ip addr show eth0
# 只看接口状态(不看 IP 地址)
ip link show
ip link show eth0
# 启用/禁用接口
ip link set eth0 up
ip link set eth0 down
# 设置接口别名(用于管理)
ip link set eth0 name lan0 # 重命名接口(需先关闭)
ip link set eth0 mtu 9000 # 修改 MTU(巨型帧)
ip link set eth0 promisc on # 开启混杂模式# 查看接口的详细统计信息
ip -s link show eth0
# 输出包含:RX/TX 的字节数、包数、错误数、丢包数
# 用于诊断网卡层面的问题
# 查看接口的队列长度
ip link show eth0 | grep qlen
# 设置接口的队列长度
ip link set eth0 txqueuelen 1000
# 查看网桥(Bridge)信息
ip link show type bridge
ip link show virbr0
# 创建网桥
ip link add name br0 type bridge
ip link set eth0 master br0
ip link set br0 upIP 地址管理
# 添加 IP 地址
ip addr add 192.168.1.100/24 dev eth0
# 添加多个 IP 地址(同一个接口)
ip addr add 192.168.1.101/24 dev eth0
ip addr add 10.0.0.1/24 dev eth0
# 删除 IP 地址
ip addr del 192.168.1.100/24 dev eth0
# 查看接口的 IP 地址
ip addr show dev eth0
# 查看接口的简要信息
ip -4 addr show eth0 # 只看 IPv4
ip -6 addr show eth0 # 只看 IPv6
# 添加 IPv6 地址
ip addr add 2001:db8::1/64 dev eth0
# 查看邻居表(ARP 表)
ip neigh show
ip -6 neigh show # IPv6 邻居表ip 命令修改是临时的
通过 ip 命令添加的 IP 地址在系统重启后会丢失。如需持久化,需要修改网络配置文件或使用 NetworkManager。
ip 命令与传统命令对照
| 传统命令 | ip 命令 | 说明 |
|---|---|---|
ifconfig | ip addr show | 查看接口和 IP |
ifconfig eth0 up | ip link set eth0 up | 启用接口 |
route -n | ip route show | 查看路由表 |
arp -a | ip neigh show | 查看 ARP 表 |
netstat -tlnp | ss -tlnp | 查看监听端口 |
netstat -an | ss -tan | 查看所有连接 |
iptunnel | ip tunnel | 管理 IP 隧道 |
路由管理
路由表操作
# 查看路由表
ip route show
ip route list
route -n # 传统方式(已弃用)
# 查看路由缓存
ip route show cache
# 添加默认路由
ip route add default via 192.168.1.1
# 添加静态路由
ip route add 10.0.0.0/8 via 192.168.1.1
ip route add 172.16.0.0/12 via 192.168.1.2
# 删除路由
ip route del 10.0.0.0/8 via 192.168.1.1
# 添加黑洞路由(丢弃匹配的流量)
ip route add blackhole 10.10.10.0/24
# 添加策略路由(基于源地址)
ip rule add from 192.168.1.100 table 100
ip route add default via 10.0.0.1 table 100# 查看路由决策过程
ip route get 8.8.8.8
# 显示到达 8.8.8.8 使用的具体路由和出接口
# 输出示例:8.8.8.8 via 192.168.1.1 dev eth0 src 192.168.1.100
ip route get 8.8.8.8 from 10.0.0.1
# 模拟从指定源地址出发的路由
# 添加带 metric 的默认路由(多条默认路由实现负载均衡)
ip route add default via 192.168.1.1 metric 100
ip route add default via 192.168.1.2 metric 200
# 优先使用 metric 小的路由路由表管理
# 查看所有路由表
ip route show table all
# 查看策略路由规则
ip rule show
# 0: from all lookup local
# 32766: from all lookup main
# 32767: from all lookup default
# 添加自定义路由表
echo "100 custom_table" >> /etc/iproute2/rt_tables
# 在自定义路由表中添加路由
ip route add 10.0.0.0/8 via 192.168.2.1 table custom_table
# 策略路由实战:双线接入
# 线路 1(电信):192.168.1.0/24,网关 192.168.1.1
# 线路 2(联通):192.168.2.0/24,网关 192.168.2.1
# 电信线路流量走 table 100
ip rule add from 192.168.1.100 table 100
ip route add default via 192.168.1.1 table 100
ip route add 192.168.1.0/24 dev eth0 table 100
# 联通线路流量走 table 200
ip rule add from 192.168.2.100 table 200
ip route add default via 192.168.2.1 table 200
ip route add 192.168.2.0/24 dev eth1 table 200网络配置持久化
CentOS 7/8 网络配置文件
# CentOS 7/8 使用 ifcfg 文件
# /etc/sysconfig/network-scripts/ifcfg-eth0
# 静态 IP 配置
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
NAME=eth0
DEVICE=eth0
ONBOOT=yes
IPADDR=192.168.1.100
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
DNS1=8.8.8.8
DNS2=114.114.114.114
IPV6_PRIVACY=no
# DHCP 配置
TYPE=Ethernet
BOOTPROTO=dhcp
DEFROUTE=yes
NAME=eth0
DEVICE=eth0
ONBOOT=yes
# 配置修改后重启网络服务
systemctl restart network # CentOS 7
nmcli connection reload # CentOS 8/9
nmcli connection up eth0 # 激活连接CentOS 9 / RHEL 9 使用 NetworkManager
# 使用 nmcli 管理网络(推荐)
# 查看连接
nmcli connection show
# 查看设备
nmcli device show
# 创建静态 IP 连接
nmcli connection add type ethernet \
con-name eth0-static \
ifname eth0 \
ipv4.addresses 192.168.1.100/24 \
ipv4.gateway 192.168.1.1 \
ipv4.dns "8.8.8.8 114.114.114.114" \
ipv4.method manual
# 修改连接
nmcli connection modify eth0-static ipv4.addresses "192.168.1.101/24"
# 启用连接
nmcli connection up eth0-static
# 使用 nmtui(文本界面工具)
nmtui
# 查看连接详情
nmcli connection show eth0-static
# 添加第二个 IP 地址
nmcli connection modify eth0-static +ipv4.addresses "10.0.0.1/24"
# 设置 MTU
nmcli connection modify eth0-static 802-3-ethernet.mtu 9000DNS 配置
# /etc/resolv.conf(传统方式,NetworkManager 会覆盖)
nameserver 8.8.8.8
nameserver 114.114.114.114
search example.com
# 通过 NetworkManager 设置 DNS(推荐)
nmcli connection modify eth0-static ipv4.dns "8.8.8.8 114.114.114.114"
# /etc/nsswitch.conf 控制名称解析顺序
# hosts: files dns
# 表示先查 /etc/hosts,再查 DNS
# /etc/hosts 本地域名解析
192.168.1.100 web-server web-server.example.com网络诊断工具
连通性测试
# Ping 测试
ping -c 4 8.8.8.8 # 发送 4 个包
ping -i 0.5 8.8.8.8 # 每 0.5 秒发送一次
ping -s 1400 8.8.8.8 # 指定包大小(测试 MTU)
ping -M do -s 1472 8.8.8.8 # 禁止分片,测试路径 MTU
# MTR(综合 traceroute + ping)
mtr --report example.com # 生成报告
mtr -r -c 10 example.com # 发送 10 个包的报告
mtr -r -c 100 --report-wide example.com # 详细报告
# Traceroute
traceroute example.com
traceroute -n example.com # 不解析主机名(更快)
traceroute -T -p 80 example.com # 使用 TCP 端口
traceroute -I example.com # 使用 ICMP
traceroute -6 example.com # IPv6 traceroute
# 测试 DNS 解析
dig example.com
dig example.com +short # 只显示 IP
dig mx example.com # 查询 MX 记录
dig +trace example.com # 跟踪解析过程
nslookup example.com
host example.com端口检查
# ss 命令(推荐,替代 netstat)
ss -tlnp # TCP 监听端口
ss -ulnp # UDP 监听端口
ss -tanp # 所有 TCP 连接
ss -tan state established # 已建立的连接
ss -tanp | grep :80 # 80 端口的连接
# 统计连接状态
ss -s
# 查看连接数最多的 IP
ss -tan | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head
# 查看每个状态的连接数
ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn
# 查看指定进程的所有连接
ss -tanp | grep nginx
# netstat(传统方式,已弃用)
netstat -tlnp # TCP 监听端口
netstat -anp | grep :80 # 80 端口的连接网络性能测试
# 带宽测试(需要 iperf3)
# 服务端
iperf3 -s -p 5201
# 客户端
iperf3 -c server_ip -p 5201 -t 30 -R # 测试 30 秒,反向传输
iperf3 -c server_ip -p 5201 -P 4 # 4 个并发流
iperf3 -c server_ip -p 5201 -u -b 100M # UDP 测试,100Mbps
# 网络延迟测试
ping -c 100 8.8.8.8 | tail -2 # 100 个包的延迟统计
# nc 端口测试
nc -zv 192.168.1.100 80 # 测试 TCP 80 端口
nc -zv -u 192.168.1.100 53 # 测试 UDP 53 端口
nc -l -p 8080 # 监听 8080 端口
# curl 测试 HTTP 连通性
curl -o /dev/null -s -w "HTTP状态码: %{http_code}\n响应时间: %{time_total}s\n" http://example.com
curl -v http://example.com 2>&1 | grep -E "Connected|HTTP"
# 检查网络连通性的完整流程
ping -c 3 8.8.8.8 # 测试外网 IP 连通性
ping -c 3 example.com # 测试 DNS 解析
traceroute -n -m 10 8.8.8.8 # 路由追踪
curl -o /dev/null -s -w "%{http_code}" http://example.com # HTTP 测试tcpdump 抓包分析
tcpdump 是 Linux 下最常用的网络抓包工具,可以实时捕获和分析网络数据包。
基本抓包
# 抓取指定接口的所有流量
tcpdump -i eth0
# 抓取指定端口的流量
tcpdump -i eth0 port 80
tcpdump -i eth0 port 443
# 抓取指定主机的流量
tcpdump -i eth0 host 192.168.1.100
# 抓取指定网段的流量
tcpdump -i eth0 net 192.168.1.0/24
# 不解析主机名(提高性能)
tcpdump -i eth0 -nn port 80
# 保存抓包到文件(用 Wireshark 分析)
tcpdump -i eth0 -w capture.pcap
# 读取抓包文件
tcpdump -r capture.pcap高级过滤
# 只抓 SYN 包(TCP 三次握手的第一个包)
tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0'
# 只抓 RST 包(连接重置)
tcpdump -i eth0 'tcp[tcpflags] & (tcp-rst) != 0'
# 只抓 HTTP GET 请求
tcpdump -i eth0 -A 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
# 抓取特定协议
tcpdump -i eth0 icmp # ICMP 协议
tcpdump -i eth0 arp # ARP 协议
tcpdump -i eth0 udp port 53 # DNS 查询
# 抓取源或目的端口
tcpdump -i eth0 'src port 80 or dst port 80'
# 抓取特定长度的包
tcpdump -i eth0 'less than 100'
# 组合过滤
tcpdump -i eth0 -nn 'host 192.168.1.100 and (port 80 or port 443)'
# 排除某些流量
tcpdump -i eth0 -nn 'not port 22 and not host 192.168.1.1'抓包分析技巧
# 显示包内容(ASCII 格式)
tcpdump -i eth0 -A port 80
# 显示包内容(十六进制 + ASCII)
tcpdump -i eth0 -X port 80
# 限制抓包数量
tcpdump -i eth0 -c 100 port 80
# 增大抓包缓冲区(避免丢包)
tcpdump -i eth0 -B 32768 -w capture.pcap
# 按包大小过滤(检测异常大包)
tcpdump -i eth0 'greater than 1500' # 超过 MTU 的包
tcpdump -i eth0 'less than 64' # 异常小包
# 抓取 TCP 重传
tcpdump -i eth0 'tcp[tcpflags] & (tcp-syn|tcp-ack) = tcp-syn and tcp[tcpflags] & tcp-rst = 0'网络命名空间
网络命名空间(Network Namespace)是 Linux 内核提供的网络隔离机制,是 Docker/Kubernetes 容器网络的底层基础。每个网络命名空间有独立的网络栈(接口、路由表、iptables 规则等)。
基本操作
# 创建网络命名空间
ip netns add ns1
ip netns add ns2
# 查看所有命名空间
ip netns list
# 在命名空间中执行命令
ip netns exec ns1 ip addr show
ip netns exec ns1 ping 10.0.0.2
# 删除命名空间
ip netns delete ns1创建 veth pair 连接两个命名空间
# 创建一对虚拟以太网卡
ip link add veth1 type veth peer name veth2
# 将 veth2 放入 ns1
ip link set veth2 netns ns1
# 将 veth1 放入 ns2
ip link set veth1 netns ns2
# 在 ns1 中配置 IP
ip netns exec ns1 ip addr add 10.0.0.1/24 dev veth2
ip netns exec ns1 ip link set veth2 up
# 在 ns2 中配置 IP
ip netns exec ns2 ip addr add 10.0.0.2/24 dev veth1
ip netns exec ns2 ip link set veth1 up
# 测试连通性
ip netns exec ns1 ping 10.0.0.2连接命名空间到宿主机网络
# 创建命名空间
ip netns add ns1
# 创建 veth pair
ip link add veth-ns type veth peer name veth-br
# 将一端放入命名空间
ip link set veth-ns netns ns1
ip netns exec ns1 ip addr add 10.0.0.1/24 dev veth-ns
ip netns exec ns1 ip link set veth-ns up
# 将另一端连接到宿主机网桥
ip link set veth-br up
ip addr add 10.0.0.254/24 dev veth-br
# 设置命名空间的默认路由
ip netns exec ns1 ip route add default via 10.0.0.254
# 配置 NAT(让命名空间可以访问外网)
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward网络命名空间与 Docker 的关系
# 查看 Docker 容器的网络命名空间
docker inspect --format '{{.State.Pid}}' container_id
# 假设 PID 为 12345
# 在容器的网络命名空间中执行命令
nsenter -t 12345 -n ip addr show
nsenter -t 12345 -n ip route show
# 查看 Docker 网络的 veth pair
ip link show type veth
# 找到容器的 veth 接口,跟踪到宿主机的 veth
# 查看宿主机上 Docker 创建的网桥
ip link show docker0
bridge fdb show # 查看网桥的转发表链路聚合(Bond)
链路聚合(Bond)将多个物理网卡绑定为一个逻辑网卡,实现网络冗余和负载均衡。
Bond 模式
| 模式 | 说明 | 适用场景 |
|---|---|---|
balance-rr (0) | 轮询 | 需要最大带宽 |
active-backup (1) | 主备冗余 | 需要高可用 |
balance-xor (2) | XOR 哈希 | 兼容性好 |
broadcast (3) | 广播 | 特殊场景 |
802.3ad (4) | LACP 动态聚合 | 交换机支持 LACP |
balance-tlb (5) | 自适应传输负载均衡 | 不需要交换机配置 |
balance-alb (6) | 自适应负载均衡 | 包含接收负载均衡 |
配置 Bond
# /etc/sysconfig/network-scripts/ifcfg-bond0
DEVICE=bond0
TYPE=Bond
BONDING_MASTER=yes
BOOTPROTO=static
IPADDR=192.168.1.200
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
BONDING_OPTS="mode=active-backup miimon=100"
# /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
MASTER=bond0
SLAVE=yes
ONBOOT=yes
# /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1
TYPE=Ethernet
MASTER=bond0
SLAVE=yes
ONBOOT=yes
# 加载 Bond 模块
modprobe bonding
# 启动 Bond
ifup bond0
# 查看 Bond 状态
cat /proc/net/bonding/bond0
# 查看活跃的网卡
ip link show bond0使用 nmcli 配置 Bond
# 创建 Bond 连接
nmcli connection add type bond \
con-name bond0 \
ifname bond0 \
mode active-backup \
miimon 100
# 添加 slave 接口
nmcli connection add type ethernet \
slave-type bond \
master bond0 \
con-name bond0-eth0 \
ifname eth0
nmcli connection add type ethernet \
slave-type bond \
master bond0 \
con-name bond0-eth1 \
ifname eth1
# 配置 Bond 的 IP
nmcli connection modify bond0 \
ipv4.addresses 192.168.1.200/24 \
ipv4.gateway 192.168.1.1 \
ipv4.method manual
# 启动
nmcli connection up bond0Bond 模式选择建议
- 服务器高可用:
active-backup(最常用,只需交换机端口配置) - 高带宽需求:
802.3ad(需要交换机支持 LACP) - 不需要交换机配置:
balance-tlb或balance-alb
常见问题排查
网络不通
# 1. 检查接口状态
ip addr show
ip link show
# 2. 检查路由
ip route show
# 3. 检查 DNS
cat /etc/resolv.conf
dig example.com
# 4. 检查防火墙
firewall-cmd --state
iptables -L -n
# 5. 抓包分析
tcpdump -i eth0 -nn host target_ip端口不通
# 1. 检查服务是否监听
ss -tlnp | grep :port
# 2. 检查防火墙规则
firewall-cmd --list-ports
iptables -L -n | grep port
# 3. 检查 SELinux
getenforce
# 4. 检查连接
nc -zv target_ip port网络延迟高
# 1. 使用 mtr 分析延迟发生在哪一跳
mtr --report target_ip
# 2. 检查网络拥塞
sar -n DEV 1 5
# 3. 检查丢包率
ping -c 100 target_ip | tail -2
# 4. 检查网卡错误
ip -s link show eth0
ethtool -S eth0网络故障排查清单
# 完整的网络排查流程
# 1. 物理层
ip link show # 接口是否 UP
ethtool eth0 | grep "Link detected" # 网线是否连接
# 2. 网络层
ip addr show # IP 是否配置
ip route show # 路由是否正确
ping -c 3 192.168.1.1 # 网关是否可达
# 3. 传输层
ss -tlnp # 服务是否监听
nc -zv target_ip port # 端口是否可达
# 4. 应用层
dig example.com # DNS 是否解析
curl -v http://example.com # HTTP 是否正常
# 5. 安全层
firewall-cmd --state # 防火墙状态
getenforce # SELinux 状态
iptables -L -n # iptables 规则