8.2 路由器架设

我们知道在局域网络里面的主机可以透过广播的方式来进行网络封包的传送,但在不同网段内的主机想要互相联机时,就得要透过路由器了。 那么什么是路由器?他的主要功能是什么?底下我们就来聊一聊!


8.2.1 什么是路由器与 IP 分享器

既然主机想要将数据传送到不同的网域时得透过路由器的帮忙,所以啦,路由器的主要功能就是:『转递网络封包』啰!也就是说,路由器会分析来源端封包的 IP 表头,在表头内找出要送达的目标 IP 后,透过路由器本身的路由表 (routing table) 来将这个封包向下一个目标 (next hop) 传送。这就是路由器的功能。 那么路由器的功能可以如何达成呢?目前有两种方法可以达成:

  • 硬件功能:例如 Cisco, TP-Link, D-Link (注2) 等公司都有生产硬件路由器, 这些路由器内有嵌入式的操作系统,可以负责不同网域间的封包转译与转递等功能;

  • 软件功能:例如 Linux 这个操作系统的核心就有提供封包转递的能力。

高阶的路由器可以连结不同的硬设备,并且可以转译很多不同的封包格式,通常...价格也不便宜啊! 在这个章节里面,我们并没有要探讨这么高阶的咚咚,仅讨论在以太网络里头最简单的路由器功能: 连接两个不同的网域。嘿嘿!这个功能 Linux 个人计算机就可以达成了!那怎么达成呢?

  • 打开核心的封包转递 (IP forward) 功能

就如同路由表是由 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 路由器的路由表设定方法的不同,通常路由器规划其路由的方式就有两种:

  • 静态路由:直接以类似 route 这个指令来直接设定路由表到核心功能当中,设定值只要与网域环境相符即可。 不过,当你的网域有变化时,路由器就得要重新设定;

  • 动态路由:透过类似 Quagga 或 zebra 软件的功能,这些软件可以安装在 Linux 路由器上, 而这些软件可以动态的侦测网域的变化,并直接修改 Linux 核心的路由表信息, 你无须手动以 route 来修改你的路由表信息喔!

了解了路由器之后,接下来你可能需要了解到什么是 NAT (Network Address Translation, 网络地址转换) 服务器, NAT 是啥?其实 IP 分享器就是最简单的 NAT 服务器啦!嘿嘿,了解了吗?没错, NAT 可以达成 IP 分享的功能, 而 NAT 本身就是一个路由器,只是 NAT 比路由器多了一个『 IP 转换』的功能。怎么说呢?

  • 一般来说,路由器会有两个网络接口,透过路由器本身的 IP 转递功能让两个网域可以互相沟通网络封包。 那如果两个接口一边是公共 IP (public IP) 但一边是私有 IP (private IP) 呢? 由于私有 IP 不能直接与公共 IP 沟通其路由信息,此时就得要额外的『 IP 转译』功能了;

  • Linux 的 NAT 服务器可以透过修改封包的 IP 表头数据之来源或目标 IP ,让来自私有 IP 的封包可以转成 NAT 服务器的公共 IP ,就可以连上 Internet !

所以说,当路由器两端的网域分别是 Public 与 Private IP 时,才需要 NAT 的功能! NAT 功能我们会在下一章防火墙时谈及, 这个章节仅谈论一下路由器而已啊! ^_^


8.2.2 何时需要路由器

一般来说,计算机数量小于数十部的小型企业是无须路由器的,只需要利用 hub/switch 串接各部计算机, 然后透过单一线路连接到 Internet 上即可。不过,如果是超过数百部计算机的大型企业环境, 由于他们的环境通常需要考虑如下的状况,因此才需要路由器的架设:

  • 实体线路之布线及效能的考虑:

    在一栋大楼的不同楼层要串接所有的计算机可能有点难度,那可以透过每个楼层架设一部路由器, 并将每个楼层路由器相连接,就能够简单的管理各楼层的网络; 此外,如果各楼层不想架设路由器,而是直接以网络线串接各楼层的 hub/switch 时, 那由于同一网域的数据是透过广播来传递的,那当整个大楼的某一部计算机在广播时, 所有的计算机将会予以回应,哇!会造成大楼内网络效能的问题;所以架设路由器将实体线路分隔, 就有助于这方面的网络效能;

  • 部门独立与保护数据的考虑:

    在阅读过第二章网络基础后,你就会晓得, 只要实体线路是连接在一起的,那么当数据透过广播时,你就可以透过类似 tcpdump 的指令来监听封包数据, 并且予以窃取~所以,如果你的部门之间的数据可能需要独立, 或者是某些重要的资料必须要在公司内部也予以保护时,可以将那些重要的计算机放到一个独立的实体网域, 并额外加设防火墙、路由器等连接上公司内部的网域。

