第 13 章 Linux 网络管理

作者: Brinnatt 分类: ARM64 Linux 基础精修 发布时间: 2022-01-21 12:13

在解释 Linux 网络管理相关的内容时,我觉得有必要先解释数据包转发功能以及因此涉及到的路由决策,这对理清路由和未来的防火墙配置有重要帮助。然后再介绍网络配置命令和相关文件。

13.1、Linux 处理数据包过程

networking

数据包的流转是个很复杂的过程,期间主要由多种 hook 函数和路由策略决定数据包从哪里来到哪里去:

  1. 数据包从网卡流入后需要对它做路由决策,根据其目标决定是流入本机数据还是转发给其他主机,如果是流入本机的数据,则数据会从内核空间进入用户空间(被应用程序接收、处理)。
  2. 当用户空间响应(应用程序生成新的数据包)时,响应数据包是本机产生的新数据包,在响应包流出之前,需要做路由决策,根据目标决定从哪个网卡流出。
  3. 如果不是流入本机的,而是要转发给其他主机的,则必然涉及到另一个流出网卡,此时数据包必须从流入网卡完整地转发给流出网卡,这要求 Linux 主机能够完成这样的转发。
  4. 但 Linux 主机默认未开启 ip_forward 功能,这使得数据包无法转发而被丢弃。
    • Linux 主机和路由器不同,路由器本身就是为了转发数据包,所以路由器内部默认就能在不同网卡间转发数据包,而 Linux 主机默认则不能转发。

