跳转到内容
严选跨境网络服务与流媒体推荐
实机测速保障 · 专属折扣
声明:以上服务由影迷漫游评测实验室进行晚高峰抽测与流媒体解锁验证。专属链接包含推广支持,不增加您的购买成本。

甲骨文云 Debian IPv6 配置指南:DD 后自动获取与排障 ​

Oracle Cloud Debian IPv6 Configuration

在甲骨文云上用 DD 方式重装 Debian 后,一个很常见的现象是:IPv4 好好的,IPv6 却怎么都不通。不少人第一反应是实例本身没有 IPv6,但多数情况下问题不在云端,而在系统里——DD 写入了一套新的网络配置,把原来能拿到 IPv6 的那套机制盖掉了。IPv4 照常用,是因为它的获取路径没变;IPv6 断掉,是因为它依赖的那条链路断了。本文就从这条链路讲起,用 Debian 自带的 systemd-networkd 把 IPv6 恢复成自动获取,并把排障的路子一并讲清。

先看清 IPv6 在甲骨文云里的位置 ​

动手改配置之前,先把甲骨文云里 IPv6 的来龙去脉捋一遍,后面排障时才知道该查哪一环。地址是从控制台一层层分下来的:虚拟云网络 VCN 拿到一段较大的 IPv6 段,习惯上是一个 /56;子网再从中切出 /64 给实例用;实例的网卡(VNIC)绑定到子网后,系统通过路由通告拿到地址前缀,再结合本地规则生成全球单播地址。任何一环没接上,系统里都不会出现可用的 IPv6。

路由和安全规则是另外两个容易漏的环节。路由表里需要有一条指向互联网网关的 ::/0,这样 IPv6 流量才知道往外走;安全列表里需要放行 IPv6 流量,否则地址拿到了、包也被拦在门口。这两处都在控制台里,不在系统配置文件里,所以只改系统是改不好的——排障时要先分清问题在云端还是在系统里。

还有一个 DD 特有的问题:DD 后的系统默认用 ifupdown 管网络,而甲骨文云的 IPv6 分配机制和 ifupdown 配合得不好。ifupdown 本身不是坏工具,只是在这条链路上,它拿不到系统需要的通告和地址,于是就有了“DD 后 IPv6 失效”这个反复出现的症状。解决办法不是给 ifupdown 打补丁,而是换一套更合适的网络管理方式,也就是下面要用的 systemd-networkd。它是 Debian 自带的,不用额外装,配置也直白,适合把这件事一次性做对。

为什么 DD 的镜像偏偏丢 IPv6 ​

甲骨文云官方镜像和 DD 镜像走的是两条不同的初始化路线。官方镜像启动时,cloud-init 会读取实例的元数据,把 VCN、子网、安全规则和地址信息一次性写成系统能用的配置,IPv6 从第一次启动就是通的。DD 镜像没有这条路:它是一份通用的 Debian 系统盘,启动后只按自己的默认规则配网,IPv4 靠 DHCP 能自己拿到,IPv6 需要的通告和链路配置却没人替它接上。于是就有了这个看似矛盾的现象——机器明明在支持 IPv6 的子网里,系统里却连个全球地址都没有。

理解这一点有两个好处。第一,排障时不用怀疑实例本身:只要控制台里子网和 VNIC 都有 IPv6,问题基本都在系统配置这一侧。第二,换系统后要重做这件事:以后每次 DD 或者换发行版,都要重新走一遍本文的流程,它不是一次配置终身有效的东西,而是每次重装都要接的一条线。把这条线记下来,比记住某几条命令更有用。

动手之前:三件事先确认 ​

第一件是控制台。登录甲骨文云,确认 VCN 已经添加了 IPv6 段、子网启用了 IPv6、路由表里有指向互联网网关的 ::/0、安全列表放行了 IPv6 流量、实例的 VNIC 上已经分配了 IPv6 地址。控制台这部分如果还没做,系统里改什么都不会生效;控制台的开启步骤可以看站内这篇甲骨文云免费服务器开启 IPv6,先把云端这一侧接通再回来。

