0%

iproute2 工具使用笔记

如今很多系统管理员依然通过组合使用诸如ifconfig、route、arp和netstat等命令行工具(统称为net-tools)来配置网络功能,解决网络故障。net-tools起源于BSD的TCP/IP工具箱,后来成为老版本Linux内核中配置网络功能的工具。但自2001年起,Linux社区已经对其停止维护。同时,一些Linux发行版比如Arch Linux和CentOS/RHEL 7则已经完全抛弃了net-tools,只支持iproute2。

作为网络配置工具的一份子,iproute2的出现旨在从功能上取代net-tools。net-tools通过 procfs(/proc)和ioctl系统调用去访问和改变内核网络配置,而iproute2则通过netlink套接字接口与内核通讯。抛开性能而言,iproute2的用户接口比net-tools显得更加直观。比如,各种网络资源(如link、IP地址、路由和隧道等)均使用合适的对象抽象去定义,使得用户可使用一致的语法去管理不同的对象。更重要的是,到目前为止,iproute2仍处在持续开发中。

如果你仍在使用net-tools,而且尤其需要跟上新版Linux内核中的最新最重要的网络特性的话,那么是时候转到iproute2的阵营了。原因就在于使用iproute2可以做很多net-tools无法做到的事情。

对于那些想要转到使用iproute2的用户,有必要了解下面有关net-tools和iproute2的众多对比。

显示所有已连接的网络接口

下面的命令显示出所有可用网络接口的列表(无论接口是否激活)

使用net-tools

1
$ ifconfig -a

使用 iproute2

1
2
3
4
5
6
7
$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DEFAULT group default qlen 1000
link/ether 04:25:c5:02:b8:a3 brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 04:25:c5:02:b8:a4 brd ff:ff:ff:ff:ff:ff

激活或停用网络接口

使用这些命令来激活或停用某个指定的网络接口。

使用 net-tools

1
2
$ sudo ifconfig eth1 up
$ sudo ifconfig eth1 down

使用 iproute2

1
2
$ sudo ip link set down eth1
$ sudo ip link set up eth1

创建与删除网络接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ ip link add [link DEV] [ name ] NAME
[ txqueuelen PACKETS ]
[ address LLADDR ]
[ broadcast LLADDR ]
[ mtu MTU ]
[ numtxqueues QUEUE_COUNT ]
[ numrxqueues QUEUE_COUNT ]
type TYPE [ ARGS ]
$ ip link delete { DEVICE | dev DEVICE | group DEVGROUP } type TYPE [ ARGS ]

TYPE := { vlan | veth | vcan | dummy | ifb | macvlan | macvtap |
bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan |
gre | gretap | ip6gre | ip6gretap | vti | nlmon |
bond_slave | geneve | bridge_slave | macsec }

示例如下:

1
2
3
4
5
6
7
8
# 在 eth0 上创建 ipvlan 设备 ipv1
$ ip link add link eth0 ipv1 type ipvlan mode l3
# 在 eth0 上创建 macvlan 设备 macv1
$ ip link add link eth0 name macv1 type macvlan mode bridge
# 创建 bridge 设备 br0
$ ip link add br0 type bridge
# 创建 veth pair veth0/1
$ ip link add veth0 type veth peer name veth1

改变网络接口的MAC地址

使用下面的命令可篡改网络接口的MAC地址,请注意在更改MAC地址前,需要停用接口。

使用net-tools

1
$ sudo ifconfig eth1 hw ether 08:00:27:75:2a:66

使用iproute2

1
$ sudo ip link set dev eth1 address 08:00:27:75:2a:67

改变网络接口参数

命令 解释
ip link set eth0 up 开启eth0网卡
ip link set eth0 down 关闭eth0网卡
ip link set eth0 promisc on 开启网卡的混合模式
ip link set eth0 promisc off 关闭网卡的混合模式
ip link set eth0 txqueuelen 1200 设置网卡队列长度
ip link set eth0 mtu 1400 设置网卡最大传输单元
ip link set eth0 netns net1 设置网卡网络命名空间

ip addr

为网络接口分配IPv4地址

使用这些命令配置网络接口的IPv4地址。

使用net-tools

1
$ sudo ifconfig eth1 10.0.0.1/24

使用iproute2

1
$ sudo ip addr add 10.0.0.1/24 dev eth1

值得注意的是,可以使用iproute2给同一个接口分配多个IP地址,ifconfig则无法这么做。使用ifconfig的变通方案是使用IP别名

1
2
3
$ sudo ip addr add 10.0.0.1/24 broadcast 10.0.0.255 dev eth1
$ sudo ip addr add 10.0.0.2/24 broadcast 10.0.0.255 dev eth1
$ sudo ip addr add 10.0.0.3/24 broadcast 10.0.0.255 dev eth1

移除网络接口的IPv4地址

就IP地址的移除而言,除了给接口分配全0地址外,net-tools没有提供任何合适的方法来移除网络接口的IPv4地址。相反,iproute2则能很好地完全。

使用net-tools

1
$ sudo ifconfig eth1 0

使用iproute2

1
$ sudo ip addr del 10.0.0.1/24 dev eth1

显示网络接口的IPv4地址

按照如下操作可查看某个指定网络接口的IPv4地址。

使用net-tools

1
$ ifconfig eth1

使用iproute2

1
2
3
4
5
6
7
$ ip addr show dev eth1
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 04:25:c5:02:b8:a4 brd ff:ff:ff:ff:ff:ff
inet 9.51.26.196/26 brd 9.51.26.255 scope global noprefixroute eth1
valid_lft forever preferred_lft forever
inet6 fe80::625:c5ff:fe02:b8a4/64 scope link
valid_lft forever preferred_lft forever

同样,如果接口分配了多个IP地址,iproute2会显示出所有地址,而net-tools只能显示一个IP地址。

为网络接口分配IPv6地址

使用这些命令为网络接口添加IPv6地址。net-tools和iproute2都允许用户为一个接口添加多个IPv6地址。

使用net-tools

1
2
$ sudo ifconfig eth1 inet6 add 2002:0db5:0:f102::1/64
$ sudo ifconfig eth1 inet6 add 2003:0db5:0:f102::1/64

使用iproute2

1
2
$ sudo ip -6 addr add 2002:0db5:0:f102::1/64 dev eth1
$ sudo ip -6 addr add 2003:0db5:0:f102::1/64 dev eth1

显示网络接口的IPv6地址

按照如下操作可显示某个指定网络接口的IPv6地址。net-tools和iproute2都可以显示出所有已分配的IPv6地址。

使用net-tools

1
$ ifconfig eth1

使用iproute2

1
$ ip -6 addr show dev eth1

移除网络设备的IPv6地址

使用这些命令可移除接口中不必要的IPv6地址。

使用net-tools

1
$ sudo ifconfig eth1 inet6 del 2002:0db5:0:f102::1/64

使用iproute2

1
$ sudo ip -6 addr del 2002:0db5:0:f102::1/64 dev eth1

ip route

linux 系统中,可以自定义从 1 - 252个路由表。其中,linux系统维护了4个路由表:

  • 0#表:系统保留表
  • 253#表:defulte table 没特别指定的默认路由都放在改表
  • 254#表:main table 没指明路由表的所有路由放在该表
  • 255#表:local table 保存本地接口地址,广播地址、NAT地址 由系统维护,用户不得更改

路由表序号和表名的对应关系在 /etc/iproute2/rt_tables 文件中,可手动编辑,路由表添加完毕即时生效。

1
2
3
4
5
6
7
8
$ cat /etc/iproute2/rt_tables
#
# reserved values
#
255 local
254 main
253 default
0 unspec

可以分别查看各个表的路由情况:

1
2
3
4
5
6
7
8
9
10
# 查看本地路由表
# 此输出中的第一个字段告诉我们该路由是针对该计算机本地托管的广播地址还是IP地址或范围。
# 随后的字段会通知我们目标可通过哪个设备到达,并且特别是(在此表中)内核已添加了这些路由,作为建立IP层接口的一部分
$ ip route show table local
broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1

$ ip route show table local # 此即是 ip route 默认输出

查看IP路由表

net-tools中有两个选择来显示内核的IP路由表:route和netstat。在iproute2中,使用命令ip route。

使用net-tools

