5. GRE 及其它通道技术 (GRE and other tunnels)
在 Linux 里面的 tunnel 共分三类﹐即 IP in IP tunneling﹑ GRE tunneling﹑以及核心以?nbsp;的 tunnels (例如﹕PPTP)。
5.1 关于 tunnels 的几项注意 (A few general remarks about tunnels):
Tunnels 可以用来做一些非比寻常的酷玩意。不过﹐如果设定不慎﹐也会将事情弄得一塌糊涂。如果您并非 胸有成竹 ﹐ 那就千万不要将您的预设网关指向 tunnel 设备。还有﹐tunneling 也会增加额?nbsp;的 overhead﹐因为它需要额?nbsp;的 IP 标头(header)。一般而言﹐每一个封包大概 20 byte 左右﹐这样﹐一个正常的网络封包体积 (MTU) 会是 1500 bytes﹐但如封包果经 tunnel 传送﹐却只有 1480 byte 而已。这其实也不算是什么问题﹐但是当您有机会用 tunnels 来连接大型网络的时候﹐请务必检查 IP 封包的碎片和重组(fragmentation/reassembly)细节。当然啰﹐建立 tunnel 的话﹐最好是从 tunnel 的两端同时着手﹐双管齐下。
5.2 IP in IP tunneling
此类 tunneling 技术其实在 Linux 里已行之有?nbsp;了。它需要两个核心模块﹕ipip.o 和 new_tunnel.o。
modprobe ipip
比方说﹐您有 3 个网络﹕A 和 B 皆为内部网络﹐而透过网络 C (或曰 Internet) 将两者连接起来。这样﹐我们的网络 A 会是如此﹕
network 10.0.1.0
netmask 255.255.255.0
router 10.0.1.1
接网络 C 的网关地址为 172.16.17.18。
而网络 B 则这般﹕
network 10.0.2.0
netmask 255.255.255.0
router 10.0.2.1
接网络 C 的网关地址为 172.19.20.21 。
对网络 C 而言﹐我们假设它能够双向的将网络 A 和 B 之间的封包送递对方。您甚至可以用 Internet 啦。
好了﹐然后您要做的事情是﹕
首先﹐确定所有模块都装好了﹕
insmod ipip.o
insmod new_tunnel.o
modprobe ipip
然后﹐在网络 A 的 router 上﹐这样做﹕
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 的 router 上﹕
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
完成后﹐将 tunnel 暂时关闭﹕
ifconfig tunl0 down
弹 指间﹐就这样搞定了。然而﹐您不能透过 IP-in-iP tunnel 传送广播或 IPv6 信息。您刚纔将两个本来不能相互沟通的 IPv4 网络连接起来了﹐然仅此而已。基于兼容考虑﹐此程序代码由来已久﹐因而逆溯至 1.3 版核心皆兼筹并顾。据我所知﹐ Linux 之 IP-in-IP tunneling 并不能在其它的作?nbsp;系统或 router 上工作。然而它短小精悍﹐实属首选﹐除非您考虑用 GRE。
5.3 GRE tunneling
GRE 是一个原本由 Cisco 开发的 tunneling 协议﹐较于 IP-in-IP tunneling﹐它略为能耐一些。例如﹐您能够透过 GRE tunnel 传送 multicast 和 IPv6 信息。
在 Linux 里﹐您得借助 ip_gre.o 模块。
modprobe ip_gre
IPv4 Tunneling
不如先让我们将 IPv4 tunneling 做起来吧﹕
比方说﹐您有 3 个网络﹕A 和 B 皆为内部网络﹐而透过网络 C (或曰 Internet) 将两者连接起来。
关于网络 A ﹐如下﹕
network 10.0.1.0
netmask 255.255.255.0
router 10.0.1.1
在网络 C 上的 router 地址为 172.16.17.18。然后让我们称这个网络为 neta (好了﹐万事起头难)。
然后﹐关于网络 B﹕
network 10.0.2.0
netmask 255.255.255.0
router 10.0.2.1
在网络 C 上的 router 地址为 172.19.20.21。然后让我们称这网络为 netb 好了(革命尚未成功﹐同志仍需努力)。
对网络 C 而言﹐我们假设它能够双向的将网络 A 和 B 之间的封包送递对方。至于何以然及何所以然﹐则非我们所要操心的。
接下来﹐在网络 A 的 router 上﹐您如此做﹕
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
这 里﹐我们不妨研究一下。在第一行里面﹐我们新增了一个 tunnel 设备﹐称之为 netb (显而易见﹐因为这正是吾之所欲也)。再来﹐我们让它使用 GRE 协议(mode gre)﹐其远程地址为 172.19.20.21 (于另一端的 router)﹐这样我们的 tunneling 封包将从 172.16.17.18 从出(您的 router 在网络 C 上可以具有好几个 IP 地址﹐并由您决定用哪一个来做 tunneling)﹐而且﹐封包的 TTL 字段被设定为 255 (ttl 255)。
第 2 行我们将这个设备启动起来。
在第 3 行﹐我们为新增的界面 netb 设定一个地址为 10.0.1.1。用这个在小网络上也未尝不可﹐只是当您踏上采金旅程之际﹐您或需用其它 IP 范围来给 tunneling 界面就是了(例如在此范例中﹐您可以使用 10.0.3.0)。
在 第 4 行﹐我们为网络 B 设定好 router。请留意﹐此处使用的 netmask 表示法并不一样。如果您不太了解其意所在﹐可以这样来理解﹕将 netmask 换算为二进制(binary)﹐然后数一数有多少个 1 就是了。如果您连这个也不会﹐万一又想知道﹐那就这样强记即可﹕255.0.0.0 是 /8﹑255.255.0.0 是 /16﹑还有 255.255.255.0 是 /24﹑而 255.255.253.0 则是 /23。
够了真是的﹐还是让我们看看网络 B 的 router 吧。
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
假如您要拿掉 router A 上的 tunnel﹐则﹕
ip link set netb down
ip tunnel del netb
当然﹐您也可以替 router B 将 netb 换成 neta。
GRE tunnels 目前所选用的 tunneling 类型。它已成标准并且也被广泛的移植到 Linux 社群之?nbsp;﹐诚是美事一桩。
5.4 Userland tunnels
在核心之?nbsp;﹐还有成打形形色色的 tunneling 实作﹐绝非夸张之谈。其中表表者非 PPP 和 PPTP 莫属﹐然而其它的也为数众多 (有的为专属的﹐有的是保密的﹐有的甚至不是使用 IP)﹐不过﹐这些实在超过本 HOWTO 的范畴了。