文章目录
  1. 1. IPv6快速入门教程
    1. 1.1. IPv6的现状
      1. 1.1.1. 为什么IPv6的发展最近加速了
    2. 1.2. IPv6之Hello World
      1. 1.2.1. IPv6地址自动配置
      2. 1.2.2. 三种IPv6地址的异同
    3. 1.3. IPv6有哪些优点
      1. 1.3.1. IPv6的全球公网地址
      2. 1.3.2. 测试公网访问个人笔记本
      3. 1.3.3. 公网地址的安全性
    4. 1.4. IPv6对开发者的影响
      1. 1.4.1. IPv6对编程的影响
      2. 1.4.2. IPv6对DNS的影响
      3. 1.4.3. IPv6对常用命令的影响
    5. 1.5. IPv4到IPv6的过渡方案
      1. 1.5.1. 双栈方案
      2. 1.5.2. 隧道技术
      3. 1.5.3. 翻译技术
    6. 1.6. 挖坑预告

转载请注明 作者:源码先生, 文章链接:https://www.debugself.com/2020/02/28/IPv6_guide/, 请勿用于商业用途

关注我,获取更多物联网IoT+云原生的技术分享。

八大物联网IoT上云协议快速入门教程
物联网IoT协议之mqtt快速入门教程
物联网IoT协议之OPC UA快速入门教程
物联网IoT协议之 LoRaWAN快速入门教程
物联网IoT协议之NB-IoT/CoAP快速入门教程
物联网IoT上云协议之Modbus快速入门教程
IPv6快速入门教程
物联网IoT协议之6LoWPAN快速入门教程
物联网IoT协议之HTTP快速入门教程
车联网V2X快速入门教程

IPv6快速入门教程

IPv6的现状

自1992年IPv6被提出来,二十年多IPv6一直处于叫好不叫座的状态,但是当前(2020年)IPv6在中国的发展现状,就得用“如火如荼”四个字来描述了。

2017年底国家印发了《推进互联网协议第六版(IPv6)规模部署行动计划》,要求以下领域全面支持IPv6
国内用户量排名前50位的商业网站及应用,省部级以上政府和中央企业外网网站系统,中央和省级新闻及广播电视媒体网站系统,工业互联网等新兴领域的网络与应用;域名托管服务企业、顶级域运营机构、域名注册服务机构的域名服务器,超大型互联网数据中心(IDC),排名前5位的内容分发网络(CDN),排名前10位云服务平台的50%云产品;互联网骨干网、骨干网网间互联体系、城域网和接入网,广电骨干网,LTE网络及业务,新增网络设备、固定网络终端、移动终端。上述要求印发后,中国IPv6的发展走上了快车道,各个大厂的应用竞先支持IPv6,比如

腾讯视频IPv6

​看到右下角的IPv6了吧,其他常见的APP,如淘宝、美团等在开屏页也可以看到IPv6字样,如果哪个APP没有IPv6字样,不是用户太少,就是江湖地位太低。

中国信通院2019-11-20发布了
首批移动互联网应用IPv6支持度测试结果发布,感兴趣的请自行围观,倘若瞄到几个对IPv6支持度是0%的APP,再一看名字,哎呦,是客大欺店的感觉。

为什么IPv6的发展最近加速了

《推进互联网协议第六版(IPv6)规模部署行动计划》中已经说得很明白了,IPv4地址已经消耗殆尽,而物联网、工业互联网、云计算、大数据、人工智能的发展又需要很多IP地址,没有IPv6不行啊,IPv6是其他产业的基础设施,要想富,先修路。

IPv6之Hello World

上面说IPv6发展很繁荣,理论上体验IPv6应该是件很容易的事,然而源码先生最开始练手IPv6时,在公司电脑上开启了IPv6功能。

Windows开启IPv6

开启IPv6后,本来能上网的电脑却上不了网了。原来,虽然Windows系统支持IPv6,但是公司的路由器却不支持IPv6。

然后看了看家里的路由器,8年前100多元买的,也不支持IPv6!

原来所谓的繁荣都是假象,IPv6的支持只局限在特定的范围,比如大厂的常用APP里!

现实生活里,IPv4依旧在完美的服役,老旧的路由器也能刷抖音,上一个离职员工编译出的程序,虽然只支持IPv4,但完全满足客户的要求。所以,当前IPv4依旧是主流。