1
2
3
4
5
6
7
8
$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 9.51.26.193 0.0.0.0 UG 0 0 0 eth1
9.0.0.0 9.51.26.193 255.0.0.0 UG 0 0 0 eth1
9.51.26.192 0.0.0.0 255.255.255.192 U 100 0 0 eth1
10.0.0.0 9.51.26.193 255.0.0.0 UG 0 0 0 eth1
$ netstat -rn

使用iproute2

1
2
3
4
5
6
7
8
$ ip route show 
default via 9.51.26.193 dev eth1
9.0.0.0/8 via 9.51.26.193 dev eth1
9.51.26.192/26 dev eth1 proto kernel scope link src 9.51.26.196 metric 100
10.0.0.0/8 via 9.51.26.193 dev eth1
10.200.0.0/26 via 10.200.0.49 dev cilium_host src 10.200.0.49
10.200.0.49 dev cilium_host scope link
10.200.0.64/26 via 10.200.0.49 dev cilium_host src 10.200.0.49 mtu 1450

添加和修改默认路由

这里的命令用来添加或修改内核IP路由表中的默认路由规则。请注意在net-tools中可通过添加新的默认路由、删除旧的默认路由来实现修改默认路由。在iproute2使用ip route命令来代替。

使用net-tools

1
2
$ sudo route add default gw 192.168.1.2 eth0
$ sudo route del default gw 192.168.1.1 eth0

使用iproute2:

1
2
$ sudo ip route add default via 192.168.1.2 dev eth0
$ sudo ip route replace default via 192.168.1.2 dev eth0

添加和移除静态路由

使用下面命令添加或移除一个静态路由。

使用net-tools

1
2
$ sudo route add -net 172.16.32.0/24 gw 192.168.1.1 dev eth0
$ sudo route del -net 172.16.32.0/24

使用iproute2

1
2
$ sudo ip route add 172.16.32.0/24 via 192.168.1.1 dev eth0
$ sudo ip route del 172.16.32.0/24

ip rule

基于策略的路由比传统路由在功能上更强大,使用更灵活,它使网络管理员不仅能够根据目的地址而且能够根据报文大小、应用或IP源地址等属性来选择转发路径。

