IPv6 配置与排错:该开还是该关

IPv6 在云服务器上基本都已经分配好了,但配置不当会带来一些奇怪的问题:能 ping 通 IP 但网站打不开、或者某些用户访问慢。

一、地址怎么读

bash
ip -6 a
# inet6 2400:xxxx:xxxx::1/64 scope global
# inet6 fe80::xxxx:xxxx/64 scope link
前缀类型说明
::1/128回环等于 IPv4 的 127.0.0.1
fe80::/10链路本地只在同网段有效,不能路由
2000::/3全局单播公网地址,就是我们要用的
fc00::/7唯一本地等于私网地址
ff00::/8组播

缩写规则:每组前导 0 可省略,连续多组 0 用 :: 代替(只能用一次)。

bash
# 这些是同一个地址
2400:cb00:2048:1:0:0:0:1
2400:cb00:2048:1::1

二、netplan 里配置

大多数云主机的 IPv6 是 SLAAC 自动分配的,不用手动配:

yaml
network:
  version: 2
  ethernets:
    eth0:
      dhcp4: true
      dhcp6: true
      # 或者只用 SLAAC
      accept-ra: true

手动配静态:

yaml
    eth0:
      addresses:
        - "2400:xxxx::10/64"
      routes:
        - to: "::/0"
          via: "2400:xxxx::1"
      nameservers:
        addresses:
          - "2606:4700:4700::1111"    # Cloudflare IPv6 DNS
          - "2400:3200::1"             # 阿里 IPv6 DNS
bash
sudo netplan try

三、测试连通性

bash
# ping(注意命令是 ping6 或 ping -6)
ping -6 -c 4 2606:4700:4700::1111

# 看地址
ip -6 a

# 看路由
ip -6 r

# 测试 IPv6 网站
curl -6 -I https://www.bzii.cn
curl -g -6 "http://[2400:xxxx::1]:80"    # 地址要用方括号

# 在线检测
# https://test-ipv6.com/

四、Nginx 监听 IPv6

nginx
server {
    listen 80;
    listen [::]:80;              # IPv6,方括号不能少

    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;

    server_name www.bzii.cn;
}
bash
sudo nginx -t && sudo systemctl reload nginx
ss -lntp | grep -E ":80|:443"
# 应该看到 tcp 和 tcp6 两行

常见坑:忘了加 listen [::]:80,导致 IPv6 用户访问不了。或者加了但 ipv6only 参数处理不当——现代 Nginx 默认 ipv6only=on 是正确的,不要手动改。

五、DNS 加 AAAA 记录

bash
dig +short AAAA www.bzii.cn
dig +short A www.bzii.cn

# 指定 IPv6 查询
dig -6 +short AAAA www.bzii.cn

在 DNS 控制台加一条:

类型主机
AAAA@2400:xxxx::1
AAAAwww2400:xxxx::1

Cloudflare 开橙色云的话,它会自动给 AAAA 记录,且 IPv6 是默认开启的。

六、双栈下的优先级问题

客户端同时有 A 和 AAAA 时,现代浏览器默认优先 IPv6(Happy Eyeballs 算法会在 IPv6 慢时快速回退 IPv4)。

可能带来的问题:

  • IPv6 通但路径差 → 部分用户访问慢;
  • 服务器 IPv6 没配好 → 部分用户直接打不开;
  • 日志里出现陌生的 IPv6 地址,封 IP 时要记得封整个 /64 段。
bash
# 封 IPv6 要封段(一个用户可能有很多地址)
sudo ip6tables -A INPUT -s 2400:xxxx::/64 -j DROP
sudo ufw deny from 2400:xxxx::/64

七、要不要开启

我的判断标准:

情况建议
云主机已分配且路径正常开,加 AAAA 记录
国内用户为主,IPv6 覆盖已不错开,能改善移动网络体验
配了但没验证过先关掉,配好了再开
用 Docker 且网络复杂先不开,Docker 的 IPv6 支持较麻烦

关键原则:要么完整配好并验证,要么干脆关掉。半配状态(有 IPv6 地址但服务没监听、或 DNS 有 AAAA 但不通)是最糟的,会造成间歇性访问失败。

临时关闭(排错用):

bash
sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
# 永久:写进 /etc/sysctl.conf
echo "net.ipv6.conf.all.disable_ipv6=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

八、Docker 与 IPv6

Docker 默认不启用 IPv6。要开的话:

json
{
  "ipv6": true,
  "fixed-cidr-v6": "fd00:dead:beef::/64",
  "experimental": true,
  "ip6tables": true
}

写入 /etc/docker/daemon.jsonsudo systemctl restart docker

个人站点我一般不在容器里开 IPv6:宿主机开 IPv6 供 Nginx 用就够了,容器内部走 IPv4 私网即可,少一层复杂度。