×

Linux的高级路由和流量控制:GRE和其他隧道

hqy hqy 发表于2019-03-26 11:08:07 浏览2328 评论0

抢沙发发表评论

Linux有3种隧道。它们是: IP-in-IP 隧道、 GRE 隧道和非内核隧道(如PPTP)。

1. 关于隧道的几点注释

隧道可以用于实现很多非常不一般而有趣的功能。但如果你的配置有问题,却也会发生可怕的错误。除非你确切地知道你在做什么,否则不要把缺省路由指向一个隧道设备。而且,隧道会增加协议开销,因为它需要一个额外的IP包头。一般应该是每个包增加20个字节,所以如果一个网络的MTU是1500字节的话,使用隧道技术后,实际的IP包长度最长只能有1480字节了。这倒不是什么原则性的问题,但如果你想使用隧道技术构建一个比较大规模的网络的话,最好仔细研究一下关于IP包的分片和汇聚的知识。哦,还有,挖一个隧道最好的方法当然是同时从两头挖。

2. IP-in-IP 隧道

这种隧道在Linux上已经实现很长一段时间了。需要两个内核模块:ipip.o 和 new_tunnel.o。

比如说你有3个网络:内部网A和B,中间网C(比如说:Internet)。

A网络的情况:
网络地址 10.0.1.0
子网掩码 255.255.255.0
路由器 10.0.1.1
路由器在C网络上的地址是172.16.17.18。

B网络的情况:
网络地址 10.0.2.0
子网掩码 255.255.255.0
路由器 1

路由器在C网络上的IP地址是 172.19.20.21。

已知C网络已经连通,我们假定它会将所有的数据包从A传到B,反之亦然。而且你可以随便使用Internet。

这就是你要做的:

首先,确认模块是否加载:

insmod ipip.o
insmod new_tunnel.o

然后,在A网络的路由器上输入:

ifconfig tunl0 10.0.1.1 pointopoint 172.19.20.21
route add -net 10.0.2.0 netmask 255.255.255.0 dev tunl0

并且在B网络的路由器上输入:

ifconfig tunl0 10.0.2.1 pointopoint 172.16.17.18
route add -net 10.0.1.0 netmask 255.255.255.0 dev tunl0

如果你想中止隧道,输入:

ifconfig tunl0 down

简单之极!但是你不能通过IP-in-IP隧道转发广播或者IPv6数据包。你只是连接了两个一般情况下无法直接通讯的IPv4网络而已。至于兼容性,这部分代码已经有很长一段历史了,它的兼容性可以上溯到1.3版的内核。据我所知,Linux的IP-in-IP 隧道不能与其他操作系统或路由器互相通讯。它很简单,也很有效。需要它的时候尽管使用,否则就使用GRE。


3. GRE 隧道

GRE是最初由CISCO开发出来的隧道协议,能够做一些IP-in-IP隧道做不到的事情。比如,你可以使用GRE隧道传输多播数据包和IPv6数据包。在Linux下,你需要ip_gre.o模块。

3.1. IPv4隧道

让我们先来做一做IPv4隧道:

比如说你有3个网络:内部网A和B,中间网C(比如说:Internet)。A网络的情况:

网络地址 10.0.1.0
子网掩码 255.255.255.0
路由器 10.0.1.1
路由器在C网络上的地址是172.16.17.18。我们称之为neta。

B网络的情况:

网络地址 10.0.2.0
子网掩码 255.255.255.0
路由器 10.0.2.1

路由器在C网络上的IP地址是 172.19.20.21。我们称之为netb。

已知C网络已经连通,我们假定它会将所有的数据包从A传到B,反之亦然。至于原因,我们不考虑。

在A网络的路由器上,输入:

ip tunnel add netb mode gre remote 172.19.20.21 local 172.16.17.18 ttl 255
ip link set netb up
ip addr add 10.0.1.1 dev netb
ip route add 10.0.2.0/24 dev netb

让我们稍微讨论一下。第1行,我们添加了一个隧道设备,并且称之为netb(为了能够表示出这个隧道通向哪里)。并且表示要使用GRE协议 (mode gre),对端地址是172.19.20.21(另一端的路由器),我们的隧道数据包发源于172.16.17.18(以便当你的路由器在C网络中拥有多个地址的时候,你可以指定哪一个应用于隧道) 并且包的TTL字段应设置为255(ttl 255)。

第2行,启用该隧道。

第3行,我们给这个新生的网卡配置了一个IP:10.0.1.1。对于小网络来说足够了,但如果你网络中的隧道多得象无证运营的小煤窑一样,你可能就要考虑给你的隧道规划一个单独的IP地址范围(在本例中,你可以使用10.0.3.0)。

第4行,我们为B网络设置了一条路由。注意子网掩码的另一种表示方法。如果你不熟悉这种表示,我就来解释一下:你把你的子网掩码写成二进制形式,数数里面由多少个1。如果你连这个也不会做,不妨就简单地记住:255.0.0.0 就是 /8,255.255.0.0 就是 /16, 255.255.255.0 就是 /24。

让我们再看看B网络的路由器。

ip tunnel add neta mode gre remote 172.16.17.18 local 172.19.20.21 ttl 255
ip link set neta up
ip addr add 10.0.2.1 dev neta
ip route add 10.0.1.0/24 dev neta

如果你想从A路由器中停止隧道,输入:

ip link set netb down
ip tunnel del netb

当然,你可以把netb换成neta,在B路由器上操作。

3.2. IPv6隧道

关于IPv6地址,请参看第6章第1节。

这就开始吧。

我们假设你有如下的IPv6网络,你想把它连接到6bone或者一个朋友那里。

Network 3ffe:406:5:1:5:a:2:1/96

你的IPv4地址是172.16.17.18,6bone 路由器的IPv4地址是172.22.23.24。

ip tunnel add sixbone mode sit remote 172.22.23.24 local 172.16.17.18 ttl 255
ip link set sixbone up
ip addr add 3ffe:406:5:1:5:a:2:1/96 dev sixbone
ip route add 3ffe::/15 dev sixbone

让我们来讨论一下。我们创建了一个叫做sixbone的隧道设备。我们设置它的模式是sit(也就是在IPv4隧道中使用IPv6)并且告诉它对端(remote)和本端 (local)在哪里。TTL设置为最大,255。接着,我们激活了这个设备(up)。然后,我们添加了我们自己的网络地址,并添加了一条通过隧道去往3ffe::/15 (现在全部属于6bone)的路由。

GRE隧道是现在最受欢迎的隧道技术。它也广泛地应用于Linux世界之外并成为一个标准,是个好东西。

4. 用户级隧道

在内核之外,还有很多实现隧道的方法,最闻名的当然要数PPP和PPTP,但实际上还有很多(有些是专有的,有些是安全的,有些甚至根本不用IP),但那远远超出了本HOWTO所涉及的范围。


打赏

本文链接:https://www.kinber.cn/post/427.html 转载需授权!

分享到:


推荐本站淘宝优惠价购买喜欢的宝贝:

image.png

 您阅读本篇文章共花了: 

群贤毕至

访客