ip rule 命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ ip rule help
Usage: ip rule { add | del } SELECTOR ACTION
ip rule { flush | save | restore }
ip rule [ list [ SELECTOR ]]
SELECTOR := [ not ] [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK[/MASK] ]
[ iif STRING ] [ oif STRING ] [ pref NUMBER ] [ l3mdev ]
[ uidrange NUMBER-NUMBER ]
[ ipproto PROTOCOL ]
[ sport [ NUMBER | NUMBER-NUMBER ]
[ dport [ NUMBER | NUMBER-NUMBER ] ]
ACTION := [ table TABLE_ID ]
[ protocol PROTO ]
[ nat ADDRESS ]
[ realms [SRCREALM/]DSTREALM ]
[ goto NUMBER ]
SUPPRESSOR
SUPPRESSOR := [ suppress_prefixlength NUMBER ]
[ suppress_ifgroup DEVGROUP ]
TABLE_ID := [ local | main | default | NUMBER ]

例子:

1
2
3
4
# 通过路由表 inr.ruhep 路由来自源地址为192.203.80/24的数据包 
$ ip rule add from 192.203.80/24 table inr.ruhep prio 220
# 把源地址为193.233.7.83的数据报的源地址转换为192.203.80.144,并通过表1进行路由
$ ip rule add from 193.233.7.83 nat 192.203.80.144 table 1 prio 320

在 Linux 系统启动时,内核会为路由策略数据库配置三条缺省的规则:

  • 0 匹配任何条件 查询路由表local(ID 255) 路由表local是一个特殊的路由表,包含对于本地和广播地址的高优先级控制路由。rule 0非常特殊,不能被删除或者覆盖。
  • 32766 匹配任何条件 查询路由表main(ID 254) 路由表main(ID 254)是一个通常的表,包含所有的无策略路由。系统管理员可以删除或者使用另外的规则覆盖这条规则。
  • 32767 匹配任何条件 查询路由表default(ID 253) 路由表default(ID 253)是一个空表,它是为一些后续处理保留的。对于前面的缺省策略没有匹配到的数据包,系统使用这个策略进行处理。这个规则也可以删除。

不要混淆路由表和策略:

  • 规则指向路由表,多个规则可以引用一个路由表,而且某些路由表可以没有策略指向它。
  • 如果系统管理员删除了指向某个路由表的所有规则,这个表就没有用了,但是仍然存在,直到里面的所有路由都被删除,它才会消失。

ip neigh

查看ARP表

使用这些命令显示内核的ARP表。

使用net-tools:

1
2
3
4
5
6
7
$ arp -an 
? (9.51.26.193) at 5c:c9:99:dc:54:27 [ether] on eth1
? (9.51.26.245) at e0:4f:43:ed:a1:e5 [ether] on eth1
? (9.51.26.204) at e0:4f:43:ed:a4:13 [ether] on eth1
? (9.51.26.216) at e0:4f:43:ed:89:6d [ether] on eth1
? (9.51.26.214) at e0:4f:43:ed:79:29 [ether] on eth1
? (9.51.26.208) at 80:d4:a5:b7:4d:26 [ether] PERM on eth1

使用iproute2:

1
2
3
4
5
6
7
$ ip neigh
9.51.26.193 dev eth1 lladdr 5c:c9:99:dc:54:27 REACHABLE
9.51.26.245 dev eth1 lladdr e0:4f:43:ed:a1:e5 REACHABLE
9.51.26.204 dev eth1 lladdr e0:4f:43:ed:a4:13 STALE
9.51.26.216 dev eth1 lladdr e0:4f:43:ed:89:6d STALE
9.51.26.214 dev eth1 lladdr e0:4f:43:ed:79:29 STALE
9.51.26.208 dev eth1 lladdr 80:d4:a5:b7:4d:26 PERMANENT

添加或删除静态ARP项

按照如下操作在本地ARP表中添加或删除一个静态ARP项

使用net-tools

1
2
$ sudo arp -s 192.168.1.100 00:0c:29:c0:5a:ef
$ sudo arp -d 192.168.1.100

使用iproute2

1
2
$ sudo ip neigh add 192.168.1.100 lladdr 00:0c:29:c0:5a:ef dev eth0
$ sudo ip neigh del 192.168.1.100 dev eth0

添加、删除或查看多播地址

使用下面的命令配置或查看网络接口上的多播地址。

使用net-tools:

1
2
3
$ sudo ipmaddr add 33:44:00:00:00:01 dev eth0
$ sudo ipmaddr del 33:44:00:00:00:01 dev eth0
$ ipmaddr show dev eth0$ netstat -g

使用iproute2

1
2
3
$ sudo ip maddr add 33:44:00:00:00:01 dev eth0
$ sudo ip maddr del 33:44:00:00:00:01 dev eth0
$ ip maddr list dev eth0

ip netns

1
2
3
4
5
6
7
8
9
10
Usage:  ip netns list
ip netns add NAME
ip netns attach NAME PID
ip netns set NAME NETNSID
ip [-all] netns delete [NAME]
ip netns identify [PID]
ip netns pids NAME
ip [-all] netns exec [NAME] cmd ...
ip netns monitor
ip netns list-id

ss

查看套接字统计信息

这里的命令用来查看套接字统计信息(比如活跃或监听状态的TCP/UDP套接字)。

使用net-tools

1
2
$ netstat
$ netstat -l

使用iproute2

1
2
3
4
5
6
7
8
9
10
11
12
$ ss
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
u_str ESTAB 0 0 * 86647 * 0
u_str ESTAB 0 0 /run/systemd/journal/stdout 37119 * 59612
u_str ESTAB 0 0 /run/dbus/system_bus_socket 61228 * 59640
u_str ESTAB 0 0 * 59612 * 37119
u_str ESTAB 0 0 * 59640 * 61228
u_str ESTAB 0 0 /usr/local/sa/agent/secubase/secu-tcs-agent-v5.unix 113479 * 118199
u_str ESTAB 0 0 /usr/local/sa/agent/secubase/secu-tcs-agent-v5.unix 113491 * 99793
u_str ESTAB 0 0 /usr/local/sa/agent/secubase/secu-tcs-agent-v5.unix 113477 * 97679
u_str ESTAB 0 0 * 118199 * 113479
$ ss -l

参考资料