如果说 IP 是门牌,那么邮差如何走到你家就是『路由』的功能啦!局域网络如果想成是条巷子,那么路由器就是那间巷子内的邮局! 其实本章应该是第二章网络基础的延伸,将网络的设定延伸到整个区网的路由器上而已。那何时会用到路由器? 如果你的环境中需要将整批 IP 再区隔出不同的广播区段时,那么就得要透过路由器的封包转递能力了。 本章是下一章防火墙与 NAT 的基础,得先看完才比较容易理解下一章想要讨论的事情喔! |
我们在第二章网络基础里面谈到过路由的相关概念, 他最大的功能就是在帮我们规划网络封包的传递方式与方向。至于路由的观察则可以使用 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 1002 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 (预设路由) 』来排列的。 而当主机的网络封包需要传送时,就会查阅上述的三个路由规则来了解如何将该封包传送出去。 那你会不会觉得奇怪,为什么会有这几个路由呢?其实路由表主要有这几种情况来设计的:
[root@www ~]# ifconfig eth1 192.168.2.100 [root@www ~]# route -n Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 192.168.1.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 1002 0 0 eth0 0.0.0.0 192.168.1.254 0.0.0.0 UG 0 0 0 eth0 |
[root@www ~]# route add -net 192.168.5.0 \ > netmask 255.255.255.0 gw 192.168.5.254 SIOCADDRT: No such process |
[root@www ~]# route add -net 192.168.5.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.5.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 192.168.1.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 1002 0 0 eth0 0.0.0.0 192.168.1.254 0.0.0.0 UG 0 0 0 eth0 |
事实上,在 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 [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 上即可。不过,如果是超过数百部计算机的大型企业环境, 由于他们的环境通常需要考虑如下的状况,因此才需要路由器的架设:
路由器就只是一个设备,要如何使用端看你的网络环境的规划!上面仅是举出一些应用案例。 底下我们先就架设一个静态路由的路由器来玩一玩吧!
假设在贵公司的网络环境当中,除了一般职员的工作用计算机是直接连接到对外的路由器来连结因特网, 在内部其实还有一个部门需要较安全的独立环境,因此这部份的网络规划可能是这样的情况 (参考图 3.2-1 内容延伸而来):
以上图的架构来说,这家公司主要有两个 class C 的网段,分别是:
其中 192.168.1.0/24 是用来做为一般员工连接因特网用的,至于 192.168.100.0/24 则是给特殊的部门用的。workstation 代表的是一般员工的计算机,clientlinux 及 winxp, win7 则是特殊部门的工作用计算机, Linux Router 则是这个特殊部门用来连接到公司内部网域的路由器。在这样的架构下, 该特殊部门的封包就能够与公司其他部门作实体的分隔了。
由上图你也不难发现,只要是具有路由器功能的设备 (Router A, Linux Router) 都会具有两个以上的接口, 分别用来沟通不同的网域,同时该路由器也都会具有一个预设路由啊! ^_^! 另外,你还可以加上一些防火墙的软件在 Linux Router 上,以保护 clientlinux, winxp, win7 呢!
那我们先来探讨一下联机的机制好了,先从 clientlinux 这部计算机谈起。如果 clientlinux 想要连上 Internet,那么他的联机情况会是如何?
观察一下两部 Router 的设定,要达到上述功能,则 Router A 必须要有两个接口,一个是对外的 Public IP 一个则是对内的 Private IP ,因为 IP 的类别不同,因此 Router A 还需要额外增加 NAT 这个机制才行,这个机制我们在后续章节会继续谈到。 除此之外,Router A 并不需要什么额外的设定。至于 Linux Router 就更简单了!什么事都不用作,将两个网络适配器设定两个 IP , 并且启动核心的封包转递功能,立刻就架设完毕了!非常简单!我们就来谈一谈这几个机器的设定吧!
在这部主机内需要有两张网卡,鸟哥在这里将他定义为 (假设你已经将刚刚实作的 eth0:0 取消掉了):
# 1. 再看看 eth0 的设定吧!虽然我们已经在第四章就搞定了: [root@www ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE="eth0" HWADDR="08:00:27:71:85:BD" NM_CONTROLLED="no" ONBOOT="yes" BOOTPROTO=none IPADDR=192.168.1.100 NETMASK=255.255.255.0 GATEWAY=192.168.1.254 <==最重要的设定啊!透过这部主机连出去的! # 2. 再处理 eth1 这张之前一直都没有驱动的网络卡吧! [root@www ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth1 DEVICE="eth1" HWADDR="08:00:27:2A:30:14" NM_CONTROLLED="no" ONBOOT="yes" BOOTPROTO="none" IPADDR=192.168.100.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.100.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 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 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 <==有回应即可 # 5. 暂时关闭防火墙!这一步也很重要喔! [root@www ~]# /etc/init.d/iptables stop |
有够简单吧!而且透过最后的 ping 我们也知道 Linux Router 可以连上 Router A 啰!这样你的 Linux Router 就 OK 了吶!此外,CentOS 6.x 默认的防火墙规则会将来自不同网卡的沟通封包剔除,所以还得要暂时关闭防火墙才行。 接下来则是要设定 clientlinux 这个被保护的内部主机网络啰。
不论你的 clientlinux 是哪一种操作系统,你的环境都应该是这样的 (图 8.2-1):
以 Linux 操作系统为例,并且 clientlinux 仅有 eth0 一张网卡时,他的设定是这样的:
[root@clientlinux ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE="eth0" NM_CONTROLLED="no" ONBOOT="yes" BOOTPROTO=none IPADDR=192.168.100.10 NETMASK=255.255.255.0 GATEWAY=192.168.100.254 <==这个设定最重要啦! DNS1=168.95.1.1 <==有这个就不用自己改 /etc/resolv.conf [root@clientlinux ~]# /etc/init.d/network restart [root@clientlinux ~]# 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 1 0 0 eth0 169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0 0.0.0.0 192.168.100.254 0.0.0.0 UG 0 0 0 eth0 [root@clientlinux ~]# ping -c 2 192.168.100.254 <==ping自己的gateway(会成功) [root@clientlinux ~]# ping -c 2 192.168.1.254 <==ping外部的gateway(会失败) |
最后一个动作有问题呦!怎么会连 ping 都没有办法 ping 到 Router A 的 IP 呢?如果连 ping 都没有办法给予回应的话, 那么表示我们的联机是有问题的!再从刚刚的响应联机需求流程来看一下吧!
发现了吗?网络是双向的,此时封包出的去,但是非常可怜的,封包回不来~那怎办呢?只好告知 Router A 当路由规则碰到 192.168.100.0/24 时,要将该封包传 192.168.1.100 就是了!所以你要这样进行。
假设我的 Router A 对外的网卡为 eth1 ,而内部的 192.168.1.254 则是设定在 eth0 上头。 那怎么在 Router A 增加一条路由规则呢?很简单啊!直接使用 route add 去增加即可!如下所示的情况:
[root@routera ~]# route add -net 192.168.100.0 netmask 255.255.255.0 \ > gw 192.168.1.100 |
不过这个规则并不会写入到配置文件,因此下次重新启动这个规则就不见了!所以,你应该要建立一个路由配置文件。 由于这个路由是依附在 eth0 网卡上的,所以配置文件的档名应该要是 route-eth0 喔!这个配置文件的内容当中,我们要设定 192.168.100.0/24 这个网域的 gateway 是 192.168.1.100,且是透过 eth0 ,那么写法就会变成:
[root@routera ~]# vim /etc/sysconfig/network-scripts/route-eth0 192.168.100.0/24 via 192.168.1.100 dev eth0 目标网域 透过的gateway 装置 [root@routera ~]# route -n Destination Gateway Genmask Flags Metric Ref Use Iface 120.114.142.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 192.168.100.0 192.168.1.100 255.255.255.0 UG 0 0 0 eth0 192.168.1.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 eth1 0.0.0.0 120.114.142.254 0.0.0.0 UG 0 0 0 eth1 |
上述观察的重点在于有没有出现 192.168.100.0 那行路由!如果有的话,请 ping 192.168.100.10 看看能不能有回应? 然后再到 clientlinux 上面去 ping 192.168.1.254 看看有没有响应,你就知道设定成功啰!好了,既然内部保护网络已经可以连上 Internet 了,那么是否代表 clientlinux 可以直接与一般员工的网域,例如 workstation 进行联机呢?我们依旧透过路由规则来探讨一下,当 clientlinux 要直接联机到 workstation 时,他的联机方向是这样的 (参考图 8.2-1):
有没有发现一个很可爱的传输流程?联机发起是没有问题啦,不过呢,响应联机竟然会偷偷透过 Router A 来帮忙呦! 这是因为 workstation 与当初的 Router A 一样,并不知道 192.168.100.0/24 在 192.168.1.100 里面啦!不过,反正 Router A 已经知道了该网域在 Linux Router 内,所以,该封包还是可以顺利的回到 clientlinux 就是了。
如果你不想要让 workstation 得要透过 Router A 才能够联机到 clientlinux 的话,那么就得要与 Router A 相同,增加那一条路由规则啰!如果是 Linux 的系统,那么如同 Router A 一样的设定如下:
[root@workstation ~]# vim /etc/sysconfig/network-scripts/route-eth0 192.168.100.0/24 via 192.168.1.100 dev eth0 [root@workstation ~]# /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.100.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 |
最后只要 clientlinux 使用 ping 可以连到 workstation,同样的,workstation 也可以 ping 到 clientlinux 的话,就表示你的设定是 OK 的啦!搞定!而透过这样的设定方式,你也可以发现到一件事,那就是:『路由是双向的,你必须要了解出去的路由与回来时的规则』。 举例来说,在预设的情况下 (Router A 与 workstation 都没有额外的路由设定时),其实封包是可以由 clientlinux 联机到 workstation 的,但是 workstation 却没有相关的路由可以响应到 clientlinux ~所以上头才会要你在 Router A 或者是 workstation 上面设定额外的路由规则啊!这样说,瞭了吧? ^_^
用 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 406 Jun 25 20:19 ripd.conf.sample -rw-r-----. 1 quagga quagga 26 Jul 22 11:11 zebra.conf -rw-r--r--. 1 root root 369 Jun 25 20:19 zebra.conf.sample .....(其他省略)..... |
这个软件所提供的各项动态路由协议都放置到 /etc/quagga/ 目录内,底下我们以较为简单的 RIPv2 协议来处理动态路由, 不过你得要注意的是,不论你要启动什么动态路由协议,那个 zebra 都必须要先启动才行!这是因为:
而各个路由服务的配置文件都必须要以 /etc/quagga/*.conf 的档名来储存才行,如上表我们可以发现 zebra 这个服务是有设定好了,不过 ripd 的档名却不是 .conf 结尾。所以我们必须要额外作些设定才行。
为了练习一下我们的 quagga ,当然得要设计一下可能的网络联机啰~假设网络联机的图标如下,共有三个区网的网段, 其中最大的是 192.168.1.0/24 这个外部区网,另有两个内部区网分别是 192.168.100.0/24 及 192.168.200.0/24 。
上图的两部 Linux Router 分别负责不同的网域,其中 Router Z1 是上个小节设定好之后就保留的,左边的 Router Z2 则是需要额外设定的路由器喔!两部 Router 可以透过 192.168.1.0/24 这个网域来沟通。在没有设定额外路由规则的情况下,那个 PC Z1 与 PC Z2 是无法沟通的!另外,quagga 必须要同时安装在两部 Linux Router 上头才行, 而且我们只要设定好这两部主机的网络接口 (eth0, eth1) 后,不需要手动输入额外的路由设定喔!可以透过 RIP 这个路由协议来搞定的!
# 1. 先设定会影响动态路由服务的 zebra 并且启动 zebra [root@www ~]# vim /etc/quagga/zebra.conf hostname www.centos.vbird <==给予这个路由器一个主机名,随便取! password linuxz1 <==给予一个密码! enable password linuxz1 <==将这个密码生效! log file /var/log/quagga/zebra.log <==将所有 zebra 产生的信息存到登录文件中 [root@www ~]# /etc/init.d/zebra start [root@www ~]# chkconfig zebra on [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 4409/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.99.15). Copyright 1996-2005 Kunihiro Ishiguro, et al. User Access Verification Password: <==在这里输入刚刚你设定的密码啊! www.centos.vbird> ? <==在这边输入『 ? 』就能够知道有多少指令可使用 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 www.centos.vbird> list <==列出所有可用指令 echo .MESSAGE ....(中间省略).... show debugging zebra show history show interface [IFNAME] ....(中间省略).... show ip protocol show ip route ....(其他省略).... www.centos.vbird> 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.100.0/24 is directly connected, eth1 <==接口产生的路由 www.centos.vbird> 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: <==这里输入密码 www.centos.vbird> 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.100.0/24 is directly connected, eth1 |
[root@www ~]# vim /etc/quagga/ripd.conf hostname www.centos.vbird <==这里是设定 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.100.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 ~]# chkconfig ripd on [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 4456/ripd udp 0 0 0.0.0.0:520 0.0.0.0:* 4456/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.100.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 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.200.0 192.168.1.200 255.255.255.0 UG 2 0 0 eth0 0.0.0.0 192.168.1.254 0.0.0.0 UG 0 0 0 eth0 # 其实看路由就知道啦!那条有点线的就是新增的路由规则!很清楚! [root@www ~]# telnet localhost 2601 Password: <==不要忘记了密码啊! www.centos.vbird> 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 C>* 192.168.100.0/24 is directly connected, eth1 R>* 192.168.200.0/24 [120/2] via 192.168.1.200, eth0, 00:02:43 |
[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的 clientlinxu, winxp, win7。 然后又因为某些因素,所以你不能变更这些计算机的 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.10, 192.168.1.20, 192.168.1.30 这三个 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.10 08:00:27:71:85:BD pub [root@www ~]# arp -i eth0 -s 192.168.1.20 08:00:27:71:85:BD pub [root@www ~]# arp -i eth0 -s 192.168.1.30 08:00:27:71:85:BD pub [root@www ~]# arp -n Address HWtype HWaddress Flags Mask Iface 192.168.1.30 * * MP eth0 192.168.1.10 * * MP eth0 192.168.1.20 * * MP eth0 # 首先需要让外部接口拥有三个 IP 的操控权,透过这三个指令来建立 ARP 对应! # 2. 开始处理路由,增加 PC2~PC4 的单机路由经过内部的 eth1 来传递 [root@www ~]# route add -host 192.168.1.10 eth1 [root@www ~]# route add -host 192.168.1.20 eth1 [root@www ~]# route add -host 192.168.1.30 eth1 [root@www ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.1.20 0.0.0.0 255.255.255.255 UH 0 0 0 eth1 192.168.1.10 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.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 0.0.0.0 192.168.1.254 0.0.0.0 UG 0 0 0 eth0 # 这样就处理好单向的单机路由啰!不过有个问题啊!那就是 192.168.1.0/24 # 的网域,两个接口都可以传送!因此,等一下第四个步骤得要将 eth1 删除才行! 3. 设定一下内部的 ARP Proxy 工作 (绑在 eth1 上头啰)! [root@www ~]# arp -i eth1 -s 192.168.1.101 08:00:27:2A:30:14 pub [root@www ~]# arp -i eth1 -s 192.168.1.254 08:00:27:2A:30:14 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 , 同时每次重新启动网络后,就得要重新执行一次该脚本,即可达到你的需求啰!
透过这个案例你也可以清楚的知道,能不能联机其实与路由的关系才大哩! 而路由是双向的,你必须要考虑到这个封包如何回来的问题喔!