使用 Routing 的功能,让 Linux Server 也可以当作 Router 来使用!此外,亦提到 IP aliases 这个好用的功能呢!
我们在第二章网络基础里面谈到过路由的相关概念,
他最大的功能就是在帮我们规划网络封包的传递方式与方向。至于路由的观察则可以使用
route 这个指令来查阅与设置。
好了,那么路由的形式有哪些?你又该如何确认路由是否正确呢?
如同第二章网络基础里面谈到的,每一部主机都有自己的路由表, 也就是说,你必须要通过你自己的路由表来传递你主机的封包到下一个路由器上头。 若发送出去后,该封包就得要通过下一个路由器的路由表来发送了,此时与你自己主机的路由表就没有关系啦! 所以说,如果网络上面的某一部路由器设置错误,那...封包的流向就会发生很大的问题。 我们就得要通过 traceroute 来尝试了解一下每个 router 的封包流向啰。
OK!那你自己主机的路由表到底有哪些部分呢?我们以底下这个路由表来说明:
[root@www ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 <== 1 169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0 <== 2 0.0.0.0 192.168.1.254 0.0.0.0 UG 0 0 0 eth0 <== 3 |
首先,我们得知道在 Linux 系统下的路由表是由小网域排列到大网域, 例如上面的路由表当中,路由是由『 192.168.1.0/24 --> 169.254.0.0/16 --> 0.0.0.0/0 (缺省路由) 』来排列的。 而当主机的网络封包需要发送时,就会查阅上述的三个路由规则来了解如何将该封包发送出去。 那你会不会觉得奇怪,为什么会有这几个路由呢?其实路由表主要有这几种情况来设计的:
Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 |
[root@www ~]# route add -net 192.168.100.0 \ > netmask 255.255.255.0 gw 192.168.100.254 SIOCADDRT: Network is unreachable |
[root@www ~]# route add -net 192.168.100.0 \ > netmask 255.255.255.0 dev eth0 [root@www ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.100.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 0.0.0.0 192.168.1.254 0.0.0.0 UG 0 0 0 eth1 |
事实上,在 Linux 的路由规则都是通过内核来达成的,所以这些路由表的规则都是在内核功能内啊!也就是在内存当中喔! ^_^
我们在 第五章的 ifconfig 指令里面谈过 eth0:0 这个设备吧?这个设备可以在原本的 eth0 上面仿真出一个虚拟接口出来,以让我们原本的网络卡具有多个 IP ,具有多个 IP 的功能就被称为 IP Alias 了。而这个 eth0:0 的设备可以通过 ifconfig 或 ip 这两个指令来达成, 关于这两个指令的用途请翻回去之前的章节阅读,这里不再浪费篇幅啊!
那你或许会问啊:『这个 IP Alias 有啥用途啊?』好问题!这个 IP Alias 最大的用途就是可以让你用来『应急』! 怎么说呢?我们就来聊一聊他的几个常见的用途好了:
[root@www ~]# ifconfig [device] [ IP ] netmask [netmask ip] [up|down] [root@www ~]# ifconfig eth0:0 192.168.0.100 netmask 255.255.255.0 up |
不过,你需要知道的是:所有的 IP Alias 都是由实体网卡仿真来的,所以当要启动 eth0:0 时,eth0 必须要先被启动才行。而当 eth0 被关闭后,所以 eth0:n 的仿真网卡将同时也被关闭。这得先要了解才行, 否则常常会搞错启动的设备啊!在路由规则的设置当中,常常需要进行一些测试,那这个 IP Alias 就派的上用场了。 尤其是学校单位的练习环境当中!
基本上,除非有特殊需求,否则建议你要有多个 IP 时,最好在不同的网卡上面达成,如果你真的要使用 IP Alias 时,那么如何在开机的时候就启动 IP alias 呢?方法有很多啦!包括将上面用 ifconfig 启动的指令写入 /etc/rc.d/rc.local 文件中 (但使用 /etc/init.d/network restart 时,该 IP alias 无法被重新启动), 但鸟哥个人比较建议使用如下的方式来处理:
[root@www ~]# cd /etc/sysconfig/network-scripts [root@www network-scripts]# vim ifcfg-eth0:0 DEVICE=eth0:0 <==相当重要!一定要与文件名相同的设备代号! ONBOOT=yes BOOTPROTO=static IPADDR=192.168.0.100 NETMASK=255.255.255.0 NETWORK=192.168.0.0 BROADCAST=192.168.0.255 [root@www network-scripts]# ifup eth0:0 [root@www network-scripts]# ifdown eth0:0 [root@www network-scripts]# /etc/init.d/network restart |
通过这个简单的方法,你就可以在开机的时候启动你的虚拟接口而取得多个 IP 在同一张网卡上了。不过需要注意的是, 如果你的这张网卡分别通过 DHCP 以及手动的方式来设置你的 IP 参数,那么 dhcp 的取得务必使用实体网卡,亦即是 eth0 之类的网卡代号,而手动的就以 eth0:0 之类的代号来设置较佳。
很多朋友可能都有一个可爱的想法,那就是:『我可不可以利用两张网卡, 利用两个相同网域的 IP 来增加我这部主机的网络流量』?事实上这是一个可行的方案, 不过必须要通过许多的设置来达成,若你有需求的话,可以参考网中人大哥写的这一篇 (注1):
如果只是单纯的以为设置好两张网卡的 IP 在同一个网域就能够增加你主机的两倍流量,那可就大错特错了~ 为什么呢?还记得我们在路由表规则里面提过网络封包的传递主要是依据主机内的路由表规则吧! 那如果你有两张网络卡时,假设:
[root@www ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 |
也就是说,(1)当要主动发送封包到 192.168.0.0/24 的网域时,都只会通过第一条规则 ,也就是通过 eth1 来传出去! (2)在回应封包方面,不管是由 eth0 还是由 eth1 进来的网络封包,都会通过 eth1 来回传!这可能会造成一些问题,尤其是一些防火墙的规则方面,很可能会发生一些严重的错误, 如此一来,根本没有办法达成负载平衡,也不会有增加网络流量的效果! 更惨的是,还可能发生封包传递错误的情况呐!所以说,同一部主机上面设置相同网域的 IP 时, 得要特别留意你的路由规则,一般来说,不应该设置同一的网段的不同 IP 在同一部主机上面。 例如上面的案例就是一个不好的示范啊!
我们知道在局域网路里面的主机可以通过广播的方式来进行网络封包的发送,但在不同网段内的主机想要互相连接时,就得要通过路由器了。
那么什么是路由器?他的主要功能是什么?底下我们就来聊一聊!
既然主机想要将数据发送到不同的网域时得通过路由器的帮忙,所以啦,路由器的主要功能就是:『转递网络封包』啰!也就是说,路由器会分析来源端封包的 IP 表头,在表头内找出要送达的目标 IP 后,通过路由器本身的路由表 (routing table) 来将这个封包向下一个目标 (next hop) 发送。这就是路由器的功能。 那么路由器的功能可以如何达成呢?目前有两种方法可以达成:
高端的路由器可以链接不同的硬件设备,并且可以转译很多不同的封包格式,通常...价格也不便宜啊! 在这个章节里面,我们并没有要探讨这么高端的咚咚,仅讨论在以太网路里头最简单的路由器功能: 连接两个不同的网域。嘿嘿!这个功能 Linux 个人电脑就可以达成了!那怎么达成呢?
就如同路由表是由 Linux 的内核功能所提供的,这个转递封包的能力也是 Linux 内核所提供, 那如何观察内核是否已经有启动封包转递呢?很简单啊,观察内核功能的显示文件即可,如下所示:
[root@www ~]# cat /proc/sys/net/ipv4/ip_forward 0 <== 0 代表没有启动, 1 代表启动了 |
要让该文件的内容变成启动值 1 最简单的方是就是使用:『echo 1 > /proc/sys/net/ipv4/ip_forward』即可。 不过,这个设置结果在下次重新开机后就会失效。因此,鸟哥建议您直接修改系统设置档的内容,那就是 /etc/sysctl.conf 来达成开机启动封包转递的功能喔。
[root@www ~]# vim /etc/sysctl.conf # 将底下这个设置值修改正确即可! (本来值为 0 ,将它改为 1 即可) net.ipv4.ip_forward = 1 [root@www ~]# sysctl -p <==立刻让该设置生效 |
sysctl 这个指令是在内核工作时用来直接修改内核参数的一个指令,更多的功能可以参考 man sysctl 查找。 不要怀疑!只要这个动作,你的 Linux 就具有最简单的路由器功能了。而由于 Linux 路由器的路由表设置方法的不同,通常路由器规划其路由的方式就有两种:
了解了路由器之后,接下来你可能需要了解到什么是 NAT (Network Address Translation, 网络地址转译) 服务器, NAT 是啥?其实 IP 分享器就是最简单的 NAT 服务器啦!嘿嘿,了解了吗?没错, NAT 可以达成 IP 分享的功能, 而 NAT 本身就是一个路由器,只是 NAT 比路由器多了一个『 IP 转换』的功能。怎么说呢?
所以说,当路由器两端的网域分别是 Public 与 Private IP 时,才需要 NAT 的功能! NAT 功能我们会在防火墙章节时谈及,这个章节仅谈论一下路由器而已啊! ^_^
一般来说,电脑数量小于数十部的小型企业是无须路由器的,只需要利用 hub/switch 串接各部电脑, 然后通过单一线路连接到 Internet 上即可。不过,如果是超过数百部电脑的大型企业环境, 由于他们的环境通常需要考虑如下的状况,因此才需要路由器的架设:
路由器就只是一个设备,要如何使用端看你的网络环境的规划!上面仅是举出一些应用案例。 底下我们先就架设一个静态路由的路由器来玩一玩吧!
假设在贵公司的网络环境当中,除了一般职员的工作用电脑是直接连接到对外的路由器来链接互联网, 在内部其实还有一个部门需要较安全的独立环境,因此这部份的网络规划可能是这样的情况:
以上图的架构来说,这家公司主要有两个 class C 的网段,分别是:
其中 192.168.1.0/24 是用来做为一般员工连接互联网用的,至于 192.168.10.0/24 则是给特殊的部门用的。PC1 代表的是一般员工的电脑, PC2 及 PC3, PC4 则是特殊部门的工作用电脑, Linux Router 则是这个特殊部门用来连接到公司内部网域的路由器。在这样的架构下, 该特殊部门的封包就能够与公司其他部门作实体的分隔了。
由上图你也不难发现,只要是具有路由器功能的设备 (Router A, Linux Router) 都会具有两个以上的接口, 分别用来沟通不同的网域,同时该路由器也都会具有一个缺省路由啊! ^_^! 另外,你还可以加上一些防火墙的软件在 Linux Router 上,以保护 PC2~PC4 的内部电脑呢!
那我们先来探讨一下连接的机制好了,先从 PC2 这部电脑谈起。如果 PC2 想要连上 Internet ,那么他的连接情况会是如何?
观察一下两部 Router 的设置,要达到上述功能,则 Router A 必须要有两个接口,一个是对外的 Public IP 一个则是对内的 Private IP ,因为 IP 的类别不同,因此 Router A 还需要额外增加 NAT 这个机制才行,这个机制我们在后续章节会继续谈到。 除此之外,Router A 并不需要什么额外的设置。至于 Linux Router 就更简单了!什么事都不用作,将两个网络适配器设置两个 IP , 并且启动内核的封包转递功能,立刻就架设完毕了!非常简单!我们就来谈一谈这几个机器的设置吧!
在这部主机内需要有两张网卡,鸟哥在这里将他定义为:
# 1. 先处理 eth0 [root@www ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 BOOTPROTO=static IPADDR=192.168.1.100 NETMASK=255.255.255.0 GATEWAY=192.168.1.254 <==最重要的设置啊!通过这部主机连出去的! ONBOOT=yes # 2. 再先处理 eth1 [root@www ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth1 DEVICE=eth1 BOOTPROTO=none ONBOOT=yes IPADDR=192.168.10.254 NETMASK=255.255.255.0 # 3. 启动 IP 转递 [root@www ~]# vim /etc/sysctl.conf net.ipv4.ip_forward = 1 # 找到上述的设置值,将默认值 0 改为上述的 1 即可!保存后离开去! [root@www ~]# sysctl -p [root@www ~]# cat /proc/sys/net/ipv4/ip_forward 1 <==这就是重点!要是 1 才可以呦! # 4. 重新启动网络,并且观察路由与 ping Router A [root@www ~]# /etc/init.d/network restart [root@www ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.10.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth1 0.0.0.0 192.168.1.254 0.0.0.0 UG 0 0 0 eth0 # 上面的重点在于最后面那个路由器的设置是否正确呦! [root@www ~]# ping -c 2 192.168.1.254 PING 192.168.1.254 (192.168.1.254) 56(84) bytes of data. 64 bytes from 192.168.1.254: icmp_seq=1 ttl=64 time=0.294 ms 64 bytes from 192.168.1.254: icmp_seq=2 ttl=64 time=0.119 ms <==有回应即可 |
有够简单吧!而且通过最后的 ping 我们也知道 Linux Router 可以连上 Router A 啰!这样你的 Linux Router 就 OK 了呐!接下来则是要设置 PC2 这个被保护的内部主机网络啰。
不论你的 PC2 是哪一种操作系统,你的环境都应该是这样的:
以 Linux 操作系统为例,并且 PC2 仅有 eth0 一张网卡时,他的设置是这样的:
[root@www ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 BOOTPROTO=static IPADDR=192.168.10.20 NETMASK=255.255.255.0 GATEWAY=192.168.10.254 <==这个设置最重要啦! ONBOOT=yes [root@www ~]# /etc/init.d/network restart [root@www ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.10.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0 0.0.0.0 192.168.10.254 0.0.0.0 UG 0 0 0 eth0 [root@www ~]# ping -c 2 192.168.1.254 |
最后一个动作有问题呦!怎么会连 ping 都没有办法 ping 到 Router A 的 IP 呢?如果连 ping 都没有办法给予回应的话, 那么表示我们的连接是有问题的!再从刚刚的回应连接需求流程来看一下吧!
发现了吗?网络是双向的,此时封包出的去,但是非常可怜的,封包回不来~那怎办呢?只好告知 Router A 当路由规则碰到 192.168.10.0/24 时,要将该封包传 192.168.1.100 就是了!所以你要这样进行。
假设我的 Router A 对外的网卡为 eth1 ,而内部的 192.168.1.254 则是设置在 eth0 上头。 那怎么在 Router A 增加一条路由规则呢?很简单啊!直接使用 route add 去增加即可!如下所示的情况:
[root@www ~]# route add -net 192.168.10.0 netmask 255.255.255.0 \ > gw 192.168.1.100 |
不过这个规则并不会写入到设置档,因此下次重新开机这个规则就不见了!所以,你应该要创建一个路由设置档。 由于这个路由是依附在 eth0 网卡上的,所以设置档的文件名应该要是 route-eth0 喔!这个设置档的内容当中,我们要设置 192.168.10.0/24 这个网域的 gateway 是 192.168.1.100 ,且是通过 eth0 ,那么写法就会变成:
[root@www ~]# vim /etc/sysconfig/network-scripts/route-eth0 192.168.10.0/24 via 192.168.1.100 dev eth0 目标网域 通过的gateway 设备 [root@www ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 120.114.142.0 0.0.0.0 255.255.255.192 U 0 0 0 eth1 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.10.0 192.168.1.100 255.255.255.0 UG 0 0 0 eth0 169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth1 0.0.0.0 120.114.142.254 0.0.0.0 UG 0 0 0 eth1 |
上述观察的重点在于有没有出现 192.168.10.0 那行路由!如果有的话,请 ping 192.168.10.20 看看能不能有回应? 然后再到 PC2 上面去 ping 192.168.1.254 看看有没有回应,你就知道设置成功啰!好了,既然内部保护网络已经可以连上 Internet 了, 那么是否代表 PC2 可以直接与一般员工的网域,例如 PC1 进行连接呢?我们依旧通过路由规则来探讨一下,当 PC2 要直接连接到 PC1 时,他的连接方向是这样的:
有没有发现一个很可爱的传输流程?连接发起是没有问题啦,不过呢,回应连接竟然会偷偷通过 Router A 来帮忙呦! 这是因为 PC1 与当初的 Router A 一样,并不知道 192.168.10.0/24 在 192.168.1.100 里面啦!不过,反正 Router A 已经知道了该网域在 Linux Router 内,所以,该封包还是可以顺利的回到 PC2 就是了。
如果你不想要让 PC1 得要通过 Router A 才能够连接到 PC2 的话,那么就得要与 Router A 相同,增加那一条路由规则啰! 如果是 Linux 的系统,那么如同 Router A 一样的设置如下:
[root@www ~]# vim /etc/sysconfig/network-scripts/route-eth0 192.168.10.0/24 via 192.168.1.100 dev eth0 [root@www ~]# /etc/init.d/network restart [root@www ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.10.0 192.168.1.100 255.255.255.0 UG 0 0 0 eth0 169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0 0.0.0.0 192.168.1.254 0.0.0.0 UG 0 0 0 eth0 |
最后只要 PC2 使用 ping 可以连到 PC1,同样的, PC1 也可以 ping 到 PC2 的话,就表示你的设置是 OK 的啦!搞定!而通过这样的设置方式,你也可以发现到一件事,那就是:『路由是双向的,你必须要了解出去的路由与回来时的规则』。 举例来说,在缺省的情况下 (Router A 与 PC1 都没有额外的路由设置时),其实封包是可以由 PC2 连接到 PC1 的,但是 PC1 却没有相关的路由可以回应到 PC2 ~所以上头才会要你在 Router A 或者是 PC1 上面设置额外的路由规则啊!这样说,瞭了吧? ^_^
用 Linux 作一个静态路由的 Router 很简单吧!以上面的案例来说,你在 Linux Router 上面几乎没有作什么额外的工作,只要将网络 IP 与网络接口对应好启动,然后加上 IP Forward 的功能, 让你的 Linux 内核支持封包转递,然后其他的工作咱们的 Linux kernel 就主动帮你搞定了!真是好简单!
不过这里必须要提醒的是,如果你的 Linux Router 有设置防火墙的话, 而且还有设置类似 NAT 主机的 IP 伪装技术,那可得特别留意,因为还可能会造成路由误判的问题~ 上述的 Linux Router 当中『并没有使用到任何 NAT 的功能』喔!特别给他留意到!
在一般的静态路由器上面,我们可以通过修改路由设置档 (route-ethN) 来设置好既定的路由规则,让你的路由器运作顺利。不过, 这样的方法总是觉得很讨厌!如果某天因为组织的再造导致需要重新规划子网络网段,如此一来,你就得要在图 8.2-1 的 Router A 与 Linux Router 再次的处理与检查路由规则,真是有够麻烦的~ 那能不能让路由器自己学习新的路由,来达成自动增加该笔路由的信息呢?
上述的功能就是所谓的动态路由。动态路由通常是用在路由器与路由器之间的沟通,所以要让你的路由器具有动态路由的功能, 你必须要了解到对方路由器上面所提供的动态路由协定才行,这样两部路由器才能够通过该协定来沟通彼此的路由规则。 目前常见的动态路由协定有:RIPv1, RIPv2, OSPF, BGP 等。
想要在 CentOS 上面搞定这些动态路由的相关机制,那就得要使用 quagga 这个软件啦!这个软件是 zebra 计划的延伸, 相关的官网说明可以参考文后的参考数据(注3)。既然要玩 quagga ,自然就得要先安装他啰!赶紧处理吧!
[root@www ~]# yum install quagga [root@www ~]# ls -l /etc/quagga -rw-r--r-- 1 root root 410 10月 21 2010 ripd.conf.sample -rw-r----- 1 quagga quagga 29 5月 23 16:14 zebra.conf -rw-r--r-- 1 root root 373 10月 21 2010 zebra.conf.sample .....(其他省略)..... |
这个软件所提供的各项动态路由协定都放置到 /etc/quagga/ 目录内,底下我们以较为简单的 RIPv2 协定来处理动态路由, 不过你得要注意的是,不论你要启动什么动态路由协定,那个 zebra 都必须要先启动才行!这是因为:
而各个路由服务的设置档都必须要以 /etc/quagga/*.conf 的文件名来保存才行,如上表我们可以发现 zebra 这个服务是有设置好了,不过 ripd 的文件名却不是 .conf 结尾。所以我们必须要额外作些设置才行。
为了练习一下我们的 quagga ,当然得要设计一下可能的网络连接啰~假设网络连接的图标如下,共有三个区网的网段, 其中最大的是 192.168.1.0/24 这个外部区网,另有两个内部区网分别是 192.168.10.0/24 及 192.168.5.0/24 。
上图的两部 Linux Router 分别负责不同的网域,且可以通过 192.168.1.0/24 这个网域来沟通。在没有设置额外路由规则的情况下,那个 PC1 与 PC2 是无法沟通的!另外,quagga 必须要同时安装在两部 Linux Router 上头才行, 而且我们只要设置好这两部主机的网络接口 (eth0, eth1) 后,不需要手动输入额外的路由设置喔!可以通过 RIP 这个路由协定来搞定的!
# 1. 先设置会影响动态路由服务的 zebra 并且启动 zebra [root@www ~]# vim /etc/quagga/zebra.conf hostname linux.router.z1 <==给予这个路由器一个主机名称,随便取! password linuxz1 <==给予一个密码! enable password linuxz1 <==将这个密码生效! log file /var/log/quagga/zebra.log <==将所有 zebra 产生的信息存到注册表中 [root@www ~]# /etc/init.d/zebra start [root@www ~]# netstat -tunlp | grep zebra Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:2601 0.0.0.0:* LISTEN 3203/zebra |
[root@www ~]# telnet localhost 2601 Trying 127.0.0.1... Connected to localhost.localdomain (127.0.0.1). Escape character is '^]'. Hello, this is Quagga (version 0.98.6). Copyright 1996-2005 Kunihiro Ishiguro, et al. User Access Verification Password: <==在这里输入刚刚你设置的密码啊! linux.router.z1> ? <==在这边输入『 ? 』就能够知道有多少指令可使用 echo Echo a message back to the vty enable Turn on privileged mode command exit Exit current mode and down to previous mode help Description of the interactive help system list Print command list quit Exit current mode and down to previous mode show Show running system information terminal Set terminal line parameters who Display who is on vty linux.router.z1> list <==列出所有可用指令 echo .MESSAGE ....(中间省略).... show debugging zebra show history show interface [IFNAME] ....(中间省略).... show ip protocol show ip route ....(其他省略).... linux.router.z1> show ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - ISIS, B - BGP, > - selected route, * - FIB route K>* 0.0.0.0/0 via 192.168.1.254, eth0 <==内核直接设置的 C>* 127.0.0.0/8 is directly connected, lo <==接口产生的路由 K>* 169.254.0.0/16 is directly connected, eth1 <==内核直接设置的 C>* 192.168.1.0/24 is directly connected, eth0 <==接口产生的路由 C>* 192.168.10.0/24 is directly connected, eth1 <==接口产生的路由 linux.router.z1> exit Connection closed by foreign host. |
[root@www ~]# vim /etc/quagga/zebra.conf # 添加底下这一行喔! ip route 10.0.0.0/24 eth0 [root@www ~]# /etc/init.d/zebra restart [root@www ~]# telnet localhost 2601 Password: <==这里输入密码 linux.router.z1> show ip route K>* 0.0.0.0/0 via 192.168.1.254, eth0 S>* 10.0.0.0/24 [1/0] is directly connected, eth0 C>* 127.0.0.0/8 is directly connected, lo K>* 169.254.0.0/16 is directly connected, eth1 C>* 192.168.1.0/24 is directly connected, eth0 C>* 192.168.10.0/24 is directly connected, eth1 |
[root@www ~]# vim /etc/quagga/ripd.conf hostname linux.router.z1 <==这里是设置 Router 的主机名称而已 password linuxz1 <==设置好你自己的密码喔! debug rip events <==可以记录较多的错误消息! debug rip packet <==鸟哥通过这个消息解决很多问题 router rip <==启动 Router 的 rip 功能 version 2 <==启动的是 RIPv2 的服务 (默认值) network 192.168.1.0/24 <==这两个就是我们管理的接口啰! network 192.168.10.0/24 interface eth0 <==针对外部的那个接口,要略过身份验证的方式 no ip rip authentication mode <==就是这个项目!不要验证身份! log file /var/log/quagga/zebra.log <==注册表设置与 zebra 相同即可 [root@www ~]# /etc/init.d/ripd start [root@www ~]# netstat -tulnp | grep ripd Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:2602 0.0.0.0:* LISTEN 6193/ripd udp 0 0 0.0.0.0:520 0.0.0.0:* 6193/ripd # 新版的 quagga 启动的 2602 仅在 127.0.0.1 ,是通过 port 520 来传递信息! |
[root@www ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.5.0 192.168.1.200 255.255.255.0 UG 2 0 0 eth0 10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.10.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth1 0.0.0.0 192.168.1.254 0.0.0.0 UG 0 0 0 eth0 # 其实看路由就知道啦!第一条就是添加的路由规则!很清楚! [root@www ~]# telnet localhost 2601 Password: <==不要忘记了密码啊! linux.router.z1> show ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - ISIS, B - BGP, > - selected route, * - FIB route K>* 0.0.0.0/0 via 192.168.1.254, eth0 S>* 10.0.0.0/24 [1/0] is directly connected, eth0 C>* 127.0.0.0/8 is directly connected, lo K>* 169.254.0.0/16 is directly connected, eth1 C>* 192.168.1.0/24 is directly connected, eth0 R>* 192.168.5.0/24 [120/2] via 192.168.1.200, eth0, 00:03:40 C>* 192.168.10.0/24 is directly connected, eth1 |
[root@www ~]# chkconfig zebra on [root@www ~]# chkconfig ripd on |
通过这个 quagga 以及 RIPv2 的路由协定的辅助,我们可以轻松的就将路由规则分享到附近区网的其他路由器上头, 比起单纯使用 route 去修改 Linux 的内核路由表,这个动作当然要快速很多!不过,如果是很小型的网络环境,那么不要使用这个 quagga 啊!因为有点多此一举的感觉。如果你的企业环境真的有够大,那么玩一玩这个 quagga 配合一些动态路由协定,嘿嘿!也是可行的啦!
如果你一开始设计的网络环境就是同一个 Class C 的网域,例如 192.168.1.0/24 , 后来因为某些因素必须要将某些主机搬到比较内部的环境中,例如图 8.2-1的 PC2 ~ PC4 。 然后又因为某些因素,所以你不能变更 PC2 ~ PC4 的 IP ,此时你的同一网域就会横跨在一个路由器的左右两边了! 举例来说,连接图标有点像底下这样:
初次见面~看到眼睛快要掉下来哩!怎么路由器的两边的主机 IP 设置都在同一个网域内?而且还被规定不能够更改原先的 IP 设置, ...真是一个头两个大啊~如此一来,在 Linux Router 两边要如何制作路由啊?好问题!真是好问题~ 因为 OSI 第三层网络层的路由是一条一条去设置比对的,所以如果两块网卡上面都是同一个网域的 IP 时, 就会发生错误。那如何处理啊?
我们先从两方面来说,第一个,当从正确的网段 (PC1) 要连接到 PC2~PC4 时,他应该是要通过 Linux Router 那部主机的对外 IP (192.168.1.100) 才行!而且 Linux Router 还必须要让该封包通过内部 IP (192.168.1.200) 连接到 PC2~PC4 。 此时,封包传递的图标有点像这样:
在这个阶段,我们可以设置PC2~PC4 的 IP 所对应的网卡卡号 (MAC) 都设置在 router 的对外网卡上, 因此, router 的对外接口可以将给 PC2~PC4 的封包给『骗』过来。接下来,就简单的通过路由设置,让封包转个接口发送出去即可。 这样 PC1 --> PC2 的问题解决了,但是 PC2 怎么发送到 PC1 呢?我们可以通过底下的图标来想像一下:
当 PC2 要发送的封包是给 PC3, PC4 的,那么这个封包得要能够直接传递。但是如果需要发送到正常网域的封包,就得要通过 router 的对内网卡,再通过路由规则来将该封包导向外部接口来传递才行!这个时候就变成内部的接口欺骗 PC2 说, PC1 与 Router A 的 IP 是在内部这张接口上就是了,然后再通过路由判断将该封包通过外部接口来对外传递出去即可。 假设 Linux router 的对外接口为 eth0 而对内为 eth1 时,我们可以这样说:
上列的步骤与图标内的线条上的顺序相符合呦!得要对照着看看。其中的 (1) 与 (3) 就是通过 ARP Proxy (代理) 的功能啦! 那啥是 ARP Proxy 呢?简单的说,就是让我的某张适配器的 MAC 代理其他主机的 IP 对应,让想要连接到这个 IP 的 MAC 封包由我帮他接下来的意思。举我们图 8.4-1 的例子来说,就是在 Linux Router 的 eth0 接口上,规定 192.168.1.20, 192.168.1.30, 192.168.1.40 这三个 IP 都对应到 eth0 的 MAC 上,所以三个 IP 的封包就会由 eth0 代为收下,因此才叫做 ARP 代理人嘛!所以啦,每一部在 eth0 那端的主机都会『误判』那三个 IP 是 Linux Router 所拥有,这样就能够让封包传给 Linux Router 啦!
再接下来,咱们的 Linux Router 必须要额外指定路由,设置情况为:
也就是说,你必须要指定路由规则当中,那个 PC2~PC4 具有优先选择权,然后其他的同网域封包才由 eth0 来发送。 这样就能够达成我们所想要的结局啦!^_^!看样子似乎很难,其实设置方面还挺简单的,你可以通过 arp 以及 route 这两个指令来达成喔!
# 1. 先设置外部 eth0 的 ARP Proxy,让三个 IP 对应到自己的 MAC [root@www ~]# arp -i eth0 -s 192.168.1.20 00:E0:81:71:7C:D6 pub [root@www ~]# arp -i eth0 -s 192.168.1.30 00:E0:81:71:7C:D6 pub [root@www ~]# arp -i eth0 -s 192.168.1.40 00:E0:81:71:7C:D6 pub [root@www ~]# arp -n Address HWtype HWaddress Flags Mask Iface 192.168.1.30 * * MP eth0 192.168.1.40 * * MP eth0 192.168.1.20 * * MP eth0 # 首先需要让外部接口拥有三个 IP 的操控权,通过这三个指令来创建 ARP 对应! # 2. 开始处理路由,增加 PC2~PC4 的单机路由经过内部的 eth1 来传递 [root@www ~]# route add -host 192.168.1.20 eth1 [root@www ~]# route add -host 192.168.1.30 eth1 [root@www ~]# route add -host 192.168.1.40 eth1 [root@www ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.1.40 0.0.0.0 255.255.255.255 UH 0 0 0 eth1 192.168.1.30 0.0.0.0 255.255.255.255 UH 0 0 0 eth1 192.168.1.20 0.0.0.0 255.255.255.255 UH 0 0 0 eth1 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth1 0.0.0.0 192.168.1.254 0.0.0.0 UG 0 0 0 eth0 # 这样就处理好单向的单机路由啰!不过有个问题啊!那就是 192.168.1.0/24 # 的网域,两个接口都可以发送!因此,等一下第四个步骤得要将他删除才行! 3. 设置一下内部的 ARP Proxy 工作 (绑在 eth1 上头啰)! [root@www ~]# arp -i eth1 -s 192.168.1.10 00:E0:4C:F0:B5:5B pub [root@www ~]# arp -i eth1 -s 192.168.1.254 00:E0:4C:F0:B5:5B pub # 这样可以骗过 PC2 ~ PC4 ,让这三部主机传递的封包可以通过 router 来传递! 4. 开始清除掉 eth1 的 192.168.1.0/24 路由 [root@www ~]# route del -net 192.168.1.0 netmask 255.255.255.0 eth1 |
所有的电脑都在同一个网域内,因此 default gatway 都是 192.168.1.254 ,而 netmask 都是 255.255.255.0, 只有 IP 不一样而已。最后,所有的电脑都可以直接跟对方连接,也能够顺利的连上 Internet ! 这样的设置就能够满足上述的功能需求啰!如果一切都没有问题,那么将上述的指令写成一个脚本档, 例如 /root/bin/network.sh ,然后将该文件设置为可运行,并将它写入 /etc/rc.d/rc.local , 同时每次重新启动网络后,就得要重新运行一次该脚本,即可达到你的需求啰!
通过这个案例你也可以清楚的知道,能不能连接其实与路由的关系才大哩! 而路由是双向的,你必须要考量到这个封包如何回来的问题喔!