第二件是备份。改网络配置之前,把现有的 interfaces 文件复制一份,把当前的地址和路由输出存下来。这样即使新配置出了问题,也能按原样恢复,不用凭记忆重建。备份花不了一分钟,却是整篇操作里最值得做的一步。

第三件是防断连。网络配置一改,SSH 很可能跟着断。稳妥的做法是先开好甲骨文云控制台里的串行控制台当备用通道,或者把所有命令准备好一次性执行,再或者设一个几分钟后自动恢复原配置的定时任务当保险。三者任选其一即可,目的是让一次失误不至于把自己锁在机器外面。

bash
# 备份 interfaces 文件
sudo cp /etc/network/interfaces /etc/network/interfaces.backup

# 存一份当前网络状态
ip addr show > ~/network_backup.txt
ip route show >> ~/network_backup.txt

配置步骤:从看网卡到切过去 ​

第一步是确认网卡名字。甲骨文云实例的网卡名因架构而异,常见的有 ens3 和 enp0s6,但不要凭印象写,一定要用命令看一眼。默认路由对应的那块网卡,或者带有 IPv4 地址的那块,就是你要配置的网卡。后面所有配置文件和命令里的网卡名都要换成实际看到的这一个,抄错名字是新手最常见的翻车点。

bash
# 查看所有网卡
ip link

# 查看默认路由对应的网卡
ip route | grep default | awk '{print $5}'

第二步是写 systemd-networkd 的配置文件。文件放在 /etc/systemd/network/ 目录下,名字以数字开头表示优先级,用 10- 加网卡名就很清楚。配置的核心思路是:IPv4 继续走 DHCP,IPv6 启用链路本地地址,让系统通过路由通告自动获取全球地址;NTP 指向甲骨文云的元数据服务地址,保持时间同步;DHCP 的 DNS 和域名搜索列表关掉,避免和系统已有的解析配置冲突。

ini
# /etc/systemd/network/10-ens3.network(网卡名请换成实际值)
[Match]
Name = ens3

[Network]
DHCP = ipv4
LinkLocalAddressing = ipv6
NTP = 169.254.169.254

[DHCP]
UseDNS = false
UseDomains = false

第三步是一次性切换。先停掉传统的 networking 服务,再启动 systemd-networkd 和 systemd-resolved,这几条命令要用 && 连起来一次执行完,中间不要留出网络已停、新服务未起的空档。执行完先别急着往下走,立刻测一下 IPv4 和 IPv6 是否都通——如果 SSH 还连着,说明切换成功了;如果断了,就用准备好的串行控制台接回去查。

bash
# 一次性执行:停旧服务,起新服务(网卡名请换成实际值)
sudo systemctl stop networking && \
sudo systemctl stop ifup@ens3 && \
sudo systemctl start systemd-networkd && \
sudo systemctl start systemd-resolved

# 测 IPv4 和 IPv6 是否都通
ping -c 3 8.8.8.8
ping -6 -c 3 2001:4860:4860::8888

第四步是收尾。确认 IPv6 正常后,把 systemd-networkd 和 systemd-resolved 设为开机自启,重启一次验证配置能持久化。至于要不要卸载 ifupdown,建议先别急着删:先只禁用 networking 服务跑一段时间,确认重启后一切正常,再考虑卸载。卸载是不可逆的清理,留着旧工具当退路并不丢人,真正稳定之后再清也不迟。

bash
# 设置开机自启
sudo systemctl enable systemd-networkd
sudo systemctl enable systemd-resolved

# 先只禁用旧服务,稳定后再考虑卸载
sudo systemctl disable networking

连通性验证:四个点逐一过 ​

配置切过去之后,验证要分四个点查,缺一个都不能算真正通了。先看地址:用 ip -6 addr show 看网卡上有没有 scope global 的地址,有全球地址才算拿到了;同时会看到一个 fe80 开头的链路本地地址,那是内网通信用的,不代表能上公网,不要把两者混为一谈。地址后面还会跟有效期,动态获取的地址有效期是有限的,到期会自动续,这是正常现象。

bash
# 查看 IPv6 地址(注意找 scope global 的那一行)
ip -6 addr show

# 预期能看到类似这样的全球地址(地址请换成实际值)
# inet6 2001:db8:abcd:ef00::1/64 scope global dynamic
# inet6 fe80::1/64 scope link

再看路由:ip -6 route show 里应当有一条经由网卡的 ::/0 默认路由,协议标注为 ra,意思是它来自路由通告。如果地址有了、默认路由没有,包还是出不去,这就是典型的“拿到地址但上不了网”,后面排障会专门讲。接着测连通:先直接 ping 一个 IPv6 地址,通了说明网络层没问题;再用域名测一次,如果 IP 通、域名不通,问题就在 DNS,不在路由。最后测实际服务,比如用 curl 走 IPv6 抓一个支持 IPv6 的站点,确认应用层也能走通。

bash
# 查看 IPv6 默认路由
ip -6 route show

# 先测 IP,再测域名,分清是路由问题还是 DNS 问题
ping -6 -c 4 2001:4860:4860::8888
curl -6 https://ipv6.google.com

最后还有一步容易被跳过:从外面验证。只在本机上 ping 通还不够,因为本机的出方向和外面的入方向走的是两套规则。找另一台机器,或者用在线的 IPv6 测试页,从外网向这台机器的 IPv6 地址发起一次连接,确认入方向也是通的。如果外面连不进来,先查安全列表和系统防火墙,而不是回头怀疑地址配置——地址、路由、DNS 都通的情况下,入方向不通几乎总是规则问题。

常见问题排障 ​

拿不到地址:先分清云端还是系统 ​

地址完全拿不到时,排查要从外往里。先回控制台确认 VNIC 上确实分配了 IPv6 地址,子网和路由都没问题;再看系统日志,用 journalctl 跟 systemd-networkd 的输出,常见的报错无非三类:配置文件语法不对、网卡名没匹配上、权限不对。配置文件写错一个字母服务就起不来,日志里会直接指出来;网卡名不对时服务虽然起了,但匹配不到任何设备,自然也不会有地址。还有一个容易忽略的点:路由器通告。系统拿地址依赖通告,如果通告没过来,可以用 ndisc6 工具包里的 rddisc6 主动探一次,确认链路上有没有通告在发;如果通告本身就没有,问题在云端配置,不在系统里。

bash
# 跟 systemd-networkd 的日志
sudo journalctl -u systemd-networkd -f

# 确认路由器通告(需安装 ndisc6)
sudo rddisc6 ens3

通而不稳:地址在,体验差 ​

地址能拿到、但时断时续或者某些网站打不开,多半出在三个地方。一是安全列表:IPv6 的入站和出站规则要单独放行,只放了 IPv4 规则是不够的,ICMPv6 尤其不能拦——IPv6 依赖 ICMPv6 做邻居发现和路径探测,把它拦掉会出现各种似通非通的怪现象。二是 MTU:甲骨文云实例常用 9000 的巨型帧,如果链路中间有设备不支持大包,就会出现大页面打不开、小页面正常的症状,这时可以先把 MTU 降下来验证,再决定永久值。三是隐私扩展:系统默认可能定期更换临时地址,个别长连接应用会因此中断,不需要这个行为时可以在 sysctl 里关掉它,让地址保持稳定。

bash
# 临时调整 MTU 验证(永久值写进 .network 文件的 [Link] 段)
sudo ip link set dev ens3 mtu 9000

# 关闭 IPv6 隐私扩展(按需,写入 sysctl 配置后用 sysctl -p 生效)
# net.ipv6.conf.all.use_tempaddr = 0
# net.ipv6.conf.default.use_tempaddr = 0

安全组漏放:地址有了,服务进不来 ​

这是最容易被误判成“IPv6 没配好”的一类问题:本机 curl 能通、外面却连不进来。先确认安全列表里放行了对应端口的 IPv6 入站,甲骨文云的安全列表对 IPv4 和 IPv6 是分开写的,只写 0.0.0.0/0 不等于放行了 ::/0。系统侧的防火墙同样要单独配 IPv6 规则,ip6tables 和 iptables 是两套表,IPv4 的放行规则不会自动覆盖 IPv6。写规则时注意两点:ICMPv6 必须放行,已建立连接的回包要放行,端口规则里用 conntrack 而不是已经过时的 state 匹配写法。

bash
# IPv6 防火墙示例(端口请换成实际需要的值)
sudo ip6tables -A INPUT -p icmpv6 -j ACCEPT
sudo ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT

重启后丢失:开机自启没接上 ​

重启后 IPv6 消失,先查两件事:systemd-networkd 是不是开机自启状态,配置文件是不是还在原位置。如果服务没设自启,重启后自然没人去拿地址;如果配置文件被别的工具覆盖过,服务起了也匹配不到。还有一个冲突源是 NetworkManager:如果它也在运行并接管了同一块网卡,两套网络管理打架,结果就是时好时坏,确认之后把它停掉并禁用,让 systemd-networkd 独管这块网卡。

bash
# 确认开机自启与配置文件
systemctl is-enabled systemd-networkd
ls -l /etc/systemd/network/10-*.network

# 排查 NetworkManager 冲突
systemctl status NetworkManager

实在修不好:回滚 ​

如果新配置怎么调都不对,先恢复到改动之前的状态再慢慢查,不要在断网的机器上硬试。停掉 systemd-networkd,把备份的 interfaces 文件拷回去,启动传统网络服务,网络就回到 DD 刚完成时的样子。回滚不是失败,而是把问题隔离到一个已知状态——很多时候恢复之后再对照着改一次,第二次就通了。

bash
# 停新服务,恢复备份,起旧服务
sudo systemctl stop systemd-networkd
sudo cp /etc/network/interfaces.backup /etc/network/interfaces
sudo systemctl start networking

可选进阶:静态地址、转发与防火墙 ​

动态获取够用之后,有三类进阶需求值得单独提一句,但都不必在第一次配置时就上。第一是静态地址:如果你需要一个长期不变的 IPv6,可以在 .network 文件里直接写 Address 和 Gateway,但前提是这个地址已经在控制台里预留好,否则写上去也是冲突的;动态环境一般没必要这么做。第二是转发:如果这台机器要给别的设备做路由,需要在 sysctl 里打开 IPv6 转发,这会改变机器的角色,打开之前先想清楚安全边界。第三是防火墙持久化:ip6tables 规则只存在于内存里,重启就丢,Debian 上通常用 iptables-persistent 这个包来存,安装时会问要不要保存当前规则,选是之后规则会写进 /etc/iptables/rules.v6,重启时自动恢复。还有一个更省事的办法是把规则写进 systemd 的服务单元里随网络服务一起加载,但对大多数人来说,用发行版自带的保存机制就够了,关键是不要只在命令行上敲完规则就以为万事大吉——重启丢规则的那次,往往就是服务暴露在外面的那次。

结尾 ​

甲骨文云 Debian 的 IPv6 配置,关键其实只有一条线:控制台把地址、路由、安全规则接通,系统里用 systemd-networkd 把地址拿下来,再用四个验证点确认真的通了。DD 之后失效,多数时候只是这条线在系统这一侧断了,换一套网络管理方式就能接回去。排障时记住从外往里查——先控制台,再日志,再路由和安全规则——大部分问题都能在半小时内定位。

下一步学习: