随着 IPv6 的普及,越来越多的服务器开始双栈部署:同时拥有 IPv4 和 IPv6 地址。但不少人配好了 IPv6 地址,却发现服务器只能 ping 通网关,访问 IPv6 网站却不行——问题多半出在 IPv6 默认路由没配好。IPv6 的路由概念和 IPv4 相似,但配置命令、持久化文件、邻居发现机制都有明显差异,直接把 IPv4 的经验套过来很容易出错。
这篇文章系统讲清 IPv6 默认路由的配置:先解释 IPv6 地址结构和网关的获取方式,再给出手工配置地址与默认路由的完整步骤,重点说明各发行版持久化配置的写法,最后给出连通性测试方法和常见坑。所有命令都用 ip -6 体系,并区分 RHEL/CentOS/Rocky 与 Debian/Ubuntu。
IPv6 有两个和 IPv4 很不一样的地方需要提前记住:一是网关地址通常通过路由器通告(RA)自动获得,手工配置时要注意网关必须是链路本地地址或同网段地址;二是 IPv6 的地址长度是 128 位,子网默认是 /64,不要按 IPv4 的 /24 习惯去配。
一、IPv6 地址与网关的基础知识
IPv6 地址是 128 位,用十六进制书写,常分成 8 组、每组 4 位十六进制,例如 2001:0db8:0000:0000:0000:0000:0000:0001。可以简写:省略前导零、用 :: 代替一段连续的 0,于是上面的地址写成 2001:db8::1。
地址类型有几个要区分:
| 类型 | 前缀 | 说明 |
|---|---|---|
| 全球单播(GUA) | 2000::/3 |
相当于公网 IPv4,可全球路由 |
| 链路本地(LLA) | fe80::/10 |
每张网卡自动生成,只在本地链路有效 |
| 唯一本地(ULA) | fc00::/7 |
相当于内网私有地址 |
| 多播 | ff00::/8 |
组播地址,ff02::1 是链路内所有节点 |
| 环回 | ::1 |
相当于 127.0.0.1 |
IPv6 里 每张启用 IPv6 的网卡都会自动有一个 fe80:: 开头的链路本地地址,它不需要手工配,主要用于邻居发现(NDP)和本地通信。IPv6 的"网关发现"靠路由器通告(Router Advertisement,RA):上游路由器周期性发送 RA 报文,主机收到后自动配置默认路由和地址前缀。所以如果网络里有支持 IPv6 的路由器,地址和默认路由往往不需要手工配,会自动获得。
手工配置时,默认网关一般写成网关的链路本地地址(fe80:: 开头),并需要指定出接口,因为链路本地地址不唯一,必须知道从哪张网卡发出去。这是初次配置 IPv6 默认路由最容易搞错的地方。
二、查看当前 IPv6 地址与路由
配置前先看清楚现状:
# 查看网卡的 IPv6 地址
ip -6 addr show
ip -6 addr show dev eth0
ip -br -6 addr # 简洁模式
# 查看 IPv6 路由表
ip -6 route show
ip -6 route show dev eth0
# 只看默认路由
ip -6 route show default
# 查看某个目标地址会走哪条路由
ip -6 route get 2400:3200::1
# 查看 IPv6 邻居表(对应 IPv4 的 ARP)
ip -6 neigh show
ip -6 neigh show dev eth0
ip -6 route show 的典型输出:
2001:db8:1::/64 dev eth0 proto kernel metric 256 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium
default via fe80::1 dev eth0 proto static metric 1024 pref medium
2001:db8:1::/64 dev eth0:直连的全局网段。fe80::/64 dev eth0:链路本地网段。default via fe80::1 dev eth0:默认路由,网关是fe80::1(链路本地地址),出接口eth0。
如果 ip -6 route show default 没有输出,说明没配默认路由,这就是访问不了外部 IPv6 的原因。还要确认网卡是否真的启用了 IPv6:
# 查看网卡是否禁用 IPv6(disable_ipv6=1 表示禁用)
cat /proc/sys/net/ipv6/conf/eth0/disable_ipv6
cat /proc/sys/net/ipv6/conf/all/disable_ipv6
# 系统是否启用了 IPv6 转发(作为路由器时才有用)
sysctl net.ipv6.conf.all.forwarding
# 临时启用某网卡 IPv6
sysctl -w net.ipv6.conf.eth0.disable_ipv6=0
有些机房或系统为了省事会默认禁用 IPv6,配置前先确认它是开的。
三、手工配置 IPv6 地址与默认路由
假设给 eth0 配上全局地址 2001:db8:1::10/64,网关为同链路另一个设备的链路本地地址 fe80::1。
# 1. 添加 IPv6 全局地址到自己网卡(-6 表示 IPv6)
ip -6 addr add 2001:db8:1::10/64 dev eth0
# 2. 添加 IPv6 默认路由
# 注意:网关是链路本地地址时,必须用 via + dev 指定出接口
ip -6 route add default via fe80::1 dev eth0
# 3. 验证
ip -6 addr show dev eth0
ip -6 route show default
ip -6 route get 2400:3200::1
如果网关给的是全球地址(比如 2001:db8:1::1,且与主机同网段),则可以不用显式指定 dev,内核能从地址推断:
ip -6 route add default via 2001:db8:1::1
# 或者用 replace 便捷替换
ip -6 route replace default via 2001:db8:1::1 dev eth0
删除路由:
ip -6 route del default via fe80::1 dev eth0
# 清空默认路由(谨慎)
ip -6 route del default
和 IPv4 一样,先删后加会有流量空窗,远程操作建议用 replace 一步到位;修改地址或路由前先备份:
ip -6 addr show > /root/ipv6-addr.bak
ip -6 route show > /root/ipv6-route.bak
四、持久化配置:各发行版写法
临时命令重启即失效,持久化要写配置文件。IPv6 的持久化在各发行版上写法不同,整理如下:
| 发行版 | 配置文件 | 关键写法 |
|---|---|---|
| RHEL/CentOS 7 | /etc/sysconfig/network-scripts/ifcfg-eth0 |
IPV6INIT=yes、IPV6ADDR=...、IPV6_DEFAULTGW=... |
| Rocky/Alma 8/9 | nmcli 或 ifcfg |
nmcli con mod eth0 ipv6.addresses ... |
| Debian 11 及更早 | /etc/network/interfaces |
iface eth0 inet6 static + gateway |
| Ubuntu 18.04+ / Debian 12 | /etc/netplan/*.yaml |
在 ethernets 下写 IPv6 地址和 routes |
RHEL/CentOS/Rocky 的 ifcfg 写法:
# /etc/sysconfig/network-scripts/ifcfg-eth0 追加:
# IPV6INIT=yes
# IPV6ADDR=2001:db8:1::10/64
# IPV6_DEFAULTGW=fe80::1%eth0
# 注意:链路本地网关要带 %eth0 接口后缀
systemctl restart network # CentOS 7
nmcli con reload && nmcli con up eth0 # NetworkManager 系统
Rocky 8/9 推荐用 nmcli:
nmcli con mod eth0 ipv6.method manual
nmcli con mod eth0 ipv6.addresses "2001:db8:1::10/64"
nmcli con mod eth0 ipv6.gateway "fe80::1"
nmcli con mod eth0 ipv6.dns "2400:3200::1,2400:3200:baba::1"
nmcli con up eth0
nmcli con show eth0 | grep -i ipv6
Debian 的 interfaces 写法:
# /etc/network/interfaces
auto eth0
iface eth0 inet6 static
address 2001:db8:1::10
netmask 64
gateway fe80::1
systemctl restart networking
Ubuntu/Debian 的 netplan 写法:
# /etc/netplan/01-netcfg.yaml
network:
version: 2
ethernets:
eth0:
addresses:
- 2001:db8:1::10/64
routes:
- to: default
via: fe80::1
on-link: true # 网关是链路本地地址时通常需要
nameservers:
addresses: [2400:3200::1, 2400:3200:baba::1]
netplan generate
netplan try # 120 秒内不确认自动回滚,远程改网必用
netplan apply
netplan try 对改网络配置特别友好:它先应用新配置,如果没有确认就自动回滚,能避免"改错配置把自己关在门外"。远程改 IPv6 配置时强烈建议用它。
五、连通性测试
IPv6 配好了,用下面这套命令验证:
# 1. 先 ping 本机 IPv6 环回
ping6 -c 3 ::1
# 或 ping -6
# 2. ping 自己的全局地址
ping6 -c 3 2001:db8:1::10
# 3. ping 网关(链路本地地址要带 %接口)
ping6 -c 3 fe80::1%eth0
# 4. ping 外部 IPv6 地址(比如公共 IPv6 DNS)
ping6 -c 3 2400:3200::1 # 阿里 IPv6 DNS
# 5. 从指定接口/源地址发
ping6 -c 3 -I eth0 2400:3200::1
ping6 -c 3 -S 2001:db8:1::10 2400:3200::1
# 6. DNS 解析测试(先确认 /etc/resolv.conf 里有 IPv6 DNS 或支持双栈的 DNS)
dig AAAA www.example.com
dig @2400:3200::1 www.example.com AAAA
# 7. HTTP 层测试(-6 强制用 IPv6)
curl -6 -I -m 10 https://www.example.com
# 8. 看路径(traceroute6)
traceroute6 2400:3200::1
mtr -6 -rw -c 20 2400:3200::1
测试时常见的现象与含义:
ping6 ::1通、ping6 全局地址不通:地址没配上,或网卡没启用 IPv6。ping6 网关通、外部不通:默认路由没配,或上游没做 IPv6 转发/NAT。- 网关也不通:链路问题,检查 VLAN、交换机是否传 IPv6、网关地址是否写对。
- DNS 解析出 AAAA 但连不上:说明解析有了但路由/连通性没通,回到 ping 那一步查。
坑五:多条默认路由并存。 IPv6 也可能出现 RA 下发的默认路由和你手工配的默认路由同时存在,导致出口选择不确定。用 ip -6 route show default 检查是否有重复;如果确实有两条,按需求用 metric 区分优先级,或关闭 RA 自动配置(sysctl -w net.ipv6.conf.eth0.accept_ra=0)。
坑六:DNS 也要配 IPv6。 配好 IPv6 网络但没配 IPv6 DNS,某些系统会优先尝试用 IPv6 去查 DNS 而超时,表现为"能 ping 通外部 IPv6 地址却解析不了域名"。检查 /etc/resolv.conf 或 netplan 的 nameservers 是否包含可用的 IPv6 DNS,或确保有支持双栈的 DNS 可用。
六、常见坑与注意事项
IPv6 有几个和 IPv4 不同的坑,配的时候要留意:
坑一:网关是链路本地地址必须带接口。 fe80:: 地址在每张网卡上可能都存在,不唯一,所以配默认路由、ping 网关时都要指明 dev eth0 或 %eth0,否则内核不知道该从哪张网卡发。
坑二:子网掩码别按 IPv4 习惯写。 IPv6 子网通常是 /64,写 /24 之类会导致地址范围和邻居发现异常。手工配时严格用分配给你的前缀长度。
坑三:RA 与手工配置冲突。 如果网络里有路由器发 RA,同时你又手工配了地址和默认路由,可能出现两套地址(自动的 + 手工的)和两条默认路由。检查 ip -6 route show default 是否有重复,必要时关闭该接口的 RA 自动配置(net.ipv6.conf.eth0.accept_ra=0)。
坑四:IPv6 的邻居发现依赖 ICMPv6。 和 IPv4 的 ARP 不同,IPv6 用 NDP(基于 ICMPv6 实现),所以防火墙必须放行 ICMPv6,否则邻居发现、路径 MTU 发现都会失败。很多"IPv6 ping 不通"就是防火墙把 ICMPv6 全封了。
# 检查是否误封了 ICMPv6(别把 ICMPv6 一刀切禁掉)
# RHEL/CentOS/Rocky:确认没禁 ipv6 相关
firewall-cmd --list-all
# Debian/Ubuntu
ufw status verbose
# 底层规则里确认没有 DROP ipv6-icmp 之类的全封规则
ip6tables -L -n -v
风险提示与回滚:远程改 IPv6 配置前,先备份 ip -6 addr、ip -6 route 输出和配置文件;优先用 netplan try、nmcli 的带回滚机制;不要把 ip6tables 的 INPUT 默认策略改成 DROP 而不放行 SSH 和 ICMPv6,否则会失联。回滚方式是还原配置文件后重启网络服务,或按备份文件重放 ip -6 命令。
常见问题
Q:服务器有 IPv6 地址,但 curl -6 访问不了 IPv6 网站,第一步查什么?
先 ip -6 route show default 看有没有默认路由。没有就是没配网关,加上即可。有的话再 ping6 网关和外部地址,逐步判断是路由还是上游问题。
Q:为什么配默认路由时提示 "Network is unreachable"?
多半是网关地址写成了链路本地地址却没指定出接口,或者指定的接口上没有对应网段的地址。网关是 fe80:: 时务必带 dev eth0,并且该网卡要有 IPv6 地址。
Q:IPv6 需要像 IPv4 那样做 NAT 吗?
不需要,IPv6 设计上追求端到端可达,全球单播地址可直接路由。但很多云环境出于安全考虑仍会做 IPv6 的防火墙或前缀委派。如果不确定,问一下云厂商的 IPv6 策略。
Q:ping6 网关通,但外部 IPv6 不通,是不是上游问题?
很可能是。检查云控制台的安全组是否放行了 IPv6 出向流量,以及子网是否真的启用了 IPv6 路由。也可以用 traceroute6 看断在哪一跳。
Q:怎么禁止某台服务器使用 IPv6?
单接口禁用:sysctl -w net.ipv6.conf.eth0.disable_ipv6=1;全局禁用:sysctl -w net.ipv6.conf.all.disable_ipv6=1,并写入 /etc/sysctl.d/ 持久化。也可以在 GRUB 内核参数加 ipv6.disable=1,但那样重启后彻底关闭 IPv6。禁用前想清楚是否有服务依赖 IPv6。
总结
IPv6 默认路由和 IPv4 原理相同,但网关多数是链路本地地址 fe80:: 开头,配置时必须用 via <网关> dev <接口> 指明出接口,这是最大的差异点。
手工配置三步:ip -6 addr add <地址/前缀> dev eth0 加地址,ip -6 route add default via <网关> dev eth0 加默认路由,再用 ip -6 route get 和 ping6 验证。
持久化按发行版选择:RHEL 系用 ifcfg(IPV6_DEFAULTGW 带 %接口)或 nmcli,Debian 用 /etc/network/interfaces,Ubuntu 18.04+ 用 netplan 的 routes(链路本地网关配 on-link: true),远程改首选 netplan try。
连通性测试顺序是 ::1 → 本机全局地址 → 网关(带 %eth0)→ 外部 IPv6 → DNS → curl -6,逐层定位。
IPv6 依赖 ICMPv6 做邻居发现,防火墙不能把 ICMPv6 全封;注意 /64 前缀、RA 与手工配置冲突、以及所有变更前备份与回滚。
企业QQ咨询




