张小烦 发表于 2017-3-1 01:05:13

FreeBSD配置IPv6

自从 FreeBSD 4.0之后,系统就已经内置对IPv6的支持了,FreeBSD的IPv6实现都基于KAME计划。需要注意的是,并不是KAME计划中的所有内容和最新更改都加入FreeBSD系统中,一些特性并没有成为FreeBSD系统的一部分,但KAME可以完整的运行在FreeBSD系统中,事实上,他们的开发工作都是基于BSD Unix的,因此也可以下载他们的最新发布的代码,得到更完整、但处于试验目的的IPv6支持。      1) IPv6 支持
    如果没有因为定制系统取消 IPv6支持,FreeBSD已经支持IPv6,由于IPv6的自动配置特征,就为网络界面设置了一个缺省地址。
      $ ifconfig sis0 inet6
      sis0: flags=8843 mtu 1500
      inet6 fe80::2d0:9ff:fea3:49fa%sis0 prefixlen 64 scopeid 0x1
            命令行中的 inet6就是表示IPv6地址,而地址形式为fe80::2d0:9ff:fea3:49fa%sis0,其中前缀fe80就是根据本地网络界面设置的IPv6地址类型,而最后八个字节为根据本地网卡的有关参数生成的数据,对于以太网卡,这就是MAC地址,而%sis0定义了地址所在的网络界面名字,这主要用于组播环境。后面的prefixlen定义了前缀长度,缺省情况下这种Ipv6地址使用64位前缀来区分网络地址和节点地址。而使用MAC地址作为节点地址,就极大的减轻了网络中地址分配的难题,简化了管理工作。而scopeid是一个索引,对于这种基于网络界面的地址用于表示网络界面的序号。
            上面的地址是最基本的 IPv6地址,它的前缀都是fe80,主要用于内部网络之间的相互通信,如果需要和外部网络进行通信,就比较困难了,因为这难以设置路由。更标准的办法是为网络界面手工设置IPv6地址,由于IPv6的特性,通常仍然保留原有的fe80地址用于本地网络通信,而设置多个alias地址。
      # ifconfig sis0 inet6 3ffe::12 prefixlen 48
            如果网络中有 IPv6路由器存在的话,就不需要手工配置IPv6地址,系统会自动从路由器中获取网络地址(网络前缀),然后使用本地MAC地址填充,成为一个有效的、可路由的IPv6地址,这就是IPv6的自动配置功能,类似于IPv4网络中的DHCP协议。
      # ifconfig sis0 inet6
      sis0: flags=8843 mtu 1500
      inet6 fe80::2d0:9ff:fea3:49fa%sis0 prefixlen 64 scopeid 0x1
      inet6 3ffe:501:ffff:1000:2d0:9ff:fea3:49fa prefixlen 64 autoconf
            上例中,第二个地址就是自动配置的地址,前面的前缀为 IPv6路由器中设置的,而autoconf就标示了这种类型的地址,这个地址与前面地址的区别就是它的路由已知,因而没有 ” %sis0 ” 这样的后缀。
            为了支持 IPv6,除了地址设置之外,还需要设置诸如网关、一些系统sysctl变量以控制网络行为等等,以设置一个基本的IPv6环境。如果这些设置通过手工的方法来进行的话,通常比较麻烦,幸运的是,通过设置rc.conf变量,FreeBSD能自动配置IPv6基本环境。最基本的变量是 ” ipv6_enable ” ,它就包括了执行自动地址配置、添加组播路由等设置,而 ” ipv6_defaultrouter ” 就用于设置 IPv6的缺省路由地址等等。
            有些应用程序, IPv4和IPv6差异比较大,系统提供了它们的IPv6对应版本,例如ping的IPv6版本ping6、ipfw的对应版本ip6fw等等,它们的用法通常是类似的。
      # ping6 ::1
      而另一些程序对于 IPv6和IPv4没有太大的差别,就可以直接使用IPv6地址,或者使用参数表示是IPv6。例如:
      # route add -inet6 ::ffff:0.0.0.0 -prefixlen 96 ::1 -reject
      # route add -inet6 ::0.0.0.0 -prefixlen 96 ::1 -reject
            上述两个指令来源于系统的 rc.network6,用于屏蔽内部地址的数据包。而rc.network6就是系统IPv6初始设置脚本,通过这个脚本可以学习到更多的IPv6设置细节。
            需要注意的,为了正常利用网络功能,需要对 IPv6地址进行域名解析,除了正确设置DNS服务器之外,还需要将一些缺省的地址,例如本地地址 ” ::1 ” , ” fe80::1%lo0 ” 等放入 /etc/hosts文件,事实上这都包括在系统缺省安装的hosts文件中了。
      2) IPv6 网关支持
    与 IPv4不同,IPv6的主机和网关差异比较大,在IPv4中,任何主机都可以打开路由功能,但它是被动的,等待其他系统认可才可以。而在IPv6中,路由器需要主动广播自身,以便告诉网络内的系统进行自动网络配置,告诉上游的路由器设置正确路由。因此,这需要执行两步操作,首先要打开针对IPv6的包转发功能,然后还要运行rtadvd守护进程,进行路由器广播。
      通常情况下,这需要设置 ” ipv6_gateway_enable ” 和 ” rtadvd_enable ” 两个变量为 ” Yes ” 。
      然而,如果为了正确启动 rtadvd,还需要设置其配置文件,缺省位置为/etc/rtadvd.conf。
      default:\
      :chlim#64:raflags#0:rltime#1800:rtime#0:retrans#0:\
      :pinfoflags#192:vltime#2592000:pltime#604800:mtu#0:
      sis0:\
      :addrs#1:addr="3ffe:501:ffff:1000::":prefixlen#64:tc=default:
      上面是一个简单的例子,但为了提高性能,必然需要对其中的参数进行更细的调整,以适合网络情况。
            进一步,可以在系统中运行 route6d等路由交换协议,支持RIP6等动态路由数据交换协议。对于这些涉及比较复杂的路由设置、网络规划内容,由于不是本书主要关心的内容,因此对此感兴趣的FreeBSD用户可以阅读RFC以及有关资料,进一步深入研究IPv6。
      3) 升级与迁移
    虽然 IPv6肯定是未来网络协议的发展方向,但真正要全面升级到IPv6也是极不现实的,因为有太多的问题存在。因而,将网络移植到IPv6是一个逐步的过程,这个时候也不能脱离现有的网络,依靠现有的IPv4互联网能带来很多便利。因此,就需要一些额外的技术,例如虚拟通道和协议转换等,以便将新网络架构在旧有网络之上。
      FreeBSD就对此提供了足够的支持,系统支持gif、stf和faith逻辑网络界面,以便能配置各种虚拟通道,进行协议转换。
      u gif通道
    人们可以在自己的局域网中非常简单的构建 IPv6网络,但一旦需要将多个IPv6的网络相互连接起来,就遇到种种问题。问题的关键在于,人们已经能够通过IPv4相互连接,因此就没有必要重新购置一套完整的IPv6连接设备。但如果直接在原有的IPv4网络设备上配置IPv6,一方面这些网络设备,是否全部支持IPv6仍然存在问题,另一方面这些网络设备也不一定属于同一个组织,网络设备繁多也对配置工作量提出了很多要求。
            因此,直接修改网络设备的配置支持 IPv6是不现实的,而虚拟通道显然是一种有效的解决方法。就是说,将IPv6的数据包,重新使用IPv4包装一次,将这个包通过现有的IPv4网络传输到对方,就不必介意这个网络是否支持IPv6了。当对方接收到数据,再重新解开数据包,获得真实数据。这个过程就相当于一个虚拟的点对点连接的通道,可以将这个通道的端点映射为一个虚拟的网络界面,那么可以直接在这个网络界面上执行IPv6网络配置,而不需要考虑中间的具体传输过程了。
      根据这个原则,就可以创建 gif虚拟通道,显然这需要涉及本地的IPv4地址、远端的IPv4地址,这样虚拟通道才能确定两个端点。
            首先,创建虚拟通道需要创建虚拟通道设备,通常是 gif0、gif1等等,应该选用一个没有被使用的gif通道设备,或者重新创建它。注意,在FreeBSD 4.1之前,gif通道设备不能随意创建,而是在系统定制的时候确定的,就无法使用下面的创建命令。
      # ifconfig gif create
      gif0
      # ifconfig gif0
      gif0: flags=8010 mtu 1280      # ifconfig gif0 destroy
      # ifconfig gif0 create
            上面的过程展示了使用 create建立通道,使用destroy撤消通道,以及再次创建通道的过程,注意,第一次创建使用的是网络界面的类型,因此ifconfig将创建的设备名自动显示出来,具体的设备序号由系统按顺序确定。而第二次就直接使用一个不存在的虚拟设备名字,ifconfig将直接创建它。
      然后就可以为通道指定两端的地址,这需要使用 gifconfig命令,其中第一个地址为本地地址,而第二个地址为对方地址。
      # gifconfig gif0 inet 192.168.100.1 192.168.1.1
      也可以将创建 gif虚拟界面指令和配置指令放在一起:
      # ifconfig gif2 create tunnel 192.168.100.1 192.168.1.1
      然后,就可以使用 ifconfig为gif0网络界面设置地址了。
      # ifconfig gif0 inet6 3ffe::2 prefixlen 64
      当然,真正要使用上面的通道进行通信,还必须在两端同时进行这样的配置,仅仅是一端是不够的。
      为了在启动时自动设置 gif通道,首先需要设置gif_interfaces变量,包括具体需要设置的gif通道设备名,然后再对每个通道设备设置其端点地址。下面为设置范例:
      gif_interfaces= ” gif0 gif1 ”
      gifconfig_gif0= ” 192.168.100.1 192.168.1.1 ”
      gifconfig_gif1= ” 192.168.10.1 192.168.111.1 ”
      u stf通道
    使用 gif通道可以将两个分离的IPv6网络通过IPv4网络连接起来,但是需要注意的是,这个设置需要两端同时手工进行,特别是需要配置特别多的连接的时候,那么就需要配置相当多的虚拟通道端点。
            为了解决这个多虚拟通道问题,可以设想建立一个多端点的通道,每个端点都能同其他端点正常通信,这样显然要求每个系统上都必须配置每个通道的对方端点情况,以便确定那些数据需要传输到哪个端点。考虑到任何一个 IPv6网络通过IPv4网络进行连接的时候,都已经拥有一个唯一的合法IPv4地址,这个IPv4地址已经是一个唯一的端点。因此,可以将整个现有互联网作为一个虚拟通道,使用现有互联网的路由策略决定一个IPv6网络的数据包应该发送给哪个IPv4目的。
            这个就是 stf通道,一个能够进行自动配置的通道类型。当一个IPv6网络通过边界点连接到IPv4网络的时候,IPv6边界路由器对IPv6数据进行封装,但根据IPv6的目的地址生成真实IPv4的目的地址,然后进行传输。这就需要边界路由器支持stf通道,而IPv6网络内部就不需要通道设置了。
            这样来讲, stf通道使用的IPv6地址必然与IPv4地址有一定关系,以便地址能够自动转换,这就是6 to 4地址映射。这个映射方式使用前缀2002::/16,然后使用边界路由器的合法IPv4地址作为子网地址,例如如果IPv4地址为190.157.137.98,那么完整的前缀为2002:be9d:8962::/48,be9d:8962就是IPv4地址的十六进制形式。
            由于前缀只有 48位,那么这个网络内部也足以容纳足够的内部系统,这种情况就是内部系统都使用IPv6的情况。对于内部拥有一个合法的IPv4网段的情况,那么内部的主机也都可以使用这种明名转换方式,这样也可以将整个IPv4网段映射到IPv6网段,例如190.157.137.0/24,那么前缀就是2002:be9d:8900::/40。
            因此,当一个发往另一个这种兼容地址的数据包传输到边界路由器的时候,它很容易就从网络前缀中获得目的路由器的 IPv4地址,并可以立即传输过去。
      设置 stf通道非常简单,但需要提前设置好合法的IPv4地址。
      # ifconfig sis0 190.157.137.98
      # ifconfig stf0 inet6 2002:be9d:8962::1 prefixlen 48 alias
      这样,使用 stf就能非常方便的与任何2002::/16中的合法IPv6系统通信,但如果需要和其他IPv6网络进行通信,还需要设置IPv6路由。
      按照上面的设置,这个边界路由器的的启动脚本设置为:
      ipv6_enable="YES"
      ipv6_router_enable="YES"
      ipv6_network_interfaces="lo0 fxp0"
      ipv6_prefix_fxp0="2002:be9d:8962"
      stf_interface_ipv4addr="190.157.137.98"
            这种设置方式最为简单,但由于总是使用 IPv4网络的路由,就不能选择更合适的路由,从而影响网络性能。当然,如果系统能连接到一个专用的IPv6连接,那么也许使用专用连接更为适合,这个时候就需要手工指定缺省网关等静态路由。
      u faith转换
    上面提到的两种虚拟通道都是用来解决在 IPv4网络的汪洋大海中,如何连接各个独立的IPv6网络的问题。更进一步的考虑是,如何在IPv6和IPv4网络之间通信。
            如果需要 IPv6和IPv4之间的通信,由于基本协议不同,那么就必然需要使用一种中转系统,这个系统能够识别两种协议,并按照一定规则在两种协议之间转换,FreeBSD提供的faith设备正是用于这个目的。
            当支持 faith的时候,需要保留一个前缀,用来提供IPv4和IPv6之间的映射关系,这里就与stf通道不同,而是使用前面的兼容地址模式,如当保留前缀为3ffe:501:9999:ffff时,一个IPv4主机的IPv6地址形式为3ffe:501:9999:ffff::192.168.100.1。
            然后,需要通过路由设置,将这个前缀相关的路由目的设置为 faith0网络界面,当然,之前要启动该网络界面,并打开系统对faith的支持(通过sysctl变量net.inet6.ip6.keepfaith)。
            最简单的方法,可以在 rc.conf中设置 ” ipv6_faith_prefix ” 变量,将在启动时自动完成这些配置,由于 faith是一种路由功能,通常也需要打开路由支持,如ipv6_gateway_enable等。例如:
      ipv6_faith_prefix= ” 3ffe:501:9999:ffff:: ”
            这样,由于发向使用这些前缀主机的路由目的为系统的 faith0界面,因而这些数据将由系统的faith设备捕获,而faith将这些数据发送给一个用户空间的进程faithd,而faithd按照前面的规则,将目的地址去除前缀,将源地址改变本机的合法地址,这样数据包将转换为合法的IPv4数据,从而与IPv4主机进行通信。
            目前 faithd只支持TCP中转,对于一个TCP目的端口,需要使用一个faith程序,并且它将占用中转主机的相应TCP端口。例如需要支持telnet端口,那就需要使用下面命令:
      # faithd telnet
页: [1]
查看完整版本: FreeBSD配置IPv6