要想体验IPv6,以下条件必须全部满足(这里以笔记本访问百度为例):

  • 笔记本必须支持IPv6,当前主流操作系统Windows,Linux,Android,IOS都已支持IPv6;
  • 笔记本连接的WIFI路由器必须支持IPv6,稍微老旧的路由器,很可能不支持IPv6;
  • 路由器上网的运营商必须支持IPv6,电信/移动/联动都支持IPv6了,但是城中村房东不知道从哪来的网络,大概率是不支持IPv6的;
  • 浏览器得支持建立IPv6套接字,大多数浏览器应该都支持IPv6;
  • 要访问的网站服务器必须支持IPv6,比如 www.baidu.com 是不支持IPv6的,要访问 ipv6.baidu.com 才行。

上述5个环节,只要有一个环节不支持IPv6,就无法享受IPv6的服务了。简单的说,IPv6的支持,需要较新的设备,这时请拿出手机。

由于手机厂商恨不得天天发新机,时不时弄出个吓人的技术,大家被吓的手机更新都比较快,所以大家的手机都是支持IPv6的,而移动运营商早已被强制要求支持IPv6,所以请打开手机的“移动数据”,通过[设置]–[系统]–[关于手机]–[状态消息]可以看到移动运营商同时分配给手机了IPv4和IPv6地址。

手机IPv6地址

IPv6地址长128位,通常写作8组,每组为四个十六进制数的形式;一个或多个连续的16bit字符为0时,可用“::”表示,但整个IPv6地址缩写中只允许有一个“::”,比如2400:da00:2::29是合法的IPv6地址。

然后打开京东APP,看到开屏页底部的IPv6字样,由于手机已经获取到IPv6地址,APP会优先选择IPv6访问服务器,所以此时肯定是通过IPv6通信的(当然手机使用WIFI时可能不支持IPv6,APP会自动使用IPv4上网)。IPv6的Hello World之旅到此结束。简单到让人怀疑,我还没感受到啥是IPv6呢。

猪八戒吃人参果

好吧,再看下Windows上使用IPv6的情况吧。首先开启笔记本的IPv6(见本文第二张图),然后打开手机的热点,让笔记本通过WIFI连接到手机的热点,然后看无线网卡的本地连接的详细信息。

本地连接

天啊,竟然有三个IPv6地址,好吧,这次慢点吃人参果,详细说明为什么需要三个IPv6地址,一切从IPv6地址自动配置开始。

IPv6地址自动配置

IPv4的时候,电脑获取IP地址有两种方式:

  • 管理员分配静态内网IP,然后用户手工配置该IP到电脑上
  • 用户配置电脑DHCP,通过DHCP自动获取动态内网IP

第一种需要管理员人工参与,第二种方式需要管理员提前在路由器上配置DHCP的分配规则,而且得到的IP都是内网IP(形如10.0.0.0/8, 172.16.0.0/12以及192.168.0.0/16)。由于IPv6的地址非常非常多,多到可以为地球上每一粒沙子分配一个独立的IP,基于这种优势,IPv6提出了更好的地址分配方式:即地址自动配置,IPv4的地址需要管理员人工参与IP地址的分配,而IPv6不需要了,IPv6的设备可以自己管理自己的IP地址啦!

首先IPv6设备根据本机的MAC地址自动生成IPv6本地链接地址,因为MAC地址是全球唯一的,所以本地地链接地址也是全球唯一的,地链接地址的固定以fe80::开头。我们知道数据链路层是通过MAC地址寻址通信的,所以IPv6本地链接地址主要用来和本地链路层其他设备直接通信,不能作为公网地址使用

有了IPv6本地链接地址,IPv6设备就可以本地其他设备通信了,其中最重要的是与路由器通信,从路由器获取网络前缀

IPv6网络前缀

默认情况下,128字节的IPv6地址,前64字节是网络前缀,后64字节是接口ID(也可以自定义分配,网络前缀+接口标识等于128字节即可)

网络前缀(也可以叫网段)是一层层分配的,比如按照国家–运营商–省–市一层层分配(类似身份证号码的划分),只要每层分配的数值唯一,就可以保证网络前缀是全球唯一的,64字节的网络前缀比IPv4的32字节大了不知道多少倍,做到全球唯一是完全没问题的。

对于普通用户,网络前缀由电信运营商分配,不用关心一层层如何分配的,反正到用户手里时,用户的路由器最终会得到一个全球唯一的网络前缀

设备使用本地链接地址,从路由器获取唯一网络前缀,然后根据一定的算法(比如使用MAC地址映射)自动生成接口标识,网络前缀+接口标识就是设备唯一的IPv6地址,前面的“ IPv6 地址”和“临时IPv6 地址”都是这样生成的。设备自己生成IPv6地址后,为了避免地址冲突,会使用IPv6定义的邻居发现(ND),尝试和其他设备(包括本地设备,以及公网上的设备)通信,如果其他设备回应IP地址冲突,设备需要抛弃当前的IP地址,然后重新生成新的IP地址;如果没有冲突,该IP就可以作为全球唯一的公网IP地址了。

IPv6也是支持DHCP的,但是不使用DHCP也没问题,IPv6根据上述流程也可以自动生成唯一IP的

三种IPv6地址的异同

  • 本地链接IPv6地址:根据MAC映射生成,只用来本地通信的地址,使用该地址通信,然后自动生成其他两种IP地址;
  • IPv6 地址:代表设备的全球唯一IP地址,可以直接用来全球公网通信;生成该地址时,可以使用固定的算法(比如MAC映射生成IPv6)生成接口标识,这样即使切换了网络环境,比如笔记本从家里的网络切换到了星巴克的网络,虽然网络前缀变化了,但是接口标识没有变化,这样依旧可以定位一个唯一的设备,MAC地址是唯一的,笔记本还是同一个笔记本嘛;
  • 临时IPv6地址:使用固定的接口标识容易被人唯一定位,暴露隐私,所以也可以生成非固定的接口标识;临时IPv6地址是Windows系统随机生成的IPv6地址,该地址用来作为公网通信,但是有效期比较短(按天计算?),防止被人定位。临时IPv6地址是可以禁用的,使用固定IPv6地址,还是使用临时IPv6地址,用户根据自己的需求自行配置。

IPv6有哪些优点

随便搜下,就可以看到IPv6的优点,比如:

  • IPv6具有更大的地址空间,可以有2的128次方个地址,大到可以做到“一沙一IP”
  • 更好的头部格式,IPV6使用新的头部格式,简化和加速了路由选择过程
  • IPv6 协议缺省支持 IPSec 协议,与 IPv4 环境下相比,无需另行部署加密手段即可实现数据加密传输
  • 配置自动化程度更高
  • 更好的服务质量(QoS)
  • 更好的支持移动设备,方便设备从一个地方移动到另外一个地方

其实吧,也没几个人关心这些细节,人们更关心的,更可能是用了IPv6,我比用IPv4多享受什么服务?

你将得到很多个全球唯一的公网IP地址!

IPv6的全球公网地址

在IPv4年代,我们从电信运营商购买了宽带,运营商只会分配给一个内网IP(形如10.0.0.0/8, 172.16.0.0/12以及192.168.0.0/16),这是因为公网IPv4不够用,运营商通过NAT技术,给多个用户分配不同的内网地址,当多个用户上网时,却复用了同一个公网IP地址;由于用户没有公网地址,用户是无法提供对外服务,比如家中有个NAS存储服务器,里面存放各种重要的文件,如果想从公司访问家里的文件,是无法直接访问,虽然可以通过各种NAT穿透(比如frp)技术间接访问,但是存在一定的技术门槛和额外的费用,总之,各种不方便。

IPv6来了,IPv6地址足够多,NAT也不再需要了,目前大部分运营商分配给用户的都是全球可访问的公网网段,注意是网段!是网段!是网段!即前面提到的网络前缀,有了这个网络前缀,用户可以自行划分IP地址给自己的N多设备了,而且所有IP地址都是全球可访问的,有下面的测试为证!

测试公网访问个人笔记本

源码先生在自己的笔记本(Win10系统)上,使用Node.js运行一个简单的Web服务器,然后通过公网来访问这个Web服务器。

首先用老婆的手机(联通4G卡)作为热点,笔记本开启IPv6并连接到这个热点上。笔记本获得了IPv6地址2408:84f3:81a:4d18:bc2e:583c:9658:2bb2。

另外要关闭系统的防火墙,不然防火墙会拦截下所有Web请求。

Win10关闭防火墙

编写名为http.js的脚本文件,代码如下(Node.js启动Web服务器是不是很简单,只需几行代码)

1
2
3
4
5
6
var http = require('http');

http.createServer(function(request, response){
response.writeHead(200, { 'Content-Type': 'text-plain' });
response.end('Hello World\n');
}).listen(80);

上面的代码中,只填写了端口80,没填写IP地址,Node.js默认会优先选择本地IPv6地址建立服务器的监听。这段代码中,所有的HTTP访问请求,服务器都会简单的返回“Hello World”。

在cmd中启动Web服务器

1
node http.js

最后我打开自己手机(移动4G卡)上的UC浏览器,输入http://[2408:84f3:81a:4d18:bc2e:583c:9658:2bb2]。正确看到了“Hello World”

手机访问IPv6地址

注意,我专门使用移动的4G网络,去访问联通的分配的IPv6地址,完全可以正常访问

目前大多数运营商的IPv6都是公网可访问的,不过有些运营商可能会限制IP地址的公网访问,不同地区、不同运营商的策略可能不同。

公网地址的安全性

IPv4中由于NAT的存在,个人的设备是作为内网主机都是隐藏在NAT后面,外部攻击是无法直接访问内网中的个人设备;而IPv6中,个人设备变成了公网可访问的主机,更容易被攻击了。为了安全起见,源码先生有如下建议:

  • 不暴露个人设备的IPv6地址;
  • 不随意搭建TCP/UDP服务器;
  • 电脑系统防火墙一定要开,系统自带的防火墙是能拦截大多数非法访问的

IPv6对开发者的影响

IPv6对编程的影响

开发者基于IPv4和基于IPv6编程区别大吗?

不大!

从的OSI标准7层网络模型看,IPv4和IPv6的区别主要是网络层的不同

OSI标准7层网络模型

这时候分层的优势就出来了,由于IPv4和IPv6主要是网络层有不同,不影响其他层,而开发者大多数都是针对应用层(如HTTP,mqtt)和传输层(TCP或UDP)来编程的,只有少部分特殊应用(比如抓包工具,网络分析工具)才会针对网络层编程,所以IPv6对开发者影响很小,把IPv4地址相关的代码(如192.168.10.100)修改为IPv6地址(如2408:84f3:81a:4d18:bc2e:583c:9658:2bb2)即可。

这里以Linux上C语言套接字编程为例,IPv4地址结构体的初始化为代码为:

1
2
3
4
struct sockaddr_in my_addr;         // IPv4地址结构体
my_addr.sin_family = PF_INET;
my_addr.sin_port = htons(myport);
my_addr.sin_addr.s_addr = inet_addr("192.168.10.100");

修改为IPv6地址结构体的初始化为代码为:

1
2
3
4
struct sockaddr_in6 my_addr;        // IPv6地址结构体  
my_addr.sin6_family = PF_INET6;
my_addr.sin6_port = htons(myport);
inet_pton(AF_INET6, "2408:84f3:81a:4d18:bc2e:583c:9658:2bb2", &my_addr.sin6_addr);

IPv4建立套接字和绑定地址的代码为:

1
2
sockfd = socket(PF_INET, SOCK_STREAM, 0);       // IPv4建立套接字
bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr));

IPv6建立套接字和绑定地址的代码为:

1
2
sockfd = socket(PF_INET6, SOCK_STREAM, 0);      // IPv6建立套接字
bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_in6));

其他函数如listen、send,write参数都是基于文件描述符fd的,所以IPv4和IPv6的代码是完全一样的

1
listen(sockfd, lisnum);                         // IPv4,IPv6监听端口的代码是一样的

源码先生网上找了个示例,可参考https://www.cnblogs.com/wuyuxuan/p/5541598.html

IPv6对DNS的影响

DNS用A(Address)记录表示域名对应的IPv4地址,Ubuntu中使用如下命令查看淘宝对应的IPv4地址:

1
dig www.taobao.com

返回结果中有两个IPv4地址:

