Linux常用网络管理命令

words: 5.2k    views:    time: 22min

整理一些在Linux中常用的网络管理命令

流量控制 tc

TC(Traffic Control)用于Linux内核的流量控制,它通过队列规则(qdisc)管理数据包的排队和调度,从而实现对网络流量的控制。TC的队列规则分为两类:无类队列规则(classless qdisc),和分类队列规则(classful qdisc)。无类队列规则相对简单,而分类队列规则可以包含多个类,并通过过滤器(filters)将数据包分配到不同类,从而提供更精细的流量控制功能。

  • qdisc队列规则

qdisc(队列规则)用来控制网络接口的发送队列,管理数据包排队、调度和速率。它会将数据包缓存起来,再按照用户设定的策略调度发送,在保证连接稳定的前提下,使网络流量更加平滑。

一般只用发送队列,即”控发不控收”,因为网络瓶颈一般不在本地网卡接收能力,而是出现在网络传输链路中。如果发送过快,容易造成拥塞,因此Linux的流量控制机制将精力主要放在了发送端限速与调度上。

  • class类

只能存在于classful qdisc中,其作用是对流量进行分类和管理。可以理解成qdisc队列规则下的逻辑分支,然后每个class可以有自己的队列规则(qdisc),用来实现不同流量的速率、优先级等控制策略

  • Filter规则

filter是附属于qdisc或class的匹配机制,本身不处理流量。作用是将数据包匹配到具体的class或qdisc。常用的过滤器有:fwmark分类器,u32分类器,基于路由的分类器,和RSVP分类器等;fwmark可结合netfilter使用,u32可按IP/端口/协议头字段匹配。

在TC中,使用”major:minor”这样的句柄来标识队列和类别。major在一个网卡的所有队列中必须是惟一的。对于队列来说,minor总是为0,即”major:0”

  • 添加
1
2
3
tc qdisc  [add|change|replace|link] [dev dev-name] [parent qdisc-id|root] [handle qdisc-id] [qdisc specific parameters]
tc class [add|change|replace] [dev dev-name] [parent qdisc-id] [classid class-id] [qdisc specific parameters]
tc filter [add|change|replace] [dev dev-name] [protocol protocol] [parent qdisc-id|root] [prio priorityfiltertype] [filtertype specific parameters] [classid classid]
  • 查看
1
2
3
tc [-s | -d ] qdisc show [ dev DEV ]
tc [-s | -d ] class show dev DEV
tc filter show dev DEV
  • 删除
1
tc qdisc del dev eth0 root

不分类队列规则

pfifo_fast 先入先出队列

pfifo_fast对所有包都一视同仁,有三个”band”(可理解为三个队列),编号分别为 0、1、2

  • 每个 band 上分别执行 FIFO 规则
  • 如果 band 0 有数据,就不会处理 band 1;同理,band 1 有数据时,不会去处理 band 2
  • 内核会检查数据包的 TOS 字段,将“最小延迟”的包放到 band 0
TBQ 令牌桶

对于没有超过预设速率的流量直接透传,但也能容忍超过预 设速率的短时抖动。TBF 非常简洁,对网络和处理器都很友好,如果只是想实现接口限速,那TBF是第一选择

TBF实现主要包括两部分:

  1. A buffer (bucket):bucket 最重要的参数是它的大小,即能容纳的 token 数量。
  2. Tokens:token 会以特定的速率(specific rate)填充 bucket 缓冲区。

当一个包到来时,会从bucket中获取一个token,然后收集这个包的信息,最后从bucket中删除这个token,这样可能有三种场景

  • 数据速率 = token速率,每个包都能找到一个对应的token,然后直接从队列出去,没有延时;
  • 数据速率 > token速率,token很快用完,如果包还是源源不断地到来,就会产生丢包;
  • 数据速率 < token速率,数据能及时发送出去,但是会产生bucket积压,极端情况会将bucket占满。这样如果数据速率突然高于token速率,可以消耗积压的token,所以能够容忍短时数据速率抖动;
SFQ 随机公平排队

SFQ是公平排队算法族的一个简单实现,相比其他算法,SFQ精准性要差一些,但它所需的计算量也少,而结果几乎是完全公平的

SFQ中的核心是conversion(会话)或 flow(流),大部分情况下对应一个TCP session或UDP stream。每个conversion对应一个FIFO queue,然后将流量分到不同queue。发送数据时,按照round robin方式,每个session轮流发送。

