Linux的高级路由和流量控制HOWTO 1 2.docx

上传人:b****3 文档编号:27392853 上传时间:2023-06-30 格式:DOCX 页数:13 大小:23.75KB
下载 相关 举报
Linux的高级路由和流量控制HOWTO 1 2.docx_第1页
第1页 / 共13页
Linux的高级路由和流量控制HOWTO 1 2.docx_第2页
第2页 / 共13页
Linux的高级路由和流量控制HOWTO 1 2.docx_第3页
第3页 / 共13页
Linux的高级路由和流量控制HOWTO 1 2.docx_第4页
第4页 / 共13页
Linux的高级路由和流量控制HOWTO 1 2.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

Linux的高级路由和流量控制HOWTO 1 2.docx

《Linux的高级路由和流量控制HOWTO 1 2.docx》由会员分享,可在线阅读,更多相关《Linux的高级路由和流量控制HOWTO 1 2.docx(13页珍藏版)》请在冰豆网上搜索。

Linux的高级路由和流量控制HOWTO 1 2.docx

Linux的高级路由和流量控制HOWTO12

Linux的高级路由和流量控制HOWTO12

Linux的高级路由和流量控制HOWTO(1.2)2010-07-1614:

28第4章规则--路由策略数据库

如果你有一个大规模的路由器,你可能不得不同时满足不同用户对于路由的不同需求。

路由策略数据库可以帮助你通过多路由表技术来实现。

如果你想使用这个特性,请确认你的内核配置中带有"IP:

advancedrouter"和"IP:

policyrouting"两项。

当内核需要做出路由选择时,它会找出应该参考哪一张路由表。

除了"ip"命令之外,以前的"route"命令也能修改main和local表。

缺省规则:

[ahu@homeahu]$iprulelist0:

fromalllookuplocal32766:

fromalllookupmain32767:

fromalllookupdefault

上面列出了规则的优先顺序。

我们看到,所有的规则都应用到了所有的包上("fromall")。

我们前面已经看到了"main"表,就是"iproutels"命令的输出,但是"local"和"default"是初次见到。

如果我们想做点有趣的事情,就可以生成一些指向不同路由表的规则,取代系统中的路由规则。

对于内核如何处理一个IP包匹配多个规则的精确意义,请参见Alexey关于ip-cref文档。

4.1.简单的源策略路由

让我们再来一个真实的例子。

我有两个CableModem,连接到了一个Linux的NAT("伪装")路由器上。

这里的室友们向我付费使用Internet。

假如我其中的一个室友因为只想访问hotmail而希望少付一些钱。

对我来说这没有问题,他们肯定只能使用那个比较次的CableModem。

那个比较快的cablemodem的IP地址是212.64.94.251,PPP链路,对端IP是212.64.94.1。

而那个比较慢的cablemodem的IP地址是212.64.78.148,对端是195.96.98.253。

local表:

[ahu@homeahu]$iproutelisttablelocalbroadcast127.255.255.255devloprotokernelscopelinksrc127.0.0.1local10.0.0.1deveth0protokernelscopehostsrc10.0.0.1broadcast10.0.0.0deveth0protokernelscopelinksrc10.0.0.1local212.64.94.251devppp0protokernelscopehostsrc212.64.94.251broadcast10.255.255.255deveth0protokernelscopelinksrc10.0.0.1broadcast127.0.0.0devloprotokernelscopelinksrc127.0.0.1local212.64.78.148devppp2protokernelscopehostsrc212.64.78.148local127.0.0.1devloprotokernelscopehostsrc127.0.0.1local127.0.0.0/8devloprotokernelscopehostsrc127.0.0.1

有很多明显的事实,其实可能还需要进一步说明。

好了,这样就行了。

"default"表为空。

让我们看看"main"路由表:

[ahu@homeahu]$iproutelisttablemain195.96.98.253devppp2protokernelscopelinksrc212.64.78.148212.64.94.1devppp0protokernelscopelinksrc212.64.94.25110.0.0.0/8deveth0protokernelscopelinksrc10.0.0.1127.0.0.0/8devloscopelinkdefaultvia212.64.94.1devppp0

我们现在为我们的朋友创建了一个叫做"John"的规则。

其实我们完全可以使用纯数字表示规则,但是不方便。

我们可以向/etc/iproute2/rt_tables文件中添加数字与名字的关联:

#echo200John/etc/iproute2/rt_tables

#ipruleaddfrom10.0.0.10tableJohn

#iprulels0:

fromalllookuplocal32765:

from10.0.0.10lookupJohn32766:

fromalllookupmain32767:

fromalllookupdefault

现在,剩下的事情就是为John的路由表创建路由项了。

别忘了刷新路由缓存:

#iprouteadddefaultvia195.96.98.253devppp2tableJohn

#iprouteflushcache

这样就做好了。

至于如何在ip-up阶段实现就留给读者自己去研究吧。

4.2.多重上连ISP的路由

下图是很常见的配置,同一个局域网(甚至是同一台计算机)通过两个ISP连接到互联网上。

_

+--+/

|||

+---+ISP1+---

__|||/

_/_+--+---++--+|

_/__|if1|/

/|||

|局域网---+Linux路由器||国际互联网

___/|||

____/|if2|

_/+--+---++--+|

|||

+---+ISP2+---

|||

+--+_

这种情况下通常会出现两个问题。

4.2.1.流量分割

首先是如何保证:

回应来自某一个ISP的数据包时,仍然使用相同的ISP。

让我们先定义一些符号。

令第一块网卡(上图的if1)的名字叫$IF1,而第二块网卡叫做$IF2。

然后设置$IF1的IP地址为$IP1,$IF2的IP地址为$IP2。

并且,令ISP1的网关地址为$P1,ISP2的网关地址为$P2。

最后,令$P1的网络地址为$P1_NET,令$P2的网络地址为$P2_NET。

额外创建两个路由表,T1和T2。

加入到/etc/iproute2/rt_tables中。

然后如下设置两个路由表中的路由:

iprouteadd$P1_NETdev$IF1src$IP1tableT1iprouteadddefaultvia$P1tableT1iprouteadd$P2_NETdev$IF2src$IP2tableT2iprouteadddefaultvia$P2tableT2

没什么大不了的,不过是建立了通向该网关的一条路由,并使之成为默认网关,分别负责一个单独的上行流,并且为这两个ISP都作这样的配置。

要指出的是,那条网络路由是必要条件,因为它能够让我们找到那个子网内的主机,也包括上述那台网关。

下一步,我们设置"main"路由表。

把包通过网卡直接路由到与网卡相连的局域网上不失为一个好办法。

要注意"src"参数,他们能够保证选择正确的出口IP地址。

iprouteadd$P1_NETdev$IF1src$IP1iprouteadd$P2_NETdev$IF2src$IP2

然后,设置你的缺省路由:

iprouteadddefaultvia$P1

接着,设置路由规则。

这实际上在选择用什么路由表进行路由。

你需要确认当你从一个给定接口路由出数据包时,是否已经有了相应的源地址:

你需要保证的就是如果你已经有了相应的源地址,就应该把数据包从相应的网卡路由出去:

ipruleaddfrom$IP1tableT1ipruleaddfrom$IP2tableT2

以上命令保证了所有的回应数据都会从他们来的那块网卡原路返回。

现在,完成了非常基本的配置。

这将对于所有运行在路由器上所有的进程起作用,实现IP伪装以后,对本地局域网也将起作用。

如果不进行伪装,那么你要么拥有两个ISP的地址空间,要么你想对两个ISP中的一个进行伪装。

无论哪种情况,你都要添加规则,基于发包的主机在局域网内的IP地址,选择从哪个ISP路由出去。

4.2.2.负载均衡

第二个问题是如何对于通过两个ISP流出的数据进行负载均衡。

如果你已经成功地实现了流量分割,这件事并不难。

与选择两个ISP中的一个作为缺省路由不同,这次是设置缺省路由为多路路由。

在缺省内核中,这会均衡两个ISP的路由。

象下面这样做(基于前面的流量分割实验):

iprouteadddefaultscopeglobalnexthopvia$P1dev$IF1weight1

nexthopvia$P2dev$IF2weight1

这样就可以均衡两个ISP的路由。

通过调整"weight"参数我们可以指定其中一个ISP的优先权高于另一个。

应该指出,由于均衡是基于路由进行的,而路由是经过缓冲的,所以这样的均衡并不是100%精确。

也就是说,对于一个经常访问的站点,总是会使用同一个ISP。

进而,如果你对此不满意,你可能需要参考以下JulianAnastasov的内核补丁:

Julian的路由补丁会弥补上述缺陷。

第5章GRE和其他隧道

Linux有3种隧道。

它们是:

IP-in-IP隧道、GRE隧道和非内核隧道(如PPTP)。

5.1.关于隧道的几点注释

隧道可以用于实现很多非常不一般而有趣的功能。

但如果你的配置有问题,却也会发生可怕的错误。

除非你确切地知道你在做什么,否则不要把缺省路由指向一个隧道设备。

