内容纲要

🗂 | 查看 Linux 专题可浏览更多内容


Linux 之前与传统 UNIX 一样使用相同的命令进行网络管理和状态检查,如 ifconfigroutenetstat

这些命令在目前大多数发行版中仍旧可用,但是目前活跃的开发活动已经转向 iproute2,其中用于包括路由选择在内的大部分日常网络配置的 ip 命令可替代 ifconfigroute 命令,而用于检查网络套接字状态的 ss 命令大体上也可用于替代 netstat

基本的网络配置

给本地网络添加新机器的步骤差不多是这样:

  1. 分配唯一的 IP 地址和主机名;
  2. 配置网络接口和 IP 地址;
  3. 设置默认路由(及可能更为复杂的路由选择配置);
  4. 设置 DNS 服务器;

一般来说可以依赖 DHCP 服务器完成大部分配置工作,现在新安装的系统一般默认都会选择通过 DHCP 配置,所以可能完全不需要手动配置网络。

在完成任何可能影响系统启动的改动后,一定要重新启动以查看机器是否正常,否则在一段时间后当电源出现故障机器无法引导时,很难再想起当初做了什么改动才引起这些问题。

在完成基本的网络配置后,可以使用 ping 或 traceroute 这类基本的工具测试网络的连通性。

查看网络配置

查看网络接口及 IP 配置

ip 是一款多用途的网络配置工具,能够全面发挥现代 Linux 内核的联网特性。它用于取代现已过时而早起普遍使用的 ifconfig

可以使用 ip 检查系统的网络接口和路由表等操作。

# 使用 iproute2
ip address show # 可以简写成 ip a
# 如果只想查看网络接口而不查看 IP 地址可以使用
ip link show
# 如只想查看 IPv4 或 IPv6 配置相关信息
ip -4 a

# 使用 net-tools
ifconfig -a
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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:fb:61:13 brd ff:ff:ff:ff:ff:ff
    altname enp2s1
    inet 192.168.1.2/24 brd 192.168.1.255 scope global dynamic ens33
       valid_lft 1198sec preferred_lft 1198sec
    inet6 fe80::20c:29ff:fefb:6113/64 scope link 
       valid_lft forever preferred_lft forever

接口的命名约定各不相同,如:

  • lo(环回接口)
  • eno1(板载网卡)
  • ens33(PCI-E 网卡)
  • enp0s3(无法获取物理信息的 PCI-E 网卡,s 表示插槽口、p 表示端口号)
  • wlan0 / wlo1(无线网卡)

Linux 当前版本试图确保接口名称不会随时间发生变化,所以名称显得有些随意,而 FreeBSD 和较久的 Linux 内核采用的是更为传统的「驱动程序」+「实例编号」的形式,如 eth0

inet 表示 IPv4 相关信息;inet6 表示 IPv6 相关信息。

查看网关

# 使用 iproute2
ip route show # 可简写成 ip r

# 使用 net-tools
route -n
default via 192.168.1.1 dev ens33 
192.168.1.0/24 dev ens33 proto kernel scope link src 192.168.1.2

配置网络接口及 IP

开启或关闭网口

# 使用 iproute2
# ens33 为网口名,通过 ifconfig -a 确认
# 开启或关闭网口
sudo ip link set ens33 up # 开启网口
sudo ip link set ens33 down # 关闭网口

# 使用 net-tools
# eth0 为网口名,通过 ifconfig -a 确认
sudo ifconfig eth0 up # 开启网口
sudo ifconfig eth0 down # 关闭网口

配置 IP 地址

⚠️ 注意,通过命令设置是非持久性,在系统重启后相关设置将会丢失,如果要永久生效需要修改配置文件,也就是说可以通过命令进行测试,待确认后修改配置文件

# 使用 iproute2
# ens33 为网口名,通过 ifconfig -a 确认
sudo ip a del 192.168.1.2/24 dev ens33 # 删除现有地址
sudo ip a add 192.168.1.3/24 dev ens33 # 添加新地址

# 使用 net-tools
# eth0 为网口名,通过 ifconfig -a 确认
sudo ifconfig eth0 192.168.1.3/24 up

修改默认网关

# 使用 iproute2
ip r del default # 删除现有默认网关
ip r add default via 192.168.1.1

# 使用 net-tools
sudo route del default gw 192.168.0.1 # 删除现有默认网关
sudo route add default gw 192.168.1.1 # 添加新的默认网关

修改 MAC 地址

# 使用 iproute2
# ens33 为网口名,通过 ifconfig -a 确认
sudo ip link set dev ens33 address aa:bb:cc:dd:ee:ff

# 使用 net-tools
# eth0 为网口名,通过 ifconfig -a 确认
sudo ifconfig eth0 down # 先关闭网口
sudo ifconfig eth0 hw ether aa:bb:cc:dd:ee:ff
sudo ifconfig eth0 up

