百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 优雅编程 > 正文

Linux高级路由教程

sinye56 2024-11-27 20:34 9 浏览 0 评论

多年来,我们在办公室使用的都是普通的ADSL——下载速度快,上传速度慢,延迟高——这样的链路费用是1美元/GB。我们在性能和可靠性方面有很多问题,经过几年的努力,我们决定获得第二个上游链路-SHDSL 5M/5M对称链路-低延迟,在7x24保持一致的速率。

然而,SHDS链路是昂贵的!虽然国内流量是免费的,但国际流量是5美元/GB。与国内和国际相同价格的1美元/GB的ADSL链路相比(表1)。

表1: ADSL链路 vs SHDSL链路


ADSL链路

SHDSL链路

速率

7Mbps下行/1Mbps上行

5Mbps下行/5Mbps上行

国内流量价格

1美元/GB

免费

国际流量价格

1美元/GB

5美元/GB




两者都有明显的优缺点,这让我想到,如果我们把ADSL链路用于国际流量,而把SHDSL链路用于国内流量,那么不就能达到最优性价比了吗。如图2:

我们还将SHDSL链路用于DMZ区,显然,我们希望所有进出DMZ区的流量都通过SHDSL链路,不管它是国内的还是国际的。如图3:

为了实现我的计划,公司的核心路由器需要一些方法来决定从办公室内网到外网的流量是国际的还是国内的,并相应地通过ADSL链路或SHDSL链路转发它。路由器使用路由表来决定它们所转发的数据包的命运和路径。一个地址为192.168.130.100的办公室工作站的简单路由表看起来像这样:

[workstation] ~ # ip route show
192.168.130.0/24 dev eth0 proto kernel  scope link  src 192.168.130.100
default via 192.168.130.1 dev eth0

意思是说,到192.168.130.0/24范围内所有其他地址的所有流量都将直接发送到连接到接口eth0的本地网段。所有其他流量遵循“默认”路由,并移交给IP为192.168.130.1的路由器来处理它。让我们假设我们正在向谷歌的公共DNS服务器8.8.4.4发送一个包。对于初学者,我们尝试“ping 8.8.4.4”,并通过tcpdump观察工作站的eth0接口上的流量:

[workstation] ~ # tcpdump -i eth0 -n -s0 -e
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
[1] 17:53:59.615650 00:16:17:ec:5c:6c > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42:
        Request who-has 192.168.130.1 tell 192.168.130.100, length 28
[2] 17:53:59.615775 00:14:c2:5b:4f:2c > 00:16:17:ec:5c:6c, ethertype ARP (0x0806), length 60:
        Reply 192.168.130.1 is-at 00:14:c2:5b:4f:2c, length 46
[3] 17:53:59.615796 00:16:17:ec:5c:6c > 00:14:c2:5b:4f:2c, ethertype IPv4 (0x0800), length 98:
        192.168.130.100 > 8.8.4.4: ICMP echo request, id 3082, seq 1, length 64

我的工作站查了路由表的目的IP地址8.8.4.4,意识到它应该把包发送到默认路由器192.168.130.1。为此,它需要路由器的底层以太网地址(也称为MAC地址),而上面tcpdump输出中的第一个包(标记为[1])正是这样做的——通过向网段上的所有节点“广播”请求来请求IP地址192.168.130.1的MAC地址。第二个包,标记为[2],是一个应答- IP地址192.168.130.1在MAC地址00:14:c2:5b:4f:2c。最后,PING包可以被发送,目的地为IP地址8.8.4.4到路由器的MAC地址00:14:c2:5b:4f:2c(标记为[3])。

很好,现在我们可以假设我们的路由器收到了数据包,并将它进一步转发到目的地。让我们看看路由器上发生了什么。

我们的路由器已经配置了ADSL链路和SHDSL链路,但默认情况下,所有流量都是通过ADSL链路转发的。ADSL链路的IP地址为192.168.128.254。目前,SHDSL链路203.0.113.36/30处于空闲状态。下面是路由表:

[router] ~ # ip route show
[1] 203.0.113.36/30 dev vlan-shdsl  proto kernel  scope link  src 203.0.113.38
[2] 192.168.128.0/24 dev vlan-adsl  proto kernel  scope link  src 192.168.128.1
[3] 192.168.130.0/24 dev vlan-office  proto kernel  scope link  src 192.168.130.1
[4] default via 192.168.128.254 dev vlan-adsl

第一行[1]是SHDSL链路——我们的路由器在该链路上配置的IP地址是203.0.113.38。第二行[2]是ADSL链路,第三行[3]是我的办公内网工作站所在的网段,最后第四行[4]是默认路由。所有数据包不匹配任何本地子网在线路1,2或3的数据包被发送到ADSL链路的下一跳地址192.168.128.254,然后将他们转发给ISP 2。这也是8.8.4.4数据包的命运。我们通过调用ip route get来快速验证将会发生什么:

[router] ~ # ip route get 8.8.4.4 from 192.168.130.100 iif vlan-office
8.8.4.4 from 192.168.130.100 via 192.168.128.254 dev vlan-adsl

如你所见,它将被通过192.168.128.254转发,这是ADSL链路。检查从我的工作站到任何给定目标地址的完整网络路径的简单方法是traceroute命令。它显示了到达目的地的所有路由器:

[workstation] ~ $ /usr/sbin/traceroute 8.8.4.4
traceroute to 8.8.4.4 (8.8.4.4), 30 hops max, 40 byte packets using UDP
 1  gw-vlan-office.e-it.co.nz (192.168.130.1)  0.156 ms  0.126 ms  0.124 ms
 2  gw-vlan-adsl.e-it.co.nz (192.168.128.254)  0.853 ms  0.831 ms  0.830 ms
 3  core-adsl.isp2 (218.101.x.y)  11.765 ms  19.173 ms  19.066 ms
 4  core-xyz.isp2 (203.98.x.y)  16.052 ms  15.515 ms  17.153 ms
[... some more hops ...]
13  64.233.x.y (64.233.x.y)  193.826 ms  194.230 ms  194.412 ms
14  * * *
15  google-public-dns-b.google.com (8.8.4.4)  196.086 ms  195.909 ms  195.816 ms

如你所见,第一个跳是我们的路由器192.168.130.1。第二跳是ADSL链路192.168.128.254。第三跳是ISP2的核心路由器之一,以此为例,在数据包最终到达目的地8.8.4.4(即google-publicdns -b.google.com)之前,它还要经过11个路由器。

国内流量 vs 国际流量
谷歌的公共DNS服务器B显然是一个离岸国际目的地。然而,新西兰有一个根DNS服务器,即IP地址为192.5.5.241的f.root-servers.net。目前,到f.root-servers.net的traceroute仍然显示ADSL链路路径:

[workstation] ~ $ /usr/sbin/traceroute f.root-servers.net
traceroute to f.root-servers.net (192.5.5.241), 30 hops max, 40 byte packets using UDP
 1  gw-vlan-office.e-it.co.nz (192.168.130.1)  0.175 ms  0.126 ms  0.125 ms
 2  gw-vlan-adsl.e-it.co.nz (192.168.128.254)  0.861 ms  0.840 ms  0.825 ms
 3  core-adsl.isp2 (218.101.x.y)  22.456 ms  22.298 ms  23.501 ms
 4  isp2.ape.net.nz (192.203.154.x)  21.035 ms  20.928 ms  21.268 ms
 5  isc2.ape.net.nz (192.203.154.y)  20.689 ms  21.724 ms  24.187 ms
 6  f.root-servers.net (192.5.5.241)  26.680 ms  26.059 ms  25.427 ms

这显然是国际流量,按照我们的计划应该通过SHDSL链路出去。我们可以手动完成,并在核心路由器上设置合适的路由:

[router] ~ # ip route add 192.5.5.241 via 203.0.113.37 dev vlan-shdsl

关于NAT我们需要知道:我们还需要将办公室地址范围192.168.130.0/24转换(或“伪装”或NAT)到我们的SHDSL链路公共IP地址203.0.113.38。如果我们不这样做,数据包的源IP地址将是192.168.130.100,并且回包将永远无法找到他们回到我的工作站的方式,因为这个地址范围在公共互联网中是不可路由的。讨论防火墙和NAT超出了本文的范围,但为了让您了解,这里有一个最简单的命令:

[router] ~ # iptables -t nat -A POSTROUTING -s 192.168.128.0/20 -o vlan-shdsl -j SNAT --to 203.0.113.38

所有源地址来自192.168.128.0/20范围的数据包通过接口vlan-shdsl将源重写为203.0.113.38。

现在,让我们检查新的网络路径:

[workstation] ~ $ /usr/sbin/traceroute f.root-servers.net
traceroute to f.root-servers.net (192.5.5.241), 30 hops max, 40 byte packets using UDP
 1  gw-vlan-office.e-it.co.nz (192.168.130.1)  0.190 ms  0.129 ms  0.125 ms
 2  rt-shdsl.isp1 (203.0.113.37)  2.676 ms  2.599 ms  2.632 ms
 3  rt3.isp1 (121.98.ab.cd)  2.715 ms  2.680 ms  2.591 ms
 4  isc2.ape.net.nz (192.203.154.z)  2.919 ms  3.033 ms  3.088 ms
 5  f.root-servers.net (192.5.5.241)  3.007 ms  2.670 ms  2.864 ms

