什么是路由器与 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 功能我们会在下一章防火墙时谈及, 这个章节仅谈论一下路由器而已啊! ^_^
何时需要路由器
一般来说,电脑数量小于数十部的小型企业是无须路由器的,只需要利用 hub/switch 串接各部电脑, 然后透过单一线路连接到 Internet 上即可。不过,如果是超过数百部电脑的大型企业环境, 由于他们的环境通常需要考虑如下的状况,因此才需要路由器的架设:
* 实体线路之布线及效能的考量:
在一栋大楼的不同楼层要串接所有的电脑可能有点难度,那可以透过每个楼层架设一部路由器, 并将每个楼层路由器相连接,就能够简单的管理各楼层的网路; 此外,如果各楼层不想架设路由器,而是直接以网路线串接各楼层的 hub/switch 时, 那由于同一网域的资料是透过广播来传递的,那当整个大楼的某一部电脑在广播时, 所有的电脑将会予以回应,哇!会造成大楼内网路效能的问题;所以架设路由器将实体线路分隔, 就有助于这方面的网路效能。
* 部门独立与保护资料的考量:
在阅读过网路基础后,你就会晓得, 只要实体线路是连接在一起的,那么当资料透过广播时,你就可以透过类似 tcpdump 的指令来监听封包资料, 并且予以窃取~所以,如果你的部门之间的资料可能需要独立, 或者是某些重要的资料必须要在公司内部也予以保护时,可以将那些重要的电脑放到一个独立的实体网域, 并额外加设防火墙、路由器等连接上公司内部的网域。
路由器就只是一个设备,要如何使用端看你的网路环境的规划!上面仅是举出一些应用案例。 底下我们先就架设一个静态路由的路由器来玩一玩吧!
静态路由之路由器
假设在贵公司的网路环境当中,除了一般职员的工作用电脑是直接连接到对外的路由器来连结网际网路, 在内部其实还有一个部门需要较安全的独立环境,因此这部份的网路规划可能是这样的情况 :
静态路由之路由器架构示意图
以上图的架构来说,这家公司主要有两个 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 呢!#p#
那我们先来探讨一下连线的机制好了,先从 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 是哪一种作业系统,你的环境都应该是这样的:
IP: 192.168.100.10
netmask: 255.255.255.0
gateway: 192.168.100.254
hostname: clientlinux.centos.vbird
DNS: 168.95.1.1#p#
以 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 的功能』喔!特别给他留意到!