长期支持版本

    社区创新版本

      配置网络

      配置 IP

      使用nmcli命令

      说明:
      使用nmcli命令配置的网络配置可以立即生效且系统重启后配置也不会丢失。

      nmcli介绍

      nmcli是NetworkManager的一个命令行工具,它提供了使用命令行配置由NetworkManager管理网络连接的方法。nmcli命令的基本格式为:

       nmcli [OPTIONS] OBJECT { COMMAND | help }
      

      其中,OBJECT选项可以是general、networking、radio、connection或device等。在日常使用中,最常使用的是-t, --terse(用于脚本)、-p, --pretty选项(用于用户)及-h, --help选项,用户可以使用“ nmcli help”获取更多参数及使用信息。

      $ nmcli help
      

      常用命令使用举例如下:

      • 显示NetworkManager状态:

        $ nmcli general status
        
      • 显示所有连接:

        $ nmcli connection show
        
      • 只显示当前活动连接,如下所示添加 -a, --active:

        $ nmcli connection show --active
        
      • 显示由NetworkManager识别到的设备及其状态:

        $ nmcli device status
        
      • 使用nmcli工具启动和停止网络接口,在root权限下执行如下命令:

        # nmcli connection up id enp3s0
        # nmcli device disconnect enp3s0
        

      设备管理

      连接到设备

      使用如下命令,NetworkManager将连接到对应网络设备,尝试找到合适的连接配置,并激活配置。

      $nmcli device connect "$IFNAME"  
      

      说明:

      如果不存在相应的配置连接,NetworkManager将创建并激活具有默认设置的新配置文件。

      断开设备连接

      使用如下命令,NetworkManager将断开设备连接,并防止设备自动激活。

      $nmcli device disconnect "$IFNAME"  
      

      设置网络连接

      列出目前可用的网络连接:

      $ nmcli con show
      
      
      NAME    UUID                                  TYPE      DEVICE
      enp4s0  5afce939-400e-42fd-91ee-55ff5b65deab  ethernet  enp4s0
      enp3s0  c88d7b69-f529-35ca-81ab-aa729ac542fd  ethernet  enp3s0
      virbr0  ba552da6-f014-49e3-91fa-ec9c388864fa  bridge    virbr0
      

      说明:
      输出结果中的NAME字段代表连接ID(名称)。

      添加一个网络连接会生成相应的配置文件,并与相应的设备关联。检查可用的设备,方法如下:

      $ nmcli dev status
      
      DEVICE      TYPE      STATE      CONNECTION
      enp3s0      ethernet  connected  enp3s0
      enp4s0      ethernet  connected  enp4s0
      virbr0      bridge    connected  virbr0
      lo          loopback  unmanaged  --
      virbr0-nic  tun       unmanaged  --
      
      配置动态IP连接
      配置IP

      要使用 DHCP 分配网络时,可以使用动态IP配置添加网络配置文件,命令格式如下:

      nmcli connection add type ethernet con-name connection-name ifname interface-name
      

      例如创建名为net-test的动态连接配置文件,在root权限下使用以下命令:

      # nmcli connection add type ethernet con-name net-test ifname enp3s0
      Connection 'net-test' (a771baa0-5064-4296-ac40-5dc8973967ab) successfully added.
      

      NetworkManager 会将参数 connection.autoconnect 设定为 yes,并将设置保存到 “/etc/sysconfig/network-scripts/ifcfg-net-test”文件中,在该文件中会将 ONBOOT 设置为 yes。

      激活连接并检查状态

      在root权限下使用以下命令激活网络连接:

      # nmcli con up net-test 
      Connection successfully activated (D-Bus active path:/org/freedesktop/NetworkManager/ActiveConnection/5)
      

      检查这些设备及连接的状态,使用以下命令:

      $ nmcli device status
      
      DEVICE      TYPE      STATE      CONNECTION
      enp4s0      ethernet  connected  enp4s0
      enp3s0      ethernet  connected  net-test
      virbr0      bridge    connected  virbr0
      lo          loopback  unmanaged  --
      virbr0-nic  tun       unmanaged  --
      
      配置静态IP连接
      配置IP

      添加静态 IPv4 配置的网络连接,可使用以下命令:

      nmcli connection add type ethernet con-name connection-name ifname interface-name ip4 address gw4 address
      

      说明:
      如果要添加 IPv6 地址和网关信息,使用 ip6 和 gw6 选项。

      例如创建名为 net-static的静态连接配置文件,在root权限下使用以下命令:

      # nmcli con add type ethernet con-name net-static ifname enp3s0 ip4 192.168.0.10/24 gw4 192.168.0.254
      

      还可为该设备同时指定 IPv6 地址和网关,示例如下:

      # nmcli con add type ethernet con-name test-lab ifname enp3s0 ip4 192.168.0.10/24 gw4 192.168.0.254 ip6 abbe::**** gw6 2001:***::*
      Connection 'net-static' (63aa2036-8665-f54d-9a92-c3035bad03f7) successfully added.
      

      NetworkManager 会将其内部参数 ipv4.method 设定为 manual,将 connection.autoconnect 设定为yes,并将设置写入 /etc/sysconfig/network-scripts/ifcfg-my-office 文件,其中会将对应 BOOTPROTO 设定为 none,将 ONBOOT 设定为 yes。

      设定两个 IPv4 DNS 服务器地址,在root权限下使用以下命令:

      # nmcli con mod net-static ipv4.dns "*.*.*.* *.*.*.*"
      

      设置两个 IPv6 DNS 服务器地址,在root权限下使用以下命令:

      # nmcli con mod net-static ipv6.dns "2001:4860:4860::**** 2001:4860:4860::****"
      
      激活连接并检查状态

      激活新的网络连接,在root权限下使用以下命令:

      # nmcli con up net-static ifname enp3s0
      Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/6)
      

      检查这些设备及连接的状态,使用以下命令:

      $ nmcli device status
      
      DEVICE      TYPE      STATE      CONNECTION
      enp4s0      ethernet  connected  enp4s0
      enp3s0      ethernet  connected  net-static
      virbr0      bridge    connected  virbr0
      lo          loopback  unmanaged  --
      virbr0-nic  tun       unmanaged  --
      

      查看配置的连接详情,使用以下命令(使用 -p, --pretty 选项在输出结果中添加标题和分段):

      $ nmcli -p con show net-static 
      ===============================================================================
      Connection profile details (net-static )
      ===============================================================================
      connection.id:                          net-static
      connection.uuid:                        b9f18801-6084-4aee-af28-c8f0598ff5e1
      connection.stable-id:                   --
      connection.type:                        802-3-ethernet
      connection.interface-name:              enp3s0
      connection.autoconnect:                 yes
      connection.autoconnect-priority:        0
      connection.autoconnect-retries:         -1 (default)
      connection.multi-connect:               0 (default)
      connection.auth-retries:                -1
      connection.timestamp:                   1578988781
      connection.read-only:                   no
      connection.permissions:                 --
      connection.zone:                        --
      connection.master:                      --
      connection.slave-type:                  --
      connection.autoconnect-slaves:          -1 (default)
      connection.secondaries:                 --
      connection.gateway-ping-timeout:        0
      connection.metered:                     unknown
      connection.lldp:                        default
      connection.mdns:                        -1 (default)
      connection.llmnr:                       -1 (default)
      
      添加 Wi-Fi 连接

      有两种方式添加Wi-Fi 连接。

      方法1,通过网络接口连接wifi

      连接到由SSID或BSSID指定的wifi网络。命令如下,该命令找到匹配的连接或创建一个连接,然后在设备上激活它。

      $ nmcli device wifi connect "$SSID" password "$PASSWORD" ifname "$IFNAME"  
      $ nmcli --ask device wifi connect "$SSID" 
      

      方法2,通过配置文件连接Wi-Fi

      1,使用以下命令查看可用 Wi-Fi 访问点:

      $ nmcli dev wifi list
      

      2,使用以下命令生成使用的静态 IP 配置,但允许自动 DNS 地址分配的 Wi-Fi 连接:

      $ nmcli con add con-name Wifi ifname wlan0 type wifi ssid MyWifi ip4 192.168.100.101/24 gw4 192.168.100.1
      

      3,请使用以下命令设定 WPA2 密码,例如 “answer”:

      $ nmcli con modify Wifi wifi-sec.key-mgmt wpa-psk
      $ nmcli con modify Wifi wifi-sec.psk answer
      

      4,使用以下命令更改 Wi-Fi 状态:

      $ nmcli radio wifi [ on | off ]
      
      更改属性

      请使用以下命令检查具体属性,比如 mtu:

      $ nmcli connection show id 'Wifi ' | grep mtu
      802-11-wireless.mtu: auto
      

      使用如下命令更改设置的属性:

      $ nmcli connection modify id 'Wifi ' 802-11-wireless.mtu 1350
      

      使用如下命令确认更改:

      $ nmcli connection show id 'Wifi ' | grep mtu
      802-11-wireless.mtu: 1350
      

      配置静态路由

      • 使用nmcli命令为网络连接配置静态路由,使用命令如下:

        $ nmcli connection modify enp3s0 +ipv4.routes "192.168.122.0/24 10.10.10.1"
        
      • 使用编辑器配置静态路由,使用如下命令:

        $ nmcli con edit type ethernet con-name enp3s0
        ===| nmcli interactive connection editor |===
        Adding a new '802-3-ethernet' connection
        Type 'help' or '?' for available commands.
        Type 'describe [<setting>.<prop>]' for detailed property description.
        You may edit the following settings: connection, 802-3-ethernet (ethernet), 802-1x, ipv4, ipv6, dcb
        nmcli> set ipv4.routes 192.168.122.0/24 10.10.10.1
        nmcli>
        nmcli> save persistent
        Saving the connection with 'autoconnect=yes'. That might result in an immediate activation of the connection.
        Do you still want to save? [yes] yes
        Connection 'enp3s0' (1464ddb4-102a-4e79-874a-0a42e15cc3c0) successfully saved.
        nmcli> quit
        
      • 使用如下命令激活连接以生效配置:

        $ nmcli con up enp3s0
        

      使用ip命令

      说明:
      使用ip命令配置的网络配置可以立即生效但系统重启后配置会丢失。

      配置IP地址

      使用ip命令为接口配置地址,命令格式如下,其中 interface-name 为网卡名称。

      ip addr [ add | del ] address dev interface-name
      
      配置静态地址

      在root权限下,配置静态IP地址,使用示例如下:

      # ip address add 192.168.0.10/24 dev enp3s0
      

      查看配置结果,在root权限使用如下命令:

      # ip addr show dev enp3s0
      2: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
          link/ether 52:54:00:aa:ad:4a brd ff:ff:ff:ff:ff:ff
          inet 192.168.202.248/16 brd 192.168.255.255 scope global dynamic noprefixroute enp3s0
             valid_lft 9547sec preferred_lft 9547sec
          inet 192.168.0.10/24 scope global enp3s0
             valid_lft forever preferred_lft forever
          inet6 fe80::32e8:cc22:9db2:f4d4/64 scope link noprefixroute
             valid_lft forever preferred_lft forever
      
      配置多个地址

      ip 命令支持为同一接口分配多个地址,可在root权限下重复多次使用 ip 命令实现分配多个地址。使用示例如下:

      # ip address add 192.168.2.223/24 dev enp4s0
      # ip address add 192.168.4.223/24 dev enp4s0
      # ip addr
      
      3: enp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
          link/ether 52:54:00:aa:da:e2 brd ff:ff:ff:ff:ff:ff
          inet 192.168.203.12/16 brd 192.168.255.255 scope global dynamic noprefixroute enp4s0
             valid_lft 8389sec preferred_lft 8389sec
          inet 192.168.2.223/24 scope global enp4s0
             valid_lft forever preferred_lft forever
          inet 192.168.4.223/24 scope global enp4s0
             valid_lft forever preferred_lft forever
          inet6 fe80::1eef:5e24:4b67:f07f/64 scope link noprefixroute
             valid_lft forever preferred_lft forever
      

      配置静态路由

      如果需要静态路由,可使用 ip route add 命令在路由表中添加,使用 ip route del 命令删除。最常使用的 ip route 命令格式如下:

      ip route [ add | del | change | append | replace ] destination-address
      

      在root权限下使用 ip route 命令显示当前的 IP 路由表。示例如下:

      # ip route
      
      default via 192.168.0.1 dev enp3s0 proto dhcp metric 100
      default via 192.168.0.1 dev enp4s0 proto dhcp metric 101
      192.168.0.0/16 dev enp3s0 proto kernel scope link src 192.168.202.248 metric 100
      192.168.0.0/16 dev enp4s0 proto kernel scope link src 192.168.203.12 metric 101
      192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
      

      在主机地址中添加一个静态路由,在 root 权限下,使用以下命令格式:

      ip route add 192.168.2.1 via 10.0.0.1 [dev interface-name]
      

      其中 192.168.2.1 是用点分隔的十进制符号中的 IP 地址,10.0.0.1 是下一个跃点,interface-name 是进入下一个跃点的退出接口。

      要在网络中添加一个静态路由,即代表 IP 地址范围的 IP 地址,请在root权限下运行以下命令格式:

      ip route add 192.168.2.0/24 via 10.0.0.1 [dev interface-name]
      

      其中 192.168.2.1 是目标网络的 IP 地址,10.0.0.1 是网络前缀,interface-name 为网卡名称。

      通过ifcfg文件配置网络

      说明:
      通过ifcfg文件配置的网络配置不会立即生效,修改文件后(以ifcfg-enp3s0为例),需要在root权限下执行nmcli con reload;nmcli con up enp3s0命令以重新加载配置文件并激活连接才生效。

      配置静态网络

      以enp4s0网络接口进行静态网络设置为例,通过在root权限下修改ifcfg文件实现,在/etc/sysconfig/network-scripts/目录中生成名为ifcfg-enp4s0的文件中,修改参数配置,示例如下:

      TYPE=Ethernet
      PROXY_METHOD=none
      BROWSER_ONLY=no
      BOOTPROTO=none
      IPADDR=192.168.0.10
      PREFIX=24
      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=enp4s0static
      UUID=08c3a30e-c5e2-4d7b-831f-26c3cdc29293
      DEVICE=enp4s0
      ONBOOT=yes
      

      配置动态网络

      要通过ifcfg文件为em1接口配置动态网络,请按照如下操作在/etc/sysconfig/network-scripts/目录中生成名为 ifcfg-em1 的文件,示例如下:

      DEVICE=em1
      BOOTPROTO=dhcp
      ONBOOT=yes
      

      要配置一个向DHCP服务器发送不同的主机名的接口,请在ifcfg文件中新增一行内容,如下所示:

      DHCP_HOSTNAME=hostname
      

      要配置忽略由DHCP服务器发送的路由,防止网络服务使用从DHCP服务器接收的DNS服务器更新/etc/resolv.conf。请在ifcfg文件中新增一行内容,如下所示:

      PEERDNS=no
      

      要配置一个接口使用具体DNS服务器,请将参数PEERDNS=no,并在ifcfg文件中添加以下行:

      DNS1=ip-address
      DNS2=ip-address
      

      其中ip-address是DNS服务器的地址。这样就会让网络服务使用指定的DNS服务器更新/etc/resolv.conf。

      配置默认网关

      在确定默认网关时,首先解析 /etc/sysconfig/network 文件,然后解析 ifcfg 文件 ,将最后读取的 GATEWAY 的取值作为路由表中的默认路由。

      在动态网络环境中,使用 NetworkManager 管理主机时,建议设置为由 DHCP 来分配。

      配置主机名

      简介

      hostname有三种类型:static、transient和pretty。

      • static:静态主机名,可由用户自行设置,并保存在/etc/hostname 文件中。
      • transient:动态主机名,由内核维护,初始是 static 主机名,默认值为“localhost”。可由DHCP或mDNS在运行时更改。
      • pretty:灵活主机名,允许使用自由形式(包括特殊/空白字符)进行设置。静态/动态主机名遵从域名的通用限制。

      说明:
      static和transient主机名只能包含a-z、A-Z、0-9、“-”、“_”和“.”,不能在开头或结尾处使用句点,不允许使用两个相连的句点,大小限制为 64 个字符。

      使用hostnamectl配置主机名

      查看所有主机名

      查看当前的主机名,使用如下命令:

      $ hostnamectl status
      

      说明:
      如果命令未指定任何选项,则默认使用status选项。

      设定所有主机名

      在root权限下,设定系统中的所有主机名,使用如下命令:

      # hostnamectl set-hostname name
      

      设定特定主机名

      在root权限下,通过不同的参数来设定特定主机名,使用如下命令:

      # hostnamectl set-hostname name [option...]
      

      其中option可以是--pretty、--static、--transient中的一个或多个选项。

      如果--static或--transient与--pretty选项一同使用时,则会将static和transient主机名简化为pretty主机名格式,使用“-”替换空格,并删除特殊字符。

      当设定pretty主机名时,如果主机名中包含空格或单引号,需要使用引号。命令示例如下:

      # hostnamectl set-hostname "Stephen's notebook" --pretty
      

      清除特定主机名

      要清除特定主机名,并将其还原为默认形式,在root权限下,使用如下命令:

      # hostnamectl set-hostname "" [option...]
      

      其中 "" 是空白字符串,option是--pretty、--static和--transient中的一个或多个选项。

      远程更改主机名

      在远程系统中运行hostnamectl命令时,要使用-H,--host 选项,在root权限下使用如下命令:

      # hostnamectl set-hostname -H [username]@hostname new_hostname
      

      其中hostname是要配置的远程主机,username为自选项,new_hostname为新主机名。hostnamectl会通过SSH连接到远程系统。

      使用nmcli配置主机名

      查询static主机名,使用如下命令:

      $ nmcli general hostname
      

      在root权限下,将static主机名设定为host-server,使用如下命令:

      # nmcli general hostname host-server
      

      要让系统hostnamectl感知到static主机名的更改,在root权限下,重启hostnamed服务,使用如下命令:

      # systemctl restart systemd-hostnamed
      

      配置网络绑定

      使用nmcli

      • 创建名为mybond0的绑定,使用示例如下:

        $ nmcli con add type bond con-name mybond0 ifname mybond0 mode active-backup
        
      • 添加从属接口,使用示例如下:

        $ nmcli con add type bond-slave ifname enp3s0 master mybond0
        

        要添加其他从属接口,重复上一个命令,并在命令中使用新的接口,使用示例如下:

        $ nmcli con add type bond-slave ifname enp4s0 master mybond0
        Connection 'bond-slave-enp4s0' (05e56afc-b953-41a9-b3f9-0791eb49f7d3) successfully added.
        
      • 要启动绑定,则必须首先启动从属接口,使用示例如下:

        $ nmcli con up bond-slave-enp3s0
        Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/14)
        
        $ nmcli con up bond-slave-enp4s0
        Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/15)
        

        现在可以启动绑定,使用示例如下:

        $ nmcli con up mybond0
        Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/16)
        

      使用命令行

      检查是否已安装Bonding内核模块

      在系统中默认已加载相应模块。要载入绑定模块,可在root权限下使用如下命令:

      # modprobe --first-time bonding
      

      显示该模块的信息,可在root权限下使用如下命令:

      # modinfo bonding
      

      更多命令请在root权限下使用modprobe --help查看。

      创建频道绑定接口

      要创建绑定接口,可在root权限下通过在 /etc/sysconfig/network-scripts/ 目录中创建名为 ifcfg-bondN 的文件(使用接口号码替换 N,比如 0)。

      根据要绑定接口类型的配置文件来编写相应的内容,比如网络接口。接口配置文件示例如下:

      DEVICE=bond0
      NAME=bond0
      TYPE=Bond
      BONDING_MASTER=yes
      IPADDR=192.168.1.1
      PREFIX=24
      ONBOOT=yes
      BOOTPROTO=none
      BONDING_OPTS="bonding parameters separated by spaces"
      

      创建从属接口

      创建频道绑定接口后,必须在从属接口的配置文件中添加 MASTER 和 SLAVE 指令。

      例如将两个网络接口enp3s0 和 enp4s0 以频道方式绑定,其配置文件示例分别如下:

      TYPE=Ethernet
      NAME=bond-slave-enp3s0
      UUID=3b7601d1-b373-4fdf-a996-9d267d1cac40
      DEVICE=enp3s0
      ONBOOT=yes
      MASTER=bond0
      SLAVE=yes
      
      TYPE=Ethernet
      NAME=bond-slave-enp4s0
      UUID=00f0482c-824f-478f-9479-abf947f01c4a
      DEVICE=enp4s0
      ONBOOT=yes
      MASTER=bond0
      SLAVE=yes
      

      激活频道绑定

      要激活绑定,则需要启动所有从属接口。请在root权限下,运行以下命令:

      # ifup enp3s0
      Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/7)
      
      # ifup enp4s0
      Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/8)
      

      说明:
      对于已经处于“up”状态的接口,请首先使用“ifdown enp3s0 ”命令修改状态为down,其中 enp3s0 为实际网卡名称。

      完成后,启动所有从属接口以便启动绑定(不将其设定为 “down”)。

      要让 NetworkManager 感知到系统所做的修改,在每次修改后,请在root权限下,运行以下命令:

      # nmcli con load /etc/sysconfig/network-scripts/ifcfg-device
      

      查看绑定接口的状态,请在root权限下运行以下命令:

      # 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: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
          link/ether 52:54:00:aa:ad:4a brd ff:ff:ff:ff:ff:ff
      3: enp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
          link/ether 52:54:00:aa:da:e2 brd ff:ff:ff:ff:ff:ff
      4: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000
          link/ether 86:a1:10:fb:ef:07 brd ff:ff:ff:ff:ff:ff
      5: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN mode DEFAULT group default qlen 1000
          link/ether 52:54:00:29:35:4c brd ff:ff:ff:ff:ff:ff
      

      创建多个绑定

      系统会为每个绑定创建一个频道绑定接口,包括 BONDING_OPTS 指令。使用这个配置方法可让多个绑定设备使用不同的配置。请按照以下操作创建多个频道绑定接口:

      • 创建多个 ifcfg-bondN 文件,文件中包含 BONDING_OPTS 指令,让网络脚本根据需要创建绑定接口。
      • 创建或编辑要绑定的现有接口配置文件,添加 SLAVE 指令。
      • 使用 MASTER 指令工具在频道绑定接口中分配要绑定的接口,即从属接口。

      以下是频道绑定接口配置文件示例:

      DEVICE=bondN
      NAME=bondN
      TYPE=Bond
      BONDING_MASTER=yes
      IPADDR=192.168.1.1
      PREFIX=24
      ONBOOT=yes
      BOOTPROTO=none
      BONDING_OPTS="bonding parameters separated by spaces"
      

      在这个示例中,使用绑定接口的号码替换 N。例如要创建两个接口,则需要使用正确的 IP 地址创建两个配置文件 ifcfg-bond0 和 ifcfg-bond1。

      IPv6使用差异说明(vs IPv4)

      约束限制

      • chrony支持全局地址(global address),不支持链路本地地址(link-local address)。
      • Firefox支持通过http/https协议访问全局地址(global address),不支持链路本地地址(link-local address)。

      配置说明

      设置接口设备MTU值

      概述

      IPv6场景中会发现整个路由路径中的最小mtu的值作为当前链接的PMTU的值,源端根据PMTU的值确定是否进行分片发送,而在整个路径中的其它设备将不再需要进行分片处理,从而可以降低中间路由设备的负载大小。其中IPv6 PMTU设置的最小值为1280。

      设置接口设备的mtu

      如果在配置了IPv6地址的接口上设置mtu的值小于1280(IPv6 PMTU设置的最小值),则会导致该接口的IPv6地址被删除。并且无法再次添加IPv6地址。所以在IPv6场景中,对接口设备的mtu的配置一定要大于等于1280。 请在root权限下运行如下命令查看具体现象:

      # ip addr show enp3s0
      3: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
          link/ether 52:54:00:62:xx:xx brd ff:ff:ff:ff:xx:xx
          inet 10.41.125.236/16 brd 10.41.255.255 scope global noprefixroute dynamic enp3s0
             valid_lft 38663sec preferred_lft 38663sec
          inet6 2001:222::2/64 scope global
             valid_lft forever preferred_lft forever
      
      # ip link set dev enp3s0 mtu 1200
      # ip addr show enp3s0
      3: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1200 qdisc pfifo_fast state UP group default qlen 1000
          link/ether 52:54:00:62:xx:xx brd ff:ff:ff:ff:xx:xx
          inet 10.41.125.236/16 brd 10.41.255.255 scope global noprefixroute dynamic enp3s0
             valid_lft 38642sec preferred_lft 38642sec
      
      # ip addr add 2001:222::2/64 dev enp3s0
      RTNETLINK answers: No buffer space available
      
      # ip link set dev enp3s0 mtu 1500
      # ip addr show enp3s0
      3: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
          link/ether 52:54:00:62:xx:xx brd ff:ff:ff:ff:xx:xx
          inet 10.41.125.236/16 brd 10.41.255.255 scope global noprefixroute dynamic enp3s0
             valid_lft 38538sec preferred_lft 38538sec
      
      # ip addr add 2001:222::2/64 dev enp3s0
      # ip addr show enp3s0
      3: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
          link/ether 52:54:00:62:xx:xx brd ff:ff:ff:ff:xx:xx
          inet 10.41.125.236/16 brd 10.41.255.255 scope global noprefixroute dynamic enp3s0
             valid_lft 38531sec preferred_lft 38531sec
          inet6 2001:222::2/64 scope global
             valid_lft forever preferred_lft forever
      

      有状态自动配置IPv6地址

      概述

      IPv6与IPv4都可以在root权限下通过DHCP的方式获得IP地址。IPv6地址有两种配置方式:无状态自动配置和有状态自动配置。

      • 无状态自动配置

        不需要DHCP服务进行管理,设备根据网络RA(路由公告)获得网络前缀,或者link-local地址为固定fe80::。而接口ID则根据ifcfg配置IPV6_ADDR_GEN_MODE的具体设置来进行自动获得:

        1. IPv6_ADDR_GEN_MODE="stable-privacy" 则根据设备及网络环境来确定一个随机接口ID。
        2. IPv6_ADDR_GEN_MODE="EUI64" 则根据设备MAC地址来确定接口ID。
      • 有状态自动配置:需要DHCP服务器进行管理分配,服从DHCPv6协议来从DHCPv6服务器端租赁IPv6地址。

        在有状态自动配置IPv6地址时,DHCPv6服务端可以通过客户端设置的vendor class将客户端进行分类,不同类别分配不同地址段的IPv6地址。在IPv4场景中,客户端可以直接用dhclient的-V选项来设置vendor-class-identifier,DHCP服务端在配置文件中根据vendor-class-identifier来对客户端进行分类处理。而IPv6场景中,如果使用同样的方法对客户端分类,则分类并不会生效。

        dhclient -6 <interface> -V <vendor-class-identifier string> <interface>
        

        这是由于DHCPv6和DHCP协议存在较大差异,DHCPv6的可选项中使用vendor-class-option替代了DHCP中的vendor-class-identifier。而dhclient的-V选项并不能设置vendor-class-option。

      有状态自动配置IPv6地址时dhclient设置vendor class方法
      • 在客户端使用配置文件方式添加对vendor class的设置,使用方法如下:

        客户端配置文件(/etc/dhcp/dhclient6.conf),文件位置可以自定义,在使用时需要通过dhclient -cf选项来指定配置文件:

        option dhcp6.vendor-class code 16 = {integer 32, integer 16, string};
        interface "enp3s0" {
                send dhcp6.vendor-class <Enterprise-ID number> <vendor class string length> <vendor class string>;
        }
        

        说明:

        • <Enterprise-ID number>,32位整型数字,企业标识号,企业通过IANA注册。
        • <vendor class string length>,16位整型数字,vendor class字符串长度。
        • <vendor class string>,要设置的vendor class字符串,例如:“HWHW”。

        客户端使用方法:

        dhclient -6 <interface> -cf /etc/dhcp/dhclient6.conf
        
      • DHCPv6服务端配置文件(/etc/dhcp/dhcpd6.conf),需要dhcpd -cf选项来指定该配置文件:

        option dhcp6.vendor-class code 16 = {integer 32, integer 16, string};
        subnet6 fc00:4:12:ffff::/64 {
                class "hw" {
                        match if substring ( option dhcp6.vendor-class, 6, 10 ) = "HWHW";
                }
                pool6 {
                        allow members of "hw";
                        range6 fc00:4:12:ffff::ff10 fc00:4:12:ffff::ff20;
                }
                pool6 {
                        allow unknown clients;
                        range6 fc00:4:12:ffff::100 fc00:4:12:ffff::120;
                }
        }
        

        说明:
        substring ( option dhcp6.vendor-class, 6, 10 ) 其中子字符串的开始位置为6,因为前面包含4个字节的<Enterprise-ID number>和2个字节的<string length>。而子字符串的结束位置为:6+<vendor class string length>。这里vendor class string为“HWHW”,字符串的长度为4,所以子字符串的结束位置为6+4=10。用户可以根据实际需要来确定<vendor class string>及相应的<vendor class string length>。

        服务端使用方法:

        dhcpd -6 -cf /etc/dhcp/dhcpd6.conf <interface>
        

      内核支持socket相关系统调用

      概述

      IPv6地址长度扩展到128比特,所以有足够的IPv6地址可供分配使用。同时IPv6头相比IPv4头进行了简化,并增强了IPv6的自动配置功能。IPv6地址分为单播地址,组播地址和任意播地址。常用的单播地址又包含:链路本地地址(link-local address),唯一本地地址(Unique local address)和全局地址(global address)。由于IPv6的全局地址十分充足,唯一本地地址一般不被使用(其前身为站点本地地址(site-local address),已于2004年被废弃)。当前主要使用的单播地址为:链路本地地址(link-local address)和全局地址(global address)。当前内核支持socket系统调用,在使用单播地址的链路本地地址和全局地址时存在差异。

      RFC 2553: Basic Socket Interface Extensions for IPv6 定义sockaddr_in6的数据结构如下;

      struct sockaddr_in6 {     
          uint8_t         sin6_len;       /* length of this struct */     
          sa_family_t     sin6_family;    /* AF_INET6 */     
          in_port_t       sin6_port;      /* transport layer port # */     
          uint32_t        sin6_flowinfo;  /* IPv6 flow information */     
          struct in6_addr sin6_addr;      /* IPv6 address */     
          uint32_t        sin6_scope_id;  /* set of interfaces for a scope */ 
      }; 
      

      说明:
      sin6_scope_id: 32位整型,对于链路本地地址(link-local address),对于链路范围的sin6_addr,它可以用来标识指定的接口索引号。如果是站点范围的sin6_addr,则用来作为站点的标识符(站点本地地址已被抛弃)。

      在使用link-local地址进行socket通信时,在构造目的地址时,需要指定该地址所对应的接口索引号。一般可以通过if_nametoindex函数将接口名转化为接口索引号。具体方式如下,

      int port = 1234;
      int sk_fd;
      int iff_index = 0;
      char iff_name[100] = "enp3s0";
      char * ll_addr[100] = "fe80::123:456:789";
      struct sockaddr_in6 server_addr;
      
      memset(&server_addr,0,sizeof(structsockaddr_in6));
      iff_index=if_nametoindex(iff_name);
      
      server_addr.sin6_family=AF_INET6;
      server_addr.sin6_port=htons(port);
      server_addr.sin6_scope_id=iff_index;
      inet_pton(AF_INET6, ll_addr, &(server_addr.sin6_addr));
      
      sk_fd=socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
      connect(sk_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in6));
      

      IPv4的dhclient守护进程持久化配置

      概述

      通过NetworkManager服务来管理网络服务时,如果接口ifcfg-<interface-name>配置文件中配置了DHCP方式获得IP地址,则相应地NetworkManager服务会拉起dhclient守护进程来通过DHCP协议方式来从DHCP服务器获取IP地址。

      dhclient提供了"-1"选项来决定dhclient进程在未获得DHCP服务响应时,是会不断持久化尝试请求地址还是会尝试时间超时后退出。针对IPv4的dhclient守护进程,可以在ifcfg-<interface-name>配置文件中设置PERSISTENT_DHCLIENT来决定是否设置IPv4的dhclient进程的持久化。

      约束限制
      1. 当dhclient进程在运行中被杀死,network服务无法自动将其拉起,可靠性需要用户自己保障。
      2. 配置了持久化选项PERSISTENT_DHCLIENT,需要确保有相应的DHCP服务器。如果在拉起network时无可用DHCP服务器,dhclient进程不断尝试发送请求包但无回应,则会导致network服务卡死直到network服务超时失败。由于network服务在拉起多个网卡的IPv4 dhclient进程时,是通过串行的方式来拉起的。如果有网卡配置了持久化而DHCP服务器没有准备好,则会导致network服务在给该网卡获取IPv4地址超时卡死,进而导致后续网卡无法获得IPv4/IPv6地址。

      以上两种约束限制是特殊的应用场景,需要用户自己进行可靠性保障。

      IPv4 DHCP和IPv6 DHCPv6方式获取地址的配置差异

      可以通过配置接口ifcfg-<interface-name>参数来分别实现IPv4和IPv6通过DHCP/DHCPv6协议来动态获取IP地址,具体配置说明如下;

      BOOTPROTO=none|bootp|dhcp
      DHCPV6C=yes|no
      PERSISTENT_DHCLIENT=yes|no|1|0
      
      • BOOTPROTO: none表示静态配置IPv4地址,bootp|dhcp则会拉起DHCP dhclient来动态获取IPv4地址。

      • DHCPV6C: no表示静态配置IPv6地址,yes则会拉起DHCPv6 dhclient来动态获取IPv6地址。

      • PERSISTENT_DHCLIENT:no|0表示IPv4的dhclient进程配置为“非持久化”,当dhclient向DHCP服务器发送一次请求报文而无响应,则会间隔一段时间后退出,退出值为2。yes|1则表示IPv4的dhclient进程配置为“持久化”,dhclient会向DHCP服务器反复发送请求报文。如果没有配置PERSISTENT_DHCLIENT项,则IPv4的dhclient会默认设置为“持久化”

        说明:
        PERSISTENT_DHCLIENT配置只针对IPv4生效,对IPv6相关dhclient -6进程不生效,IPv6默认不进行持久化配置。

      iproute相关命令配置IPv4与IPv6时的差异说明

      概述

      由于IPv4和IPv6是两个不同的协议标准,iproute相关命令在使用方法上存在一定的差异。本章节主要梳理iproute包中用户经常使用到命令在IPv4和IPv6使用方面的差异,从而可以更好地指导用户使用iproute包中相关命令。

      iproute相关命令均需要在root权限下运行。

      IPv6地址的生命周期

      IPv6状态

      解释

      tentative

      临时状态:刚添加地址还处于地址重复检测DAD过程。

      preferred

      首选状态:完成DAD过程,没有收到相应的NA报文,表示该地址没有冲突。

      deprecated

      弃用状态:地址有一定的使用时限(valid_lft和preferred_lft),preferred_lft到期后地址会变化deprecated状态。

      该状态下的地址不能用于创建新的连接,但是原有的连接可以继续使用。

      invalid

      无效状态:使用时限超过preferred_lft一段时间后仍然没有成功进行租约续约,则valid_lft时间到后地址状态会被设置为invalid,表示该地址不可以再被使用。

      其它说明:

      • preferred_lft:preferred lifetime,地址为首选状态的寿命,preferred_lft没有到期的地址可以用于正常通信使用,若有多个preferred地址则按照内核具体机制选择地址。
      • valid_lft: valid lifetime,地址有效的寿命,在[preferred_lft, valid_lft]时间段内该地址不能被用于新建连接,已经创建的连接继续有效。

      命令:

      ip link set IFNAME mtu MTU
      

      IPv6中PMTU的最小值为1280,如果mtu值设置小于1280则会导致IPv6地址丢失。其它设备无法ping通该IPv6地址。

      ip addr命令
      1. 命令:

        ip [-6] addr add IFADDR dev IFNAME
        

        添加IPv6地址可以选择添加-6选项也可以不添加,ip addr命令会根据具体地址类型来判断是ipv4地址还是IPv6地址。

        如果指定“-6”选项,但是IFADDR 是ipv4地址则会有错误返回。

      2. 命令:

        ip [-6] addr add IFADDR  dev IFNAME [home|nodad]
        

        [home|nodad] 选项只针对IPv6地址有效。

        • home:将该地址指定为RFC 6275中定义的家庭地址。(这是移动节点从家庭链路获取的地址, 是移动节点的永久地址,如果移动节点保持在相同的归属链路中,则各种实体之间的通信照常进行。)
        • nodad:配置该项(仅限IPv6)添加此地址时不执行重复地址检测DAD(RFC 4862)。如果一台设备上多个接口通过nodad配置了多个相同的IPv6地址,则会按照接口顺序使用该IPv6地址。同一个接口上不能添加一个nodad一个非nodad的相同IPv6地址。因为两个地址是一样的,所以会报“RTNETLINK answers: File exists”。
      3. 命令:

        ip [-6] addr del IFADDR dev IFNAME
        

        删除IPv6地址可以选择添加-6选项也可以不添加,ip addr del命令会根据具体地址类型来判断是ipv4地址还是IPv6地址。

      4. 命令:

        ip [-6] addr show dev IFNAME [tentative|-tentative|deprecated|-deprecated|dadfailed|-dadfailed|temporary]
        
        • 不指定-6选项,则会同时打印IPv4和IPv6地址。指定-6选项则只打印IPv6地址。
        • [tentative|-tentative|deprecated|-deprecated|dadfailed|-dadfailed|temporary],这些选项只针对IPv6,可以根据IPv6地址状态对地址进行筛选查看。
          1. tentative:(仅限IPv6)仅列出尚未通过重复地址检测的地址。
          2. -tentative:(仅限IPv6)仅列出当前未处于重复地址检测过程中的地址。
          3. deprecated:(仅限IPv6)仅列出已弃用的地址。
          4. -deprecated:(仅限IPv6)仅列出未弃用的地址。
          5. dadfailed:(仅限IPv6)仅列出重复地址检测失败的地址。
          6. -dadfailed:(仅限IPv6)仅列出未重复地址检测失败的地址。
          7. temporary:(仅限IPv6)仅列出临时地址
      ip route命令
      1. 命令:

        ip [-6] route add ROUTE [mtu lock MTU]
        
        • -6选项:添加IPv6路由可以选择添加-6选项也可以不添加,ip route命令会根据具体地址类型来判断是IPv4地址还是IPv6地址。

        • mtu lock MTU:锁定路由的MTU值。如果不锁定MTU,则MTU的值则可能在PMTUD过程中被内核改变。如果锁定MTU,则不会尝试PMTUD,所有IPv4包都将不设置DF位发出,IPv6包则会按照MTU进行分段处理。

      2. 命令:

        ip [-6] route del ROUTE
        

        删除IPv6路由可以选择添加-6选项也可以不添加,ip route命令会根据具体地址类型来判断是IPv4地址还是IPv6地址。

      ip rule命令
      1. 命令:

        ip [-6] rule list
        

        -6选项:设置-6选项打印IPv6的策略路由,不设置-6选项打印IPv4的策略路由。所以需要根据具体协议类型来配置-6选项。

      2. 命令:

        ip [-6] rule [add|del] [from|to] ADDR table TABLE pref PREF
        

        -6选项:IPv6相关的策略路由表项需要设置-6选项,否则会报错:“Error: Invalid source address.”。相应地,IPv4相关的策略路由表项不可以设置-6选项,否则会报错:“Error: Invalid source address.”。

      NetworkManager服务配置差异说明

      概述

      NetworkManager服务使用ifup/ifdown的逻辑接口定义进行高级网络设置。其参数大多数都是在/etc/sysconfig/network和/etc/sysconfig/network-scripts/ifcfg-<interface-name>两个配置文件设置。前者为全局设置,后者为指定网卡的设置,当两者有冲突时,后者生效。

      配置差异说明

      其中在/etc/sysconfig/network下的配置差异有:

      IPv4

      IPv6

      含义说明

      NA

      IPV6FORWARDING=yes|no

      IPv6转发,默认不转发。

      NA

      IPV6_AUTOCONF=yes|no

      IPv6转发打开是no,否则是yes。

      NA

      IPV6_ROUTER=yes|no

      IPv6转发打开是yes,否则是no。

      NA

      IPV6_AUTOTUNNEL=yes|no

      指定Tunnel为自动隧道模式,默认是no。

      GATEWAY

      IPV6_DEFAULTGW=<IPv6 address[%interface]> (optional)

      在IPv6中设置默认网关。

      NA

      IPV6_DEFAULTDEV=<interface> (optional)

      指定默认转发的网卡。

      NA

      IPV6_RADVD_PIDFILE=<pid-file> (optional)

      默认ipv6_radvd_pid路径:/var/run/radvd/radvd.pid。

      NA

      IPV6_RADVD_TRIGGER_ACTION=startstop|reload|restart|SIGHUP (optional)

      radvd默认触发动作。

      而在/etc/sysconfig/network-scripts/ifcfg-<interface-name>下的差异主要有:

      IPv4

      IPv6

      含义说明

      IPADDRn

      IPV6ADDR=<IPv6 address>[/<prefix length>]

      ip地址。

      PREFIXn

      NA

      网络前缀,网络别名和ppp无效,优先级高于NETMASK。

      NETMASKn

      NA

      子网掩码,仅用于别名和ppp。

      GATEWAY

      IPV6_DEFAULTGW=<IPv6 address[%interface]> (optional)

      默认网关。

      MTU

      IPV6_MTU=<MTU of link> (optional)

      默认MTU。

      IPV4_FAILURE_FATAL=yes|no

      IPV6_FAILURE_FATAL

      默认值是no。若设置为yes,dhclient失败ifup-eth会直接退出。

      NA

      IPV6_PRIVACY=rfc3041

      默认禁用。

      NA

      IPV6INIT=yes|no

      默认开启IPv6。

      NA

      IPV6FORWARDING=yes|no

      默认关闭,已废弃。

      FAQ

      iscsi-initiator-utils不支持登录fe80 IPv6地址

      问题现象

      客户端通过IPv6登录iscsi服务端时,使用如“iscsiadm -m node -p ipv6address -l”的命令格式登录,如果是全局地址(global address),直接替换将命令范例中的“ipv6address”替换为全局地址即可;但如果是链路本地地址(link-local address,fe80开头的IPv6地址)则无法使用,因为iscsi-initiator-utils目前机制还不支持用链路本地地址(link-local address)地址登录iscsi服务端。

      原因分析

      如果使用格式如“iscsiadm -m node -p fe80::xxxx -l”登录,会登录超时返回,这是因为使用链路本地地址必须指定接口,否则使用iscsi_io_tcp_connect函数调用connect函数会失败,并且产生标准错误码22。

      如果使用格式如“iscsiadm -m node -p fe80::xxxx%enp3s0 -l”登录时,iscsi_addr_match函数会将地址“fe80::xxxx%enp3s0”与服务端返回的node信息中的地址“fe80::xxxx”对比,对比结果不匹配,导致登录失败。

      因此,iscsi-initiator-utils目前机制还不支持用链路本地地址(link-local address)登录iscsi服务端

      网卡down掉之后,IPv6地址丢失

      问题现象

      通过ip link down+up网卡或ifconfig down+up网卡命令,将网卡down掉之后再上线,查看网卡上配置的ip地址,发现ipv4地址不丢失,而配置的IPv6地址丢失。

      原因分析

      内核中的处理逻辑为如果网卡设置为down状态,会清空所有IPv4及IPv6地址,将网卡重新up之后,ipv4地址自动恢复,网卡上自动配置的IPv6链路本地地址也会恢复,但是其他IPv6地址默认会丢失。如果需要保留这些IPv6地址,可以通过“sysctl -w net.ipv6.conf.<网卡名>.keep_addr_on_down=1”来实现。

      bond口已具有多个IPv6地址时,添加或删除IPv6地址耗时过久

      问题现象

      下列方式配置或删除(包括flush)IPv6地址,X为动态变化的低16位,并且配置在bond口时,耗时会随已配置的IPv6地址数量成倍增加。例如由4个物理网卡组成的bond口添加IPv6地址时,单线程添加删除3000个IPv6地址均需大概5分钟,而普通物理网卡耗时在10秒内。

      ip a add/del 192:168::18:X/64 dev DEVICE
      
      原因分析

      bond口在添加IPv6地址时,会生成IPv6组播地址,并进行同步到所有的物理网卡上,此耗时会随IPv6数量增加而增加,导致耗时过长。

      解决方法

      IPv6的组播地址是由IPv6地址的低24位与33-33-ff组合生成,组播地址过多会导致添加删除耗时增加,如果生成的组播地址为少量,耗时不会受此影响。

      建议添加IPv6地址时,可保持低24位一致,保持高位变动,单网卡中仅需一个网段的一个地址即可与外部正常通信,此配置更符合常规使用。

      Rsyslog在IPv4和IPv6混合使用场景中日志传输延迟

      问题现象

      rsyslog客户端配置文件同时配置IPv4和IPv6地址,且端口配置相同的情况下,服务端收集log时会概率性出现日志打印延迟。

      原因分析

      延迟是因为rsyslog内部存在缓冲队列机制,默认情况下需要缓冲区队列达到一定数量才会写入文件。

      解决方法

      可在root权限下通过配置Direct模式,关闭缓冲队列机制解决该问题。在rsyslog远程传输服务端的/etc/rsyslog.d目录下新增的远程传输配置文件中,最开头增加如下配置:

      $ActionQueueType Direct
      $MainMsgQueueType Direct
      

      说明:

      • Direct模式减少队列大小为1,所以在队列中会保留1条日志到下次日志打印;
      • Direct模式会降低服务器端的rsyslog性能。

      文档捉虫

      “有虫”文档片段

      问题描述

      提交类型 issue

      有点复杂...

      找人问问吧。

      PR

      小问题,全程线上修改...

      一键搞定!

      问题类型
      规范和低错类

      ● 错别字或拼写错误;标点符号使用错误;

      ● 链接错误、空单元格、格式错误;

      ● 英文中包含中文字符;

      ● 界面和描述不一致,但不影响操作;

      ● 表述不通顺,但不影响理解;

      ● 版本号不匹配:如软件包名称、界面版本号;

      易用性

      ● 关键步骤错误或缺失,无法指导用户完成任务;

      ● 缺少必要的前提条件、注意事项等;

      ● 图形、表格、文字等晦涩难懂;

      ● 逻辑不清晰,该分类、分项、分步骤的没有给出;

      正确性

      ● 技术原理、功能、规格等描述和软件不一致,存在错误;

      ● 原理图、架构图等存在错误;

      ● 命令、命令参数等错误;

      ● 代码片段错误;

      ● 命令无法完成对应功能;

      ● 界面错误,无法指导操作;

      风险提示

      ● 对重要数据或系统存在风险的操作,缺少安全提示;

      内容合规

      ● 违反法律法规,涉及政治、领土主权等敏感词;

      ● 内容侵权;

      您对文档的总体满意度

      非常不满意
      非常满意
      提交
      根据您的反馈,会自动生成issue模板。您只需点击按钮,创建issue即可。
      文档捉虫
      编组 3备份