做运维这几年,我见过太多团队因为IPv4地址不够用焦头烂额。NAT一层套一层,网络拓扑越做越复杂,排查问题像在走迷宫。而IPv6,这个喊了十几年的"下一代互联网协议",终于从"未来"变成了"现在进行时"。
2019年11月25日,全球最后一批IPv4地址分配完毕。这不是某个遥远的预言,而是我们每个运维都必须面对的现实。今天这篇文章,我会从最基础的概念讲起,带你走完IPv6从入门到落地的全过程。
全文约5000字,涵盖IPv6核心概念、与IPv4的本质区别、Linux三大主流发行版配置实战、以及运维工作中最常见的排障技巧。建议收藏,需要的时候可以随时查阅。
一、IPv6到底是什么?为什么我们必须用它
很多人第一次接触IPv6,最大的感受就是:这地址怎么这么长?
让我们从最直观的对比开始:
IPv4地址:32位,写成4组十进制数,比如 192.168.1.1。总数约43亿个,听起来很多,但实际上早就不够用了。
IPv6地址:128位,写成8组十六进制数,比如 2001:0db8:85a3:0000:0000:8a2e:0370:7334。总数是多少呢?340,282,366,920,938,463,463,374,607,431,768,211,456个。
这个数字大到什么概念?如果把地球表面都铺满沙子,每个沙子都能分到一个IPv6地址还绰绰有余。
1.1 IPv6地址的缩写规则
128位写出来太长了,所以IPv6有一套标准的缩写规则:
• 每组中的前导零可以省略:2001:0db8 → 2001:db8
• 连续的全零组可以用双冒号 :: 代替,而且只能用一次:
# 原始地址
2001:0db8:0000:0000:0000:0000:0000:0001
# 省略前导零
2001:db8:0:0:0:0:0:1
# 用::压缩连续零
2001:db8::1
这里有个坑:::只能出现一次。如果写成 2001::1::1,计算机就不知道中间该补多少个零了。
1.2 IPv6地址类型
IPv6地址主要分三类,记住这三个前缀就够了:
• 链路本地地址(Link-Local):以 fe80::/10 开头,同一个局域网内通信使用,相当于IPv4的169.254.x.x。每个网卡启用IPv6后自动生成,不需要配置。
• 唯一本地地址(ULA):以 fc00::/7 开头,相当于IPv4的内网地址(192.168.x.x、10.x.x.x),只能在内网使用,不可路由到公网。
• 全局单播地址(Global Unicast):以 2000::/3 开头,公网可路由的地址,相当于IPv4的公网IP。
1.3 IPv6 vs IPv4:不只是地址变长了
很多人以为IPv6只是"地址更多的IPv4",其实两者的设计理念差得很远:
• NAT的消亡:IPv4时代因为地址不够,我们不得不搞NAT地址转换。但NAT破坏了端到端的连接模型,P2P应用、VoIP、在线游戏都深受其害。IPv6地址充足,每个设备都能拥有公网地址,彻底告别NAT。
• 即插即用(SLAAC):IPv6设备可以自动配置自己的地址,不需要DHCP服务器。开机接入网络,自动获取前缀,加上自己的接口ID,就能上网。
• 组播(Multicast)优化:IPv6没有广播(Broadcast),全部改用组播。这大大减少了网络中的无效流量,对物联网设备尤其友好。
• IPSec内置支持:IPv6原生支持IPSec加密,理论上更安全。虽然实际用的人不多,但这是设计上的进步。
二、Linux系统:先确认你的系统支持IPv6
现代Linux发行版(2010年以后的)基本都默认开启了IPv6支持,但保险起见,我们还是先检查一下。
2.1 检查内核是否支持IPv6
# 方法1:查看/proc/net/if_inet6是否存在
cat /proc/net/if_inet6
# 方法2:检查内核模块
lsmod | grep ipv6
# 方法3:最直接的命令
sysctl net.ipv6.conf.all.disable_ipv6
如果最后一条命令返回 net.ipv6.conf.all.disable_ipv6 = 0,说明IPv6已经启用。如果是1,说明被禁用了。
2.2 如果IPv6被禁用了怎么办
有些服务器厂商的镜像会默认关闭IPv6,需要手动开启:
# 临时开启(重启后失效)
sysctl -w net.ipv6.conf.all.disable_ipv6=0
sysctl -w net.ipv6.conf.default.disable_ipv6=0
# 永久开启
echo 'net.ipv6.conf.all.disable_ipv6 = 0' >> /etc/sysctl.conf
echo 'net.ipv6.conf.default.disable_ipv6 = 0' >> /etc/sysctl.conf
sysctl -p
还有一些系统是通过grub参数禁用IPv6的,检查 /etc/default/grub 里是否有 ipv6.disable=1,如果有,删掉然后更新grub。
三、三大主流发行版IPv6配置实战
这部分是全文的核心。我会分别介绍CentOS/RHEL、Ubuntu、Debian这三个最常用服务器发行版的配置方法。
3.1 CentOS/RHEL 7/8/9 系列
CentOS系列用NetworkManager管理网络,配置文件在 /etc/sysconfig/network-scripts/ 目录下。
# 第一步:找到你的网卡名
ip addr show
# 假设网卡是eth0,编辑配置文件
vi /etc/sysconfig/network-scripts/ifcfg-eth0
# 添加或修改以下内容:
IPV6INIT=yes
IPV6_AUTOCONF=no # 关闭自动配置,用静态地址
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6ADDR=2408:xxxx:xxxx:xxxx::100/64 # 你的IPv6地址/前缀长度
IPV6_DEFAULTGW=fe80::1 # 网关地址(通常是链路本地地址)
IPV6_DNS1=2400:3200::1 # 阿里IPv6 DNS
IPV6_DNS2=2400:3200:baba::1
# 重启网络服务生效
systemctl restart NetworkManager
注意:CentOS 9已经弃用network-scripts,全部改为nmcli命令配置:
# CentOS 9 nmcli方式配置
# 查看连接列表
nmcli con show
# 修改连接的IPv6配置
nmcli con mod 'Wired connection 1' \\
ipv6.method manual \\
ipv6.addresses '2408:xxxx::100/64' \\
ipv6.gateway 'fe80::1' \\
ipv6.dns '2400:3200::1,2400:3200:baba::1'
# 重启连接
nmcli con up 'Wired connection 1'
3.2 Ubuntu 18.04/20.04/22.04 系列
Ubuntu从17.10开始改用netplan管理网络,配置文件是YAML格式。
# 编辑netplan配置文件(文件名可能不同)
vi /etc/netplan/00-installer-config.yaml
# 添加IPv6配置:
network:
ethernets:
eth0:
addresses:
- 2408:xxxx:xxxx:xxxx::100/64 # IPv6地址
gateway6: fe80::1 # IPv6网关
nameservers:
addresses:
- 2400:3200::1 # DNS1
- 2400:3200:baba::1 # DNS2
version: 2
# 应用配置
netplan apply
YAML对缩进极其敏感,必须用两个空格,不能用Tab。配置错了轻则不生效,重则网络直接断掉。配置前最好开个屏幕会话,免得连不上服务器。
3.3 Debian 系列
Debian传统上用interfaces文件配置网络:
vi /etc/network/interfaces
# 添加以下内容
iface eth0 inet6 static
address 2408:xxxx:xxxx:xxxx::100/64
gateway fe80::1
dns-nameservers 2400:3200::1 2400:3200:baba::1
# 重启网络
systemctl restart networking
新版Debian 12也开始支持netplan了,配置方法和Ubuntu一样。
四、配置完别着急走:验证与测试
配置完网络,第一件事就是验证配置是否生效。千万不要配置完就关终端走人,下次连不上哭都来不及。
4.1 查看IPv6地址
# 最常用命令
ip -6 addr show
# 查看指定网卡
ip -6 addr show eth0
# 传统ifconfig(需要net-tools)
ifconfig eth0
正常情况下,你应该能看到至少两个地址:一个 fe80:: 开头的链路本地地址,一个你配置的全局单播地址。
4.2 查看IPv6路由表
ip -6 route show
# 你应该能看到类似这样的默认路由
default via fe80::1 dev eth0 proto ra metric 1024
4.3 连通性测试
这一步最关键。IPv6的ping命令是 ping6,或者新版iputils的 ping -6。
# 先ping网关
ping6 -c 3 fe80::1%eth0 # 注意:链路本地地址需要加%网卡名
# ping公网IPv6 DNS
ping6 -c 3 2400:3200::1
# ping域名(测试DNS解析)
ping6 -c 3 ipv6.google.com
ping6 -c 3 www.6rank.edu.cn
重要提醒:ping链路本地地址时,必须加上 %网卡名,比如 fe80::1%eth0。因为fe80开头的地址每个网卡都有,系统不知道该走哪个网卡。
4.4 常用的IPv6测试地址
收藏这些测试地址,排障的时候用得上:
• 阿里DNS:2400:3200::1
• 腾讯DNS:2402:4e00::
• 谷歌DNS:2001:4860:4860::8888
• 清华IPv6测试站:www.6rank.edu.cn
五、运维排障:最常见的IPv6坑及解决方法
这是我这几年踩过的坑,以及帮客户解决过的问题。IPv6看似简单,实际落地时坑真不少。
5.1 问题一:能ping6地址,但ping6域名不通
症状:ping6 2400:3200::1 通,但 ping6 ipv6.google.com 不通。
排查思路:
# 第一步:检查DNS是否返回了AAAA记录
nslookup -type=aaaa ipv6.google.com
# 或者
dig AAAA ipv6.google.com
# 如果没有返回AAAA记录,说明DNS服务器不支持IPv6解析
# 换一个IPv6 DNS试试
# 第二步:检查/etc/resolv.conf
cat /etc/resolv.conf
# 确保nameserver配置的是支持IPv6的DNS
常见原因:很多内网DNS只配置了IPv4的转发,没有IPv6转发能力。这种情况要么换成公网DNS,要么在内网DNS上配置IPv6转发。
5.2 问题二:IPv6地址配置了,但无法访问外网
症状:ip -6 addr能看到地址,ping网关也通,但ping公网地址不通。
排查思路:
# 第一步:检查默认路由
ip -6 route show default
# 如果没有默认路由,手动添加
ip -6 route add default via fe80::1 dev eth0
# 第二步:检查防火墙是否阻止了IPv6流量
ip6tables -L -n -v
# CentOS 7/8可能默认阻止了IPv6转发
sysctl net.ipv6.conf.all.forwarding
# 如果是0,需要开启转发
sysctl -w net.ipv6.conf.all.forwarding=1
我遇到过的真实案例:某客户配置完IPv6后死活上不了网,排查了整整一天,最后发现是云平台的安全组里没有放行IPv6的出站流量。白名单只加了IPv4,忘了加IPv6。
5.3 问题三:SSH连接IPv6地址很慢
症状:用IPv4连接SSH很快,用IPv6连接要等好几秒甚至十几秒。
原因:SSH默认开启了DNS反向解析,服务器收到连接后会反向解析客户端的IPv6地址,如果DNS配置有问题,解析超时就会很慢。
# 解决方法:关闭SSH的DNS解析
vi /etc/ssh/sshd_config
# 找到或添加
UseDNS no
# 重启SSH服务
systemctl restart sshd
这个问题在IPv4环境下也存在,但IPv6环境下尤为明显,因为很多IPv6的PTR记录根本就没配置。
5.4 问题四:应用程序不监听IPv6地址
症状:IPv6网络通了,但Nginx、MySQL等服务只能用IPv4访问,用IPv6访问不了。
# 检查服务监听地址
netstat -tulpn | grep :80
# 或者(更推荐)
ss -tulpn | grep :80
# 如果看到的是 0.0.0.0:80,说明只监听IPv4
# 如果看到的是 :::80,说明同时监听IPv4和IPv6
# Nginx配置示例
vi /etc/nginx/nginx.conf
# 改为监听双栈
listen 80;
listen [::]:80 ipv6only=off;
# MySQL配置
vi /etc/my.cnf
bind-address = :: # 监听所有IPv6地址(同时也监听IPv4)
这里有个知识点:当服务监听 :: 时,Linux默认会同时接受IPv4和IPv6连接(IPv4映射为IPv4-mapped IPv6地址)。所以很多情况下,只要把bind-address从0.0.0.0改成::,就能双栈兼容。
5.5 问题五:iptables只配了IPv4,忘了IPv6
这是最容易踩的坑。很多运维把IPv4的防火墙配得滴水不漏,却完全忘了还有ip6tables这回事。结果IPv6一开,等于裸奔。
# 查看当前ip6tables规则
ip6tables -L -n -v
# 如果是空的,赶紧加上基本规则
# 允许本地回环
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A OUTPUT -o lo -j ACCEPT
# 允许已建立的连接
ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 允许SSH
ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT
# 允许ping6(可选,但建议开启)
ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -j ACCEPT
# 默认拒绝
ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP
# 保存规则(CentOS)
service ip6tables save
# Ubuntu/Debian
ip6tables-save > /etc/ip6tables/rules.v6
重要:IPv6的ICMPv6非常重要,比如邻居发现(NDP)就靠ICMPv6工作。不要像IPv4那样把ICMP全禁了,至少要允许邻居发现的相关类型。
六、进阶配置:IPv6运维最佳实践
6.1 双栈 vs 纯IPv6
目前阶段,强烈建议采用双栈模式(同时启用IPv4和IPv6)。因为还有大量网站和服务只支持IPv4,纯IPv6环境下很多事情做不了。
双栈的正确姿势是:
• 对外服务:DNS同时返回A记录和AAAA记录,让客户端自己选择用哪个
• 内部通信:能用IPv6就优先用IPv6,逐步减少对IPv4的依赖
• 监控告警:两套网络都要监控,不能只监控IPv4
6.2 IPv6地址规划建议
IPv6地址空间很大,但也不能乱分配。建议按用途规划:
• ::1 - ::100:网络设备(路由器、交换机、防火墙)
• ::101 - ::200:服务器
• ::201 - ::254:网关、负载均衡
后面留给动态分配的客户端设备。这样规划的好处是,看地址就知道是什么设备,排障时心里有数。
6.3 监控IPv6的几个关键点
# 1. 监控IPv6地址是否存在
ip -6 addr show eth0 | grep -q 'inet6.*global'
# 2. 监控IPv6默认路由
ip -6 route show | grep -q 'default'
# 3. 定期ping6测试连通性
ping6 -c 1 -W 2 2400:3200::1 > /dev/null 2>&1
# 4. 监控NDP邻居表(类似IPv4的ARP表)
ip -6 neigh show
很多监控系统默认只监控IPv4,记得把IPv6的监控也加上。不然IPv6断了半个月都没人发现。
6.4 常用的IPv6工具
最后推荐几个IPv6排障常用的工具:
# traceroute6 - IPv6路由追踪
traceroute6 ipv6.google.com
# tcpdump - 抓IPv6包
tcpdump -i eth0 ip6
tcpdump -i eth0 icmp6 # 只抓ICMPv6
# mtr - 综合路由测试(支持IPv6)
mtr -6 2400:3200::1
# curl - 用IPv6访问网站
curl -6 https://ipv6.google.com
总结一下
IPv6的推广是必然趋势,早学会早受益。今天我们从最基础的概念讲起,覆盖了:
• IPv6地址格式与缩写规则,三大地址类型
• IPv6与IPv4的本质区别,为什么我们必须迁移
• CentOS、Ubuntu、Debian三大发行版的配置方法
• 配置验证与连通性测试的完整流程
• 五大常见故障及排障思路
• 运维最佳实践与常用工具
这篇文章前后花了我整整一周时间整理,从基础概念到实战排障,把我这些年在IPv6上踩过的坑都写进去了。如果你觉得有用,欢迎转发给你的同事和朋友。
技术在变,但学习的态度不变。我们下期见。
🏷️ #IPv6 #Linux运维 #网络技术 #系统管理员