IPv6简介
https://segmentfault.com/a/1190000008794218
IPv6的优点
更大的地址空间
名字叫IPv6,但它的长度并不是64位,而是128位,总的地址空间大约为3.4*1038,一个亿是10的8次方,那么IPv6就有340万亿亿亿亿个地址(4个亿连一起),所以说给地球上的每一粒沙子分配一个IP地址不是在吹牛,是真可以。
可以参考这篇文章和这篇文章,里面提到地球上所有沙滩的沙子大约有7.5*1018粒,这个值跟IPv6的1038相差了很多个数量级,就算加上沙漠等其它的地方,IPv6的数量也足够覆盖它。
点到点通信更方便
IPv6完全有能力为联网的每个设备分配一个公网IP,于是我们可以不再需要NAT,从而非常方便的实现点到点的直接通信。
说好处之前,先了解一下NAT的缺点:
使用了NAT之后,每次通信都要做一次NAT转换,影响性能。
处于两个不同NAT网络内部的机器不能直接通信,他们之间的通信得依赖第三方的服务器,极大的限制了网络的连通性,同时所有的数据都会被第三方所监控。
为了支持NAT,很多网络协议变得很复杂,大大增加了网络的复杂性。
没有了NAT之后,当然上面的这些缺点也就没有了,同时会带来下面这些比较直观的好处:
更方便: 想象一下,每个电脑都有公网IP,你电脑出了点问题,找我帮忙看一下,只要把你的IP给我,我就可以连上去了,而我们现在的情况是,两个人都是内网IP,没法直接访问,非得用QQ共享桌面之类的软件。
更安全: 配合点到点的加密,让网络更安全,不给第三方监听的机会; 以网络聊天为例,通过使用点到点的聊天软件,就不用担心被人监听聊天记录了;同时访问家里的摄像头不再需要经过第三方服务器,不用担心给别人看直播了。
IP配置更方便
IPv6有一个功能叫Stateless Auto Configuration,简单点说,就是可以不借助DHCP服务器实现IP地址的分配,插上网线就能上网。
系统起来后,就会为每个网卡生成一个Link-Local的IP地址,简单点说就是一个固定的前缀加上mac地址,由于mac地址全球唯一,所以这样构成的IP地址是唯一的,有了这个地址后,就可以局域网进行通信了,但是这种地址路由器是不会转发的。
如果网络里有路由器; 系统会通过广播的方式问路由器,路由器会返回一个子网前缀,类似于IPv4里面的192.168.0.0/16,系统将子网前缀和mac地址组合起来,构成了一个唯一的IP地址,这个IP地址可以通过路由器路由。
也就是说,就算不做任何配置,系统启动起来后,网卡就一定会有IPv6地址,有了IPv6地址就可以通信。
当然IP地址也可以由DHCP6服务器来分配,这种方式分配叫做Stateful Auto Configuration。
局域网内更安全
由Neighbor Discovery代替了IPv4里面的ARP协议,没有ARP后,跟ARP相关的攻击就不存在了
路由更快
跟IPv4不同,IPv6包头的字段长度是固定的,没有可选字段,所以路由器不需要检查IP包头是否包含可选字段。
IPv6包头里面没有checksum字段,不需要像IPv4那样每次TTL减1后都需要重新计算包头的checksum。
IPv6不支持在中途被分片和重组,即不能在路由器和防火墙上被分片,从而减轻了路由器的负担。
IPv6包头里面没有checksum,那么会不会不安全呢?如果数据传输的过程中损坏了怎么办呢?首先,现在的网络都比较好,出现损坏的情况很少;其次,就算损坏了,有两种情况,一种是被路由器丢弃或者发到了错误的主机,这种情况不会造成什么问题,因为IP层本来就不保证可靠的传输,而是由上面的传输层来保证(如TCP),另一种情况是接受方收到了数据包,但由于数据包受损,内容已经和发送方发出来的不一样了,这种情况也是交给上面的传输层协议处理,比如UDP、TCP,它们都有自己的校验码,完全有能力发现数据损坏的问题。
不允许路由器对IPv6包进行分片,那么怎么保证发送端不会发送太大的数据包呢?首先,IPv6要求入网链路至少能传输1280字节的IP包,如果出现不能传输1280字节IP包这种情况,需要链路层自己处理分片和重组的过程;其次,跟IPv4里面PMTUD(Path MTU Discovery)是可选的不同,在IPv6里面,PMTUD是一个非常重要且必须的功能;所以一般情况下发送小于等于1280字节的IP包肯定能到达目的地,加上现在大部分人都用以太网(MTU为1500,包含以太网的包头),绝大部分情况下一个包过去就能确定PMTU(Path MTU ),不会影响数据传输性能。
更安全
在设计IPv4的时候,根本没有考虑过安全问题。
而在设计IPv6的时候,安全问题作为一个很重要的方面被考虑进来了,尤其是端到端的安全,IPsec正是在这样的背景下被设计出来的,有了IPsec后,在IP层就能实现安全传输。
虽然IPsec也被引入到了IPv4,但由于IPsec连传输层的端口都进行了加密,导致IPsec碰到NAT网络的时候,会造成很多麻烦,虽然现在已经有了解决办法,但IPsec在IPv4网络里面还是受到诸多限制。
更好的QoS
IPv6的包头里面包含了一个叫做Flow Label的字段,专门为QoS服务。
更好的支持移动设备
移动网络要求设备能在不同的网络里面快速的切换,并且现有的通信不受切换的影响,在IPv6里面,有专门的协议Mobile IPv6 (MIPv6)来处理这个事情。
IPv6格式
这里不介绍报文的格式,只介绍IPv6地址的格式。
地址表示方式
IPv6地址的128位分成了由冒号分割的8段,每段2个字节16位,这16位由16进制表示,这里是一些例子,左边是完整的格式,右边是缩写格式:
1 |
|
两条缩写规则:
用冒号分割的每段里面的前面的0可以省略掉,如:0001:可以缩写成:1:,:0000:可以缩写成:0:
如果冒号里面的是0的话,可以忽略掉(相邻的多个0可以一起忽略掉),直接写成两个冒号,如:0000:0000:可以被缩写成::
注意:如果地址中有多个连续为0的段,只能将其中的一个缩写成::,如果两个都缩写了,就不知道每个缩写了多少个0,这也是上面的表格中2001:0DB8:0000:0000:ABCD:0000:0000:1234被缩写成2002:DB8::ABCD:0:0:1234或者2001:DB8:0:0:ABCD::1234的原因,它不能被缩写成2001:DB8::ABCD::1234,一般的做法是哪种方法省略的0越多就用哪种。
网段表示方式
IPv6和IPv4一样,也有网段和子网的概念,在IPv6里面,表示子网号或者网段的时候,也是类似的方法,如:2001:0:0:CD30::/60,这个时候前面的地址只需要写前60位,后面的所有位都用::来缩写,类似于IPv4里面的192.168.0。0/16,不过要注意的是,这里2001:0:0:CD30::不能把前面的两个0也缩写,因为这样就不是一个合法的IPv6地址了。
IPv6地址类型
IPv6里面有三种地址类型;
Unicast: 单播地址,就是我们常用的地址,唯一标识一个网络接口
Anycast: 任意播(直译有点怪),一类特殊的IP地址,多个网络接口(不同的设备)都配上相同的地址,往这个地址发送数据的时候,路由器会只发往其中的一个接口,一般发往最近的那一个。(这个好像对实现负载均衡比较有用)
Multicast: 多播地址,代表一类unicast的集合,但往这个地址发送数据的时候,会将数据发给属于这个多播组的每个unicast地址。
IPv6里面没有类似于IPv4那样单独的广播概念,它的功能被包含在多播里面。
- 本人对anycast和multicast不是特别了解,所以没法描述的很清楚。
IPv6地址分类
现有的IP地址被分配成如下几大类:
1 |
|
预定义的多播地址
这里是两个常用的预定义的多播地址:
1 |
|
后面有例子演示如何使用多播
子网的划分
IPv6要求所有的单播(unicast)地址的子网必须是64位的,即下面这种格式:
1 |
|
如果子网的长度不是64位的话,会导致一些IPv6的功能不可用,详情请参考IPv6 Unicast Address Assignment Considerations。
Interface ID为Modified EUI-64格式,标准里面提供了如何将48位mac地址转换成EUI-64格式的方法。
IPv6标准要求单播地址的子网必须是64位的,主要是为了简化IPv6的管理,同时路由也方便,毕竟现在CPU都是64位的,如果子网号超过64位的话,会给路由造成一定的困难,同时64位的接口ID也比较容易存放一个UUID,比如可以容纳48位的mac地址,为Stateless Auto Configuration的地址分配提供了足够的空间。
64位的子网够用吗?64位的子网已经可以容纳264的设备了,相当于40亿个现在的IPv4地址空间的规模,实在是想不出还有哪种场合需要更大的子网。
64位的子网浪费吗?想想IPv4时代,几个人或者一群人通过NAT共享1个公网IP,而到了IPv6时代,这些人竟然可以拥有264个IP地址,想用几个用几个,为几个人分配一个64位的子网是不是有点浪费呢?其实谈不上浪费,IPv6的地址就是有那么多,大家都空着不用也是浪费,按道理64位的IP地址在可预见的将来已经够用了,而之所以采用128位IP加64位子网的方式,是因为能给我们的管理和使用方面带来很多的方便,如上面提到的便于路由和地址分配等。就算以后IP不够用了,再来放开子网位数的限制应该问题也不大。
想起了一句话: 等我有了钱,要装两条宽带,一条玩游戏,一条聊QQ。
Linux上配置IPv6
下面的所有例子都在ubuntu-server-x86_64 16.04下执行通过
现在的大部分Linux发行版默认情况下都启用了IPv6,如果没有,请参考发行版相关文档进行配置
1 |
|
IPv6启用后,每个网卡都会有一个IPv6地址,如下:
1 |
|
这里lo的IPv6地址是环回地址::1,而enp0s3有一个“Scope:Link”的IPv6地址fe80::a00:27ff:fe03:d0e7,这个IP地址即上面说到的Link-local地址,它没法通过路由器,只能在子网内部使用。
由于IPv6对交换机没有要求,所以就算没有支持IPv6的路由器,我们也可以在本地局域网内试玩一下IPv6
通过ip命令就可以给网卡添加IPv6地址,和一个网卡只能有一个IPv4地址不同,一个网卡可以配置多个IPv6地址。
1 |
|
再来看看系统默认的路由表:
1 |
|
从“Next Hop”列可以看出,这里的所有网段都是本地接口可以直接到达的网段,不需要路由器转发。
使用IPv6
上节配置好了IPv6之后,我们这节来看看怎么使用这些地址
这里只用一台机器来演示怎么和自己通信,大家有条件的话可以试试两台机器之间通信,效果是一样的。
ping6
和IPv4里面的ping相对于的命令是ping6,对于不同类型的地址,ping的方式不一样(为了节省篇幅,示例中省略了ping成功时的输出):
1 |
|
从上面可以看出,ping环回地址和global地址时,直接ping就可以了,而ping多播和Link-Local地址时,需要指定从哪个接口出去,这是因为机器上所有接口的Link-Local地址都属于同一个网段,当有多个接口时,根本没办法自动的判断应该从哪个接口出去。(不过从上面的路由表里面可以看出,在本地只有一个接口时,已经标识fe80::/64和ff00::/8可以从enp0s3口出去,不确定为什么在这种情况下,应用层的程序还要求指定接口名称,可能是为了保持统一吧,不管有几个接口,都一样的用法)。
注意: 如果是访问其它机器的link-local地址,-I参数和百分号的后面一定要指定本机出去的接口名称,而不是目的IP对应的接口名称
DNS
DNS里面有一个专门的IPv6类型,叫AAAA,查询的时候指定类型就可以了
1 |
|
SSH
下面四种方式都可以登陆当前机器
1 |
|
http
下面以curl来进行演示,如果有图形界面的浏览器的话,可以直接在浏览器里面输入同样的地址
1 |
|
IPv6编程示例
这里以python代码为示例,写了一个UDP的服务器和客户端,演示如何同时支持IPv4和IPv6。(为了简化起见,代码里面没有做错误处理)
server.py
1 |
|
client.py
1 |
|
如果参数传入的是域名或者主机名,getaddrinfo函数可能返回多个IP,这时候客户端需要根据自己的应用特点选择一个或多个进行通信,在本例中是发送数据包给所有的IP。
getaddrinfo返回的IP列表里面的顺序是有讲究的,如果对这个很在意的话,请参考rfc6724,默认情况一般是IPv6的地址在前面,在Linux下还可以通过/etc/gai.conf来配置相关的顺序。
server使用示例
1 |
|
server绑定所有IPv4和IPv6的接口, 然后client用不同的方式发包
`` dev@ubuntu:~/ipv6$ python3 server.py :: 8000 Listening on [::]:8000… Recvfrom [fe80::a00:27ff:fe03:d0e7%enp0s3]:48033 b'hello' Recvfrom [fe80::a00:27ff:fe03:d0e7%enp0s3]:50298 b'hello' Recvfrom [2001::1]:60882 b'hello' Recvfrom [::1]:44664 b'hello' Recvfrom [::ffff:127.0.0.1]:46676 b'hello' Recvfrom [::1]:55518 b'hello' Recvfrom [::ffff:127.0.0.1]:35961 b'hello' Recvfrom [fe80::a00:27ff:fe03:d0e7%enp0s3]:36281 b'hello'
1 |
|
IPv6简介的更多相关文章
- ipv4 ipv6简介
互联网协议地址(英语:Internet Protocol Address,又译为网际协议地址),缩写为IP地址(IP Address),在Internet上,一种给主机编址的方式.常见的IP地址,分为 ...
- 在 Linux 平台及 IPv4 环境中构建 IPv6局域网 测试环境
在 Linux 平台及 IPv4 环境中构建 IPv6 测试环境 1 IPv6简介 IPv6(Internet Protocol Version 6)作为 IPv4 的升级版本,它是作为一共软件升级安 ...
- IPv6地址表示方式
1.IPv6 简介 IPv6是英文“Internet Protocol version 6”(互联网协议第6版)的缩写,是互联网工程任务组(IETF)设计的用于替代IPv4的下一代IP协议,其地 ...
- TCP/IP入门(2) --网络层
/** 本篇博客由 126(127不可用) 2^24 -2 B 2^14 -1 128.1 191.255 2^16 -2 C 2^21 -1 192.0.1 223.255.255 2^8 -2 D ...
- <<高级计算机网络>>(Advaned Computer Networks) 徐恪 徐明伟 陈文龙 马东超
目录 第1章 计算机网络与Internet1 1.1 引言1 1.2 Internet发展历史2 1.2.1 互联网发展的主要阶段4 1.2.2 互联网在中国的发展5 1.2.3 互联网主要创新5 1 ...
- Linux实战教学笔记19:Linux相关网络知识梳理
第十九节 Linux相关网络知识梳理 标签(空格分隔): Linux实战教学笔记-陈思齐 一,前言 一个运维有时也要和网络打交道,所以具备最基本的网络知识,对一个运维人员来说是必要的.但,对于我们的工 ...
- 【Linux网络基础】网络拓扑、OSI层次模型、TCP/IP协议簇
一.前言 一个运维有时也要和网络打交道,所以具备最基本的网络知识,对一个运维人员来说是必要的.但,对于我们的工作来说这些并不是重点,因此,我不可能从最基础的网络知识开始讲起.本节内容更多是从一个梳理和 ...
- IPv6 相关的工作简介
这里说明下,仅仅是IPv6在开发板上的相关的工作简介,没有很详细,都是自己一边积累,一边实践的.能帮助其他人最好,也算是给自己做个备忘录. 一.首先说下DHCPv6相关的.这里我使用的是DHCP6s. ...
- 套接字编程简介: IPV4套接字地址结构/ 通用套接字地址结构/ IPV6套接字地址结构/新通用套接字地址结构
IPv4套接字地址结构通常也称为“网际套接字地址结构”,它以sockaddr_in命名,定义在<netinet/in.h>头文件中. struct in_addr { in_addr_t ...
随机推荐
- 通过修改hosts解决gist.github.com无法访问的问题
1.打开mac终端先ping一下 ping 192.30.253.119 如果能ping通的话 ,说明可以访问 2.修改hosts文件,添加如下语句: 192.30.253.118 gist.gith ...
- Perl中的自增、自减
自增和自减 perl也支持数值类型的自增和自减操作.不仅如此,还支持字符.字符串的自增.自减. 如果自增(++)和自减(--)符号放在数值的前面,则先增减,再返回: 如果自增(++)和自减(--)符号 ...
- java 开发 websocket 网页端聊天室
博客地址:https://ainyi.com/67 WebSocket协议是基于TCP的一种新的网络协议.它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端. ...
- HangFire循环作业中作业因执行时间太长未完成新作业开启导致重复数据的问题
解决方法:在执行的任务方法前加上Mutex特性即可,如果作业未完成,新作业开启的话,新作业会放入计划中的作业队列中,直到前面的作业完成. 必须使用Hangfire.Pro.Redis 和 Hangfi ...
- SVN、CVS、VSS区别
废话不多说,撸起袖子敲黑板 !~~ #首先向大家简要描述一下SVN与CVS.VSS的介绍与对比: 介绍: 三种都是版本控制软件, 多数用于源代码管理1.CVS(Concurrent Version S ...
- java_自定义标签,我的第一个自定义标签!
自定义标签,我的第一个自定义标签! 总共分两步 编写一个实现tag接口的java类,把jsp页面中的java代码移到这个类中,(标签处理器类) 编写标签库描述符(tld)文件,在tld文件中把标签处理 ...
- Netty实战六之ChannelHandler和ChannelPipeline
1.Channel的生命周期 Interface Channel定义了一组和ChannelInboundHandler API密切相关的简单但功能强大的状态模型,以下列出Channel的4个状态. C ...
- Java学习笔记之——枚举类
枚举可以限定类的值只是有限个,例如:星期,只有星期一到星期天 语法案例:
- vmware启动黑屏(本来是好的)
在cmd下运行 netsh winsock reset 重启真实系统
- JS隐藏号码中间4位
function resetPhone(phone) { var str = String(phone) var len = str.length; var prev,next; if (len &g ...