路由器就只是一个设备,要如何使用端看你的网络环境的规划!上面仅是举出一些应用案例。 底下我们先就架设一个静态路由的路由器来玩一玩吧!


8.2.3 静态路由之路由器

假设在贵公司的网络环境当中,除了一般职员的工作用计算机是直接连接到对外的路由器来连结因特网, 在内部其实还有一个部门需要较安全的独立环境,因此这部份的网络规划可能是这样的情况 (参考图 3.2-1 内容延伸而来):

图 8.2-1、静态路由之路由器架构示意图

以上图的架构来说,这家公司主要有两个 class C 的网段,分别是:

  • 一般区网(192.168.1.0/24) :包括 Router A, workstation 以及 Linux Router 三部主机所构成;
  • 保护内网(192.168.100.0/24):包括 Linux Router, clientlinux, winxp, win7 等主机所构成。

其中 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,那么他的联机情况会是如何?

  • 发起联机需求:clientlinux --> Linux Router --> Router A --> Internet
  • 响应联机需求:Internet --> Router A --> Linux Router --> clientlinux

观察一下两部 Router 的设定,要达到上述功能,则 Router A 必须要有两个接口,一个是对外的 Public IP 一个则是对内的 Private IP ,因为 IP 的类别不同,因此 Router A 还需要额外增加 NAT 这个机制才行,这个机制我们在后续章节会继续谈到。 除此之外,Router A 并不需要什么额外的设定。至于 Linux Router 就更简单了!什么事都不用作,将两个网络适配器设定两个 IP , 并且启动核心的封包转递功能,立刻就架设完毕了!非常简单!我们就来谈一谈这几个机器的设定吧!


  • Linux Router

在这部主机内需要有两张网卡,鸟哥在这里将他定义为 (假设你已经将刚刚实作的 eth0:0 取消掉了):

  • eth0: 192.168.1.100/24
  • eth1: 192.168.100.254/24
# 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 为例

不论你的 clientlinux 是哪一种操作系统,你的环境都应该是这样的 (图 8.2-1):

  • IP: 192.168.100.10
  • netmask: 255.255.255.0
  • gateway: 192.168.100.254
  • hostname: clientlinux.centos.vbird
  • DNS: 168.95.1.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 都没有办法给予回应的话, 那么表示我们的联机是有问题的!再从刚刚的响应联机需求流程来看一下吧!

  • 发起联机:clientlinux --> Linux Router (OK) --> Router A (OK)
  • 回应联机:Router A (此时 router A 要响应的目标是 192.168.100.10),Router A 仅有 public 与 192.168.1.0/24 的路由,所以该封包会由 public 界面再传出去,因此封包就回不来了...

发现了吗?网络是双向的,此时封包出的去,但是非常可怜的,封包回不来~那怎办呢?只好告知 Router A 当路由规则碰到 192.168.100.0/24 时,要将该封包传 192.168.1.100 就是了!所以你要这样进行。


  • 特别的路由规则: Router A 所需路由

假设我的 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):

  • 联机发起: clientlinux --> Linux Router (OK) --> workstation (OK)
  • 回应联机: workstation (联机目标为 192.168.100.10,因为并没有该路由规则,因此联机丢给 default gateway,亦即是 Router A) --> Router A (OK) --> Linux Router (OK) --> clientlinux

有没有发现一个很可爱的传输流程?联机发起是没有问题啦,不过呢,响应联机竟然会偷偷透过 Router A 来帮忙呦! 这是因为 workstation 与当初的 Router A 一样,并不知道 192.168.100.0/24 在 192.168.1.100 里面啦!不过,反正 Router A 已经知道了该网域在 Linux Router 内,所以,该封包还是可以顺利的回到 clientlinux 就是了。


  • 让 workstation 与 clientlinux 不透过 Router A 的沟通方式

如果你不想要让 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 的功能』喔!特别给他留意到!