修改网络配置文件

各个发行版对于网络配置文件的应用有所不同,这里以 Debian 和 Ubuntu 为例:

Debian & NetworkManager

Debian 使用 NetworkManager 进行管理网络,修改 IP 地址、网络掩码和默认路由的主要配置为 /etc/network/interfaces

# 先将配置文件备份以防万一
sudo cp /etc/network/interfaces  /etc/network/interfaces.bak

# 编辑配置
sudo vim /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
allow-hotplug ens33
iface ens33 inet dhcp

上述示例中 iface ens33 inet dhcp 表示接口 ens33 的 IPv4 正在使用 DHCP 获取配置,如果想要手动配置:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
allow-hotplug ens33
iface ens33 inet static
address 192.168.1.100
netmask 255.255.255.0
gateway 192.168.1.1

dhcp 修改为 static 然后填写 IP 地址、网络掩码和默认路由的配置。

保存配置后重启服务:

sudo systemctl restart networking

Ubuntu & Netplan

Ubuntu 原先也使用 NetworkManager,但从 17.10 开始转为使用 Netplan

它的配置文件位置也不一样,位于 /etc/netplan/

ls /etc/netplan/

要使用 ls 命令查看下默认的配置文件名,因为它不是固定的,它可能是 00-installer-config.yaml50-cloud-init.yaml 或是其他。

# 先将配置文件备份一下以防万一
sudo cp /etc/netplan/00-installer-config.yaml /etc/netplan/00-installer-config.yaml.bak

# 编辑配置文件
sudo vim /etc/netplan/00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
  ethernets:
    ens33:
      dhcp4: true
  version: 2

配置内容其实大同小异,比如此处网卡 ens33 使用 DHCP 获取 IPv4 配置信息,进行手动配置:

network:
  ethernets:
    ens33:
      addresses: [192.168.1.100/24]
      gateway4: 192.168.1.1
      nameservers:
        addresses: [1.1.1.1, 8.8.8.8]
  version: 2
  • addresses:即 IP 地址,此处为一个数组,如果你有多个地址需要配置可以就写成:[192.168.1.121/24,192.168.1.122/24],如果你有 IPv6 地址可以写成 [192.168.1.121/24, 2002:7111:236b:1::1/64],而网络掩码不像之前使用类似 255.255.255.0 而是以 /24 形式配置。
  • gateway4:即网关,此处的 4 表示 IPv4,举一反三如果要配置 IPv6 的网关便是 gateway6
  • nameservers: 也就是 DNS 服务器地址,同样以数组的方式进行多个配置。

除了上述还有一些其他配置可以查看 Netplan官网的 示例配置

需要注意的是文件格式为 YAML,如果你从未了解过该格式很可能在格式缩进等问题上出岔子,所以在编辑完成后可以先使用测试命令:

sudo netplan try

如果配置的格式上没有问题会提示配置成功,按「回车键」即可应用。

如果你很自信认为绝对没问题配置一次过也可以使用命令直接应用配置:

sudo netplan apply

配置 DNS 及本地映射

DNS 配置

传统的修改 DNS 方法为修改配置文件:/etc/resolv.conf

sudo vim /etc/resolv.conf
nameserver 1.0.0.1
nameserver 1.1.1.1
nameserver 8.8.4.4

如上 nameserver 字段不变后面写上 DNS 服务器的 IP 即可,最多可以有 3 个条目且可能的话应该不止有 1 个。

应当将「距离最近的」、稳定的 DNS 服务器放到最前面,服务器会按照出现的顺序依次访问,但尝试访问下一个服务器之前的超市等待时间较长。

但目前不少发行版已经不在此进行配置 DNS,你可能会看到这样的配置:

# This file is managed by man:systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients to the
# internal DNS stub resolver of systemd-resolved. This file lists all
# configured search domains.
#
# Run "resolvectl status" to see details about the uplink DNS servers
# currently in use.
#
# Third party programs must not access this file directly, but only through the
# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
# replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.

nameserver 127.0.0.53
options edns0 trust-ad

开头提示此文件已经被 systemd-resolved 托管了不要进行编辑。有些文档指出可以通过系统管理守护进程查看是 init 还是 systemd 以进行区分,但这并不准确。

如果使用的是 systemd-resolved,可以在 /etc/systemd/resolved.conf 中进行持久性更改

sudo vim /etc/systemd/resolved.conf
DNS=1.0.0.1 8.8.4.4
#FallbackDNS=
#Domains=
#LLMNR=no
#MulticastDNS=no
#DNSSEC=no
#DNSOverTLS=no
#Cache=no-negative
#DNSStubListener=yes
#ReadEtcHosts=yes