1
2
3
4
;; ANSWER SECTION:
www.taobao.com. 516 IN CNAME www.taobao.com.danuoyi.tbcache.com.
www.taobao.com.danuoyi.tbcache.com. 36 IN A 101.37.183.170
www.taobao.com.danuoyi.tbcache.com. 36 IN A 101.37.183.171

DNS用AAAA记录表示域名对应的IPv6地址,Ubuntu中使用如下命令查看淘宝对应的IPv6地址:

1
dig www.taobao.com AAAA

返回结果中有两个IPv6地址

1
2
3
4
;; ANSWER SECTION:
www.taobao.com. 484 IN CNAME www.taobao.com.danuoyi.tbcache.com.
www.taobao.com.danuoyi.tbcache.com. 60 IN AAAA 240e:ff:d800:500:3::3f9
www.taobao.com.danuoyi.tbcache.com. 60 IN AAAA 240e:ff:d800:500:3::3fa

DNS服务器中可以只存在A记录(对应IPv4地址),可以只存在AAAA记录(对应IPv6地址),也可以同时存在A记录和AAAA记录。

以浏览器访问网站为例,当网站域名只存在A记录时,浏览器只能访问A记录对应的IPv4地址;当网站域名同时存在A记录和AAAA记录时,浏览器一般会智能判断:

  • 用户主机只支持IPv4时,浏览器会访问A记录对应的IPv4地址;
  • 用户主机只支持IPv6时,浏览器会访问AAAA记录对应的IPv6地址;
  • 用户主机同时支持IPv4和IPv6时,浏览器会优先访问AAAA记录对应的IPv6地址;

IPv6对常用命令的影响

Windows中ping IPv6地址

1
ping -6 ipv6.baidu.com

Linux中ping IPv6地址

1
ping6 ipv6.baidu.com

Linux中大部分命令通过-4、-6参数指定IPv4或者IPv6,比如查看traceroute的帮助

1
traceroute --help

帮助结果中可以看到

1
2
3
4
5
Options:
-4 Use IPv4
-6 Use IPv6
-d --debug Enable socket level debugging
-F --dont-fragment Do not fragment packets

其他命令如telnet、ssh、nc也都支持-4、-6这种用法。

浏览器中使用IPv6地址访问Web(2400:da00:2::29是百度的IPv6地址,可以在手机浏览器中访问测试),注意必须有[]:

1
http://[2400:da00:2::29]

Linux中使用curl 访问IPv6地址,注意IP地址必须有引号,且[]必须转义:

1
2
curl -v "http://\[2400:da00:2::29\]"
curl -v -6 "http://\[2400:da00:2::29\]" //等效上面,使用ipv6地址时,可以省略-6

IPv4到IPv6的过渡方案

IPv4只是没有更多地址分配了,但是已分配的地址是可以正常使用的,不要幻想IPv6完全替代IPv4,未来IPv4和IPv6是共存的。IPv4到IPv6的过渡主要有三种方案。

双栈方案

程序同时支持IPv4和IPv6,根据当前环境(本地IP地址,服务器IP地址等)动态选择IPv4或者IPv6。对于仅支持IPv4的程序,需要修改程序源码支持IPv6并重新编译,重新部署。

隧道技术

隧道技术主要用来解决孤岛问题,比如自己的电脑支持IPv6,无奈路由器或者运营商只支持IPv4,这时电脑要访问IPv6服务,可以借助隧道技术。

IPv6孤岛

隧道的原理,就是把IPv6的数据包封装为IPv4数据包,使用现有的IPv4网络传输IPv6数据。源码先生推荐个免费的隧道服务商https://www.tunnelbroker.net ,通过简单的配置,即使运营商不支持IPv6时,也可享受IPv6服务。

翻译技术

翻译技术是把IPv6数据转换为IPv4,而且转换过程对用户透明,用户正常访问IPv6,IPv6数据被后台自动转换为IPv4,用户感觉不到转换过程。基于这种技术,可以不用修改程序源码,不需要重新编译。

虽然存在各种过渡方案,其实最好建立纯IPv6服务,这样IPv6的优势才能体现出来,各种过渡方案由于依旧使用了IPv4,也丢失了IPv6的优势,过渡方案只时用来兼容旧设备的折中方案。

挖坑预告

本文主要讲了IPv6在通用场景的应用,这里预留个坑,后续用IPv6在物联网中的应用来填坑。