正如我们在之前的这个LFCE(Linux Foundation Certified Engineer)系列的教程中预料到的那样,在本文中我们将讨论静态和动态的IP流量路由以及特定应用。

介绍Linux基金会认证计划
首先,让我们明确一些定义:
- 简单来说,数据包是在网络内传输信息的基本单元。使用TCP/IP作为网络协议的网络遵循相同的数据传输规则:实际信息被分割成数据包,其中包括数据和应该发送到的地址。
- 路由是在网络内“引导”数据从源到目的地的过程。
- 静态路由需要在路由表中手动配置的一组规则。这些规则是固定的,用于定义数据包在从一台机器到另一台机器的传输过程中必须经过的路径。
- 动态路由,或者说智能路由(如果你愿意的话),意味着系统可以根据需要自动更改数据包的路径。
高级IP和网络设备配置
该iproute软件包提供了一组工具,用于管理网络和流量控制,在本文中我们将使用它们,因为它们代表了诸如ifconfig和route等传统工具的替代品。
iproute套件中的核心实用程序简称为ip。其基本语法如下:
# ip object command
其中对象只能是以下之一(仅显示最常见的对象 – 您可以参考man ip获取完整列表):
- link:网络设备。
- addr:设备上的协议(IP或IPv6)地址。
- route:路由表条目。
- rule:路由策略数据库中的规则。
而命令表示可以在对象上执行的特定操作。您可以运行以下命令以显示可以应用于特定对象的完整命令列表:
# ip object help
例如,
# ip link help

上图显示,您可以使用以下命令更改网络接口的状态:
# ip link set interface {up | down}
有关“ip”命令的更多示例,请阅读10个有用的“ip”命令以配置IP地址
示例1:禁用和启用网络接口
在此示例中,我们将禁用并启用eth1:
# ip link show # ip link set eth1 down # ip link show

如果要重新启用eth1,
# ip link set eth1 up
我们可以指定其中一个而不是显示所有网络接口:
# ip link show eth1
这将返回eth1的所有信息。
示例2:显示主路由表
您可以使用以下3个命令之一查看当前的主路由表:
# ip route show # route -n # netstat -rn

三个命令的输出中的第一列表示目标网络。在ip route show的输出中(在关键字dev之后),还显示了作为这些网络物理网关的网络设备。
尽管现在更倾向于使用ip命令而不是route,但您仍然可以参考man ip-route和man route以获取对其余列的详细解释。
示例3:使用Linux服务器在两个私有网络之间路由数据包
我们希望将icmp(ping)数据包从dev2路由到dev4,反之亦然(请注意,两台客户机位于不同的网络上)。每个网卡的名称及其对应的IPv4地址均在方括号内给出。
我们的测试环境如下:
Client 1: CentOS 7 [enp0s3: 192.168.0.17/24] - dev1 Router: Debian Wheezy 7.7 [eth0: 192.168.0.15/24, eth1: 10.0.0.15/24] - dev2 Client 2: openSUSE 13.2 [enp0s3: 10.0.0.18/24] - dev4
让我们查看dev1(CentOS主机)中的路由表:
# ip route show
然后修改它,以便使用其enp0s3网卡和连接到192.168.0.15的方式访问10.0.0.0/24网络中的主机:
# ip route add 10.0.0.0/24 via 192.168.0.15 dev enp0s3
这基本上是指,“通过enp0s3网络接口使用192.168.0.15作为网关向10.0.0.0/24网络添加一条路由”。

同样,在dev4(openSUSE主机)中ping 192.168.0.0/24网络中的主机:
# ip route add 192.168.0.0/24 via 10.0.0.15 dev enp0s3

最后,我们需要在Debian路由器中启用转发:
# echo 1 > /proc/sys/net/ipv4/ip_forward
现在让我们进行ping测试:

以及,

要使这些设置在启动时持久化,编辑路由器上的/etc/sysctl.conf,确保net.ipv4.ip_forward变量设置为true。
net.ipv4.ip_forward = 1
配置两个客户端上的NIC(在openSUSE中查找/etc/sysconfig/network中的配置文件,在CentOS中查找/etc/sysconfig/network-scripts中的配置文件 – 在这两种情况下都称为ifcfg-enp0s3)。
这是来自openSUSE框的配置文件:
BOOTPROTO=static BROADCAST=10.0.0.255 IPADDR=10.0.0.18 NETMASK=255.255.255.0 GATEWAY=10.0.0.15 NAME=enp0s3 NETWORK=10.0.0.0 ONBOOT=yes
示例4:使用Linux服务器在私有网络和Internet之间路由数据包
另一个Linux机器可用作路由器的情况是当您需要与私有LAN共享Internet连接时。
Router: Debian Wheezy 7.7 [eth0: Public IP, eth1: 10.0.0.15/24] - dev2 Client: openSUSE 13.2 [enp0s3: 10.0.0.18/24] - dev4
除了在客户端中设置数据包转发和静态路由表之外,还需要在路由器中添加一些iptables规则:
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE # iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT # iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
第一个命令向nat(网络地址转换)表中的POSTROUTING链添加规则,指示应使用eth0 NIC进行出站数据包。
MASQUERADE指示此NIC具有动态IP,并且在将数据包发送到Internet的“疯狂世界”之前,数据包的私有源地址必须更改为路由器的公共IP。
在具有许多主机的LAN中,路由器在/proc/net/ip_conntrack中跟踪已建立的连接,以便知道从Internet返回响应的位置。
以下截图仅显示:
# cat /proc/net/ip_conntrack
输出的一部分。