DNS 前的井号移除(使其不是注释)并配置 DNS 服务器 IP,保存配置后应用生效:

# 重启 systemd-resolved 服务
sudo systemctl restart systemd-resolved

# 查看是否生效
resolvectl status | grep 'DNS Servers'

本地映射

配置 /etc/hosts 文件是一种名称映射到 IP 地址最古老也是最简单的方法:

sudo vim /etc/hosts
127.0.0.1 localhost

文件中每一行以一个 IP 地址开头,后面跟着 地址即可。

主机名

可以使用 hostname 命令查看现在的主机名。

传统的修改主机名方式为修改 /etc/hostname 文件,在使用 systemd 的系统上可以使用命令:

sudo hostnamectl set-hostname <主机名>

网络检查与监控

ping

ping 是基本的网络命令。

该命令会向指定主机发送名为「ICMP ECHO_REQUEST」的特殊网络分组。接收到此分组的多数网络设备会回应,以此就可以核实网络连接的连通性。

# ping <域名或 IP>
ping google.com
PING google.com (142.250.72.142) 56(84) bytes of data.
64 bytes from lax17s49-in-f14.1e100.net (142.250.72.142): icmp_seq=1 ttl=121 time=0.507 ms
64 bytes from lax17s49-in-f14.1e100.net (142.250.72.142): icmp_seq=2 ttl=121 time=4.72 ms
64 bytes from lax17s49-in-f14.1e100.net (142.250.72.142): icmp_seq=3 ttl=121 time=0.841 ms
^C
--- google.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2006ms
rtt min/avg/max/mdev = 0.507/2.023/4.723/1.913 ms

如果不使用 -c 选项指定数量将会持续发送,直到中断

💡 可以使用 Ctrl + C 中断

❓ 从第一行可以看到当前解析到的 google.com 的 IP 地址为 142.250.72.142,但为什么下面会显示 lax17s49-in-f14.1e100.net,因为一个 IP 地址可以设置多个不同的域名,而 ping 向系统 DNS 查询反响解析 IP 的域名,如果要阻止 ping 的反向 DNS 查找操作可以使用 -n 选项:

ping google.com -n
  • 64 bytes 表示数据包大小;
  • icmp_seq=1 表示数据包编号;
  • ttl=121 表示接收到的数据包的生存时间,通常是源和目标之间的跃点数或路由器数;
  • time=0.507 ms 表示数据包到达所需的往返时间或 RTT;

使用 -t 选项查看第几跳的 TTL:

# -n 阻止 IP 反响查找
# -t 第几跳
ping google.com -n -c 1 -t 1

使用 ping 排查步骤

一般来说遇到网络故障可以这么使用 ping

  1. 使用 ip r 查看网关,然后 ping 网关,如果不通就可能是因为 DHCP 获取或本地没有正确设置 IP 等信息,亦或是路由器配置不正确;
  2. 如果到路由器网关正常,可以 ping 一个公共 DNS 地址,如 1.0.0.1119.29.29.29 等;
  3. 如果公共 DNS 也是可以通的,就可以尝试 ping 一些域名,如果域名不通,那就是本地配置的 DNS 出现了故障或是配置错误,可以换上能通的公共 DNS 一般问题就可以得到解决;

traceroute

traceroute 会列出网络流量从本地系统到指定主机经过的所有跳(hop)数:

traceroute google.com
traceroute to google.com (142.250.72.142), 30 hops max, 60 byte packets
 1  216.24.255.1 (216.24.255.1)  0.695 ms  1.015 ms  1.075 ms
 2  multacom.com (96.45.162.9)  0.860 ms  0.781 ms  0.842 ms
 3  206.72.211.148.any2ix.coresite.com (206.72.211.148)  0.495 ms  0.420 ms  0.420 ms
 4  108.170.247.193 (108.170.247.193)  1.697 ms 108.170.247.225 (108.170.247.225)  0.590 ms 108.170.247.193 (108.170.247.193)  1.186 ms
 5  142.251.60.111 (142.251.60.111)  0.516 ms  0.465 ms 142.251.60.109 (142.251.60.109)  0.467 ms
 6  lax17s49-in-f14.1e100.net (142.250.72.142)  0.460 ms  0.508 ms  0.564 ms

ss & netstat

ss 用来显示处于活动状态的套接字信息。ss 命令可以用来获取 socket 统计信息,它可以显示和 netstat 类似的内容。但 ss 的优势在于它能够显示更多更详细的有关TCP和连接状态的信息,而且比 netstat 更快速更高效。

# 获取监听端口列表
ss -tupan
netstat -tupan

# 显示 TCP socket
ss -at

# 显示 UDP socket
ss -au

# 显示 socket 使用摘要
ss -s

# 显示进程 socket 使用摘要
ss -pl