而且,隧道会增加协议开销,因为它需要一个额外的IP包头。

一般应该是每个包增加20个字节,所以如果一个网络的MTU是1500字节的话,使用隧道技术后,实际的IP包长度最长只能有1480字节了。

这倒不是什么原则性的问题,但如果你想使用隧道技术构建一个比较大规模的网络的话,最好仔细研究一下关于IP包的分片和汇聚的知识。

哦,还有,挖一个隧道最好的方法当然是同时从两头挖。

5.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

路由器10.0.2.1

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

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

而且你可以随便使用Internet。

这就是你要做的:

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

insmodipip.oinsmodnew_tunnel.o

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

ifconfigtunl010.0.1.1pointopoint172.19.20.21routeadd-net10.0.2.0netmask255.255.255.0devtunl0

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

ifconfigtunl010.0.2.1pointopoint172.16.17.18routeadd-net10.0.1.0netmask255.255.255.0devtunl0

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

ifconfigtunl0down

简单之极!

但是你不能通过IP-in-IP隧道转发广播或者IPv6数据包。

你只是连接了两个一般情况下无法直接通讯的IPv4网络而已。

至于兼容性,这部分代码已经有很长一段历史了,它的兼容性可以上溯到1.3版的内核。

据我所知,Linux的IP-in-IP隧道不能与其他操作系统或路由器互相通讯。

它很简单,也很有效。

需要它的时候尽管使用,否则就使用GRE。

5.3.GRE隧道

GRE是最初由CISCO开发出来的隧道协议,能够做一些IP-in-IP隧道做不到的事情。

比如,你可以使用GRE隧道传输多播数据包和IPv6数据包。

在Linux下,你需要ip_gre.o模块。

5.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网络的路由器上,输入:

iptunneladdnetbmodegreremote172.19.20.21local172.16.17.18ttl255iplinksetnetbupipaddradd10.0.1.1devnetbiprouteadd10.0.2.0/24devnetb

让我们稍微讨论一下。

第1行,我们添加了一个隧道设备,并且称之为netb(为了能够表示出这个隧道通向哪里)。

并且表示要使用GRE协议(modegre),对端地址是172.19.20.21(另一端的路由器),我们的隧道数据包发源于172.16.17.18(以便当你的路由器在C网络中拥有多个地址的时候,你可以指定哪一个应用于隧道)并且包的TTL字段应设置为255(ttl255)。

第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网络的路由器。

iptunneladdnetamodegreremote172.16.17.18local172.19.20.21ttl255iplinksetnetaupipaddradd10.0.2.1devnetaiprouteadd10.0.1.0/24devneta

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

iplinksetnetbdowniptunneldelnetb

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

5.3.2.IPv6隧道

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

这就开始吧。

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

Network3ffe:

406:

5:

1:

5:

a:

2:

1/96

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

iptunneladdsixbonemodesitremote172.22.23.24local172.16.17.18ttl255iplinksetsixboneupipaddradd3ffe:

406:

5:

1:

5:

a:

2:

1/96devsixboneiprouteadd3ffe:

/15devsixbone

让我们来讨论一下。

我们创建了一个叫做sixbone的隧道设备。

我们设置它的模式是sit(也就是在IPv4隧道中使用IPv6)并且告诉它对端(remote)和本端(local)在哪里。

TTL设置为最大,255。

接着,我们激活了这个设备(up)。

然后,我们添加了我们自己的网络地址,并添加了一条通过隧道去往3ffe:

/15(现在全部属于6bone)的路由。

GRE隧道是现在最受欢迎的隧道技术。

它也广泛地应用于Linux世界之外并成为一个标准,是个好东西。

5.4.用户级隧道

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

第6章用Cisco和6bone实现IPv6隧道

MarcoDavidsmarco@sara.nl著

NOTEtomaintainer:

AsfarasIamconcerned,thisIPv6-IPv4tunnelingisnotperdefinitionGREtunneling.YoucouldtunnelIPv6overIPv4bymeansofGREtunneldevices(GREtunnelsANYtoIPv4),butthedeviceusedhere("sit")onlytunnelsIPv6overIPv4andisthereforesomethingdifferent.

6.1.IPv6隧道

这是Linux隧道能力的另一个应用。

这在IPv6的早期实现中非常流行。

下面动手试验的例子当然不是实现IPv6隧道的唯一方法。

然而,它却是在Linux与支持IPv6的CISCO路由器之间搭建隧道的常用方法,经验证明多数人都是照这样做的。

八成也适合于你.。

简单谈谈IPv6地址:

相对于IPv4地址而言,IPv6地址非常大,有128bit而不是32bit。

