1. 配置前的准备工作:为什么新装系统的以太网卡往往没有地址
如果你刚装完一套 Linux 服务器,插上网线之后习惯性地ping www.example.com,大概率会得到Name or service not known或者Network is unreachable的报错。别急着怀疑网卡坏了,绝大多数情况下只是因为你还没有给以太网接口配置 IP 地址。无论是 IPv4 还是 IPv6,系统默认的网络栈不会自动帮你决定该用哪个地址,除非你明确开启了 DHCP 客户端或者手工指定了静态地址。
这里涉及的其实是网络服务最基础的一环:以太网接口的地址分配。所谓“网络服务(2)”,通常意味着你已经了解了网卡驱动和链路层的基础,那么接下来要面对的就是网络层配置。很多人习惯跳过这一步,直接依赖某一套图形化工具或者云平台的一键网络设置,结果到了需要排查问题的时候,连ip addr的输出都看不懂。我建议所有管理员都把手工配置这条路走一遍,哪怕最终你维护的环境全部用 DHCP,理解静态配置的原理也会让你在排障时少走很多弯路。
1.1 默认网络栈的初始化逻辑
现代 Linux 系统启动时,内核会枚举所有以太网设备,但默认并不会主动给它们分配任何 IPv4 地址。IPv6 的情况稍好一点,因为内核默认启用了 IPv6 的自动配置机制,但这也要取决于路由器是否发送 Router Advertisement(RA)报文。如果你的交换机端口没有配置 IPv6 路由通告,那么 IPv6 地址同样不会出现。
我见过不少新手管理员,在/etc/sysconfig/network-scripts/(RHEL 系)或者/etc/network/interfaces(Debian 系)里写了配置,但忘了重启网络服务,或者没有执行ip addr flush清掉旧地址,结果新旧配置混在一起,产生了意料之外的路由。所以,配置前先确认你当前网卡的真实状态非常关键,不要想当然。
1.2 找出网卡接口名称与驱动状态
我一般会先用两个命令确认当前状态:
ip link show这个命令会列出所有网络接口,包括状态为 DOWN 的接口。注意接口名称,常见的有eth0、ens33、enp3s0这类。如果你使用的是虚拟化环境,接口名可能是ens18或者enp0s3。拿到接口名之后,再执行:
ip addr show eth0如果看到state DOWN,就先把它启用:
ip link set eth0 up启用后再次查看,如果还是没有 IPv4 地址,那就说明当前没有 DHCP 服务,或者你没有配置静态地址。这时候你才真正进入了以太网配置 IPv4 和 IPv6 的主题。
2. IPv4 地址配置的核心步骤与静态规划
IPv4 的配置看起来简单,就是给接口一个IP/掩码,再配上网关和 DNS。但真正做好静态规划并不容易,尤其是当你面对多块网卡、多个网段的服务器时,掩码和网关一旦配错,轻则本地通信失败,重则影响整个路由表。
2.1 静态 IPv4 配置的完整命令流程
我以 RHEL 系系统为例,因为它的nmcli工具既强大又很适合脚本化操作。假设我要把eth0配置成192.168.10.10/24,网关为192.168.10.1,DNS 为223.5.5.5,那么可以这样:
nmcli connection modify eth0 ipv4.addresses 192.168.10.10/24 nmcli connection modify eth0 ipv4.gateway 192.168.10.1 nmcli connection modify eth0 ipv4.dns "223.5.5.5" nmcli connection modify eth0 ipv4.method manual nmcli connection up eth0每一步都值得解释一下。第一条是设置 IP 地址和掩码,这里用的是 CIDR 表示法,写成192.168.10.10 255.255.255.0也是等价的,但 CIDR 更简洁。第二条设置默认网关,第三条设置 DNS 服务器,第四条是关键——ipv4.method manual告诉系统不要试图通过 DHCP 获取地址,而是采用我们手工指定的配置。最后一条激活连接。
如果你用的是 Debian/Ubuntu 系,配置文件/etc/netplan/01-netcfg.yaml大概是这样的:
network: version: 2 ethernets: eth0: dhcp4: false addresses: - 192.168.10.10/24 routes: - to: default via: 192.168.10.1 nameservers: addresses: - 223.5.5.5然后执行netplan apply即可。这里有一个容易被忽略的点:routes部分要写成to: default,而不是写gateway4,因为新版本 netplan 已经弃用了gateway4字段。如果你沿用网上的旧教程,可能直接报错。
2.2 网关与 DNS 的关联:路由表的形成
很多人在配完 IP 后,发现能 ping 通同网段的机器,但访问外网失败。这通常不是 IP 配错了,而是默认路由没有生效。你可以用ip route show查看路由表:
default via 192.168.10.1 dev eth0 192.168.10.0/24 dev eth0 proto kernel scope link src 192.168.10.10如果只有第二行而没有第一行,说明默认路由缺失。这时你就要检查网关配置是否写对了。网关必须和你的 IP 在同一个网段内,否则系统根本没法把包发到网关。这个逻辑就像快递员要知道处理中心在哪里,如果处理中心的地址和你的寄件地址不在同一个城市,快递就送不到。
DNS 配置同样重要。我看到有人只配了 IP 和网关,然后就抱怨域名解析失败。检查一下/etc/resolv.conf,里面有没有nameserver行。在 systemd 系统里,这个文件往往由systemd-resolved管理,你直接改文件可能会被覆盖。最好还是通过nmcli或者 netplan 来配置 DNS,这样系统重启后也不会丢。
3. IPv6 配置:从 SLAAC 到手工静态地址
IPv6 的配置比 IPv4 多了一些新概念,比如链路本地地址、全局单播地址、SLAAC(无状态地址自动配置)、DHCPv6 等等。很多人第一次接触 IPv6 时被这些术语吓住,其实只要抓住一条主线:IPv6 地址是怎么产生的,以及路由是怎么确定的。
3.1 IPv6 地址的组成与 EUI-64 原理
IPv6 地址是 128 位,通常写成八组十六进制数。配置静态 IPv6 时,你至少要指定一个前缀长度和接口标识符。如果你不想手工算 EUI-64,可以用ip命令直接指定完整地址:
ip -6 addr add 2001:db8:100::10/64 dev eth0这里2001:db8:100::10就是我手工指定的地址,/64是前缀长度。但在生产环境,我更推荐使用 EUI-64 格式,即用网卡的 MAC 地址自动生成接口 ID。怎么实现呢?Linux 下你可以这样操作:
ip -6 addr add 2001:db8:100::/64 dev eth0注意,我写的是2001:db8:100::/64,没有指定主机部分。内核会使用网卡的 MAC 地址,根据 EUI-64 规则填充后 64 位接口标识符,从而生成一个完整的可全局路由地址。这样做的最大好处是,只要前缀不变,任何一块物理网卡都会得到一个相对稳定的 IPv6 地址,不需要你去记手工 ID。
这种机制的原理在于,EUI-64 会把 Mac 地址的中间部分插入ff:fe,再把第 7 位翻转(U/L 位)。比如 MAC 是00:1a:2b:3c:4d:5e,生成的接口 ID 就会类似021a:2bff:fe3c:4d5e。你不需要手工去算,内核会替你完成,但理解这个过程对排查“为什么我的 IPv6 地址和我预期的不一样”很有帮助。
3.2 手工配置与自动获取的取舍
IPv6 有两条自动配置路径:SLAAC 和 DHCPv6。SLAAC 依赖路由器的路由通告,不需要额外状态记录,所以很轻量。DHCPv6 则更接近传统的 IPv4 DHCP,能下发 DNS、域名等额外参数。
我见过一些网络环境,管理员把 RA 广播关掉了,导致客户端拿不到 IPv6 地址,然后又来问我为什么 IPv6 不通。实际上,如果你只在局域网内部测试 IPv6,完全可以手工静态配置,不需要依赖任何自动机制。下面是一个手工配置同时生效 IPv4 和 IPv6 的例子:
nmcli connection modify eth0 ipv6.addresses "2001:db8:100::10/64" nmcli connection modify eth0 ipv6.gateway "2001:db8:100::1" nmcli connection modify eth0 ipv6.method manual nmcli connection modify eth0 ipv4.addresses "192.168.10.10/24" nmcli connection modify eth0 ipv4.gateway "192.168.10.1" nmcli connection modify eth0 ipv4.dns "223.5.5.5" nmcli connection modify eth0 ipv6.dns "2400:3200::1" nmcli connection up eth0这里有个经验点:很多人只改了ipv6.method manual,但忘了设置ipv6.gateway。如果没有网关,IPv6 通信只能在同一链路内进行,无法访问外部网络。IPv6 的默认路由和 IPv4 是独立存在的,你必须确认路由表里有:
ip -6 route show看到类似default via 2001:db8:100::1 dev eth0的条目,说明 IPv6 默认路由已经生效。
4. 双栈共存:IPv4 与 IPv6 的优先级切换实践
现代网络基本都是双栈,同一个网卡既跑 IPv4 又跑 IPv6。双栈的好处是应用层可以用更先进的协议访问资源,坏处是配置复杂度上升,容易在 DNS 解析和路由策略上踩坑。
4.1 双栈环境下的 DNS 解析行为
双栈环境下,getaddrinfo会尝试解析 A 记录(IPv4)和 AAAA 记录(IPv6)。默认情况下,Linux 的gai.conf会优先选择 IPv6,但前提是系统检测到本机有可用的全局 IPv6 地址。如果你只配了 IPv4,没有配 IPv6,那么即使 DNS 返回了 AAAA 记录,程序也会自动跳过,回落到 IPv4。
我见过一个有意思的问题:双栈服务器上,某个应用总是优先走 IPv6,但管理的交换机没有完全配置好 IPv6 路由,导致连接超时。这时就能通过修改/etc/gai.conf中的precedence规则来调整优先级。比如将 IPv4 的优先级调高:
precedence ::ffff:0:0/96 100这个配置表示所有 IPv4 映射地址都有最高优先级 100。保存后,重启相关服务,你就会发现应用开始优先使用 IPv4 连接。
4.2 修改地址族选择策略的实战
修改优先级到底怎么验证?我通常用一个小工具测试:
getent ahosts example.com这个命令会输出example.com解析出来的所有地址,并且显示顺序。如果第一行是 IPv6 地址,说明当前策略优先 IPv6;如果第一行是 IPv4 地址,说明优先 IPv4。
实际调整时,除了gai.conf,还要看系统层面是否启用了disable_ipv6。有些管理员为了省事,直接在内核参数里关了 IPv6:
sysctl -w net.ipv6.conf.all.disable_ipv6=1这么做当然可以彻底避免 IPv6 问题,但也会让你丧失双栈的能力。我更倾向于保持 IPv6 启用,只在应用层做策略切换。毕竟 IPv6 地址资源充足,某些场景下反而更好用,比如做远程管理的静态地址时,不用担心和内网自动分配冲突。
5. 配置后的连通性验证与常见故障排查
地址配好了,路由也配好了,接下来就是验证。验证的方法决定了你排障的效率。很多人只会ping,但ping的报错信息有限,无法区分是本地地址问题、路由问题还是远端防火墙问题。
5.1 ping、traceroute、ip 命令的组合用法
我建议按以下顺序排查:
- 先看接口地址是否正确:
ip addr show eth0。 - 再看路由表是否完整:
ip route show和ip -6 route show。 - 然后 ping 同网段的网关:
ping -c 4 192.168.10.1,IPv6 则用ping6 -c 4 2001:db8:100::1。 - 如果网关通了,再 ping 外网地址,注意不要一开始就 ping 域名,因为域名解析可能本身就有问题。先 ping 一个公网 IPv4 地址,比如
ping -c 4 223.5.5.5,以及公网 IPv6 地址,比如ping6 -c 4 2400:3200::1。 - 如果 IP 通但域名不通,就排查 DNS:
cat /etc/resolv.conf,再用nslookup或dig测试。 - 如果某一跳不通,用
traceroute或者traceroute6看是在哪一跳丢包。
这套流程适用于绝大多数连通性故障。注意,ping6在现代系统里可能已经并入ping -6,我用的是ping -6也完全可以。
5.2 我踩过的几个配置雷区
第一个雷区是忘记把接口配置做成持久化。比如我用ip addr add临时配置成功后,感觉很顺利,结果系统一重启,配置全部丢失,进入无法远程连接的尴尬局面。临时命令只适合测试环境,生产环境必须写入nmcli connection或者 netplan 或/etc/sysconfig/network-scripts/,确保重启后依然生效。
第二个雷区是 IPv4 和 IPv6 的默认路由互相干扰。有些系统会同时下发 IPv4 和 IPv6 的默认路由,但其中一个网段实际不可达,导致数据包走到“黑洞”。我建议配置完成后立刻检查路由表,把多余的默认路由删掉,保留真正可用的一条。删除方法:
ip route del default via 192.168.10.1或者针对 IPv6:
ip -6 route del default via 2001:db8:100::1第三个雷区是 DNS 解析超时。systemd-resolved会默认向所有配置的 DNS 服务器发起请求,如果其中一个不可达,会导致解析时间变长。你可以在/etc/systemd/resolved.conf里设置DNSStubListener=no或者使用FallbackDNS,但最简单的方案还是确保 DNS 服务器地址是可用的。
第四个雷区是链路本地地址和全局地址混淆。IPv6 的接口一定有一个fe80::开头的链路本地地址,这是自动生成的,不需要配置。你不能用链路本地地址作为默认网关,因为它只在同一链路内有效。检查有没有全局 IPv6 地址,就看有没有2001:或者公网前缀开头的地址,而链路本地地址永远以fe80:开头。
在我自己的维护经历里,最让人抓狂的一次是一台服务器的网卡配置看起来完全正确,IPv4 和 IPv6 地址都在,路由也在,但就是无法和同一交换机上的另一台机器通信。后来我发现,问题出在对端机器的防火墙规则上,它只放行了 IPv4 的 ICMP,却没有放行 IPv6 的 ICMPv6。IPv6 的邻居发现协议依赖 ICMPv6,如果对端丢弃了 ICMPv6,即使你的配置毫无问题,邻居表也无法建立,通信自然失败。所以,排查双栈问题时,一定不要只盯本地配置,还要检查对端防火墙和交换机端口的 IPv6 支持情况。
最后,分享一个我在实际配置中养成的习惯:在/etc/hosts里先写好本机的主机名解析,这样系统启动时就不会因为 DNS 不可用而卡住某些服务。配完 IP 和路由后,我会立刻执行ping -c 1 网关并同时测试getent ahosts,用最小代价确认端到端链路是否完整。配置网络这件事,往往最花时间的不是敲命令,而是理清地址、路由和 DNS 之间的逻辑关系。只要这三条线捋顺了,IPv4 和 IPv6 其实都一样——一个是大家熟悉的旧地址体系,一个是需要多点耐心的新地址体系,掌握好它们之间的联系与区别,大多数网络问题都能迎刃而解。