这种机制会产生非常公平的结果,不会因为单个conversion太大而把其他conversion的带宽都挤占掉。SFQ被称为”随机的”是因为它其实并没有为每个session分配一个queue,而是用算法将流量哈希到了一组有限的queue。

分类队列规则

PRIO 优先级排队规则

PRIO可以理解为pfifo_fast的升级版,它也有多个band,但每个band都是一个独立的class,而不是简单的FIFO。

当一个包到PRIO qdisc之后,它会根据设置的filters选择一个class,并将包送到这个class。默认情况下会创建三个class,每个class默认情况下包含一个纯FIFO qdisc,没有其他内部结构,但你可以用其他类型的qdisc替换掉FIFO。

当从PRIO qdisc取出数据包时,会先尝试 :1。只有lower classes没有数据包可取时,才会尝试higher classes。这样,如果希望基于tc filters而不仅仅是TOS flags做流量优先级分类时,这个qdisc会非常有用,因为可以向这三个预置的classes添加额外的qdisc,而pfifo_fast只能提供简单的FIFO qdisc。

CBQ

CBQ是最复杂、最花哨、最少被理解、也可能是最难用对的qdisc。

HTB 层级令牌桶

Martin Devera意识到CBQ太复杂,并且没有针对很多典型的场景进行优化。因此他设计了HTB,这种层级化的方式对下面这些场景很适用:

  • 有一个固定总带宽,想将其分割成几个部分,分别用作不同目的
  • 每个部分的带宽是有保证的(guaranteed bandwidth)
  • 还可以指定每个部分向其他部分借带宽

HTB内部其实是一个classful TBF(令牌桶过滤器),这也是它叫层级令牌桶的原因

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 添加根队列规则,指定默认的class为 1:12
tc qdisc add dev eth0 root handle 1: htb default 12

# 添加根类别
tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit ceil 100mbit

# 添加子类别,高优先级流量
# rate 10mbi 保证带宽
# ceil 20mbit 最大带宽
# burst 15k 突发流量,对应令牌桶容量
# cburst 30k 当速率超过rate,向上借带宽时,允许的突发大小
# quantum 1500 调度器一次分配的流量字节数,一般设为MTU的整数倍,quantum越大,调度公平性越差,但效率更高
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 10mbit ceil 20mbit burst 15k cburst 30k prio 1 quantum 1500

# 添加子类别,中等优先级流量
tc class add dev eth0 parent 1:1 classid 1:11 htb rate 30mbit ceil 50mbit burst 25k prio 2

# 添加子类别,低优先级流量
tc class add dev eth0 parent 1:1 classid 1:12 htb rate 10mbit ceil 10mbit prio 3

# 添加过滤器,基于端口的过滤(对于 parent 1:0 下的流量进行过滤,过滤后的结果归类到 classid 1:10下)
# prio 1:表示优先级,同一个class下面可以加多个过滤器,按从小到大优先过滤
# u32 匹配器:u32 match <层> <字段> <值> <掩码>
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dport 80 0xffff classid 1:10

# 添加过滤器,基于源地址的过滤
tc filter add dev eth0 protocol ip parent 1:0 prio 2 u32 match ip src 192.168.1.100/32 classid 1:11

# 添加过滤器,基于防火墙标记的过滤
# fw 依赖iptables给数据包打的fwmark,将打过标记的数据包分到目标类中
# 比如:iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 12
tc filter add dev eth0 protocol ip parent 1:0 prio 3 fw classid 1:12

# 查看网卡流量统计
# -s 示统计信息,包括发送的字节数、数据包数、丢包数、超限数等
# -d 显示详细信息,包括 qdisc 或 class 的配置参数、层级等
# -p 用更易读的格式显示输出,方便阅读层级关系
tc -s -d -p qdisc show dev ens160

数据包过滤转发 iptables

iptables是位于用户空间的一个面向Linux系统管理员的防火墙管理工具,真正实现防火墙功能的是netfilter,它是Linux实现包过滤的内核模块,iptables对应在内核中的模块是ip_tables,可以通过modinfo ip_tables查看。相对tc控制流量的发送端,iptables就是控制流量的接收端了,所以也称为防火墙。

图中的“四表五链”是对用户设置规则的分类管理,四表存放着功能一致的规则,五链则存放着数据包所处链路一致的规则。其中表和链之间是多对多的对应关系(如上图所示),但是不管一个链对应多少表,表的处理优先级是固定的:raw -> mangle -> nat -> filter

  • filter表:用来对数据包进行过滤,具体的规则要求决定如何处理一个数据包;
  • nat表:用来修改数据包的 IP 地址、端口号信息;
  • mangle表:用来修改数据包的服务类型,生存周期,为数据包设置标记,实现流量整形、策略路由等;
  • raw表:用来决定是否对数据包进行状态跟踪;