这让我们得到了我们需要的东西--非常非常多的IP地址。

确切地说,有340,282,266,920,938,463,463,374,607,431,768,211,465个。

同时,IPv6(或者叫Ipng,下一代IP)还能让Internet上的骨干路由器的路由表变得更小、设备的配置更简单、IP层的安全性更好以及更好地支持QoS。

例如:

2002:

836b:

9820:

0000:

0000:

0000:

836b:

9886

写下一个IPv6地址确实是件麻烦事。

所以我们可以使用如下规则来进行简化:

.数字打头的零不要写,就像IPv4一样。

.每16bit或者两个字节之间使用冒号分隔。

.当出现很多连续的零时可简写成":

"。

在一个地址中只能使用一次。

例如:

地址2002:

836b:

9820:

0000:

0000:

0000:

836b:

9886可以写成:

2002:

836b:

9820:

836b:

9886,看上去更简单些。

另一个例子:

地址3ffe:

0000:

0000:

0000:

0000:

0020:

34A1:

F32C可以写成3ffe:

20:

34A1:

F32C,要短得多。

IPv6将可能取代现有的IPv4。

因为它采用了相对更新的技术,所以现在还没有全球范围的IPv6网络。

为了能够平滑地过渡,引入了6bone计划。

IPv6网络中的站点通过现有的IPv4体系互联,把IPv6数据包封装在IPv4数据包中进行传输。

这就是为什么引入隧道机制的原因。

为了能够使用IPv6,我们需要一个能够支持它的内核。

现在有很多文档都很好地说明了这个问题。

不外乎以下几步:

.找到一个新版的Linux发行版,要有合适的glibc库。

.找到一份最新的内核源代码。

都准备好了以后,就可以继续编译一个带IPv6支持的内核了:

.cd/usr/src/linux

.makemenuconfig

.选择"NetworkingOptions"

.选择"TheIPv6protocol"、"IPv6:

enableEUI-64tokenformat","IPv6:

disableproviderbasedaddresses"

提示:

不要编译成内核模块,那样经常会出问题。

换句话说,就是把IPv6内置入内核。

然后你就可以象往常一样保存配置并编译内核了。

提示:

在编译之前,可以修改一下Makefile,把EXTRAVERSION=-x变成EXTRAVERSION=-x-IPv6

有很多文档都很好地说明了如何编译并安装一个内核,我们这篇文档不是讨论这个问题的。

如果你在这个过程中出现了问题,请参阅合适的资料。

你可以先看看/usr/src/linux/README。

当你完成之后,用新的内核重启系统,你可以输入"/sbin/ifconfig-a"看看有没有新的"sit0-device"设备。

SIT的意思是"简单Internet过渡"(SimpleInternetTransition)。

如果到这里没有问题,你就可以奖励自己了,你已经向着下一代IP网络迈进了一大步。

现在继续下一步。

你需要把你的主机,或甚至整个局域网连接到另外一个IPv6网络上。

这个网络很可能是"6bone",它就是为了这个特定的目的而专门设立的。

让我们假定你有如下IPv6网络:

3ffe:

604:

6:

8:

/64,并且希望连接到6bone,或者其他地方。

请注意,/64这个子网声明的意义与IPv4相同。

你的IPv4地址是145.100.24.181,6bone的路由器的IPv4地址是145.100.1.5。

#iptunneladdsixbonemodesitremote145.100.1.5[local145.100.24.181ttl255]

#iplinksetsixboneup

#ipaddradd3FFE:

604:

6:

7:

2/126devsixbone

#iprouteadd3ffe:

0/16devsixbone

让我们讨论一下。

第1行,我们创建了一个叫做sixbone的隧道。

设置为sit(让IPv4隧道承载IPv6数据包)模式,并设置对端与本端IP。

TTL设为最大--255。

下一步,我们激活(up)了这个设备。

然后添加我们自己的网络地址,并设置利用隧道通往3ffe:

/15(whichiscurrentlyallof6bone)的路由。

如果你运行这个的这台机器是你的IPv6网关,就得考虑运行下面的命令:

#echo1/proc/sys/net/ipv6/conf/all/forwarding

#/usr/local/sbin/radvd

下面的一行,radvd是一个类似于zebra的路由公告守护程序,用来支持IPv6的自动配置特性。

如果感兴趣的话就用你最喜欢的搜索引擎找一找。

你可以检查一下:

#/sbin/ip-finet6addr

如果你的Linux网关支持IPv6且运行了radvd,在局域网上启动后,你就可以享受IPv6的自动配置特性了:

#/s

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1