如同我們在之前的這個LFCE(Linux Foundation 認證工程師)系列教程中預期的那樣,本文將討論使用特定應用程序靜態和動態地路由 IP 流量。

介紹 Linux 基金會認證計劃
首先,讓我們先明確一些定義:
- 簡單來說,一個數據包是在網絡內傳輸信息所使用的基本單位。使用 TCP/IP 作為網絡協議的網絡遵循相同的數據傳輸規則:實際信息被分割成數據包,這些數據包包含數據和它應該發送到的地址。
- 路由是將數據從源頭引導到目的地的過程。
- 靜態路由需要在路由表中手動配置一組規則。這些規則是固定的,用於定義數據包從一台機器到另一台機器的路徑。
- 動態路由,或者(如果你願意的話)智能路由,意味著系統可以根據需要自動更改數據包的路徑。
高級 IP 和網絡設備配置
這個iproute套件提供了一組工具,用於管理網絡和流量控制,我們將在本文中使用這些工具,因為它們代表了傳統工具(如ifconfig和route)的替代方案。
在iproute套件中,中心工具简称为ip。其基本语法如下:
# ip object command
其中object只能是以下之一(仅显示最常见的对象 – 您可以参考man ip获取完整列表):
- link:网络设备。
- addr:设备上的协议(IP或IPv6)地址。
- route:路由表条目。
- rule:路由策略数据库中的规则。
而command代表可以在对象上执行的特定操作。您可以运行以下命令来显示可应用于特定对象的所有命令的完整列表:
# 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 command 而不是 route,但您仍然可以參考 man ip-route 和 man route 以獲得對其餘列的詳細解釋。
範例3:使用Linux伺服器在兩個私人網絡之間路由封包
我們希望從 dev2 到 dev4 路由 icmp(ping)封包,同時也反向進行(請注意,兩個客戶端機器位於不同的網絡上)。每個網卡的名稱以及其對應的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 機器)中對 192.168.0.0/24 網絡中的主機進行 ping:
# 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
在兩個客戶端上配置網卡(在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伺服器在私人網路和互聯網之間進行封包路由
另一種情況下,Linux機器可用作路由器的是當您需要將您的互聯網連接與私人局域網共享時。
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網卡應用於傳出封包。
MASQUERADE表示此網卡具有動態IP,並且在將封包發送到互聯網的“wild wild world”之前,封包的私有源地址必須更改為路由器的公共IP。
在具有許多主機的LAN中,路由器在/proc/net/ip_conntrack中跟蹤已建立的連接,以便知道從互聯網返回響應的位置。
僅顯示了:
# cat /proc/net/ip_conntrack
的部分輸出如下截圖所示。

其中封包的原始(openSUSE盒子的私有IP)和目的地(Google DNS)被突顯出來。這是在openSUSE盒子上運行:
# curl www.tecmint.com
的結果。
正如您可能已经猜到的那样,路由器正在使用Google的8.8.8.8作为名称服务器,这解释了为什么出站数据包的目的地指向该地址。
注意:来自互联网的传入数据包只有在它们是已建立连接的一部分时才会被接受(命令#2),而出站数据包允许“自由出口”(命令#3)。
不要忘记按照本系列中第8部分 – 配置Iptables防火墙中概述的步骤使您的iptables规则持久化。
使用Quagga进行动态路由
如今,在Linux中用于动态路由的最常用工具是quagga。它允许系统管理员使用成本相对较低的Linux服务器实现与功能强大(成本高昂)的Cisco路由器提供的相同功能。
该工具本身不处理路由,而是在学习处理数据包的新最佳路由时修改内核路由表。
由于它是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是Routing Information Protocol的配置文件,它提供了路由器可到達哪些網絡以及它們有多遠(按跳數計算)的信息。
請注意,這只是可以與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盒子路由器。隨時添加您想要的任意多個路由器,並進行盡可能多的實驗。如果您有任何意見或問題,請不要猶豫使用下面的聯繫表格與我們聯繫。