raw表只使用在PREROUTING链和OUTPUT链上,因为优先级最高,从而可以在系统对收到的数据包进行ip_conntrack(连接跟踪)前进行处理。一但用户使用了raw表,在某个链上,raw表处理完后,将跳过NAT表和ip_conntrack处理,不再做地址转换和数据包的链接跟踪处理了。一般可以应用在那些不需要做nat的情况下,以提高性能;

  • input链:收到访问本机地址的数据包时,将应用此链中的规则;
  • output链:本机向外发送数据包时,将应用此链中的规则;
  • forward链:收到需要通过本机转发给其他地址的数据包时,将应用此链中的规则;
  • prerouting链:对数据包做路由选择之前,将应用此链中的规则;
  • postrouting链:对数据包做路由选择之后,将应用此链中的规则;

命令语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
iptables [-t 表名] 管理选项 [链名] [匹配条件] [-j 控制类型]

管理选项:
-A: 在指定链的末尾添加一条新的规则
-D: 删除指定链中的某一条规则,可删除指定序号或具体内容
-I: 在指定链中插入一条新规则,未指定序号时默认作为第一条规则
-R: 修改、替换指定链中的某一条规则,可指定规则序号或具体内容
-L: 列出指定链中所有的规则,未指定链名,则列出表中的所有链
-F: 清空指定链中所有的规则,未指定链名,则清空表中的所有链
-P: 设置指定链的默认策略
-n: 使用数字形式显示输出结果
-v: 查看规则列表时显示详细的信息
-h: 查看命令帮助信息
--line-numbers: 查看规则列表时,同时显示规则在链中的顺序号

常用匹配条件:
-i:网络接口名称 #指定数据包从哪个网络接口进入
-m:匹配的模块 #指定数据包规则所使用的过滤模块
-o:网络接口名称 #指定数据包从哪个网络接口输出
-p:协议名称 #指定数据包匹配的协议,如TCP、UDP和ICMP等
-s:源地址或子网地址 #指定数据包匹配的源地址
-state:数据包当前状态 #指定ESTABLISHED,RELATED等
-sport:源端口号 #指定数据包匹配的源端口号
-dport:目的端口号 #指定数据包匹配的目的端口号iptables规则的动作

常用控制类型:
LOG: 日志功能,将符合规则的数据包的相关信息记录在日志中,便于分析和排错
ACCEPT: 接受数据包
REJECT: 拒绝数据包
DROP: 丢弃数据包,相对于拒绝,常用于隐藏服务,防止扫描或探测
EDIRECT: 与DROP基本一样,区别在于它除了阻塞包之外,还向发送者返回错误信息
MASQUERADE: IP伪装,改写数据包来源IP为本机IP及端口,和SNAT不同的是,当进行IP伪装时,不需指定要伪装成哪个IP,IP会从网卡直接读取
SNAT: 源地址转换,改变数据包的源地址
DNAT: 目标地址转换,改变数据包的目的地址

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
iptables -I INPUT -p tcp --dport 3306 -j ACCEPT        # 允许外部访问指定的端口
iptables -I INPUT -s 192.168.1.0/24 -j DROP # 丢掉所有来自192.168.1.0网段的数据包
iptables -I INPUT -s 172.168.0.1 -p icmp -j DROP # 禁止某个ip的ICMP协议

只允许指定ip(192.168.1.123、192.168.1.124)访问指定端口(顺序相关)
iptables -I INPUT -p tcp --dport 50070 -j DROP
iptables -I INPUT -s 192.168.1.123 -p tcp --dport 50070 -j ACCEPT
iptables -I INPUT -s 192.168.1.124 -p tcp --dport 50070 -j ACCEPT

本机开放从TCP端口20-1024提供的应用服务
iptables -A INPUT -p tcp --dport 20:1024 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 20:1024 -j ACCEPT

允许转发来自192.168.0.0/24局域网段的DNS解析请求数据包
iptables -A FORWARD -s 192.168.0.0/24 -p udp --dport 53 -j ACCEPT
iptables -A FORWARD -d 192.168.0.0/24 -p udp --sport 53 -j ACCEPT

网络性能测试 iperf

详细命令参数:https://iperf.fr/iperf-doc.php

1
2
3
4
5
# 服务端启动端口监听
iperf3 -s -p 5001 -i 1