注意:IP 地址是属于内核的,不尽如此,整个 tcp/ip 协议栈都属于内核,包括端口号;这个概念在使用 iptables 时尤其要注意,可能会疑惑,为什么 ip_forward 没有打开,两个不同的 ip 地址段之间可以通信,因为 IP 地址是属于内核的,不是属于网卡的。

  • 举例:某 Linux 主机有两网卡 eth0:172.16.10.5 和 eth1:192.168.100.20,某 192.168.100.22 主机网关指向 192.168.100.20,若它 ping 172.16.10.5,结果将是通的,因为地址属于内核,从 eth1 进来的数据包被内核分析时,发现目标地址为本机地址,直接就回应 192.168.100.22,回应数据包继续从 eth1 出去。

  • 举例:Linux 主机 A 有两网卡 eth0:172.16.10.5 和 eth1:192.168.100.20,某 192.168.100.22 主机网关指向 192.168.100.20,某 172.16.10.7 主机网关指向 172.16.10.5;若 192.168.100.22 直接 ping 172.16.10.7 是不通的,必须开启 Linux 主机 A 的 ip_forward 功能才能通起来。

    方法1: # echo 1 > /proc/sys/net/ipv4/ip_forward
    方法2: # sysctl -w net.ipv4.ip_forward=1
    • 以上两种方法是临时生效的,若要永久生效,则应该写入配置文件,建议写在 /etc/sysctl.d/*.conf 中,这是 systemd 提供自定义内核修改项的目录。
    # echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/ip_forward.conf
    • 可以使用以下几种方式查看是否开启了转发功能。
    [root@arm64v8 ~]# sysctl net.ipv4.ip_forward
    net.ipv4.ip_forward = 0
    [root@arm64v8 ~]# 
    [root@arm64v8 ~]# cat /proc/sys/net/ipv4/ip_forward
    0
    [root@arm64v8 ~]# 
    [root@arm64v8 ~]# sysctl -a | grep ip_forward
    net.ipv4.ip_forward = 0
    net.ipv4.ip_forward_use_pmtu = 0

13.2、网络配置文件

13.2.1、网卡配置文件

在 /etc/sysconfig/network-scripts/ 目录下有不少文件,绝大部分都是脚本类的文件,但有一类 ifcfg 开头 的文件为网卡配置文件(interface config),所有 ifcfg 开头的文件在启动网络服务的时候都会被加载读取,但具体的文件名 ifcfg-XX 的 XX 可以随意命名。

以下是一个 Aarch64 CentOS 7上 ifcfg-XX 文件的内容示例:

[root@arm64v8 ~]# ls /etc/sysconfig/network-scripts/ifcfg-*
/etc/sysconfig/network-scripts/ifcfg-enp1s0f0  /etc/sysconfig/network-scripts/ifcfg-enp1s0f3
/etc/sysconfig/network-scripts/ifcfg-enp1s0f1  /etc/sysconfig/network-scripts/ifcfg-lo
/etc/sysconfig/network-scripts/ifcfg-enp1s0f2
[root@arm64v8 ~]# 
[root@arm64v8 ~]# cat /etc/sysconfig/network-scripts/ifcfg-enp1s0f0 
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=enp1s0f0
UUID=d4838e7b-fd55-48b3-bf03-91c0bc2a6df9
DEVICE=enp1s0f0     # 显示的名称,必须 /sys/class/net/ 目录下的某个网卡名相同
ONBOOT=yes
IPADDR=10.60.20.74
GATEWAY=10.60.20.250
DNS1=223.5.5.5
NETMASK=255.255.255.0
[root@arm64v8 ~]#

服务器通常有多块网卡,有板载集成的,同时也有插在 PCIe 插槽的。Linux 系统的命名原来是 eth0, eth1 这样的形式,但是这个编号往往不一定准确对应网卡接口的物理顺序。

13.2.1.1、一致网络设备命名规范

在 Centos5 的时候,我们习惯了 eth0 这样的网络设备命名。在 Centos6 发现网络设备变成了 em1 这样的命名,这是 dell 开发的 biosdevname 方案所致。那时我们启动系统时,给内核启动参数加上 biosdevname=0,就可以继续使用 eth0 这样的命名。

升级到 Centos7 后,发现原有的参数 biosdevname=0 不起作用了,网络设备变成了 eno1 这样的名称。

Centos7 这种变化的原因是由于 systemd v197 和 udev 引入了一种新的网络设备命名方式:一致网络设备命名。一致网络设备命名规范,支持 biosdevname 和 net.ifnames 两种命名规范。

biosdevname 命名规范

设备 旧名称 新名称 示例
内嵌网络接口(LOM) eth[0123…] em[1234...][a] em1
PCI 卡网络接口 eth[0123…] pp[b] p3p4
虚拟功能 eth[0123…] pp_ p3p4_1

注:新枚举从 1 开始。

net.ifnames 命令规范

net.ifnames 命名规范为:设备类型 + 设备位置 + 数字

设备类型

字符串 含义
en 代表以太网
wl 代表无线局域网(WLAN)
ww 代表无线广域网(WWAN)

设备命名

格式 描述
o :on-board device index number 板载设备索引号
s[f][d] :hotplug slot index number 热插拔插槽索引号
x:MAC address MAC 地址
ps[f][d]: PCI geographical location PCI 地理位置
ps[f][u][..][i]:USB port number chain USB 端口链

示例

  • eno1 板载 1 号网卡
  • enp0s2 PCI 扩展卡的 2 号端口
  • ens33 热插拔插槽 3 号 PCI-E 插槽的 3 号端口
  • wlp3s0 第 3 号 PCI 扩展卡的 0 号端口

13.2.1.2、系统默认命令规则

默认情况下,systemd 会使用以下策略,采用支持的命名方案为接口命名:

  • Scheme 1(方案 1): 如果从 BIOS 中能够取到可用的,板载网卡的索引号,则使用这个索引号命名,例如: eno1,如不能则尝试 Scheme 2
  • Scheme 2(方案 2): 如果从 BIOS 中能够取到可以用的,网卡所在的 PCI-E 热插拔插槽的索引号,则使用这个索引号命名,例如: ens1,如不能则尝试 Scheme 3
  • Scheme 3(方案 3): 如果能拿到设备所连接的物理位置信息,则使用这个信息命名,例如: enp2s0,如不能则尝试 Scheme 5
  • Scheme 4(方案 4): 使用网卡的 MAC 地址来命名,这个方法一般不使用。
  • Scheme 5(方案 5): 传统的 kernel 命名方法,例如: eth0,这种命名方法的结果不可预知的,即可能第二块网卡对应 eth0,第一块网卡对应 eth1。

操作系统内核在 boot 过程是默认使用 ethX 方式来命名的,每次启动的时候都不确定,启动后再通过 systemd 和 udev 重新 rename。

13.2.1.3、rename 流程

# 按照如下顺序执行 udev 的 rule
1./usr/lib/udev/rules.d/60-net.rules
2./usr/lib/udev/rules.d/71-biosdevname.rules
3./lib/udev/rules.d/75-net-description.rules
4./usr/lib/udev/rules.d/80-net-name-slot.rules
  • step1 依据 /usr/lib/udev/rules.d/60-net.rules, 查看是否有 ifcfg-xx 配置文件(路径在 /etc/sysconfig/network-scripts/),是否有定义了指定 MAC 地址的配置文件(ifcfg-xx ,xx 必须和配置文件的内容 DEVICE 一致),如果有,则命名该网卡;

  • step2 依据 /usr/lib/udev/rules.d/71-biosdevname.rules,如果 biosdevname 开启了(安装了 biosdevname 这个包,且内核启动参数显式设置为 1),且网卡没有在 step1 中定义,则按照 biosdevname 命名规则 rename 网卡;

    • 注意:如果没有安装 biosdevname 这个包,就没有这个文件
  • step3 依据 /lib/udev/rules.d/75-net-description.rules,udev 工具将会根据 device 属性填写网卡的属性命名,可能一个网卡会有多个维度的名称;

    • 系统识别网卡有好几种维度,比如上一小节中的 Scheme 1-3(eno1 ens1 enp1);

    • 同一个网卡通常同时具有多个维度的名称,systemd 在选取的时候,按照有先后次序,使用先命中的;

    • 顺序可以简单理解为 eno1 -> ens1 -> enp1

      [root@arm64v8 ~]# udevadm info /sys/class/net/enp1s0f0 | grep ID_NET_NAME
      E: ID_NET_NAME_MAC=enx00073e9088a9
      E: ID_NET_NAME_PATH=enp1s0f0
      [root@arm64v8 ~]#
  • step4 udev 根据 step3 中的赋值,按照指定的 scheme 规则,去给在 step1 step2 中没有命名的网卡命名;

注意:这个 step 顺序是在我们没有自定义自己的 rules 的前提下,如果用户自定义了自己的 rules,则用户自定义的优先级最高;

13.2.1.4、用户自定义网卡名

  1. 在用户没有自定义 rules 文件前提下,step1 中的网卡命名方式也可认为是一种用户自定义的网卡命名;
    • 即在 /etc/sysconfig/network-scripts/ifcfg-xx 文件,xx 就是这个网卡名称,文件内容中体现MAC_ADDRESS、NAME,这种情况下,则会按照配置文件中指定的名称来命名网卡;
  2. 如果用户自定义了 rules 文件,放在 /etc/udev/rules.d/ 目录下,则这个优先级是最高的;比 1 中 ifcfg-xx 方式优先级更高,但是如果两者不一致,则在重启 network 服务时,会依据 ifcfg-xx 命名,所以用户不应该同时采用这两种方式给同一个网卡命不同的名称;

/etc/udev/udev.conf 是 udev 主配置文件,用户定制的规则文件在 /etc/udev/rules.d 目录下。对于网卡设备的配置一般社区约定的是 /etc/udev/rules.d/70-persistent-net.rules 文件。

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:07:3e:90:88:a9", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
  • 具体的 udev 规则集语法这里不详细介绍,可以参考 https://wiki.debian.org/udev,这里只介绍上述规则集的含义。
    • 规则集文件的写法都是 key/value 格式,但分为匹配 key/vaule 和动作 key/value。上述例子中,从 SUBSYSTEM 直到 KERNEL 都是使用 "==" 号,表示匹配 key/value,最后一个 NAME 使用单 "=" 号,表示赋值 key/value。
    • 所以上述文件的意思是:当 /sys 中的某设备各信息都能匹配上述某条规则,则赋值该设备名称为 eth0,/sys/class/net 目录下也由此名称命名设备信息的目录,ifcfg-* 配置文件中的 DEVICE 的值必须和它们相同
  • 克隆虚拟机时,总是会出现 MAC 地址冲突,这是因为规则集文件和 ifcfg 配置文件都被克隆了,而新克隆出来的机器中 MAC 地址又是新的,所以会生成新的规则集,但克隆过来的 ifcfg 配置文件中的 DEVICE 值和该规则对应不上,导致克隆主机的网络将启动不了。
    • 解决办法是清空该文件,然后重启克隆主机,这样内核将新生成对应新 MAC 地址的规则集文件。当然,在克隆前清空模板主机的规则集文件,然后再克隆也是可以的。
  • 值得一提的是,在 CentOS 7 中,systemd 已经将 udevd 的功能整合在了一起,udev 的规则集文件几乎都放到了 /usr/lib/udev/rules.d/ 目录下,但却更方便了,克隆 CentOS 7 主机时,根本就不会出现 MAC 地址冲突的可能。不过,显式书写在 /etc/udev/rules.d/ 目录下的规则集文件仍然是生效的。
  • 注意,网络规则集文件会由内核检测到设备时自动生成或写入,因此清空它不会有任何影响

注意:/etc/udev/rules.d/70-persistent-net.rules/lib/udev/write_net_rules 这两个配套使用的文件已经废弃了,但是目前在 Centos 7 上依然可以使用。

内核启动参数 biosdevnane、net.ifnames

默认就是内核启动参数没有 biosdevname 也没有 net.ifnames 参数;

其实默认是 net.ifnames=1,biosdevname=0;这种情况下就按照 rename 中进行网卡命名;eno-ens-enp 的方式逐个匹配。

但是如果开启了 biosdevname,则会使用 biosdevname 命名 step1 中没有命名的网卡;要么是 em 开头,要么是 p 开头;

biosdevname

怎么开启 biosdevname 呢?

  1. 安装 biosdevname 包;
  2. 在内核启动参数中明确 biosdevname=1,否则开启不了;
  3. 如果用户自定义了udev rules,则用户自定义的 rules 优先。

net.ifname

如果在内核启动参数中增加 net.ifname=0,这个参数会在 /lib/udev/rule.d/80-net-name-slot.rules 文件中体现使用价值,告诉系统不用 scheme 的方式来命名,这个时候,会恢复 ethx 这种不确定性的命名方式;

[root@arm64v8 ~]# vim /etc/sysconfig/grub
GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=cl/root rd.lvm.lv=cl/swap net.ifnames=0 biosdevname=0 rhgb quiet"
[root@arm64v8 ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
[root@arm64v8 ~]# mv /etc/sysconfig/network-scripts/ifcfg-enp1s0f0 /etc/sysconfig/network-scripts/ifcfg-eth0
NAME=eth0
DEVICE=eth0
[root@arm64v8 ~]# systemctl restart network.service

13.2.2、DNS 配置文件

/etc/resolv.conf 用于设置 DNS 指向,以及解析顺序。该文件格式如下:

domain  domain_name       # 声明本地域名,即解析时自动隐式补齐的域名
search  domain_name_list  # 指定域名搜索顺序(最多6个),和domain不能共存,若共存了,则后面的行生效
nameserver  IP1           # 设置DNS指向,最多3个
nameserver  IP2
nameserver  IP3        
options timeout:n attempts:n  # 指定解析超时时间(默认5秒)和解析次数(默认2次)

例如将 /etc/resolv.conf 设置如下所示,为了测试,暂且不设置 nameserver。

domain brinnatt.com

当解析不带点 "." 的主机名时,如 "www",认为不是 fqdn,将自动加上 ".brinnatt.com" 变成解析 "www.brinnatt.com"。

[root@arm64v8 ~]# host -a www
Trying "www.brinnatt.com"
;; connection timed out; no servers could be reached
[root@arm64v8 ~]#

当解析的名称末尾不带点但中间带了点的,如 "www.host",认为是 fqdn,将直接解析 "www.host"

[root@arm64v8 ~]# host -a www.host
Trying "www.host"
;; connection timed out; no servers could be reached
[root@arm64v8 ~]#

search 关键字的作用和 domain 是一样的,只不过 search 同时还暗含域名搜索的顺序。例如设置 search 为如下内容:

search brinnatt.com britural.com yidam.com

此时若解析 "www",将依次解析 "www.brinnatt.com","www.britural.com","www.yidam.com"。

domain 部分和 search 部分不能共存,如果共存了,则最后出现的行有效。

13.2.3、服务端口定义文件

/etc/services 中记录的是端口和服务的对应关系。

[root@arm64v8 ~]# grep -E "^ftp|^ssh" /etc/services 
ftp-data        20/tcp
ftp-data        20/udp
ftp             21/tcp
ftp             21/udp          fsp fspd
ssh             22/tcp                          # The Secure Shell (SSH) Protocol
ssh             22/udp                          # The Secure Shell (SSH) Protocol
ftp-data        20/sctp                 # FTP
ftp             21/sctp                 # FTP
ssh             22/sctp                 # SSH
ftp-agent       574/tcp                 # FTP Software Agent System
ftp-agent       574/udp                 # FTP Software Agent System
sshell          614/tcp                 # SSLshell
sshell          614/udp                 #       SSLshell
ftps-data       989/tcp                 # ftp protocol, data, over TLS/SSL
ftps-data       989/udp                 # ftp protocol, data, over TLS/SSL
ftps            990/tcp                 # ftp protocol, control, over TLS/SSL
ftps            990/udp                 # ftp protocol, control, over TLS/SSL
ssh-mgmt        17235/tcp               # SSH Tectia Manager
ssh-mgmt        17235/udp               # SSH Tectia Manager
[root@arm64v8 ~]#

13.3、网络接口和主机名配置

13.3.1、ifconfig 命令

该命令虽然在 man 文档中被说明已废弃,但大众显然无法忘记它。ifconfig 命令是一个接口配置命令,但更多的被用来显示已激活的网络接口信息。

ifconfig [ interface | -a ]
ifconfig interface options

选项说明:
interface:指定被操作的网络接口名,如eth0
up       :激活指定的网络接口,如果在命令行中为网络接口分配了IP地址,则默认会up
down     :将指定的接口设置为down状态
[-]arp   :启用或禁用该接口上使用ARP协议,如"ifconfig eth0 -arp"
mtu N    :设置指定接口的最大传输单元(MTU)
netmask  :设置该接口的IP netmask,默认会采用A/B/C类地址的掩码位数
address  :要分配给该接口的IP地址

ifconfig 示例:

[root@arm64v8 ~]# ifconfig enp1s0f0:1 192.168.100.20 netmask 255.255.255.0 up   # 添加IP地址
[root@arm64v8 ~]# ifconfig enp1s0f0:2 192.168.100.21/24 up                      # 也可使用CIDR格式掩码
[root@arm64v8 ~]# ifconfig 
enp1s0f0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.60.20.74  netmask 255.255.255.0  broadcast 10.60.20.255
        inet6 fe80::207:3eff:fe90:88a9  prefixlen 64  scopeid 0x20<link>
        ether 00:07:3e:90:88:a9  txqueuelen 1000  (Ethernet)
        RX packets 1021846  bytes 182866067 (174.3 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 612715  bytes 116383304 (110.9 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device memory 0x61e00000-61e1ffff  

enp1s0f0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.100.20  netmask 255.255.255.0  broadcast 192.168.100.255
        ether 00:07:3e:90:88:a9  txqueuelen 1000  (Ethernet)
        device memory 0x61e00000-61e1ffff  

enp1s0f0:2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.100.21  netmask 255.255.255.0  broadcast 192.168.100.255
        ether 00:07:3e:90:88:a9  txqueuelen 1000  (Ethernet)
        device memory 0x61e00000-61e1ffff

[root@arm64v8 ~]# ifconfig eth1 up       # 激活该网络接口
[root@arm64v8 ~]# ifconfig eth1 down     # 临时down掉eth1接口
[root@arm64v8 ~]# ifconfig eth1 -arp     # 抑制eth1上的arp
[root@arm64v8 ~]# ifconfig eth1 arp      # 启用eth1上的arp

需要注意的是,ifconfig 所有的配置都是应用于内核的,所以只会临时生效,重启网络服务后会立即失效。

对于 slave 地址,即别名地址,若要永久生效,应该建立对应的别名接口配置文件,如 /ets/sysconfig/network-scripts/ifcfg-eth0:0,然后在该文件中的 DEVICE 关键字上给定 eth0:0 名称,该 DEVICE 项必须配置正确。

13.3.2、hostname 命令

用于设置主机名,但也有几个其它好用的功能。

hostname [-I] [-f] [-d] [-s] [hostname]

选项说明:
-I         :获取该主机上所有非环回IP地址,该选项不依赖于主机名解析
-f,--fqdn  :获取fqdn
-d,--domain:获取fqdn的域名部分,等价于命令dnsdomainname
-s,--short :获取fqdn的主机名部分,严格地说是获取第一个"."前的部分,例如"www.baidu.com"将获取为"www"

使用 -I 选项可以直接获取该主机上的所有 IP 地址,包括别名地址,这在某些时候太方便了。

[root@arm64v8 ~]# hostname -I
10.60.20.74 192.168.100.20 192.168.100.21 
[root@arm64v8 ~]#

hostname 修改的主机名为临时生效,它修改的其实是 /proc/sys/kernel/hostname 文件。

[root@arm64v8 ~]# cat /proc/sys/kernel/hostname 
arm64v8
[root@arm64v8 ~]#
  • 想要永久生效,直接使用 hostnamctl set-hostname \<NAME> 即可,实际上修改了配置文件 /etc/hostname(CentOS 7+);如果是 Centos 6-,手动写入 /etc/sysconfig/network(CentOS 6)。

13.4、网关和路由

Linux 上分为 3 种路由:

  1. 主机路由:直接指明到某台具体的主机怎么走,主机路由也就是所谓的静态路由
  2. 网络路由:指明某类网络怎么走
  3. 默认路由:不走主机路由的和网络路由的就走默认路由。操作系统上设置的默认路由一般也称为网关。

若 Linux 上到某主机有多条路由可以选择,这时候会挑选优先级高的路由。在 Linux 中,路由条目的优先级确定方式是先匹配掩码位长度,再比较管理距离(比如 metric)。

  • 也就是说,掩码位长的路由条目优先级一定比掩码位短的优先级高,所以主机路由的优先级最高,然后是直连网络(即同网段) 的路由(也算是网络路由) 次之,再是网络路由,最后才是默认路由。
  • 若路由条目的掩码长度相同,则比较节点之间的管理距离,管理距离短的生效。
[root@arm64v8 ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.230.2   0.0.0.0         UG    0      0        0 ens35
169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 ens32
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 ens32
192.168.0.0     192.168.230.129 255.255.0.0     UG    0      0        0 ens35
192.168.230.0   0.0.0.0         255.255.255.0   U     0      0        0 ens35
192.168.230.129 192.168.230.131 255.255.255.255 UGH   0      0        0 ens35
[root@arm64v8 ~]#
  • 如果 ping 192.168.10.7,首先匹配 192.168.230.129,发现行不通;再匹配 192.168.230.0,还是不对;再匹配 192.168.0.0,终于能匹配,于是走这条路由。至于能不能到达目的地,那是下一步的事情。
  • 以上路由条目由我特意设计,看起来很怪,但是可以说明问题。
[root@arm64v8 ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.0.1     0.0.0.0         UG    0      0        0 ens32
10.1.1.0        0.0.0.0         255.255.255.0   U     100    0        0 ens32
10.1.1.0        0.0.0.0         255.255.255.0   U     101    0        0 ens35
169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 ens32
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 ens32
192.168.230.0   0.0.0.0         255.255.255.0   U     0      0        0 ens35
[root@arm64v8 ~]#
  • 如果 ping 10.1.1.10,则匹配第 2 条和第 3 条,但是 Metric 距离短的优先,所以最终匹配 Metric 为 100 这条路由。

13.4.1、route 命令

route 命令用于显示和管理路由表。当使用了 add 或 del 选项时,route 命令将设置路由条目,否则 route 命令将显示路由表。

要显示路由表信息,只需简单的 route -n 即可,其中 -n 选项表示不解析主机名。

[root@computer1 ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.1.1.254      0.0.0.0         UG    0      0        0 enp11s0f0
10.1.1.0        0.0.0.0         255.255.255.0   U     0      0        0 enp11s0f0
10.1.1.0        0.0.0.0         255.255.255.0   U     100    0        0 enp11s0f0
10.1.3.0        0.0.0.0         255.255.255.0   U     0      0        0 bond1
169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 enp11s0f0
169.254.0.0     0.0.0.0         255.255.0.0     U     1008   0        0 bond1
169.254.64.0    0.0.0.0         255.255.192.0   U     0      0        0 br_conn_all_ns
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
[root@computer1 ~]#
  • Centos 7+ 版本的内核不再使用 Metric 和 Ref,保留的原因是有些路由软件可能会用上。
  • 对于 Flags 列,如果没有安装路由软件,则只可能出现下面的 3 种值:
    • U (route is up)
    • H (target is a host)
    • G (use gateway,下一跳的路由条目)

若要管理路由表,则使用 add 或 del 选项:

route [add/del] [-host/-net/default] [address[/mask]] [netmask] [gw] [dev]

选项说明:
add/del:    增加或删除路由条目
-net:       增加或删除的是一条网络路由
-host:      增加或删除的是一条主机路由
default:    增加或删除的是一条默认路由
netmask:    明确使用netmask关键字指定掩码,要可以不使用该选项直接在地址上使用cidr格式的掩码,即IP/MASK。
gw:         指定下一跳的地址。要求下一跳地址必须是能到达的,且一般是和本网段直连的接口。
dev:        强制将路由条目关联到指定的接口上。一般内核会自动判断路由条目应该关联到哪个网络接口。
  1. 添加和删除默认路由

    shell> route add default gw 192.168.100.10   # 可以使用 0.0.0.0 替代 default 关键字
    shell> route del default
    shell> route del default gw 192.168.100.10   # 若有多条默认路由,则再加上 gw 即可唯一删除指定条目
  2. 添加和删除网络路由

    shell> route add -net 172.16.10.0/24 gw 192.168.100.70
    shell> route add -net 172.16.10.0 netmask 255.255.255.0 gw 192.168.100.70

    若实在不知道下一跳给谁,那么指定本机接口也是可以的。

    shell> route add -net 172.16.10.0/24 dev eth0

    删除路由可以直接在增加路由的语句上将 add 改为 del 关键字

    shell> route del -net 172.16.10.0/24 gw 192.168.100.70
    shell> route del -net 172.16.10.0 netmask 255.255.255.0 gw 192.168.100.70
    shell> route del -net 172.16.10.0/24 dev eth0

    但大多数时候,可以偷懒,只要能唯一确定删除的是哪条路由即可

    shell> route del -net 172.16.10.0/24
  3. 添加和删除主机路由

    shell> route add -host 172.16.10.55 gw 192.168.10.20
    shell> route del -host 172.16.100.55

13.4.2、配置永久路由

根据接口创建路由配置文件 /etc/syconfig/network-scripts/route-ethX,要从那个接口出去 X 就是几。

路由配置文件的配置格式非常简单,每一行一个路由条目,先是要到达的目标,然后是 via 关键字,最后是下一跳地址。要求下一跳必须能到达,且一般都和 ethX 同网段。

DEST    via     nexthop

例如 eth0 网卡的 IP 地址是 192.168.10.123,要通过网卡 eth0 出去到达 10.0.0.10,那么下一跳的地址要和 eth0 的地址在同网段,如 192.168.10.222。

10.0.0.0 via 192.168.10.222

添加主机路由、默认路由、网段路由示例如下,其中 dev 是可以省略的,因为没有任何用处,配置在哪个 eth 文件中就会从哪个接口出去。

#默认路由
default             via     192.168.100.1
0.0.0.0/0           via     192.168.100.1

#网段路由
192.168.10.0/24     via     192.168.100.1

#主机路由
192.168.100.52/32   via     192.168.100.33 dev eth1
  • 配置完后,重启 network 服务即可立即生效。

配置永久路由时,需要注意几点:

  1. route-ethX 的对应网卡配置文件 ifcfg-ethX 必须存在,否则路由无效。
  2. 如果在文件中配置永久默认路由,则必须保证所有使用了 DHCP 服务的网卡配置文件 ifcfg-ethX 中的 DEFROUTE 指令设置为 "no",表示 DHCP 不设置默认路由。
  3. 如果在 route-ethX 文件中配置永久路由,且该网卡使用了 DHCP 服务分配地址,则必须保证该网卡的 ifcfg-ethX 文件中的 PEERROUTES 指令设置为 "no",表示 DHCP 设置的路由允许被覆盖。

13.5、arp 和 arping 命令

维护或查看系统 arp 缓存,该命令已废弃,使用 ip neigh 代替。arp 为地址解析协议,将给定的 ipv4 地址在网络中查找其对应的 MAC 地址。一般会使用 arp 协议获取局域网内的主机 MAC,所以局域网主机之间也互称为网络邻居。

13.5.1、arp 命令

arp 命令语法:

arp -n -v -i           # 查看arp缓存
arp -i -d hostname     # 删除arp缓存条目

选项说明:
-n:不解析ip地址为名称
-v:详细信息
-i:指定操作的接口
-d:删除一个arp条目

hostname:操作该主机的 arp 条目,除了删除还有其他动作,如手动添加主机的 arp 条目,此处就不解释该用法了

[root@controller1 ~]# arp -n
Address                  HWtype  HWaddress           Flags Mask            Iface
10.1.1.14                ether   00:07:3e:92:7b:4d   C                     ens1
10.1.1.15                ether   00:09:06:2a:3a:92   C                     ens1
10.1.1.12                ether   00:07:3e:92:52:9c   C                     ens1
10.1.1.254               ether   98:35:ed:31:44:4b   C                     ens1
10.1.1.13                ether   00:07:3e:92:53:20   C                     ens1
10.1.1.10                        (incomplete)                              ens1
10.1.1.11                ether   00:07:3e:92:52:60   C                     ens1
10.1.1.111               ether   fa:f0:b1:bc:dd:00   C                     ens1
10.1.1.4                 ether   00:09:06:2a:3a:8e   C                     ens1
10.1.1.9                 ether   00:09:06:2a:3a:8e   C                     ens1
10.1.1.22                ether   00:07:3e:92:df:80   C                     ens1
10.1.1.199               ether   00:e0:4c:36:01:01   C                     ens1
10.1.1.2                 ether   00:09:06:2a:3a:76   C                     ens1
10.1.1.3                 ether   00:09:06:2a:3a:a4   C                     ens1
10.1.1.23                ether   00:07:3e:92:e0:b8   C                     ens1
10.1.1.21                ether   00:07:3e:92:53:5f   C                     ens1
[root@controller1 ~]#

其实查看的信息是 /proc/net/arp 文件中的内容

[root@controller1 ~]# cat /proc/net/arp
IP address       HW type     Flags       HW address            Mask     Device
10.1.1.14        0x1         0x2         00:07:3e:92:7b:4d     *        ens1
10.1.1.15        0x1         0x2         00:09:06:2a:3a:92     *        ens1
10.1.1.12        0x1         0x2         00:07:3e:92:52:9c     *        ens1
10.1.1.254       0x1         0x2         98:35:ed:31:44:4b     *        ens1
10.1.1.13        0x1         0x2         00:07:3e:92:53:20     *        ens1
10.1.1.10        0x1         0x0         00:00:00:00:00:00     *        ens1
10.1.1.11        0x1         0x2         00:07:3e:92:52:60     *        ens1
10.1.1.111       0x1         0x2         fa:f0:b1:bc:dd:00     *        ens1
10.1.1.4         0x1         0x2         00:09:06:2a:3a:8e     *        ens1
10.1.1.9         0x1         0x2         00:09:06:2a:3a:8e     *        ens1
10.1.1.22        0x1         0x2         00:07:3e:92:df:80     *        ens1
10.1.1.199       0x1         0x2         00:e0:4c:36:01:01     *        ens1
10.1.1.2         0x1         0x2         00:09:06:2a:3a:76     *        ens1
10.1.1.3         0x1         0x2         00:09:06:2a:3a:a4     *        ens1
10.1.1.23        0x1         0x2         00:07:3e:92:e0:b8     *        ens1
10.1.1.21        0x1         0x2         00:07:3e:92:53:5f     *        ens1
[root@controller1 ~]#
[root@controller1 ~]# arp -d 10.1.1.21 -i ens1      # 删除arp缓存条目

arp 命令一次只能删除一条 arp 条目,要批量删除或清空整个 arp 条目,使用 ip neigh flush 命令。如:

[root@controller1 ~]# ip neigh flush all        # 清空所有
[root@controller1 ~]# ip neigh flush dev ens1   # 删除ens1上缓存的arp条目

13.5.2、arping 命令

arping 用于发送 arp 请求报文,解析并获取目标地址的 MAC。默认将先发送广播报文,收到回复后再发送单播报文,局域网内所有主机都能收到广播报文,但只有目标主机才会回复自己的 MAC 地址。

arping [-fqbDU] [-c count] [-w timeout] [-I device] [-s source] destination
-f:             收到第一个reply就立即退出
-q:             安静模式,什么都不输出
-b:             只发送广播,不发送单播
-D:             地址冲突检测
-U:             主动更新邻居的arp缓存(Unsolicited ARP mode)
-c count:       发送多少个arp请求包后退出
-w timeout:     等待reply的超时时间
-I device:      使用哪个接口发送请求包。发送arp请求包接口的MAC地址将缓存在目标主机上
-s source:      指定arp请求报文中源地址,若发送的接口和源地址不同,则目标主机将缓存该地址和接口的MAC地址,而非该源地址所在接口的MAC地址
 destination:   向谁发送arp请求报文,即要获取该IP或主机名的MAC地址
  1. 请求解析 10.1.1.21 主机的 MAC 地址

    [root@controller1 ~]# arping -f 10.1.1.21
    ARPING 10.1.1.21 from 10.1.1.1 ens1
    Unicast reply from 10.1.1.21 [00:07:3E:92:53:5F]  0.598ms
    Sent 1 probes (1 broadcast(s))
    Received 1 response(s)
    [root@controller1 ~]#

    这将会发送广播报文,直到收到 10.1.1.21 的回复才退出。

    同时,10.1.1.21 也会缓存本机的 IP 和 MAC 对应条目,由于此处没有指定请求报文的发送接口和源地址,所以发送报文时是根据路由表来选择接口和对应该接口地址的。

  2. 指定发送一个请求报文给 10.1.1.21 就退出,发送报文的接口为 ens1,并指定请求报文中的源地址为本机 ens1 接口上的地址 10.1.1.10

    [root@controller1 ~]# arping -c 1 -I ens2 -s 10.1.1.10 10.1.1.21
    ARPING 10.1.1.21 from 10.1.1.10 ens1
    Unicast reply from 10.1.1.21 [00:07:3E:92:53:5F]  0.613ms
    Sent 1 probes (1 broadcast(s))
    Received 1 response(s)
    [root@controller1 ~]#

    发送这样的 arp 请求包,将会使得目标主机 10.1.1.21 缓存本机的 arp 条目为 "10.1.1.10 MAC_ens2",但实际上,10.1.1.10 所在接口的 MAC 地址为 MAC_ens1。

    arping 命令仅能实现这种简单的 arp 欺骗,更多的 arp 欺骗方法可以使用专门的工具。

  3. 探测对方主机是否存活

    例如发送 4 个探测报文,有回复就说明对方存活

    [root@controller1 ~]# arping -c 4 -I ens1 10.1.1.13
    ARPING 10.1.1.13 from 10.1.1.1 ens1
    Unicast reply from 10.1.1.13 [00:07:3E:92:53:20]  0.608ms
    Unicast reply from 10.1.1.13 [00:07:3E:92:53:20]  0.586ms
    Unicast reply from 10.1.1.13 [00:07:3E:92:53:20]  0.573ms
    Unicast reply from 10.1.1.13 [00:07:3E:92:53:20]  0.571ms
    Sent 4 probes (1 broadcast(s))
    Received 4 response(s)
    [root@controller1 ~]#

    可见发送了 4 个探测报文,其中第一个报文是广播报文,并且收到了 4 个回复。

13.6、ip 命令

这是一个极其强大的命令,前面所有的网络信息显示和管理的命令,都可以由 ip 命令来替代完成。它是一个严格模式化的命令。

13.6.1、ip 命令帮助

先简单说明下 ip 命令的基础和获取帮助的方法。

[root@computer4 ~]# ip -h
Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }
       ip [ -force ] -batch filename
where  OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |
                   tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |
                   netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila |
                   vrf | sr | nexthop }
       OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |
                    -h[uman-readable] | -iec | -j[son] | -p[retty] |
                    -f[amily] { inet | inet6 | mpls | bridge | link } |
                    -4 | -6 | -I | -D | -M | -B | -0 |
                    -l[oops] { maximum-addr-flush-attempts } | -br[ief] |
                    -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |
                    -rc[vbuf] [size] | -n[etns] name | -N[umeric] | -a[ll] |
                    -c[olor]}
[root@computer4 ~]#

可见命令非常复杂,有很多 options,还有很多 object,每个 Object 又对应不同的命令。但其实常用到的就几个object:addr/route/neigh/link。

使用 ip object help 可以获取到该 object 的语法帮助。例如:

[root@computer4 ~]# ip addr help
Usage: ip address {add|change|replace} IFADDR dev IFNAME [ LIFETIME ]
                                                      [ CONFFLAG-LIST ]
       ip address del IFADDR dev IFNAME [mngtmpaddr]
       ip address {save|flush} [ dev IFNAME ] [ scope SCOPE-ID ]
                            [ to PREFIX ] [ FLAG-LIST ] [ label LABEL ] [up]
       ip address [ show [ dev IFNAME ] [ scope SCOPE-ID ] [ master DEVICE ]
                         [ type TYPE ] [ to PREFIX ] [ FLAG-LIST ]
                         [ label LABEL ] [up] [ vrf NAME ] ]
       ip address {showdump|restore}
IFADDR := PREFIX | ADDR peer PREFIX
          [ broadcast ADDR ] [ anycast ADDR ]
          [ label IFNAME ] [ scope SCOPE-ID ] [ metric METRIC ]
SCOPE-ID := [ host | link | global | NUMBER ]
FLAG-LIST := [ FLAG-LIST ] FLAG
FLAG  := [ permanent | dynamic | secondary | primary |
           [-]tentative | [-]deprecated | [-]dadfailed | temporary |
           CONFFLAG-LIST ]
CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG
CONFFLAG  := [ home | nodad | mngtmpaddr | noprefixroute | autojoin ]
LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]
LFT := forever | SECONDS
TYPE := { vlan | veth | vcan | vxcan | dummy | ifb | macvlan | macvtap |
          bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan | lowpan |
          gre | gretap | erspan | ip6gre | ip6gretap | ip6erspan | vti |
          nlmon | can | bond_slave | ipvlan | geneve | bridge_slave |
          hsr | macsec | netdevsim }
[root@computer4 ~]#

在 ip 命令行下,任何 object 都可以写其全名,也可以写其缩写名,例如 address 这个 object,可以简写为 addr,也可以简写为一个字母 a。

[root@computer4 ~]# ip a help       # 等价于ip address help和ip addr help

尽管还有一个 a 开头的 object 为 addrlabel。这时因为 ip 会从上述语法给出的 object 顺序从前向后匹配,例如 "ip m" 将匹配到 "ip maddr",如果想匹配别的,如 addrlabel,则写长一点即可 "ip addrl"。

对于 CentOS 6,man ip 时会输出整个 ip 的帮助文档,包括每个 object 的命令和说明。在 CentOS 7 中,则要对每个 object 独立进行 man,例如 addr 这个 object。

[root@computer4 ~]# man ip-address

以下是所有 Object 的 man 列表。

[root@arm64v8 ~]# rpm -ql iproute | grep "man8/ip-"
/usr/share/man/man8/ip-address.8.gz
/usr/share/man/man8/ip-addrlabel.8.gz
/usr/share/man/man8/ip-fou.8.gz
/usr/share/man/man8/ip-gue.8.gz
/usr/share/man/man8/ip-l2tp.8.gz
/usr/share/man/man8/ip-link.8.gz
/usr/share/man/man8/ip-macsec.8.gz
/usr/share/man/man8/ip-maddress.8.gz
/usr/share/man/man8/ip-monitor.8.gz
/usr/share/man/man8/ip-mroute.8.gz
/usr/share/man/man8/ip-neighbour.8.gz
/usr/share/man/man8/ip-netconf.8.gz
/usr/share/man/man8/ip-netns.8.gz
/usr/share/man/man8/ip-ntable.8.gz
/usr/share/man/man8/ip-route.8.gz
/usr/share/man/man8/ip-rule.8.gz
/usr/share/man/man8/ip-tcp_metrics.8.gz
/usr/share/man/man8/ip-token.8.gz
/usr/share/man/man8/ip-tunnel.8.gz
/usr/share/man/man8/ip-vrf.8.gz
/usr/share/man/man8/ip-xfrm.8.gz
[root@arm64v8 ~]#

13.6.2、ip address 命令

ip address 用于管理网络设备上的 ip 地址,也可以查看 ip 地址的属性信息。在老版本的 Linux 中,一块网卡上设置多个 IP,这些 IP 称为别名 IP,但是从 CentOS 6 开始,这些 IP 称为 secondary IP 或 slave IP,因为这些 IP 自身也可以附带属性。

13.6.2.1、ip address add/del 子命令

ip address { add | del } IFADDR dev STRING
IFADDR := PREFIX [ broadcast ADDR ] [ anycast ADDR ] [ label STRING ]

dev NAME:                   指定要设置IP地址的网卡
local ADDRESS (default):    接口的IP地址。IP地址的格式依赖于是ipv4还是ipv6。对于ipv4而言,给定地址,可能还需要给定cidr的掩码位长度
broadcast ADDRESS:          接口的广播地址
label NAME:                 为该接口的IP地址设置label名,label名称必须以网络接口名开头后接冒号,如eth0:X

del和add的参数相同,且dev是必须要给定的,其余的参数可选,因为del的时候是通配del,如果删除时有多个满足条件的条目,则删除第一个条目。
[root@controller2 ~]# ip -4 add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    inet 10.1.1.2/24 brd 10.1.1.255 scope global ens1
       valid_lft forever preferred_lft forever
[root@controller2 ~]# 
[root@controller2 ~]# ip addr add 192.168.10.7/24 dev ens1
[root@controller2 ~]#
[root@controller2 ~]# ip -4 add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    inet 10.1.1.2/24 brd 10.1.1.255 scope global ens1
       valid_lft forever preferred_lft forever
    inet 192.168.10.7/24 scope global ens1
       valid_lft forever preferred_lft forever
[root@controller2 ~]#
[root@controller2 ~]# ifconfig ens1
ens1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.1.1.2  netmask 255.255.255.0  broadcast 10.1.1.255
        inet6 fe80::209:6ff:fe2a:3a76  prefixlen 64  scopeid 0x20<link>
        ether 00:09:06:2a:3a:76  txqueuelen 1000  (Ethernet)
        RX packets 191797931  bytes 77343172607 (72.0 GiB)
        RX errors 0  dropped 1868146  overruns 0  frame 0
        TX packets 184903392  bytes 24743236828 (23.0 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device memory 0x80061200000-800612fffff  

[root@controller2 ~]#
  • 此方式添加的地址不会在 ifconfg 命令中显示,ifconfg 能捕捉到的是别名,所以可以为地址加上 label,以让 secondary 被 ifconfig 查看到。例如:

    [root@controller2 ~]# ip addr add 192.168.10.8/24 dev ens1 label ens1:0
    [root@controller2 ~]# ip -4 addr
    1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
      inet 127.0.0.1/8 scope host lo
         valid_lft forever preferred_lft forever
    2: ens1:  mtu 1500 qdisc mq state UP group default qlen 1000
      inet 10.1.1.2/24 brd 10.1.1.255 scope global ens1
         valid_lft forever preferred_lft forever
      inet 192.168.10.7/24 scope global ens1
         valid_lft forever preferred_lft forever
      inet 192.168.10.8/24 scope global secondary ens1:0
         valid_lft forever preferred_lft forever
    [root@controller2 ~]# 
    [root@controller2 ~]# ifconfig 
    ens1: flags=4163  mtu 1500
          inet 10.1.1.2  netmask 255.255.255.0  broadcast 10.1.1.255
          inet6 fe80::209:6ff:fe2a:3a76  prefixlen 64  scopeid 0x20
          ether 00:09:06:2a:3a:76  txqueuelen 1000  (Ethernet)
          RX packets 191801282  bytes 77344392183 (72.0 GiB)
          RX errors 0  dropped 1868177  overruns 0  frame 0
          TX packets 184906493  bytes 24743634534 (23.0 GiB)
          TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
          device memory 0x80061200000-800612fffff  
    
    ens1:0: flags=4163  mtu 1500
          inet 192.168.10.8  netmask 255.255.255.0  broadcast 0.0.0.0
          ether 00:09:06:2a:3a:76  txqueuelen 1000  (Ethernet)
          device memory 0x80061200000-800612fffff

要删除 ip,则简单的多,但必须指定 dev,且最好也指定 cidr 的掩码长度。

[root@controller2 ~]# ip address del 192.168.10.7/24 dev ens1
[root@controller2 ~]# ip address del 192.168.10.8/24 dev ens1 label ens1:0
[root@controller2 ~]# ip -4 add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    inet 10.1.1.2/24 brd 10.1.1.255 scope global ens1
       valid_lft forever preferred_lft forever
[root@controller2 ~]#

13.6.2.2、ip addr show 子命令

其实刚才使用 ip addr 就相当于 ip addr show,这是 ip 命令使用起来很方便的地方,支持灵活缩写。

[root@controller2 ~]# ip add
[root@controller2 ~]# ip a
[root@controller2 ~]# ip add show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:09:06:2a:3a:76 brd ff:ff:ff:ff:ff:ff
    inet 10.1.1.2/24 brd 10.1.1.255 scope global ens1
       valid_lft forever preferred_lft forever
    inet6 fe80::209:6ff:fe2a:3a76/64 scope link 
       valid_lft forever preferred_lft forever

13.6.2.3、ip addr flush 子命令

用于批量删除地址,该命令其实非常危险,一个不小心就会误伤无辜,所幸的是 flush 的时候不给定任何参数或者没有任何条目可以匹配上的时候将不执行 flush 动作,总之该命令要小心使用。同样也必须给定 dev 参数。

[root@controller2 ~]# ip a flush dev ens1           # 删除ens1上所有地址
[root@controller2 ~]# ip a f secondary dev ens1     # 删除ens1上所有的secondary地址

13.6.3、ip route 命令

该命令维护和查看内核中的路由表。

13.6.3.1、ip route add/replace/MORE 子命令

语法格式为:

ip route { add | del | change | append | replace } dest[/cidr_mask] [ via ADDRESS ] [ dev STRING ]

其中 dest 为目标地址,可以是主机地址、网段地址,一般在地址后都会带上 cidr 格式的掩码长度,不带时默认为 32 位长度。如果 dest 为 "0/0" 或者写为 "default",则表示默认路由。

例如添加/修改/替换普通路由:

[root@controller2 ~]# ip route add/change/replace 192.168.10.0/24 via 10.10.10.1

添加/修改/替换默认路由:

[root@controller2 ~]# ip route add/change/replace default via 10.10.10.1
[root@controller2 ~]# ip route add/change/replace 0/0 via 10.10.10.1

删除某路由:

[root@controller2 ~]# ip route del 192.168.10.0/24
[root@controller2 ~]# ip route del default          # 删除默认路由

13.6.3.2、ip route show 子命令

语法格式为:

ip route show [to [ root | match | exact ] ADDR_pattern ] [ via ADDR ]
  • 其中 to 关键字是默认关键字,用来匹配路由的目标地址,其后可以跟上修饰符 root/match/exact。
    • exact 为默认修饰符,表示精确匹配掩码位长度;
    • root 修饰符表示匹配的掩码位长度大于或等于 ADDR_pattern 给定的掩码位长度;
    • match 修饰符匹配短于或等于 ADDR_pattern 掩码位长度。
  • 例如 "to match 16.0/16" 将能匹配到 "16.0/16"、"16/8" 和 "0/0",但却无法匹配 "16.1/16" 和 "16.0/24" 以及 "16.0.1/24",而 "to root 16.0/16" 将能匹配 "16.0/24" 和 "16.0.1/24"。
[root@controller2 ~]# ip route show | column -t
default         via  10.1.1.254  dev    ens1                       
10.1.1.0/24     dev  ens1        proto  kernel  scope   link  src  10.1.1.2
169.254.0.0/16  dev  ens1        scope  link    metric  1002       
[root@controller2 ~]# 
[root@controller2 ~]# ip route show to match 10.1.1.0/24 | column -t
default      via  10.1.1.254  dev    ens1                      
10.1.1.0/24  dev  ens1        proto  kernel  scope  link  src  10.1.1.2
[root@controller2 ~]# 
[root@controller2 ~]# ip route show to root 10.1/16 | column -t
10.1.1.0/24  dev  ens1  proto  kernel  scope  link  src  10.1.1.2
[root@controller2 ~]#

13.6.3.3、ip route flush 子命令

批量删除路由表条目。参数和 ip route show 的参数一样。

例如删除由 ens1 出去的路由条目。

[root@controller2 ~]# ip route flush ens1

删除下一跳为 10.10.10.1 的路由条目。

[root@controller2 ~]# ip r flush via 10.10.10.1

删除目标为 192.168.0.0/16 网段的路由

[root@controller2 ~]# ip route flush 192.168/16

13.6.3.4、ip route save/restore 子命令

用于保存当前的路由表以及恢复路由表。保存路由表时,路由表将以二进制裸数据的格式输出,也就是看不懂的二进制文件。

恢复路由表时,要求设备的设置和保存路由表时是一样的,恢复时已存在于路由表中的路由条目将被忽略。

例如当前路由表信息如下:

[root@controller2 ~]# ip route
default via 10.1.1.254 dev ens1 
10.1.1.0/24 dev ens1 proto kernel scope link src 10.1.1.2 
169.254.0.0/16 dev ens1 scope link metric 1002 
[root@controller2 ~]#

保存当前路由表。

[root@controller2 ~]# ip route save > /tmp/route.txt

删除几条路由表。

[root@controller2 ~]# ip route flush dev ens1

恢复路由表。

[root@controller2 ~]# ip route restore < /tmp/route.txt

13.6.4、ip link 命令

link 表示 link layer 的意思,即链路层。该命令用于管理和查看网络接口,甚至可以添加虚拟网络接口,将网络接口分组进行管理。

13.6.4.1、ip link set 子命令

ip link set DEVICE  { up | down | arp { on | off } | name NEWNAME | address LLADDR }  

选项说明:
dev DEVICE:         指定要操作的设备名
up and down:        启动或停用该设备
arp on or arp off:  启用或禁用该设备的arp协议
name NAME:          修改指定设备的名称,建议不要在该接口处于运行状态或已分配IP地址时重命名
address LLADDRESS:  设置指定接口的MAC地址

例如,启用/禁用 ens1 网卡。

[root@controller2 ~]# ip link set ens1 up/down

其实等价于:

[root@controller2 ~]# ifconfig ens1 up/down

修改网卡 ens1 的 MAC 地址。

[root@controller2 ~]# ip link set ens1 address 00:09:06:2a:3a:76

13.6.4.2、ip link show 子命令

语法格式:

ip [ -s | -h ] link show [dev DEV]  

选项说明:
-s:将显示各网络接口上的流量统计信息
-h:以人类可读的方式显式,即单位转换。注:"-h"在CentOS 7上才支持。

例如:

[root@controller2 ~]# ip -s -h link show dev ens1
2: ens1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether 00:09:06:2a:3a:76 brd ff:ff:ff:ff:ff:ff
    RX: bytes  packets  errors  dropped overrun mcast   
    77.8G      193M     0       1.88M   0       0       
    TX: bytes  packets  errors  dropped carrier collsns 
    24.9G      186M     0       0       0       0       
[root@controller2 ~]# 

13.7、nmcli 命令

nmcli 实用工具是由 NetworkManager(网络管理器) 包提供,Centos7+ 默认已经安装。

[root@arm64v8 ~]# nmcli help
Usage: nmcli [OPTIONS] OBJECT { COMMAND | help }

OPTIONS
  -t[erse]                                       terse output
  -p[retty]                                      pretty output
  -m[ode] tabular|multiline                      output mode
  -c[olors] auto|yes|no                          whether to use colors in output
  -f[ields] <field1,field2,...>|all|common       specify fields to output
  -g[et-values] <field1,field2,...>|all|common   shortcut for -m tabular -t -f
  -e[scape] yes|no                               escape columns separators in values
  -a[sk]                                         ask for missing parameters
  -s[how-secrets]                                allow displaying passwords
  -w[ait] <seconds>                              set timeout waiting for finishing operations
  -v[ersion]                                     show program version
  -h[elp]                                        print this help

OBJECT
  g[eneral]       NetworkManager's general status and operations
  n[etworking]    overall networking control
  r[adio]         NetworkManager radio switches
  c[onnection]    NetworkManager's connections
  d[evice]        devices managed by NetworkManager
  a[gent]         NetworkManager secret agent or polkit agent
  m[onitor]       monitor NetworkManager changes

[root@arm64v8 ~]#
  • nmcli 命令通用的常用选项 -t 简洁输出、-p 美化输出、-f 指定输出字段、-h 查看使用帮助。

  • nmcli 支持对象操作,上述帮助文档已经非常简洁明了,如果想查看每个 OBJECT 的详细使用方法,可以使用 nmcli OBJECT help 获取帮助。

    [root@arm64v8 ~]# nmcli general help
    Usage: nmcli general { COMMAND | help }
    
    COMMAND := { status | hostname | permissions | logging }
    
    status
    
    hostname []
    
    permissions
    
    logging [level ] [domains ]
    
    [root@arm64v8 ~]#
  • 当然,使用 man nmcli 可以一览无余。

13.7.1、nmcli general 命令

命令格式:nmcli general {status|hostname|permissions|logging}
命令描述:使用此命令可以显示网络管理器状态和权限,你可以获取和更改系统主机名,以及网络管理器日志记录级别和域。

13.7.1.1、status 子命令

显示网络管理器的整体状态。

[root@arm64v8 ~]# nmcli general status 
STATE      CONNECTIVITY  WIFI-HW  WIFI     WWAN-HW  WWAN    
connected  full          enabled  enabled  enabled  enabled 
[root@arm64v8 ~]#

13.7.1.2、hostname 子命令

获取主机名或更改主机名,在没有给定参数的情况下,打印配置的主机名,当指定了参数,它将被移交给NetworkManager,以设置为新的系统主机名。

[root@arm64v8 ~]# nmcli general hostname 
arm64v8
[root@arm64v8 ~]# 
[root@arm64v8 ~]# nmcli general hostname arm64v8_by_Brinnatt
[root@arm64v8 ~]# nmcli general hostname 
arm64v8_by_Brinnatt
[root@arm64v8 ~]#

13.7.1.3、permissions 子命令

显示当前用户对网络管理器可允许的操作权限。 如启用和禁用网络、更改 WI-FI 和 WWAN 状态、修改连接等。

[root@arm64v8 ~]# nmcli general permissions 
PERMISSION                                                        VALUE 
org.freedesktop.NetworkManager.enable-disable-network             yes   
org.freedesktop.NetworkManager.enable-disable-wifi                yes   
org.freedesktop.NetworkManager.enable-disable-wwan                yes   
org.freedesktop.NetworkManager.enable-disable-wimax               yes   
org.freedesktop.NetworkManager.sleep-wake                         yes   
org.freedesktop.NetworkManager.network-control                    yes   
org.freedesktop.NetworkManager.wifi.share.protected               yes   
org.freedesktop.NetworkManager.wifi.share.open                    yes   
org.freedesktop.NetworkManager.settings.modify.system             yes   
org.freedesktop.NetworkManager.settings.modify.own                yes   
org.freedesktop.NetworkManager.settings.modify.hostname           yes   
org.freedesktop.NetworkManager.settings.modify.global-dns         yes   
org.freedesktop.NetworkManager.reload                             yes   
org.freedesktop.NetworkManager.checkpoint-rollback                yes   
org.freedesktop.NetworkManager.enable-disable-statistics          yes   
org.freedesktop.NetworkManager.enable-disable-connectivity-check  yes   
[root@arm64v8 ~]#

13.7.1.4、loggin 子命令

获取和更改网络管理器日志记录级别和域,没有任何参数则显示当前日志记录级别和域。为了更改日志记录状态,请提供级别和域参数,有关可用级别和域值,参阅 NetworkManager.conf(5)

[root@arm64v8 ~]# nmcli -p general logging 
==========================
  NetworkManager logging
==========================
LEVEL  DOMAINS                                                                                                                                                                                                                       
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
INFO   PLATFORM,RFKILL,ETHER,WIFI,BT,MB,DHCP4,DHCP6,PPP,IP4,IP6,AUTOIP4,DNS,VPN,SHARING,SUPPLICANT,AGENTS,SETTINGS,SUSPEND,CORE,DEVICE,OLPC,INFINIBAND,FIREWALL,ADSL,BOND,VLAN,BRIDGE,TEAM,CONCHECK,DCB,DISPATCH,AUDIT,SYSTEMD,PROXY 
[root@arm64v8 ~]#

13.7.2、nmcli networking 命令

命令格式:nmcli networking {on|off|connectivity}

命令描述:查询网络管理器网络状态,开启和关闭网络

选项:

  • on:开启 NetworkManager 管理所有网络接口
  • off:禁用 NetworkManager 管理所有网络接口
  • connectivity [check]:获取网络连接状态,可选参数 [check] 告诉网络管理器重新检查连接性,否则显示最近已知的状态,而无需重新检查。
    • 可能的状态有:
    • none:主机没有连接任何网络。
    • portal:主机被囚禁在一个门户网站后面,无法访问整个互联网。
    • limited:主机连接到一个网络,但是不能访问互联网。
    • full:主机连接到一个网络,并且完全可以访问互联网。
    • unknown:未知的连接状态。
[root@arm64v8 ~]# nmcli networking connectivity 
full
[root@arm64v8 ~]# nmcli networking connectivity check 
full
[root@arm64v8 ~]#

13.7.3、nmcli radio 命令

命令格式:nmcli radio {all|wifi|wwan}

显示无线开关状态,或启用和禁用开关

[root@arm64v8_by_Brinnatt ~]# nmcli radio all
WIFI-HW  WIFI     WWAN-HW  WWAN    
enabled  enabled  enabled  enabled 
[root@arm64v8_by_Brinnatt ~]# 
[root@arm64v8_by_Brinnatt ~]# nmcli radio all off
[root@arm64v8_by_Brinnatt ~]# 
[root@arm64v8_by_Brinnatt ~]# nmcli radio all
WIFI-HW  WIFI      WWAN-HW  WWAN     
enabled  disabled  enabled  disabled 
[root@arm64v8_by_Brinnatt ~]# 
[root@arm64v8_by_Brinnatt ~]# nmcli radio wifi on
[root@arm64v8_by_Brinnatt ~]# nmcli radio wwan on
[root@arm64v8_by_Brinnatt ~]# nmcli radio all
WIFI-HW  WIFI     WWAN-HW  WWAN    
enabled  enabled  enabled  enabled 
[root@arm64v8_by_Brinnatt ~]#

13.7.4、nmcli monitor 命令

活动监视器(ACTIVITY MONITOR)

观察 NetworkManager 活动。监视设备连接状态的变化或配置文件的变化。

另请参阅 nmcli connection monitornmcli device monitor 监视某些设备或连接中的更改。

13.7.5、nmcli connection 命令

命令格式:nmcli connection {show|up|down|modify|add|edit|clone|delete|monitor|reload|load|import|export}

NetworkManager 将所有网络配置存储为 "connections",它是描述如何创建或者连接网络的数据(二层链路、三层 IP 等) 集合;当一个设备用一个 connection 的配置创建或者连接一个网络时,则表示这个 connection 是活动状态。一个设备可能有多个 connections,但是任何一个时刻,只能有一个 connection 是活动状态。

13.7.5.1、show 子命令

列出活动的连接,或进行排序( + - 为升降序)

# 查看所有连接状态
[root@arm64v8 ~]# nmcli connection show
NAME      UUID                                  TYPE      DEVICE   
enp1s0f0  3b71932d-657e-4c79-9dd6-3dd56b3a9c4c  ethernet  enp1s0f0 
virbr0    e597548d-e652-41a1-a044-176f0e7277b7  bridge    virbr0   
enp1s0f1  83634972-548c-40c9-8acb-ca0279e0a616  ethernet  --       
enp1s0f2  89ab6348-29b0-4ff9-807a-f37518c4b297  ethernet  --       
enp1s0f3  7dbfb2be-4a88-42f8-b293-cb05763fbbf8  ethernet  --       
[root@arm64v8 ~]#

# 以活动的连接进行排序
[root@arm64v8 ~]# nmcli connection show --order +active
NAME      UUID                                  TYPE      DEVICE   
enp1s0f0  3b71932d-657e-4c79-9dd6-3dd56b3a9c4c  ethernet  enp1s0f0 
virbr0    e597548d-e652-41a1-a044-176f0e7277b7  bridge    virbr0   
enp1s0f2  89ab6348-29b0-4ff9-807a-f37518c4b297  ethernet  --       
enp1s0f3  7dbfb2be-4a88-42f8-b293-cb05763fbbf8  ethernet  --       
enp1s0f1  83634972-548c-40c9-8acb-ca0279e0a616  ethernet  --       
[root@arm64v8 ~]#

# 将所有连接以名称排序
[root@arm64v8 ~]# nmcli connection show --order +name
NAME      UUID                                  TYPE      DEVICE   
enp1s0f0  3b71932d-657e-4c79-9dd6-3dd56b3a9c4c  ethernet  enp1s0f0 
enp1s0f1  83634972-548c-40c9-8acb-ca0279e0a616  ethernet  --       
enp1s0f2  89ab6348-29b0-4ff9-807a-f37518c4b297  ethernet  --       
enp1s0f3  7dbfb2be-4a88-42f8-b293-cb05763fbbf8  ethernet  --       
virbr0    e597548d-e652-41a1-a044-176f0e7277b7  bridge    virbr0   
[root@arm64v8 ~]#

# 将所有连接以类型排序(倒序)
[root@arm64v8 ~]# nmcli connection show --order -type
NAME      UUID                                  TYPE      DEVICE   
virbr0    e597548d-e652-41a1-a044-176f0e7277b7  bridge    virbr0   
enp1s0f2  89ab6348-29b0-4ff9-807a-f37518c4b297  ethernet  --       
enp1s0f0  3b71932d-657e-4c79-9dd6-3dd56b3a9c4c  ethernet  enp1s0f0 
enp1s0f3  7dbfb2be-4a88-42f8-b293-cb05763fbbf8  ethernet  --       
enp1s0f1  83634972-548c-40c9-8acb-ca0279e0a616  ethernet  --       
[root@arm64v8 ~]#

查看指定连接的详细信息

[root@arm64v8 ~]# nmcli connection show enp1s0f0 
connection.id:                          enp1s0f0
connection.uuid:                        3b71932d-657e-4c79-9dd6-3dd56b3a9c4c
connection.stable-id:                   --
connection.type:                        802-3-ethernet
connection.interface-name:              enp1s0f0
connection.autoconnect:                 yes
connection.autoconnect-priority:        0
......

13.7.5.2、up 子命令

激活连接,提供连接名称或 uuid 进行激活,若未提供,则可以使用 ifname 指定设备名进行激活。

# 以连接名进行激活
[root@arm64v8 ~]# nmcli connection up enp1s0f1

# 以uuid进行激活
[root@arm64v8 ~]# nmcli connection up 83634972-548c-40c9-8acb-ca0279e0a616

# 以设备接口名进行激活
[root@arm64v8 ~]# nmcli connection up ifname enp1s0f0
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/7)
[root@arm64v8 ~]#

13.7.5.3、down 子命令

停用连接,提供连接名或 uuid 进行停用,若未提供,则可以使用 ifname 指定设备名进行激活。

# 以连接名进行停用
[root@arm64v8 ~]# nmcli connection down enp1s0f1

# 以uuid进行停用
[root@arm64v8 ~]# nmcli connection down 83634972-548c-40c9-8acb-ca0279e0a616

# 以设备接口名进行停用
[root@arm64v8 ~]# nmcli connection down ifname enp1s0f1

13.7.5.4、modify 子命令

属性可以用 nmcli connection show <INTERFACE> 进行获取,然后可以修改、添加或删除属性,若要设置属性,只需指定属性名称后跟值,空值将删除属性值,同一属性添加多个值使用 +。同一属性删除指定值用 - 加索引。

添加多个 ip

# 添加三个
[root@arm64v8 ~]# nmcli connection modify enp1s0f0 +ipv4.addresses 192.168.100.101/24
[root@arm64v8 ~]# nmcli connection modify enp1s0f0 +ipv4.addresses 192.168.100.102/24
[root@arm64v8 ~]# nmcli connection modify enp1s0f0 +ipv4.addresses 192.168.100.103/24
[root@arm64v8 ~]#

# 查看
[root@arm64v8 ~]# nmcli -f IP4 connection show enp1s0f0
IP4.ADDRESS[1]:                         10.1.1.2/24
IP4.GATEWAY:                            10.1.1.1
IP4.ROUTE[1]:                           dst = 10.1.1.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[2]:                           dst = 0.0.0.0/0, nh = 10.1.1.1, mt = 100
IP4.DNS[1]:                             223.5.5.5
[root@arm64v8 ~]#

# 启用配置
[root@arm64v8 ~]# nmcli connection up enp1s0f0 
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/8)
[root@arm64v8 ~]# 

# 再次查看
[root@arm64v8 ~]# nmcli -f IP4 connection show enp1s0f0 
IP4.ADDRESS[1]:                         10.1.1.2/24
IP4.ADDRESS[2]:                         192.168.100.101/24
IP4.ADDRESS[3]:                         192.168.100.102/24
IP4.ADDRESS[4]:                         192.168.100.103/24
IP4.GATEWAY:                            10.1.1.1
IP4.ROUTE[1]:                           dst = 10.1.1.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[2]:                           dst = 192.168.100.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[3]:                           dst = 192.168.100.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[4]:                           dst = 192.168.100.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[5]:                           dst = 0.0.0.0/0, nh = 10.1.1.1, mt = 100
IP4.DNS[1]:                             223.5.5.5
[root@arm64v8 ~]#

删除指定 ip

[root@arm64v8 ~]# nmcli -f IP4 connection show enp1s0f0
IP4.ADDRESS[1]:                         10.1.1.2/24
IP4.ADDRESS[2]:                         192.168.100.101/24
IP4.ADDRESS[3]:                         192.168.100.102/24
IP4.ADDRESS[4]:                         192.168.100.103/24
IP4.GATEWAY:                            10.1.1.1
IP4.ROUTE[1]:                           dst = 10.1.1.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[2]:                           dst = 192.168.100.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[3]:                           dst = 192.168.100.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[4]:                           dst = 192.168.100.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[5]:                           dst = 0.0.0.0/0, nh = 10.1.1.1, mt = 100
IP4.DNS[1]:                             223.5.5.5
[root@arm64v8 ~]#

# 删除索当前索引为2的地址
[root@arm64v8 ~]# nmcli connection modify enp1s0f0 -ipv4.addresses 2

# 查看
[root@arm64v8 ~]# nmcli -f IP4 connection show enp1s0f0 
IP4.ADDRESS[1]:                         10.1.1.2/24
IP4.ADDRESS[2]:                         192.168.100.101/24
IP4.ADDRESS[3]:                         192.168.100.102/24
IP4.ADDRESS[4]:                         192.168.100.103/24
IP4.GATEWAY:                            10.1.1.1
IP4.ROUTE[1]:                           dst = 10.1.1.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[2]:                           dst = 192.168.100.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[3]:                           dst = 192.168.100.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[4]:                           dst = 192.168.100.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[5]:                           dst = 0.0.0.0/0, nh = 10.1.1.1, mt = 100
IP4.DNS[1]:                             223.5.5.5
[root@arm64v8 ~]#

# 再次激活
[root@arm64v8 ~]# nmcli connection up enp1s0f0 
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/9)
[root@arm64v8 ~]#

# 查看
[root@arm64v8 ~]# nmcli -f IP4 connection show enp1s0f0 
IP4.ADDRESS[1]:                         10.1.1.2/24
IP4.ADDRESS[2]:                         192.168.100.101/24
IP4.ADDRESS[3]:                         192.168.100.103/24
IP4.GATEWAY:                            10.1.1.1
IP4.ROUTE[1]:                           dst = 10.1.1.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[2]:                           dst = 192.168.100.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[3]:                           dst = 192.168.100.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[4]:                           dst = 0.0.0.0/0, nh = 10.1.1.1, mt = 100
IP4.DNS[1]:                             223.5.5.5
[root@arm64v8 ~]#

说明:

  1. nmcli connection modify 是直接修改 /etc/sysconfig/network-scripts/ifcfg-INTERFACE 网络接口配置文件。
  2. 网络接口配置文件修,不代表直接生效了,需要使用 nmcli connection up INTERFACE 激活配置,相当于使用 systemctl restart network 重启网络服务。

13.7.5.5、add 子命令

这是创建一个新的连接,需要指定新创建连接的属性,语法与 modify 相同。

[root@arm64v8 ~]# nmcli con add con-name "default" type ethernet ip4 192.168.100.1/24 gw4 192.168.100.254 autoconnect yes ifname enp1s0f0

# con-name          (别名)connection.id,连接名称,如果不指定,默认格式为 <type>[-<ifname>][-<num>]
# type              (别名)connection.type,连接类型
# ip4               (别名)ipv4.addresses,同时设置 ipv4.method to manual
# gw4               (别名)ipv4.gateway
# autoconnect       (别名)connection.autoconnect,是否自动连接
# ifname            (别名)connection.interface-name,连接到的设备名称

其实我们常用的也不过如此,在项目中,可能用到的比较多的还有 type bond 方式,可以参见 man nmcli-examples。

13.7.5.6、clone 子命令

克隆连接,克隆一个存在的连接,除了连接名称和 uuid 是新生成的,其他都是一样的。

[root@arm64v8 ~]# nmcli connection clone enp1s0f0 enp1s0f0_clone
enp1s0f0 (3b71932d-657e-4c79-9dd6-3dd56b3a9c4c) cloned as enp1s0f0_clone (a9700e49-28fa-40aa-94a9-4e29fcd754fe).
[root@arm64v8 ~]#
[root@arm64v8 ~]# ls /etc/sysconfig/network-scripts/ifcfg-enp1s0f0*
/etc/sysconfig/network-scripts/ifcfg-enp1s0f0
/etc/sysconfig/network-scripts/ifcfg-enp1s0f0_clone
[root@arm64v8 ~]#

13.7.5.7、delete 子命令

删除连接,这将删除一个连接。

[root@arm64v8 ~]# nmcli connection delete enp1s0f0_clone 
Connection 'enp1s0f0_clone' (a9700e49-28fa-40aa-94a9-4e29fcd754fe) successfully deleted.
[root@arm64v8 ~]# 
[root@arm64v8 ~]# ls /etc/sysconfig/network-scripts/ifcfg-enp1s0f0*
/etc/sysconfig/network-scripts/ifcfg-enp1s0f0
[root@arm64v8 ~]#

13.7.5.8、load 子命令

从磁盘加载或重新加载一个或多个连接文件,例如你手动创建了一个 /etc/sysconfig/network-scripts/ifcfg-ethx 连接文件,你可以将其加载到网络管理器,以便管理。

[root@arm64v8 ~]# echo -e "TYPE=Ethernet\nNAME=ethx" > /etc/sysconfig/network-scripts/ifcfg-ethx
[root@arm64v8 ~]# nmcli connection show
NAME      UUID                                  TYPE      DEVICE   
enp1s0f0  3b71932d-657e-4c79-9dd6-3dd56b3a9c4c  ethernet  enp1s0f0 
virbr0    e597548d-e652-41a1-a044-176f0e7277b7  bridge    virbr0   
enp1s0f1  83634972-548c-40c9-8acb-ca0279e0a616  ethernet  --       
enp1s0f2  89ab6348-29b0-4ff9-807a-f37518c4b297  ethernet  --       
enp1s0f3  7dbfb2be-4a88-42f8-b293-cb05763fbbf8  ethernet  --       
[root@arm64v8 ~]# 
[root@arm64v8 ~]# nmcli connection load /etc/sysconfig/network-scripts/ifcfg-ethx 
[root@arm64v8 ~]# nmcli connection show
NAME      UUID                                  TYPE      DEVICE   
enp1s0f0  3b71932d-657e-4c79-9dd6-3dd56b3a9c4c  ethernet  enp1s0f0 
virbr0    e597548d-e652-41a1-a044-176f0e7277b7  bridge    virbr0   
enp1s0f1  83634972-548c-40c9-8acb-ca0279e0a616  ethernet  --       
enp1s0f2  89ab6348-29b0-4ff9-807a-f37518c4b297  ethernet  --       
enp1s0f3  7dbfb2be-4a88-42f8-b293-cb05763fbbf8  ethernet  --       
ethx      d45d97fb-8530-60e2-2d15-d92c0df8b0fc  ethernet  --       
[root@arm64v8 ~]#

13.7.5.9、monitor 子命令

监视连接配置文件活动。每当指定的连接更改时, 此命令都会打印一行。要监视的连接由其名称、UUID 或 D 总线路径标识。

如果 ID 不明确, 则可以使用关键字 id、uuid 或路径。有关 ID 指定关键字的说明, 请参阅 nmcli con show。

# 第一个终端监视着
[root@arm64v8 ~]# nmcli connection monitor enp1s0f0 
enp1s0f0: connection profile changed    # 说明有人动了配置文件
enp1s0f0: connection profile changed    # 说明有人动了配置文件

# 第二个终端修改一下被监视接口的配置文件
[root@arm64v8 ~]# nmcli connection modify enp1s0f0 +ipv4.addresses 192.168.100.101/24
[root@arm64v8 ~]# nmcli connection modify enp1s0f0 -ipv4.addresses 192.168.100.101/24

13.7.5.10、示例:配置 IP 隧道

与 VPN 类似,IP 隧道通过网络(如互联网)直接连接两个网络。然而,不是所有的隧道协议都支持加密。两个建立隧道网络的路由器至少需要两个接口:

  • 一个连接到本地网络的接口
  • 一个连接到建立隧道的网络的接口。

NetworkManager 支持以下 IP 隧道:

  • 通用路由封装(GRE)
  • IPv6 上的通用路由封装(IP6GRE)
  • 通用路由封装终端接入点(GRETAP)
  • 通用路由登录在 IPv6(IP6GRETAP)上
  • IPv4 over IPv4(IPIP)
  • IPv4 over IPv6(IPIP6)
  • IPv6 over IPv6(IP6IP6)
  • 简单的互联网转换(SIT)

根据类型,这些通道在 Open Systems Interconnection(OSI)的第 2 层或 3 层动作。

使用 nmcli 配置 IPIP 隧道来封装 IPv4 数据包中的 IPv4 流量

IP over IP(IPIP)隧道在 OSI 层 3 上运行,并封装 IPv4 数据包中的 IPv4 流量,如 RFC 2003 所述

注意:通过 IPIP 隧道发送的数据没有加密。出于安全考虑,只在已经加密的数据中使用隧道,比如 HTTPS。IPIP 隧道只支持单播数据包。如果您需要支持多播的 IPv4 隧道,请参考下面使用 nmcli 配置 GRE 隧道来封装 IPv4 数据包中的第 3 层流量。

此流程描述了如何在两个 RHEL 路由器之间创建 IPIP 隧道以通过互联网连接两个内部子网,如下图所示:

IPIP-tunnel

先决条件

  • 每个 RHEL 路由器都有一个网络接口,它连接到其本地子网。
  • 每个 RHEL 路由器都有一个网络接口,它连接到互联网。
  • 您需要通过隧道发送的流量是 IPv4 单播。

流程

  1. 在网络 A 的 RHEL 路由器上:

    1. 创建名为 tun0 的 IPIP 隧道接口:

      # nmcli connection add type ip-tunnel ip-tunnel.mode ipip con-name tun0 ifname tun0 remote 198.51.100.5 local 203.0.113.10
      • remotelocal 参数设置远程和本地路由器的公共 IP 地址。
    2. 将 IPv4 地址设置为 tun0 设备:

      # nmcli connection modify tun0 ipv4.addresses '10.0.1.1/30'
      • 请注意,有两个可用的 IP 地址的 /30 子网足以满足隧道的需要。
    3. tun0 连接配置为使用手动 IPv4 配置:

      # nmcli connection modify tun0 ipv4.method manual
    4. 添加将流量路由到 172.16.0.0/24 网络的静态路由到路由器 B 的隧道 IP:

      # nmcli connection modify tun0 +ipv4.routes "172.16.0.0/24 10.0.1.2"
    5. 启用 tun0 连接。

      # nmcli connection up tun0
    6. 启用数据包转发:

      # echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf
      # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
  2. 在网络 B 中的 RHEL 路由器中:

    1. 创建名为 tun0 的 IPIP 隧道接口:

      # nmcli connection add type ip-tunnel ip-tunnel.mode ipip con-name tun0 ifname tun0 remote 203.0.113.10 local 198.51.100.5
      • remotelocal 参数设置远程和本地路由器的公共 IP 地址。
    2. 将 IPv4 地址设置为 tun0 设备:

      # nmcli connection modify tun0 ipv4.addresses '10.0.1.2/30'
    3. tun0 连接配置为使用手动 IPv4 配置:

      # nmcli connection modify tun0 ipv4.method manual
    4. 添加将流量路由到 192.0.2.0/24 网络的静态路由到路由器 A 的隧道 IP:

      # nmcli connection modify tun0 +ipv4.routes "192.0.2.0/24 10.0.1.1"
    5. 启用 tun0 连接。

      # nmcli connection up tun0
    6. 启用数据包转发:

      # echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf
      # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf

验证步骤

从每个 RHEL 路由器中,ping 路由器的内部接口的 IP 地址:

  • 在路由器 A 中,ping 172.16.0.1:

    # ping 172.16.0.1
  • 在路由器 B 中,ping 192.0.2.1:

    # ping 192.0.2.1

使用 nmcli 配置 GRE 隧道来封装 IPv4 数据包中的层 3 流量

Generic Routing Encapsulation(GRE)隧道封装 IPv4 数据包中的第 3 层流量,如 RFC 2784 所述。GRE 隧道可以使用有效的以太网类型封装任何第 3 层协议。

注意:通过 GRE 隧道发送的数据没有加密。出于安全考虑,只在已经加密的数据中使用隧道,比如 HTTPS。

此流程描述了如何在两个 RHEL 路由器之间创建 GRE 隧道以通过互联网连接两个内部子网,如下图所示:

GRE-tunnel

注意:gre0 设备名称被保留。为该设备使用 gre1 或者不同名称。

先决条件

  • 每个 RHEL 路由器都有一个网络接口,它连接到其本地子网。
  • 每个 RHEL 路由器都有一个网络接口,它连接到互联网。

流程

  1. 在网络 A 的 RHEL 路由器上:

    1. 创建名为 gre1 的 GRE 隧道接口:

      # nmcli connection add type ip-tunnel ip-tunnel.mode gre con-name gre1 ifname gre1 remote 198.51.100.5 local 203.0.113.10
      • remotelocal 参数设置远程和本地路由器的公共 IP 地址。
    2. 将 IPv4 地址设置为 gre1 设备:

      # nmcli connection modify gre1 ipv4.addresses '10.0.1.1/30'
      • 请注意,有两个可用的 IP 地址的 /30 子网足以满足隧道的需要。
    3. gre1 连接配置为使用手动 IPv4 配置:

      # nmcli connection modify gre1 ipv4.method manual
    4. 添加将流量路由到 172.16.0.0/24 网络的静态路由到路由器 B 的隧道 IP:

      # nmcli connection modify tun0 +ipv4.routes "172.16.0.0/24 10.0.1.2"
    5. 启用 gre1 连接。

      # nmcli connection up gre1
    6. 启用数据包转发:

      # echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf
      # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
  2. 在网络 B 中的 RHEL 路由器中:

    1. 创建名为 gre1 的 GRE 隧道接口:

      # nmcli connection add type ip-tunnel ip-tunnel.mode ipip con-name gre1 ifname gre1 remote 203.0.113.10 local 198.51.100.5
      • remotelocal 参数设置远程和本地路由器的公共 IP 地址。
    2. 将 IPv4 地址设置为 gre1 设备:

      # nmcli connection modify gre1 ipv4.addresses '10.0.1.2/30'
    3. gre1 连接配置为使用手动 IPv4 配置:

      # nmcli connection modify gre1 ipv4.method manual
    4. 添加将流量路由到 192.0.2.0/24 网络的静态路由到路由器 A 的隧道 IP:

      # nmcli connection modify tun0 +ipv4.routes "192.0.2.0/24 10.0.1.1"
    5. 启用 gre1 连接。

      # nmcli connection up gre1
    6. 启用数据包转发:

      # echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf
      # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf

验证步骤

从每个 RHEL 路由器中,ping 路由器的内部接口的 IP 地址:

  • 在路由器 A 中,ping 172.16.0.1:

    # ping 172.16.0.1
  • 在路由器 B 中,ping 192.0.2.1:

    # ping 192.0.2.1

配置 GRETAP 隧道来通过 IPv4 传输以太网帧

Generic Routing Encapsulation Terminal Access Point(GRETAP)隧道在 OSI 级别 2 上运行,并封装 IPv4 数据包中的以太网流量,如 RFC 2784 所述。

注意:通过 GRETAP 隧道发送的数据没有加密。出于安全考虑,通过 VPN 或不同的加密连接建立隧道。

此流程描述了如何在两个 RHEL 路由器之间创建 GRETAP 隧道以使用桥接连接两个网络,如下图所示:

GRETAP-tunnel

注意:gretap0 设备名称被保留。为该设备使用 gretap1 或者不同名称。

先决条件

  • 每个 RHEL 路由器都有一个网络接口,它连接到其本地网络,接口没有分配 IP 配置。
  • 每个 RHEL 路由器都有一个网络接口,它连接到互联网。

流程

  1. 在网络 A 的 RHEL 路由器上:

    1. 创建名为 bridge0的网桥接口:

      # nmcli connection add type bridge con-name bridge0 ifname bridge0
    2. 配置网桥的 IP 设置:

      # nmcli connection modify bridge0 ipv4.addresses '192.0.2.1/24'
      # nmcli connection modify bridge0 ipv4.method manual
    3. 为连接到本地网络的接口添加新连接配置集到网桥:

      # nmcli connection add type ethernet slave-type bridge con-name bridge0-port1 ifname enp1s0 master bridge0
    4. 为网桥添加 GRETAP 隧道接口的新连接配置集:

      # nmcli connection add type ip-tunnel ip-tunnel.mode gretap slave-type bridge con-name bridge0-port2 ifname gretap1 remote 198.51.100.5 local 203.0.113.10 master bridge0
      • remotelocal 参数设置远程和本地路由器的公共 IP 地址。
    5. 可选:如果您不需要,STP(Spanning Tree Protocol):

      # nmcli connection modify bridge0 bridge.stp no
      • 默认情况下,STP 被启用并导致在使用连接前出现延迟。
    6. 配置激活 bridge0 连接会自动激活网桥端口:

      # nmcli connection modify bridge0 connection.autoconnect-slaves 1
    7. 激活 bridge0 连接:

      # nmcli connection up bridge0
  2. 在网络 B 中的 RHEL 路由器中:

    1. 创建名为 bridge0的网桥接口:

      # nmcli connection add type bridge con-name bridge0 ifname bridge0
    2. 配置网桥的 IP 设置:

      # nmcli connection modify bridge0 ipv4.addresses '192.0.2.2/24'
      # nmcli connection modify bridge0 ipv4.method manual
    3. 为连接到本地网络的接口添加新连接配置集到网桥:

      # nmcli connection add type ethernet slave-type bridge con-name bridge0-port1 ifname enp1s0 master bridge0
    4. 为网桥添加 GRETAP 隧道接口的新连接配置集:

      # nmcli connection add type ip-tunnel ip-tunnel.mode gretap slave-type bridge con-name bridge0-port2 ifname gretap1 remote 203.0.113.10 local 198.51.100.5 master bridge0
      • remotelocal 参数设置远程和本地路由器的公共 IP 地址。
    5. 可选:如果您不需要,STP(Spanning Tree Protocol):

      # nmcli connection modify bridge0 bridge.stp no
    6. 配置激活 bridge0 连接会自动激活网桥端口:

      # nmcli connection modify bridge0 connection.autoconnect-slaves 1
    7. 激活 bridge0 连接:

      # nmcli connection up bridge0

验证步骤

  1. 在两个路由器中,验证 enp1s0gretap1 连接是否已连接,并且 CONNECTION 列显示了端口的连接名称:

    # nmcli device
    nmcli device
    DEVICE   TYPE      STATE      CONNECTION
    ...
    bridge0  bridge    connected  bridge0
    enp1s0   ethernet  connected  bridge0-port1
    gretap1  iptunnel  connected  bridge0-port2
  2. 从每个 RHEL 路由器中,ping 路由器的内部接口的 IP 地址:

    • 在路由器 A 中,ping 192.0.2.2:

      # ping 192.0.2.2
    • 在路由器 B 中,ping 192.0.2.1:

      # ping 192.0.2.1

13.7.6、nmcli device 命令

命令格式:nmcli device {status|show|set|connect|reapply|modify|disconnect|delete|monitor|wifi|lldp}

显示和管理网络接口。nmcli device 功能也很强大,下面介绍一些常见的用法。

13.7.6.1、status 子命令

显示所有设备状态信息,如果 nmcli device 不接子命令,status 就是默认的动作。

[root@arm64v8 ~]# nmcli device status 
DEVICE      TYPE      STATE        CONNECTION 
enp1s0f0    ethernet  connected    enp1s0f0   
virbr0      bridge    connected    virbr0     
enp1s0f1    ethernet  unavailable  --         
enp1s0f2    ethernet  unavailable  --         
enp1s0f3    ethernet  unavailable  --         
lo          loopback  unmanaged    --         
virbr0-nic  tun       unmanaged    --         
[root@arm64v8 ~]#

13.7.6.2、show 子命令

show [ifname]

显示设备的详细信息,如果后面不接参数,所有设备将被检测一遍;想要获得某接口详细信息,则必须指定接口。

[root@arm64v8 ~]# nmcli device show enp1s0f0
GENERAL.DEVICE:                         enp1s0f0
GENERAL.TYPE:                           ethernet
GENERAL.HWADDR:                         00:07:3E:90:88:A9
GENERAL.MTU:                            1500
GENERAL.STATE:                          100 (connected)
GENERAL.CONNECTION:                     enp1s0f0
GENERAL.CON-PATH:                       /org/freedesktop/NetworkManager/ActiveConnection/11
WIRED-PROPERTIES.CARRIER:               on
IP4.ADDRESS[1]:                         10.1.1.2/24
IP4.GATEWAY:                            10.1.1.1
IP4.ROUTE[1]:                           dst = 10.1.1.0/24, nh = 0.0.0.0, mt = 100
IP4.ROUTE[2]:                           dst = 0.0.0.0/0, nh = 10.1.1.1, mt = 100
IP4.DNS[1]:                             223.5.5.5
IP6.ADDRESS[1]:                         fe80::6f3:8a3e:587:7dc8/64
IP6.GATEWAY:                            --
IP6.ROUTE[1]:                           dst = ff00::/8, nh = ::, mt = 256, table=255
IP6.ROUTE[2]:                           dst = fe80::/64, nh = ::, mt = 256
IP6.ROUTE[3]:                           dst = fe80::/64, nh = ::, mt = 100
[root@arm64v8 ~]#

13.7.6.3、set 子命令

set [ifname] ifname [autoconnect {yes | no}] [managed {yes | no}]

设置设备属性

[root@arm64v8 ~]# nmcli device set enp1s0f0 autoconnect yes managed yes

13.7.6.4、connect 子命令

connect ifname

连接设备,NetworkManager 会偿试找到一个合适的连接,并且激活;如果不指定 --wait 超时时间,默认为 90 秒。

[root@arm64v8 ~]# nmcli device connect enp1s0f0
Device 'enp1s0f0' successfully activated with '3b71932d-657e-4c79-9dd6-3dd56b3a9c4c'.
[root@arm64v8 ~]#

13.7.6.5、reapply 子命令

reapply ifname

NetworkManager 偿试将未生效的设备更改更新到 connection 中去,使其生效。

[root@arm64v8 ~]# nmcli device reapply enp1s0f0
Connection successfully reapplied to device 'enp1s0f0'.
[root@arm64v8 ~]#

13.7.6.6、modify 子命令

modify ifname {option value | [+|-]setting.property value}...

更改当前活动设备的设置,这个命令会临时更改活动设备的配置信息,但是不会保存到 connection 配置文件当中;语法跟 nmcli connection modify 一样,但是 nmcli connection modify 会立即将配置写入 connection 配置文件持久化。

[root@arm64v8 ~]# nmcli device modify enp1s0f0 +ipv4.addresses 192.168.100.101/24
Connection successfully reapplied to device 'enp1s0f0'.
[root@arm64v8 ~]#
[root@arm64v8 ~]# nmcli -f IP4.ADDRESS device show enp1s0f0
IP4.ADDRESS[1]:                         10.1.1.2/24
IP4.ADDRESS[2]:                         192.168.100.101/24
[root@arm64v8 ~]#
[root@arm64v8 ~]# nmcli device modify enp1s0f0 -ipv4.addresses 192.168.100.101/24
Connection successfully reapplied to device 'enp1s0f0'.
[root@arm64v8 ~]# nmcli -f IP4.ADDRESS device show enp1s0f0
IP4.ADDRESS[1]:                         10.1.1.2/24
[root@arm64v8 ~]#

13.7.6.7、disconnect 子命令

disconnect ifname

断开设备连接,并且阻止设备自动激活 connection,除非人工干预。注意断开连接的软件设备将会消失。如果 --wait 不指定超时时间,默认超时间为 10 秒。

[root@arm64v8 ~]# nmcli device disconnect enp1s0f1

13.7.6.8、delete 子命令

delete ifname

删除一个设备,这个命令将会移除操作系统中的网络接口,注意移除接口只适用于软件设备,比如 bonds、bridges、teams等;硬件设备不能被这个命令删除。

[root@arm64v8 ~]# nmcli connection add type bond ifname mybond0 mode active-backup
Connection 'bond-mybond0-1' (2ebb2f18-8bff-4832-b809-cd32018f2aed) successfully added.
[root@arm64v8 ~]# nmcli device show mybond0
GENERAL.DEVICE:                         mybond0
GENERAL.TYPE:                           bond
GENERAL.HWADDR:                         0A:85:96:46:70:52
GENERAL.MTU:                            1500
GENERAL.STATE:                          70 (connecting (getting IP configuration))
GENERAL.CONNECTION:                     bond-mybond0-1
GENERAL.CON-PATH:                       /org/freedesktop/NetworkManager/ActiveConnection/14
[root@arm64v8 ~]#
[root@arm64v8 ~]# nmcli device delete mybond0
Device 'mybond0' successfully removed.
[root@arm64v8 ~]# nmcli device show mybond0
Error: Device 'mybond0' not found.
[root@arm64v8 ~]#

13.7.6.9、wifi 子命令

wifi [list [--rescan | auto | no | yes] [ifname ifname] [bssid BSSID]]

列出可用的 Wi-Fi 热点,ifname 和 bssid 选项可以分别列出某个特定接口上的 AP 或者列出某个特定的 bssid。默认情况下,nmcli 可以保证热点处于 30s 内刷新状态,如果使用 --rescan 则会强制立即刷新。

[root@arm64v8 ~]# nmcli device wifi list --rescan yes ifname wlp6s0u1
IN-USE  SSID             MODE   CHAN  RATE        SIGNAL  BARS  SECURITY
        CMCC-NaAn        Infra  9     130 Mbit/s  100     ▂▄▆█  WPA1 WPA2
*       Britural-router  Infra  2     195 Mbit/s  79      ▂▄▆_  WPA2
        CU-5D60          Infra  8     130 Mbit/s  72      ▂▄▆_  WPA1 WPA2
        MERCURY_07D8     Infra  6     270 Mbit/s  69      ▂▄▆_  --
[root@arm64v8 ~]#
[root@arm64v8 ~]# nmcli device wifi list bssid C8:3A:35:3D:8C:91
IN-USE  SSID             MODE   CHAN  RATE        SIGNAL  BARS  SECURITY
        Britural-router  Infra  2     195 Mbit/s  100     ▂▄▆█  WPA2
[root@arm64v8 ~]# nmcli device wifi list bssid Britural-router
Success
[root@arm64v8 ~]# 

wifi connect (B)SSID [password password] [wep-key-type {key | phrase}] [ifname ifname] [bssid BSSID] [name name] [private {yes | no}] [hidden {yes | no}]

通过指定 SSID/ESSID(WLAN名) 或者 BSSID(AP MAC地址) 连接到一个 Wi-Fi 网络。

这个命令会通过一个合适设备找到一个合适的连接并且激活它,实际上这是在图形界面上点击 SSID 图标对应的命令行机制。

如果连接已经存在,该命令会偿试激活连接 nmcli connection up id <name>。注意,如果不存在以前的连接,则只支持开放的 WEP 和 WPA-PSK 网络,期间假设 IP 配置是通过 DHCP 获得的。--wait 选项如果不手动指定,默认为 90s 超时时间。

可使用的选项如下:

字段 含义
password 接入安全网络的密码
wep-key-type WEP 密码类型,密钥为 ASCII/HEX 密钥或密码短语
ifname 用来激活的接口
bssid 如果指定 BSSID,创建的 connection 就会限制于 BSSID
name 如果指定 name,connection 将会使用该名字;或者 NM 自动创建一个名字
private 如果设置为 yes,connection 只为创建者可见;默认是系统级别,所有人可见
hidden 当第一次连接一个不广播 SSID 的 AP 时,要设置为 yes;否则 SSID 找不到,连接失败

wifi hotspot [ifname ifname] [con-name name] [ssid SSID] [band {a | bg}] [channel channel] [password password]

创建一个 Wi-Fi 热点,该命令会根据 Wi-Fi 设备的能力创建一个热点 connection 配置文件并且激活该设备。如果设备支持则使用 WPA 加密,否则使用 WEP 加密。使用 connection down 或 device disconnect 关闭热点。

可使用的选项如下:

字段 含义
ifname 使用的 Wi-Fi 设备
con-name 创建热点 connection 配置文件的名字
ssid 热点的 SSID
band 将要使用的 Wi-Fi 带宽
channel 将要使用的 Wi-Fi 频道
password 设置接入密码,如果不提供,nmcli 会自动创建一个密码,密码是 WPA 预共享密钥或者 WEP 密钥。
--show-secrets 全局选项可以用来打印热点密码,这在自动生成密码时非常有用。

wifi rescan [ifname ifname] [ssid SSID...]

让 NetworkManager 立即扫描可用的热点,虽然 NetworkManager 自动间期性重扫描,但是有时还是需要手动进行扫描,特别对于隐藏的 APs 很实用。

这个命令并不会显示 APs,要使用 nmcli device wifi list 显示可用热点。

13.7.7、示例(nmcli-examples)

上面已经很详细介绍了 nmcli 的用法,并且分别举了一些实际生产中的例子,只要吃透上面的用法,使用 nmcli 就会得心应手。下面例出官方的例子,用来作为参照。

Example 1. Listing available Wi-Fi APs

$ nmcli device wifi list
*  SSID               MODE    CHAN  RATE       SIGNAL  BARS  SECURITY
   netdatacomm_local  Infra   6     54 Mbit/s  37      ▂▄__  WEP
*  F1                 Infra   11    54 Mbit/s  98      ▂▄▆█  WPA1
   LoremCorp          Infra   1     54 Mbit/s  62      ▂▄▆_  WPA2 802.1X
   Internet           Infra   6     54 Mbit/s  29      ▂___  WPA1
   HPB110a.F2672A     Ad-Hoc  6     54 Mbit/s  22      ▂___  --
   Jozinet            Infra   1     54 Mbit/s  19      ▂___  WEP
   VOIP               Infra   1     54 Mbit/s  20      ▂___  WEP
   MARTINA            Infra   4     54 Mbit/s  32      ▂▄__  WPA2
   N24PU1             Infra   7     11 Mbit/s  22      ▂___  --
   alfa               Infra   1     54 Mbit/s  67      ▂▄▆_  WPA2
   bertnet            Infra   5     54 Mbit/s  20      ▂___  WPA1 WPA2

Example 2. Showing general information and properties for a Wi-Fi interface

$ nmcli -p -f general,wifi-properties device show wlan0
===========================================================================
Device details (wlan0)
===========================================================================
GENERAL.DEVICE:           wlan0
GENERAL.TYPE:             wifi
GENERAL.VENDOR:           Intel Corporation
GENERAL.PRODUCT:          PRO/Wireless 5100 AGN [Shiloh] Network Connection
GENERAL.DRIVER:           iwlwifi
GENERAL.DRIVER-VERSION:   3.8.13-100.fc17.x86_64
GENERAL.FIRMWARE-VERSION: 8.83.5.1 build 33692
GENERAL.HWADDR:           00:1E:65:37:A1:D3
GENERAL.MTU:              1500
GENERAL.STATE:            100 (connected)
GENERAL.REASON:           0 (No reason given)
GENERAL.UDI:              /sys/devices/pci0000:00/0000:00:1c.1/net/wlan0
GENERAL.IP-IFACE:         wlan0
......

Example 3. Listing NetworkManager polkit permissions

$ nmcli general permissions
PERMISSION                                                VALUE
org.freedesktop.NetworkManager.enable-disable-network     yes
org.freedesktop.NetworkManager.enable-disable-wifi        yes
org.freedesktop.NetworkManager.enable-disable-wwan        yes
org.freedesktop.NetworkManager.enable-disable-wimax       yes
......

Example 4. Listing NetworkManager log level and domains

$ nmcli general logging
LEVEL  DOMAINS
INFO   PLATFORM,RFKILL,ETHER,WIFI,BT,MB,DHCP4,DHCP6,PPP,WIFI_SCAN,IP4,IP6,A
UTOIP4,DNS,VPN,SHARING,SUPPLICANT,AGENTS,SETTINGS,SUSPEND,CORE,DEVICE,OLPC,
WIMAX,INFINIBAND,FIREWALL,ADSL,BOND,VLAN,BRIDGE,DBUS_PROPS,TEAM,CONCHECK,DC
B,DISPATCH

Example 5. Changing NetworkManager logging

$ nmcli g log level DEBUG domains CORE,ETHER,IP
$ nmcli g log level INFO domains DEFAULT

Example 6. Activating a VPN connection profile requiring interactive password input

$ nmcli --ask con up my-vpn-con

Example 7. Adding a bonding master and two slave connection profiles

$ nmcli con add type bond ifname mybond0 mode active-backup
$ nmcli con add type ethernet ifname eth1 master mybond0
$ nmcli con add type ethernet ifname eth2 master mybond0

Example 8. Adding a team master and two slave connection profiles

$ nmcli con add type team con-name Team1 ifname Team1 config team1-master-json.con
f
$ nmcli con add type ethernet con-name Team1-slave1 ifname em1 master Team1
$ nmcli con add type ethernet con-name Team1-slave2 ifname em2 master Team1
$ nmcli con up Team1-slave1
$ nmcli con up Team1-slave2

Example 9. Adding a bridge and two slave profiles

$ nmcli con add type bridge con-name TowerBridge ifname TowerBridge
$ nmcli con add type ethernet con-name br-slave-1 ifname ens3 master TowerBridge
$ nmcli con add type ethernet con-name br-slave-2 ifname ens4 master TowerBridge
$ nmcli con modify TowerBridge bridge.stp no

Example 10. Adding an ethernet connection profile with manual IP configuration

$ nmcli con add con-name my-con-em1 ifname em1 type ethernet \
  ip4 192.168.100.100/24 gw4 192.168.100.1 ip4 1.2.3.4 ip6 abbe::cafe
$ nmcli con mod my-con-em1 ipv4.dns "8.8.8.8 8.8.4.4"
$ nmcli con mod my-con-em1 +ipv4.dns 1.2.3.4
$ nmcli con mod my-con-em1 ipv6.dns "2001:4860:4860::8888 2001:4860:4860::8844"
$ nmcli -p con show my-con-em1

Example 11. Convenient field values retrieval for scripting

$ nmcli -g ip4.address connection show my-con-eth0
  192.168.1.12/24

$ nmcli -g ip4.address,ip4.dns connection show my-con-eth0
  192.168.1.12/24
  192.168.1.1

$ nmcli -g ip4 connection show my-con-eth0
  IP4:192.168.1.12/24:192.168.1.1::192.168.1.1::

Example 12. Adding an Ethernet connection and configuring SR-IOV VFs

$ nmcli con add type ethernet con-name EthernetPF ifname em1
$ nmcli con modify EthernetPF sriov.total-vfs 3 sriov.autoprobe-drivers false
$ nmcli con modify EthernetPF sriov.vfs '0 mac=00:11:22:33:44:55 vlans=10, 1 trust\
  =true spoof-check=false'
$ nmcli con modify EthernetPF +sriov.vfs '2 max-tx-rate=20'

Example 13. Escaping colon characters in tabular mode

$ nmcli -t -f general -e yes -m tab dev show eth0
GENERAL:eth0:ethernet:Intel Corporation:82567LM Gigabit Network Connection:
e1000e:2.1.4-k:1.8-3:00\:22\:68\:15\:29\:21:1500:100 (connected):0 (No reas
on given):/sys/devices/pci0000\:00/0000\:00\:19.0/net/eth0:eth0:yes:yes:no:
ethernet-13:89cbcbc6-dc85-456c-9c8b-bd828fee3917:/org/freedesktop/NetworkMa
nager/ActiveConnection/9

Example 14. nmcli usage in a NetworkManager dispatcher script to make Ethernet and Wi-Fi mutually exclusive

#!/bin/bash
export LC_ALL=C

enable_disable_wifi ()
{
    result=$(nmcli dev | grep "ethernet" | grep -w "connected")
    if [ -n "$result" ]; then
        nmcli radio wifi off
    else
        nmcli radio wifi on
    fi
}

if [ "$2" = "up" ]; then
    enable_disable_wifi
fi

if [ "$2" = "down" ]; then
    enable_disable_wifi
fi

This dispatcher script makes Wi-Fi mutually exclusive with wired networking. When a wired interface is connected, Wi-Fi will be set to airplane mode (rfkilled). When the wired interface is disconnected, Wi-Fi will be turned back on. Name this script e.g. 70-wifi-wired-exclusive.sh and put it into /etc/NetworkManager/dispatcher.d/ directory. See NetworkManager(8) manual page for more information about NetworkManager dispatcher scripts.
标签云