突出显示了数据包的源(openSUSE框的私有IP)和目的地(Google DNS)。这是在openSUSE框上运行:
# curl www.tecmint.com
的结果。
正如您可能已经猜到的那样,路由器正在使用谷歌的8.8.8.8作为名称服务器,这解释了为什么出站数据包的目的地指向该地址。
注意:来自互联网的传入数据包只有在它们是已建立连接的一部分时才会被接受(命令 #2),而出站数据包允许“自由退出”(命令 #3)。
不要忘记按照本系列的《第8部分 – 配置Iptables防火墙》中概述的步骤使您的iptables规则持久化。
使用Quagga进行动态路由
如今,在Linux中用于动态路由的最常用工具是quagga。它允许系统管理员使用成本相对较低的Linux服务器来实现与强大(且昂贵)的思科路由器提供的相同功能。
该工具本身并不处理路由,而是在学习到新的最佳路由以处理数据包时修改内核路由表。
由于它是zebra的一个分支,而zebra的开发已经停止了一段时间,出于历史原因,它保持了与zebra相同的命令和结构。这就是为什么从这一点开始,您会看到很多关于zebra的参考。
请注意,无法在一篇文章中涵盖动态路由和所有相关协议,但我相信这里呈现的内容将为您搭建起一个起点。
在Linux中安装Quagga
安装 quagga 在您选择的发行版上:
# aptitude update && aptitude install quagga [On Ubuntu] # yum update && yum install quagga [CentOS/RHEL] # zypper refresh && zypper install quagga [openSUSE]
我们将使用与示例 #3 相同的环境,唯一的区别是 eth0 连接到 IP 192.168.0.1 的主网关路由器。
接下来,编辑 /etc/quagga/daemons,并加入以下内容,
zebra=1 ripd=1
现在创建以下配置文件。
# /etc/quagga/zebra.conf # /etc/quagga/ripd.conf
并添加以下行(用您选择的主机名和密码替换):
service quagga restart hostname dev2 password quagga
# service quagga restart

注意: ripd.conf 是路由信息协议的配置文件,它提供了路由器可以到达哪些网络以及它们的距离(以跳数的数量)的信息。
请注意,这只是 quagga 可以与之一起使用的协议之一,我选择了它作为本教程的原因是因为易于使用,并且大多数网络设备都支持它,尽管它具有明文传递凭据的缺点。因此,您需要为配置文件分配适当的权限:
# chown quagga:quaggavty /etc/quagga/*.conf # chmod 640 /etc/quagga/*.conf
示例 5:设置 quagga 动态路由 IP 流量
在此示例中,我们将使用以下设置与两个路由器(确保按前面解释的方式为 路由器 #2 创建配置文件):

重要:不要忘记为两台路由器重复以下设置。
连接到 zebra(监听端口为 2601),它是路由器和内核之间的逻辑中间件:
# telnet localhost 2601
输入在 /etc/quagga/zebra.conf 文件中设置的密码,然后启用配置:
enable configure terminal
请输入每个网卡的IP地址和网络掩码:
inter eth0 ip addr 192.168.0.15 inter eth1 ip addr 10.0.0.15 exit exit write

现在我们需要连接到 RIP 守护进程终端(端口2602):
# telnet localhost 2602
输入在 /etc/quagga/ripd.conf 文件中配置的用户名和密码,然后输入以下命令(加粗部分为了说明,附加了注释):
enable turns on privileged mode command. configure terminal changes to configuration mode. This command is the first step to configuration router rip enables RIP. network 10.0.0.0/24 sets the RIP enable interface for the 10.0.0.0/24 network. exit exit write writes current configuration to configuration file.

注意:在这两种情况下,配置都会附加到我们之前添加的行上(/etc/quagga/zebra.conf 和 /etc/quagga/ripd.conf)。
最后,再次连接到两台路由器上的zebra服务,并注意它们各自是如何“学习”到彼此后面的网络路由,以及到达该网络的下一跳是什么,通过运行命令 show ip route:
# show ip route

如果您想尝试不同的协议或设置,您可能需要参考 Quagga 项目网站 获取更多文档。
结论
在本文中,我们解释了如何设置静态和动态路由,使用 Linux 路由器。随意添加任意数量的路由器,并尽情实验。如果您有任何评论或问题,请随时通过下面的联系表格与我们联系。