# 客户端启动打流,使用10路并发流,每路限制10Mbps,统计打印间隔每秒一次,持续10000秒。
iperf3 -c 20.20.20.20 -p 5001 -t 10000s -i 1s -b 10M -P 10

网络抓包 tcpdump

tcpdump可以将网络数据包截获下来提供分析,支持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来进行过滤

常用选项:

1
2
3
4
5
6
7
8
9
10
11
12
-i <iface>	指定接口,例如 -i eth0。
-n 不解析主机名,直接显示 IP 地址。
-nn 不解析主机名和端口号,显示数字形式。
-v / -vv / -vvv 增加输出的详细程度。
-c <count> 捕获指定数量的数据包后退出。
-s <snaplen> 指定抓包长度,默认 262144 字节。
-X 显示数据包的 十六进制 + ASCII。
-XX 显示以太网头 + 十六进制 + ASCII。
-A 以 ASCII 形式显示数据内容(适合 HTTP 请求)。
-w <file> 将抓到的数据包写入文件(例如 .pcap),可用于 Wireshark 分析。
-r <file> 从抓包文件读取数据。
-tt / -ttt / -T 显示时间戳格式,可精确到微秒。

示例:

1
2
3
4
5
# 针对指定主机抓包
tcpdump -i any -n -nn host 192.168.1.10 -w ./$(date +%Y%m%d%H%M%S).pcap

# 针对指定端口抓包
tcpdump -i any -n -nn tcp and port 80 -w ./$(date +%Y%m%d%H%M%S).pcap

网络设备管理 ip

  • 常用命令
1
2
3
4
5
6
7
8
9
ip link show            # 查看所有网络接口 ifconfig -a
ip link show dev eth0 # 查看指定接口 ifconfig eth0

ip link set eth0 up # 启用接口 ifconfig eth0 up
ip link set eth0 down # 启用接口 ifconfig eth0 down

ip link set eth0 address 00:11:22:33:44:55 # 修改MAC地址 ifconfig eth0 hw ether 00:11:22:33:44:55
ip link set eth0 mtu 1500 # 修改MTU值 ifconfig eth0 mtu 1500
ip link set eth0 name wan0 # 重命名接口
  • 常用设备
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
物理设备 (Physical Layer)
├── 物理有线网卡 (eth0, enp3s0, ens33)
├── 物理无线网卡 (wlan0, wlp2s0)
├── 环回接口 (lo)
└── 其他物理接口 (ppp0, usb0)


ip link add vrf-blue type vrf table 10
ip link set dev vrf-blue up
ip link set dev eth0 master vrf-blue

虚拟设备 (Virtual Layer)
├── VLAN 接口 => 在一个物理网卡上可以创建多个逻辑网络,起到网络隔离的作用
│ ├── eth0.100 (VLAN ID 100) => ip link add link eth0 name eth0.100 type vlan id 100
│ └── eth0.200 (VLAN ID 200) => ip addr add 192.168.100.1/24 dev eth0.100
│ => ip link set eth0.100 up
│ => ip link show type vlan

├── vrf 虚拟路由转发 => 在多网卡多网络的场景下,本机逻辑路由划分,避免所有接口共享同一张路由表
│ => ip link add vrf-manage type vrf table 10
│ => ip link set dev vrf-manage up
│ => ip link set dev eth0 master vrf-manage
│ => ip route show vrf vrf-manage
│ => ip vrf exec <vrf-name> <command>

├── 网桥设备 (Bridge) => 二层虚拟设备,作用类似于交换机,将加入它的设备放在同一个二层网络里
│ ├── docker0 (Docker网桥) => ip link add name br0 type bridge & ip link set br0 up
│ ├── br0 (自定义网桥) => ip addr add 192.168.3.1/24 dev br0
│ │ ├── 虚拟设备 veth0 => ip link add veth0 type veth peer name veth1
│ │ ├── 虚拟设备 veth1 => ip link set veth0 up & ip link set veth0 master br0
│ │ └── 物理设备 eth1 => ip link set veth1 up & ip addr add 192.168.3.2/24 dev veth1
│ └── virbr0 (Libvirt网桥) => ip link set eth1 master br0
│ => ping 192.168.3.1
│ => ping 192.168.3.2


├── TAP/TUN 设备 => ip tuntap add dev tap0 mode tap & ip link set dev tap0 up
│ ├── tap0 (二层隧道) => ip link set tap0 master br0
│ └── tun0 (三层隧道) => ip tuntap add dev tun0 mode tun & ip link set dev tun0 up
│ => ip addr add 10.8.0.1 peer 10.8.0.2 dev tun0
│ => ip route add 10.8.0.0/24 dev tun0
│ => iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE


└── 绑定接口 (Bonding) => 虚拟网卡,可以将多个物理网卡绑成一块逻辑网卡,起到提高带宽(多网卡并发)、冗余容错的作用
├── bond0 (链路聚合)
│ ├── 物理设备 eth2 (从设备)
│ └── 物理设备 eth3 (从设备)
└── team0 (新一代聚合)

地址管理 ip addr

  • 常用命令
1
2
3
4
5
ip addr show            # 查看所有IP地址
ip addr flush dev eth0 # 清空所有IP

ip addr add 192.168.1.100/24 dev eth0 # 添加IP地址
ip addr del 192.168.1.100/24 dev eth0 # 删除IP地址

路由管理 ip route

  • 常用命令
1
2
3
4
5
6
7
8
9
10
11
12
13
ip route show          # 查看路由表
ip route flush cache # 清空路由表

ip route add default via 192.168.1.1 dev eth0 # 添加默认网关
ip route add 10.0.0.0/8 via 192.168.1.1 # 添加路由
ip route add 172.16.0.0/16 via 192.168.1.1 dev eth0 # 添加路由,指定接口
ip route add 192.168.2.0/24 via 10.0.0.1 src 10.0.0.2 # 添加路由,指定源ip
ip route add 10.8.0.0/24 dev tun0 # 隧道路由

ip route add 192.168.32.21 dev pcie0 # 目的地址是192.168.32.21的包,直接从pcie0接口出去

ip route del default # 删除路由
ip route del 10.0.0.0/8 # 删除路由

ARP管理 ip neigh

  • 常用命令
1
2
3
4
5
6
7
ip neigh show            # 查看ARP表 arp -n
ip neigh flush dev eth0 # 清空ARP表 arp -d -a

ip neigh add 192.168.1.100 lladdr 00:11:22:33:44:55 dev eth0 # 添加静态ARP arp -s 192.168.1.100 00:11:22:33:44:55
ip neigh add 192.168.1.100 lladdr 00:11:22:33:44:55 dev eth0 nud permanent # 添加永久静态ARP

ip neigh del 192.168.1.100 dev eth0 # 删除ARP条目 arp -d 192.168.1.100

策略路由 ip rule

  • 常用命令
1
2
3
4
5
6
7
8
9
# 查看路由策略
ip rule show

# 添加策略路由
ip rule add from 192.168.1.100 table 100
ip rule add to 10.0.0.0/8 table 200

# 删除策略
ip rule del from 192.168.1.100

隧道管理 ip tunnel

  • 常用命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
本地局域网: 192.168.1.0/24,隧道端点: 192.168.1.100,公网IP: 203.0.113.100

ip tunnel add tun0 mode ipip remote 198.51.100.200 local 203.0.113.100 # 创建隧道
ip link set tun0 up # 启用隧道
ip addr add 172.16.0.1 peer 172.16.0.2/30 dev tun0 # 为隧道接口分配IP
ip route add 10.2.2.0/24 via 172.16.0.2 dev tun0 # 添加路由


对端局域网段: 10.2.2.0/24,隧道端点: 10.2.2.100,公网IP: 198.51.100.200

ip tunnel add tun0 mode ipip remote 203.0.113.100 local 198.51.100.200 # 创建隧道
ip link set tun0 up # 启用隧道
ip addr add 172.16.0.2 peer 172.16.0.1/30 dev tun0 # 为隧道接口分配IP
ip route add 192.168.1.0/24 via 172.16.0.1 dev tun0 # 添加路由

组播地址管理 ip maddr

组播地址范围:224.0.0.0 ~ 239.255.255.255

1
2
3
4
5
ip maddr show   # 查看组播地址

ip maddr add 224.0.0.1 dev eth0 # 添加组播地址

ip link set eth0 multicast on # 启用组播功能

组播路由管理 ip mroute

1
2
3
ip mroute show  # 查看组播路由

ip mroute add 239.1.1.1/32 via 192.168.1.10 dev eth1 # 只接受来自192.168.1.10的组播流


参考:

  1. https://arthurchiao.art/blog/lartc-qdisc-zh
  2. https://tinychen.com/20200414-iptables-principle-introduction
  3. https://iperf.fr/iperf-doc.php
  4. https://www.zhaohuabing.com/post/2020-02-24-linux-taptun