现在好多了。第一跳保持不变,那是我的工作站的路由器,但第二跳不再是ADSL链路。相反,它是SHDSL ISP1链路的核心路由器。它也清楚地显示了延迟的改善,从26ms的ADSL链路到3ms的SHDSL链路。

让我们再次删除手动配置的路由,以避免任何混乱的路由,并查询路由表:

[router] ~ # ip route get 192.5.5.241 from 192.168.130.100 iif vlan-office
192.5.5.241 from 192.168.130.100 via 203.0.113.37 dev vlan-shdsl        # SHDSL链路

[router] ~ # ip route delete 192.5.5.241 via 203.0.113.37 dev vlan-shdsl

[router] ~ # ip route get 192.5.5.241 from 192.168.130.100 iif vlan-office
192.5.5.241 from 192.168.130.100 via 192.168.128.254 dev vlan-adsl      # ADSL链路

所以我们现在只需要一个所有国家IP地址的列表,把它们放到路由表中,然后就完成了。但是如何做?手动配置吗?即使在新西兰这样的小国家,也有数百个本地IP地址和前缀,而且列表是动态的,每天都在变化。没有办法手动管理这样的列表。我们需要一个更好的方式。

GET IT,使用BGP!

BGP是当今Internet的路由协议。这个星球上的每一个ISP都会告诉其他所有ISP它的网络中有哪些IP地址,以及其他哪些IP地址可以通过这个ISP的网络到达。交换这种信息的协议称为BGP (Border Gateway protocol)。

我不打算深入讨论BGP的细节。我们只需要知道我们的ISP1可以使用BGP向我们发送所有国家前缀的列表。我们不再手动输入它们,而是侦听“BGP消息”并从它更新我们的路由表。这部分需要与互联网供应商协调,所以我要求我们的ISP1请给我们分配一个私有的ASN,并发送给我们一个带国家前缀的BGP。BGP通常在由ASN (Autonomous System Number)标识的自治系统之间运行。任何足够大的组织都可以申请和支付自己的官方ASN,但就我们的目的而言,从ISP分配的私人范围内使用ASN就足够了。表2显示了我从他们那里收到的信息。

表2:


ISP

Company

ASN

177XY

6452X

Router IP

203.0.113.37

203.0.113.38

Prefixes advertised

all national ones

none

现在我们在链路的两边都有路由器的IP地址,有ASN和他们将发送给我们的前缀的确认(“所有国家的”)。这就是我们需要的全部信息。
许多BGP软件可用于Linux。我选择了Bird(当时最新的版本是1.3.4),并从RPM安装了它。

Bird的配置很简单。配置文件位于/etc/bird/bird.conf,如下所示:

log syslog all;
protocol kernel {
        import none;
        export all;
}
protocol device {
        scan time 10;
}
protocol bgp {
        description "ISP1 National Routes";
        local as 64526;
        neighbor 203.0.113.37 as 17746;
        source address 203.0.113.38;
        import all;     # Accept all prefixes from our neighbor
        export none;    # Don't send the neighbor any prefixes
}

本质上,Bird进程与BGP邻居对话,并将所有发布的前缀引入到它的内部路由列表中。它还与内核进行对话,并将它所知道的所有路由(即通过BGP学习到的所有路由)“导出到内核”。这样,它就从BGP提供内核路由表。

引入BGP路由后,目前内核路由表有4000多条记录:

[router] ~ # ip route show
   [1] 203.0.113.36/30 dev vlan-shdsl  proto kernel scope link  src 203.0.113.38
   [2] 192.168.128.0/24 dev vlan-adsl  proto kernel  scope link  src 192.168.128.1
   [3] 192.168.130.0/24 dev vlan-office  proto kernel  scope link  src 192.168.130.1
   [4] default via 192.168.128.254 dev vlan-adsl
   [5] 14.1.32.0/19 via 203.0.113.37 dev vlan-shdsl  proto bird
   [6] 27.252.0.0/16 via 203.0.113.37 dev vlan-shdsl  proto bird
   [7] 58.28.0.0/16 via 203.0.113.37 dev vlan-shdsl  proto bird
 ....
[4509] 203.97.0.0/17 via 203.0.113.37 dev vlan-shdsl  proto bird
[4510] 222.153.128.0/18 via 203.0.113.37 dev vlan-shdsl  proto bird
[4511] 222.155.96.0/19 via 203.0.113.37 dev vlan-shdsl  proto bird

从[1]到[4]的行与前面看到的相同—所有直接连接的子网和默认路由。[5] ~[4511]是通过BGP接收的路由。

现在,让我们来查询新填充的路由,以找到我们最喜欢的f.root-servers.net的路径:

[router] ~ # ip route get 192.5.5.241 from 192.168.130.100 iif vlan-office
192.5.5.241 from 192.168.130.100 via 203.0.113.37 dev vlan-shdsl        # SHDSL链路

太好了,这正是我们想要的!从工作站到国内和国际目的地运行一对traceroute,验证新路径是否按预期使用。

希望本文对您有所帮助,非常感谢!

相关推荐

程序员:JDK的安装与配置(完整版)_jdk的安装方法

对于Java程序员来说,jdk是必不陌生的一个词。但怎么安装配置jdk,对新手来说确实头疼的一件事情。我这里以jdk10为例,详细的说明讲解了jdk的安装和配置,如果有不明白的小伙伴可以评论区留言哦下...

Linux中安装jdk并配置环境变量_linux jdk安装教程及环境变量配置

一、通过连接工具登录到Linux(我这里使用的Centos7.6版本)服务器连接工具有很多我就不一一介绍了今天使用比较常用的XShell工具登录成功如下:二、上传jdk安装包到Linux服务器jdk...

麒麟系统安装JAVA JDK教程_麒麟系统配置jdk

检查检查系统是否自带java在麒麟系统桌面空白处,右键“在终端打开”,打开shell对话框输入:java–version查看是否自带java及版本如图所示,系统自带OpenJDK,要先卸载自带JDK...

学习笔记-Linux JDK - 安装&配置

前提条件#检查是否存在JDKrpm-qa|grepjava#删除现存JDKyum-yremovejava*安装OracleJDK不分系统#进入安装文件目...

Linux新手入门系列:Linux下jdk安装配置

本系列文章是把作者刚接触和学习Linux时候的实操记录分享出来,内容主要包括Linux入门的一些理论概念知识、Web程序、mysql数据库的简单安装部署,希望能够帮到一些初学者,少走一些弯路。注意:L...

测试员必备:Linux下安装JDK 1.8你必须知道的那些事

1.简介在Oracle收购Sun后,Java的一系列产品就被整合到Oracle官网中,打开官网乍眼一看也不知道去哪里下载,还得一个一个的摸索尝试,而且网上大多数都是一些Oracle收购Sun前,或者就...

Linux 下安装JDK17_linux 安装jdk1.8 yum

一、安装环境操作系统:JDK版本:17二、安装步骤第一步:下载安装包下载Linux环境下的jdk1.8,请去官网(https://www.oracle.com/java/technologies/do...

在Ubuntu系统中安装JDK 17并配置环境变量教程

在Ubuntu系统上安装JDK17并配置环境变量是Java开发环境搭建的重要步骤。JDK17是Oracle提供的长期支持版本,广泛用于开发Java应用程序。以下是详细的步骤,帮助你在Ubuntu系...

如何在 Linux 上安装 Java_linux安装java的步骤

在桌面上拥抱Java应用程序,然后在所有桌面上运行它们。--SethKenlon(作者)无论你运行的是哪种操作系统,通常都有几种安装应用程序的方法。有时你可能会在应用程序商店中找到一个应用程序...

Windows和Linux环境下的JDK安装教程

JavaDevelopmentKit(简称JDK),是Java开发的核心工具包,提供了Java应用程序的编译、运行和开发所需的各类工具和类库。它包括了JRE(JavaRuntimeEnviro...

linux安装jdk_linux安装jdk软连接

JDK是啥就不用多介绍了哈,外行的人也不会进来看我的博文。依然记得读大学那会,第一次实验课就是在机房安装jdk,编写HelloWorld程序。时光飞逝啊,一下过了十多年了,挣了不少钱,买了跑车,娶了富...

linux安装jdk,全局配置,不同用户不同jdk

jdk1.8安装包链接:https://pan.baidu.com/s/14qBrh6ZpLK04QS8ogCepwg提取码:09zs上传文件解压tar-zxvfjdk-8u152-linux-...

运维大神教你在linux下安装jdk8_linux安装jdk1.7

1.到官网下载适合自己机器的版本。楼主下载的是jdk-8u66-linux-i586.tar.gzhttp://www.oracle.com/technetwork/java/javase/downl...

window和linux安装JDK1.8_linux 安装jdk1.8.tar

Windows安装JDK1.8的步骤:步骤1:下载JDK打开浏览器,找到JDK下载页面https://d.injdk.cn/download/oraclejdk/8在页面中找到并点击“下载...

最全的linux下安装JavaJDK的教程(图文详解)不会安装你来打我?

默认已经有了linux服务器,且有root账号首先检查一下是否已经安装过java的jdk任意位置输入命令:whichjava像我这个已经安装过了,就会提示在哪个位置,你的肯定是找不到。一般我们在...

取消回复欢迎 发表评论: