伺服器架設篇 - CentOS 5.x

第八章、路由觀念與路由器設定

使用 Routing 的功能,讓 Linux Server 也可以當作 Router 來使用!此外,亦提到 IP aliases 這個好用的功能呢!

最近更新時間: 2010/10/26

本文資料主要針對 CentOS 5.x 的系統進行說明,而 CentOS 5.x 已經在 2017 年 3 月份正式不再進行維護,事實上,在 2012 年底幾乎就不再維護了。 因此,建議您前往本站查詢最新版本的 Linux distribution 文章來閱讀,比較不會浪費時間。那為何還需要編輯 CentOS 5 的資料呢? 鳥哥只想要做個自己曾經撰寫過的文件內容保存而已囉! ^_^!最新文章請前往鳥站首頁查閱囉!
如果說 IP 是門牌,那麼郵差如何走到你家就是『路由』的功能啦!區域網路如果想成是條巷子,那麼路由器就是那間巷子內的郵局! 其實本章應該是第二章網路基礎的延伸,將網路的設定延伸到整個區網的路由器上而已。那何時會用到路由器? 如果你的環境中需要將整批 IP 再區隔出不同的廣播區段時,那麼就得要透過路由器的封包轉遞能力了。 本章是下一章防火牆與 NAT 的基礎,得先看完才比較容易理解下一章想要討論的事情喔!

8.1 路由

我們在第二章網路基礎裡面談到過路由的相關概念, 他最大的功能就是在幫我們規劃網路封包的傳遞方式與方向。至於路由的觀察則可以使用 route 這個指令來查閱與設定。 好了,那麼路由的形式有哪些?你又該如何確認路由是否正確呢?

8.1.1 路由表產生的類型

如同第二章網路基礎裡面談到的,每一部主機都有自己的路由表, 也就是說,你必須要透過你自己的路由表來傳遞你主機的封包到下一個路由器上頭。 若傳送出去後,該封包就得要透過下一個路由器的路由表來傳送了,此時與你自己主機的路由表就沒有關係啦! 所以說,如果網路上面的某一部路由器設定錯誤,那...封包的流向就會發生很大的問題。 我們就得要透過 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     0      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 (預設路由) 』來排列的。 而當主機的網路封包需要傳送時,就會查閱上述的三個路由規則來瞭解如何將該封包傳送出去。 那你會不會覺得奇怪,為什麼會有這幾個路由呢?其實路由表主要有這幾種情況來設計的:

  • 依據網路介面產生的 IP 而存在的路由

    例如 192.168.1.0/24 這個路由的存在是由於鳥哥的這部主機上面擁有 192.168.1.11 這個 IP 的關係! 也就是說,你主機上面有幾個網路介面的存在時,該網路介面就會存在一個路由才對。 所以說,萬一你的主機有兩個網路介面時,例如 192.168.1.11, 192.168.2.11 時,那路由至少就會有:
    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.2.0  0.0.0.0     255.255.255.0  U     0      0      0 eth1
    

  • 手動或預設路由(default route)

    你可以使用 route 這個指令手動的給予額外的路由設定,例如那個預設路由 (0.0.0.0/0) 就是額外的路由。 使用 route 這個指令時,最重要的一個概念是:『你所規劃的路由必須要是你的裝置 (如 eth0) 或 IP 可以直接溝通 (broadcast) 的情況』才行。舉例來說,以上述的環境來看, 我的環境裡面僅有 192.168.1.11 及 192.168.2.11 ,那我如果想要連接到 192.168.100.254 這個路由器時, 下達:
    [root@www ~]# route add -net 192.168.100.0  \
    > netmask 255.255.255.0 gw 192.168.100.254
    SIOCADDRT: Network is unreachable
    
    看吧!系統就會回應沒有辦法連接到該網域,因為我們的網路介面與 192.168.100.0/24 根本就沒有關係嘛! 那如果 192.168.100.254 真的是在我們的實體網路連接上,那其實你應該是這樣做:
    [root@www ~]# route add -net 192.168.100.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.100.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
    0.0.0.0        192.168.1.254  0.0.0.0        UG    0      0     0 eth1
    
    這樣你的主機就會直接用 eth0 這個裝置去嘗試連接 192.168.100.254 了! 另外,上面路由輸出的重點其實是那個『Flags 的 G 』了!因為那個 G 代表使用外部的裝置作為 Gateway 的意思!而那個 Gateway (192.168.1.254) 必須要在我們的已存在的路由環境中。 這可是很重要的概念喔! ^_^

  • 動態路由的學習

    除了上面這兩種可以直接使用指令的方法來增加路由規則之外,還有一種透過路由器與路由器之間的協商以達成動態路由的環境, 不過,那就需要額外的軟體支援了,例如: zebra (http://www.zebra.org/) 或 CentOS 上面的 Quagga (http://www.quagga.net/) 這幾個軟體了!

事實上,在 Linux 的路由規則都是透過核心來達成的,所以這些路由表的規則都是在核心功能內啊!也就是在記憶體當中喔! ^_^

8.1.2 一個網卡綁多個 IP: IP Alias 的測試用途

我們在 第五章的 ifconfig 指令裡面談過 eth0:0 這個裝置吧?這個裝置可以在原本的 eth0 上面模擬出一個虛擬介面出來,以讓我們原本的網路卡具有多個 IP ,具有多個 IP 的功能就被稱為 IP Alias 了。而這個 eth0:0 的裝置可以透過 ifconfigip 這兩個指令來達成, 關於這兩個指令的用途請翻回去之前的章節閱讀,這裡不再浪費篇幅啊!

那你或許會問啊:『這個 IP Alias 有啥用途啊?』好問題!這個 IP Alias 最大的用途就是可以讓你用來『應急』! 怎麼說呢?我們就來聊一聊他的幾個常見的用途好了:

  • 測試用

    怎麼說用來測試呢?舉例來說,現在使用 IP 分享器的朋友很多吧,而 IP 分享器的設定通常是使用 WWW 介面來提供的。這個 IP 分享器通常會給予一個私有 IP 亦即是 192.168.0.1 來讓使用者開啟 WWW 介面的瀏覽。問題來了,那你要如何連接上這部 IP 分享器呢?嘿嘿!在不更動既有的網路環境下,你可以直接利用:
    [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 分享器了,也不會更動到你原本的網路參數設定值哩!

  • 在一個實體網域中含有多個 IP 網域

    另外,如果像是在補習班或者是學校單位的話,由於原本的主機網路設定最好不要隨便修改, 那如果要讓同學們大家互通所有的電腦資訊時,就可以讓每個同學都透過 IP Alias 來設定同一網域的 IP , 如此大家就可以在同一個網段內進行各項網路服務的測試了,很不錯吧!

  • 既有設備無法提供更多實體網卡時

    如果你的這部主機需要連接多個網域,但該設備卻無法提供安裝更多的網卡時,你只好勉為其難的使用 IP Alias 來提供不同網段的連線服務了!

不過,你需要知道的是:所有的 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 無法被重新啟動), 但鳥哥個人比較建議使用如下的方式來處理:

  • 透過建立 /etc/sysconfig/network-scripts/ifcfg-eth0:0 設定檔

    舉例來說,你可以透過底下這個方法來建立一個虛擬裝置的設定檔案:
    [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
    NETWORK=192.168.0.0
    BROADCAST=192.168.0.255
    
    [root@www network-scripts]# ifup eth0:0
    [root@www network-scripts]# ifdown eth0:0
    [root@www network-scripts]# /etc/init.d/network restart
    
    關於裝置的設定檔案內的更多參數說明, 請參考第四章手動設定 IP 參數一文的相關說明, 在此不再敘述!使用這個方法有個好處,就是當你使用『 /etc/init.d/network restart 』時,系統依舊會使用你的 ifcfg-eth0:0 檔案內的設定值來啟動你的虛擬網卡喔!另外,不論 ifcfg-eth0:0 內的 ONBOOT 設定值為何,只要 ifcfg-eth0 這個實體網卡的設定檔中, ONBOOT 為 yes 時,開機就會將全部的 eth0:n 都啟動

透過這個簡單的方法,你就可以在開機的時候啟動你的虛擬介面而取得多個 IP 在同一張網卡上了。不過需要注意的是, 如果你的這張網卡分別透過 DHCP 以及手動的方式來設定你的 IP 參數,那麼 dhcp 的取得務必使用實體網卡,亦即是 eth0 之類的網卡代號,而手動的就以 eth0:0 之類的代號來設定較佳。

Tips 鳥哥 在舊版的 CentOS 4.x 中,如果你的 eth0 是使用 DHCP 來取得 IP 參數的話,那麼由於 ifup 及 /etc/init.d/network 這兩個 script 內程式碼撰寫的方式,將會導致 ifcfg-eth0:0 這個設定檔不會被使用到喔!不過這個問題在 CentOS 5.x 中已經被克服囉!

8.1.3 重複路由的問題

很多朋友可能都有一個可愛的想法,那就是:『我可不可以利用兩張網卡, 利用兩個相同網域的 IP 來增加我這部主機的網路流量』?事實上這是一個可行的方案, 不過必須要透過許多的設定來達成,若你有需求的話,可以參考網中人大哥寫的這一篇 (註1):

如果只是單純的以為設定好兩張網卡的 IP 在同一個網域就能夠增加你主機的兩倍流量,那可就大錯特錯了~ 為什麼呢?還記得我們在路由表規則裡面提過網路封包的傳遞主要是依據主機內的路由表規則吧! 那如果你有兩張網路卡時,假設:

  • eth0 : 192.168.0.100
  • eth1 : 192.168.0.200
那你的路由規則會是如何呢?理論上會變成這樣:
[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 在同一部主機上面。 例如上面的案例就是一個不好的示範啊!

Tips 鳥哥 為什麼會特別強調這個觀念呢?大約十年前 (2000) 鳥哥剛接觸 Linux 時,由於當時的網路速度相當緩慢, 為了提升網路流量鳥哥費盡心思啊~後來想到說,如果有兩片網卡,不就可以增加流量了嗎?於是就設定了兩個同網域的 IP 在一部主機的兩張網卡上,結果呢?很多服務都無法連通了!就是因為痛過,所以才有更強烈的印象啊!錯誤經驗學習法則 ^_^!

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 靜態路由之路由器

假設在貴公司的網路環境當中,除了一般職員的工作用電腦是直接連接到對外的路由器來連結網際網路, 在內部其實還有一個部門需要較安全的獨立環境,因此這部份的網路規劃可能是這樣的情況:

靜態路由之路由器架構示意圖
圖 8.2-1、靜態路由之路由器架構示意圖

以上圖的架構來說,這家公司主要有兩個 class C 的網段,分別是:

  • 一般區網(192.168.1.0/24) :包括 Router A, PC1 以及 Linux Router 三部主機所構成;
  • 保護內網(192.168.10.0/24):包括 Linux Router, PC2, PC3, PC4 等主機所構成。

其中 192.168.1.0/24 是用來做為一般員工連接網際網路用的,至於 192.168.10.0/24 則是給特殊的部門用的。PC1 代表的是一般員工的電腦, PC2 及 PC3, PC4 則是特殊部門的工作用電腦, Linux Router 則是這個特殊部門用來連接到公司內部網域的路由器。在這樣的架構下, 該特殊部門的封包就能夠與公司其他部門作實體的分隔了。

由上圖你也不難發現,只要是具有路由器功能的設備 (Router A, Linux Router) 都會具有兩個以上的介面, 分別用來溝通不同的網域,同時該路由器也都會具有一個預設路由啊! ^_^! 另外,你還可以加上一些防火牆的軟體在 Linux Router 上,以保護 PC2~PC4 的內部電腦呢!

那我們先來探討一下連線的機制好了,先從 PC2 這部電腦談起。如果 PC2 想要連上 Internet ,那麼他的連線情況會是如何?

  • 發起連線需求:PC2 --> Linux Router --> Router A --> Internet
  • 回應連線需求:Internet --> Router A --> Linux Router --> PC2

觀察一下兩部 Router 的設定,要達到上述功能,則 Router A 必須要有兩個介面,一個是對外的 Public IP 一個則是對內的 Private IP ,因為 IP 的類別不同,因此 Router A 還需要額外增加 NAT 這個機制才行,這個機制我們在後續章節會繼續談到。 除此之外,Router A 並不需要什麼額外的設定。至於 Linux Router 就更簡單了!什麼事都不用作,將兩個網路介面卡設定兩個 IP , 並且啟動核心的封包轉遞功能,立刻就架設完畢了!非常簡單!我們就來談一談這幾個機器的設定吧!



  • Linux Router

在這部主機內需要有兩張網卡,鳥哥在這裡將他定義為:

  • eth0: 192.168.1.100/24
  • eth1: 192.168.10.254/24
# 1. 先處理 eth0 
[root@www ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=static
IPADDR=192.168.1.100
NETMASK=255.255.255.0
GATEWAY=192.168.1.254   <==最重要的設定啊!透過這部主機連出去的!
ONBOOT=yes

# 2. 再先處理 eth1 
[root@www ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1
BOOTPROTO=none
ONBOOT=yes
IPADDR=192.168.10.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.1.0     0.0.0.0        255.255.255.0  U     0      0      0 eth0
192.168.10.0    0.0.0.0        255.255.255.0  U     0      0      0 eth1
169.254.0.0     0.0.0.0        255.255.0.0    U     0      0      0 eth1
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 <==有回應即可

有夠簡單吧!而且透過最後的 ping 我們也知道 Linux Router 可以連上 Router A 囉!這樣你的 Linux Router 就 OK 了吶!接下來則是要設定 PC2 這個被保護的內部主機網路囉。



  • 受保護的網域,以 PC2 為例

不論你的 PC2 是哪一種作業系統,你的環境都應該是這樣的:

  • IP: 192.168.10.20
  • netmask: 255.255.255.0
  • gateway: 192.168.10.254

以 Linux 作業系統為例,並且 PC2 僅有 eth0 一張網卡時,他的設定是這樣的:

[root@www ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=static
IPADDR=192.168.10.20
NETMASK=255.255.255.0
GATEWAY=192.168.10.254   <==這個設定最重要啦!
ONBOOT=yes

[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.10.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 eth0
0.0.0.0       192.168.10.254  0.0.0.0         UG    0      0      0 eth0

[root@www ~]# ping -c 2 192.168.1.254

最後一個動作有問題呦!怎麼會連 ping 都沒有辦法 ping 到 Router A 的 IP 呢?如果連 ping 都沒有辦法給予回應的話, 那麼表示我們的連線是有問題的!再從剛剛的回應連線需求流程來看一下吧!

  • 發起連線:PC2 --> Linux Router (OK) --> Router A (OK)
  • 回應連線:Router A (此時 router A 要回應的目標是 192.168.10.20),Router A 僅有 public 與 192.168.1.0/24 的路由,因此封包傳到 Router A 後,這個封包就回不來了...

發現了嗎?網路是雙向的,此時封包出的去,但是非常可憐的,封包回不來~那怎辦呢?只好告知 Router A 當路由規則碰到 192.168.10.0/24 時,要將該封包傳 192.168.1.100 就是了!所以你要這樣進行。



  • 特別的路由規則: Router A 所需路由

假設我的 Router A 對外的網卡為 eth1 ,而內部的 192.168.1.254 則是設定在 eth0 上頭。 那怎麼在 Router A 增加一條路由規則呢?很簡單啊!直接使用 route add 去增加即可!如下所示的情況:

[root@www ~]# route add -net 192.168.10.0 netmask 255.255.255.0 \
>  gw 192.168.1.100

不過這個規則並不會寫入到設定檔,因此下次重新開機這個規則就不見了!所以,你應該要建立一個路由設定檔。 由於這個路由是依附在 eth0 網卡上的,所以設定檔的檔名應該要是 route-eth0 喔!這個設定檔的內容當中,我們要設定 192.168.10.0/24 這個網域的 gateway 是 192.168.1.100 ,且是透過 eth0 ,那麼寫法就會變成:

[root@www ~]# vim /etc/sysconfig/network-scripts/route-eth0
192.168.10.0/24 via 192.168.1.100 dev eth0
目標網域            透過的gateway     裝置

[root@www ~]# route -n
Kernel IP routing table
Destination   Gateway         Genmask         Flags Metric Ref    Use Iface
120.114.142.0 0.0.0.0         255.255.255.192 U     0      0        0 eth1
192.168.1.0   0.0.0.0         255.255.255.0   U     0      0        0 eth0
192.168.10.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 eth1
0.0.0.0       120.114.142.254 0.0.0.0         UG    0      0        0 eth1

上述觀察的重點在於有沒有出現 192.168.10.0 那行路由!如果有的話,請 ping 192.168.10.20 看看能不能有回應? 然後再到 PC2 上面去 ping 192.168.1.254 看看有沒有回應,你就知道設定成功囉!好了,既然內部保護網路已經可以連上 Internet 了, 那麼是否代表 PC2 可以直接與一般員工的網域,例如 PC1 進行連線呢?我們依舊透過路由規則來探討一下,當 PC2 要直接連線到 PC1 時,他的連線方向是這樣的:

  • 連線發起: PC2 --> Linux Router (OK) --> PC1 (OK)
  • 回應連線: PC1 (連線目標為 192.168.10.20 ,因為並沒有該路由規則,因此連線丟給 default gateway ,亦即是 Router A) --> Router A (OK) --> Linux Router (OK) --> PC2

有沒有發現一個很可愛的傳輸流程?連線發起是沒有問題啦,不過呢,回應連線竟然會偷偷透過 Router A 來幫忙呦! 這是因為 PC1 與當初的 Router A 一樣,並不知道 192.168.10.0/24 在 192.168.1.100 裡面啦!不過,反正 Router A 已經知道了該網域在 Linux Router 內,所以,該封包還是可以順利的回到 PC2 就是了。



  • 讓 PC1 與 PC2 不透過 Router A 的溝通方式

如果你不想要讓 PC1 得要透過 Router A 才能夠連線到 PC2 的話,那麼就得要與 Router A 相同,增加那一條路由規則囉! 如果是 Linux 的系統,那麼如同 Router A 一樣的設定如下:

[root@www ~]# vim /etc/sysconfig/network-scripts/route-eth0
192.168.10.0/24 via 192.168.1.100 dev eth0

[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.1.0    0.0.0.0        255.255.255.0   U     0      0      0 eth0
192.168.10.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

最後只要 PC2 使用 ping 可以連到 PC1,同樣的, PC1 也可以 ping 到 PC2 的話,就表示你的設定是 OK 的啦!搞定!而透過這樣的設定方式,你也可以發現到一件事,那就是:『路由是雙向的,你必須要瞭解出去的路由與回來時的規則』。 舉例來說,在預設的情況下 (Router A 與 PC1 都沒有額外的路由設定時),其實封包是可以由 PC2 連線到 PC1 的,但是 PC1 卻沒有相關的路由可以回應到 PC2 ~所以上頭才會要你在 Router A 或者是 PC1 上面設定額外的路由規則啊!這樣說,瞭了吧? ^_^

用 Linux 作一個靜態路由的 Router 很簡單吧!以上面的案例來說,你在 Linux Router 上面幾乎沒有作什麼額外的工作,只要將網路 IP 與網路介面對應好啟動,然後加上 IP Forward 的功能, 讓你的 Linux 核心支援封包轉遞,然後其他的工作咱們的 Linux kernel 就主動幫你搞定了!真是好簡單!

不過這裡必須要提醒的是,如果你的 Linux Router 有設定防火牆的話, 而且還有設定類似 NAT 主機的 IP 偽裝技術,那可得特別留意,因為還可能會造成路由誤判的問題~ 上述的 Linux Router 當中『並沒有使用到任何 NAT 的功能』喔!特別給他留意到!

8.3 動態路由器架設:quagga (zebra + ripd)

在一般的靜態路由器上面,我們可以透過修改路由設定檔 (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      410 10月 21  2010 ripd.conf.sample
-rw-r----- 1 quagga quagga     29  5月 23 16:14 zebra.conf
-rw-r--r-- 1 root   root      373 10月 21  2010 zebra.conf.sample
.....(其他省略).....

這個軟體所提供的各項動態路由協定都放置到 /etc/quagga/ 目錄內,底下我們以較為簡單的 RIPv2 協定來處理動態路由, 不過你得要注意的是,不論你要啟動什麼動態路由協定,那個 zebra 都必須要先啟動才行!這是因為:

  • zebra 這個 daemon 的功能在更新核心的路由規則;
  • RIP 這個 daemon 則是在向附近的其他 Router 溝通協調路由規則的傳送與否。

而各個路由服務的設定檔都必須要以 /etc/quagga/*.conf 的檔名來儲存才行,如上表我們可以發現 zebra 這個服務是有設定好了,不過 ripd 的檔名卻不是 .conf 結尾。所以我們必須要額外作些設定才行。

為了練習一下我們的 quagga ,當然得要設計一下可能的網路連線囉~假設網路連線的圖示如下,共有三個區網的網段, 其中最大的是 192.168.1.0/24 這個外部區網,另有兩個內部區網分別是 192.168.10.0/24 及 192.168.5.0/24 。

練習動態路由所設定的網路連線示意圖
圖 8.3-1、練習動態路由所設定的網路連線示意圖

上圖的兩部 Linux Router 分別負責不同的網域,且可以透過 192.168.1.0/24 這個網域來溝通。在沒有設定額外路由規則的情況下,那個 PC1 與 PC2 是無法溝通的!另外,quagga 必須要同時安裝在兩部 Linux Router 上頭才行, 而且我們只要設定好這兩部主機的網路介面 (eth0, eth1) 後,不需要手動輸入額外的路由設定喔!可以透過 RIP 這個路由協定來搞定的!



  • 設定 zebra

    我們先設定圖 8.3-1 右手邊那一部 Router Z1,關於 zebra.conf 你可以這樣設定的:
    # 1. 先設定會影響動態路由服務的 zebra 並且啟動 zebra
    [root@www ~]# vim /etc/quagga/zebra.conf
    hostname linux.router.z1            <==給予這個路由器一個主機名稱,隨便取!
    password linuxz1                    <==給予一個密碼!
    enable password linuxz1             <==將這個密碼生效!
    log file /var/log/quagga/zebra.log  <==將所有 zebra 產生的資訊存到登錄檔中
    
    [root@www ~]# /etc/init.d/zebra start
    [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  3203/zebra
    
    仔細看,由於 zebra 這個服務的任務主要是在修改 Linux 系統核心內的路由, 所以他僅監聽本機介面而已,並不會監聽外部的介面才對!另外,在 zebra.conf 這個檔案當中, 我們所設定的那個密碼是有作用的喔!可以讓我們登入 zebra 這套軟體呢! 好了,我們來查一查這個 2601 的 port 是否正確的啟動的呢?
    [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.98.6).
    Copyright 1996-2005 Kunihiro Ishiguro, et al.
    
    User Access Verification
    
    Password: <==在這裡輸入剛剛你設定的密碼啊!
    linux.router.z1> ? <==在這邊輸入『 ? 』就能夠知道有多少指令可使用
      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
    linux.router.z1> list <==列出所有可用指令
      echo .MESSAGE
    ....(中間省略)....
      show debugging zebra
      show history
      show interface [IFNAME]
    ....(中間省略)....
      show ip protocol
      show ip route
    ....(其他省略)....
    linux.router.z1> 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.10.0/24 is directly connected, eth1 <==介面產生的路由
    linux.router.z1> exit
    Connection closed by foreign host.
    
    仔細看到,我們登入這個 zebra 的服務之後,可以輸入『help』或問號『?』, zebra 就會顯示出你能夠執行的指令有哪些,比較常用的當然是查詢路由規則囉!以『 show ip route 』來查閱,結果可以發現目前的介面與預設路由都被顯示出來了,顯示的結果當中:

    • K :代表以類似 route 指令加入核心的路由規則,包括 route-ethN 所產生的規則;
    • C :代表由你的網路介面所設定的 IP 而產生的相關的路由規則
    • S :以 zebra 功能所設定的靜態路由資訊;
    • R :就是透過 RIP 協定所增加的路由規則囉!

    事實上,如果你還想要增加額外的靜態路由的話,也可以透過 zebra 而不必使用 route 指令呢! 例如想要增加 10.0.0.0/24 給 eth0 來處理的話,可以這樣做:
    [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: <==這裡輸入密碼
    linux.router.z1> 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.10.0/24 is directly connected, eth1
    
    嘿嘿!立刻就會多出一筆路由的規則,而且最右邊會顯示 S,亦即是靜態路由 (Static route) 的意思。 如此一來,我們系統管理員可就輕鬆多了!設定完右邊 Router Z1 的 zebra 之後,不要忘記設定你的 Router Z2 呦! 同樣的設定再來一遍啦!只是主機名稱與密碼應該給予不同才是呦!接下來我們可以開始看看 ripd 這個服務囉!


  • 設定 ripd 服務

    ripd 這個服務可以在兩部 Router 之間進行路由規則的交換與溝通,當然啦,如果你的環境裡面有類似 Cisco 或者是其他有提供 RIP 協定的路由器的話,那麼你當然也是可以透過這個 RIP 讓你的 Linux Router 與其他硬體路由器互相溝通的吶! 只不過 CentOS 5.x 的 quagga 所提供的 ripd 服務使用的是 RIPv2 版本,這個版本預設就要求得要進行身份驗證的動作, 但是我們是個小型網路,並不想要加入這個身份驗證的功能,因此就得要增加某些設定值才能夠順利的啟動 ripd 呦!

    先來設定 Router Z1 吧!在 Router Z1 當中,我們主要是透過 eth0 發送所有的網域路由資訊,同時,我們管理的網域有 192.168.1.0/24, 192.168.10.0/24。再加上取消身份驗證的設定值後,我們的 ripd 就會變成這樣:
    [root@www ~]# vim /etc/quagga/ripd.conf
    hostname linux.router.z1            <==這裡是設定 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.10.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 ~]# 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 6193/ripd
    udp        0      0 0.0.0.0:520    0.0.0.0:*              6193/ripd
    # 新版的 quagga 啟動的 2602 僅在 127.0.0.1 ,是透過 port 520 來傳遞資訊!
    
    基本上,這樣就設定完成一部路由器的 RIP 動態路由協定了!在上頭 ripd.conf 的設定當中, 他會主動以 eth0 及 192.168.1.0/24 這個網域的功能來進行搜索,如此一來,未來你進行任何路由規則的變動, 或者是整個網域的主機 IP 進行更動,你將不需要重新到每部 Router 上更動! 因為這些路由器會自動的更新他們自己的規則喔!嘿嘿!接下來,同樣的動作請你到 圖 8.3-1 左邊那部 Router Z2 上面設定一下! 因為整個設定的流程都一樣,所以這裡鳥哥就省略啦!


  • 檢查 RIP 協定的溝通結果

    在兩部 Linux Router 都設定妥當之後,你可以登入 zebra 去看這兩部主機的路由更新結果喔! 舉例來說,鳥哥登入圖 8.3-1 右邊那部 Router Z1 後,並且登入 zebra , 觀察路由會是這樣的情況:
    [root@www ~]# route -n
    Kernel IP routing table
    Destination   Gateway        Genmask        Flags Metric Ref  Use Iface
    192.168.5.0   192.168.1.200  255.255.255.0  UG    2      0      0 eth0
    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.10.0  0.0.0.0        255.255.255.0  U     0      0      0 eth1
    169.254.0.0   0.0.0.0        255.255.0.0    U     0      0      0 eth1
    0.0.0.0       192.168.1.254  0.0.0.0        UG    0      0      0 eth0
    # 其實看路由就知道啦!第一條就是新增的路由規則!很清楚!
    
    [root@www ~]# telnet localhost 2601
    Password: <==不要忘記了密碼啊!
    linux.router.z1> 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
    R>* 192.168.5.0/24 [120/2] via 192.168.1.200, eth0, 00:03:40
    C>* 192.168.10.0/24 is directly connected, eth1
    
    如果你有看到上述的字體,嘿嘿!那就是成功啦!那個最左邊的 R 代表的是透過 RIP 通訊協定所設定的路由規則啦! 如此一來,咱們的路由器設定就搞定囉~如果一切都沒有問題,你也想要啟動 zebra, ripd ,那麼還得要這樣:
    [root@www ~]# chkconfig zebra on
    [root@www ~]# chkconfig ripd on
    

透過這個 quagga 以及 RIPv2 的路由協定的輔助,我們可以輕鬆的就將路由規則分享到附近區網的其他路由器上頭, 比起單純使用 route 去修改 Linux 的核心路由表,這個動作當然要快速很多!不過,如果是很小型的網路環境,那麼不要使用這個 quagga 啊!因為有點多此一舉的感覺。如果你的企業環境真的有夠大,那麼玩一玩這個 quagga 配合一些動態路由協定,嘿嘿!也是可行的啦!

Tips 鳥哥 鳥哥差一點被這一版的 ripd.conf 設定內容搞死~因為 CentOS 5.x 預設的 RIPv2 會去進行身份驗證,所以原先在 CentOS 4.x 的設定是不能用的,偏偏登錄檔又看不出個所以然..後來查到可以透過 ripd.conf 內的 debug 參數去設定除錯登錄, 才發現 RIPv2 的認證問題!最終 google 一下才解決問題~好累啊!

8.4 特殊狀況:路由器兩邊界面是同一個 IP 網段: ARP Proxy

如果你一開始設計的網路環境就是同一個 Class C 的網域,例如 192.168.1.0/24 , 後來因為某些因素必須要將某些主機搬到比較內部的環境中,例如圖 8.2-1的 PC2 ~ PC4 。 然後又因為某些因素,所以你不能變更 PC2 ~ PC4 的 IP ,此時你的同一網域就會橫跨在一個路由器的左右兩邊了! 舉例來說,連線圖示有點像底下這樣:

在路由器兩個介面兩邊的 IP 是在同一個網域的設定情況
圖 8.4-1、在路由器兩個介面兩邊的 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 。 此時,封包傳遞的圖示有點像這樣:

正常的網段想要傳送到內部電腦去的封包流向
圖 8.4-2、正常的網段想要傳送到內部電腦去的封包流向

在這個階段,我們可以設定PC2~PC4 的 IP 所對應的網卡卡號 (MAC) 都設定在 router 的對外網卡上, 因此, router 的對外介面可以將給 PC2~PC4 的封包給『騙』過來。接下來,就簡單的透過路由設定,讓封包轉個介面發送出去即可。 這樣 PC1 --> PC2 的問題解決了,但是 PC2 怎麼傳送到 PC1 呢?我們可以透過底下的圖示來想像一下:

內部電腦想要傳送到正常網域時的封包流向
圖 8.4-3、內部電腦想要傳送到正常網域時的封包流向

當 PC2 要傳送的封包是給 PC3, PC4 的,那麼這個封包得要能夠直接傳遞。但是如果需要傳送到正常網域的封包,就得要透過 router 的對內網卡,再透過路由規則來將該封包導向外部介面來傳遞才行!這個時候就變成內部的介面欺騙 PC2 說, PC1 與 Router A 的 IP 是在內部這張介面上就是了,然後再透過路由判斷將該封包透過外部介面來對外傳遞出去即可。 假設 Linux router 的對外介面為 eth0 而對內為 eth1 時,我們可以這樣說:

  1. 當 Linux Router 的 eth0 那個網域主機想要連接到 PC2~PC4 的主機時,由 Linux Router 負責接收;
  2. 當 Linux Router 要傳送資料到 PC2~PC4 時,務必要由 eth1 來傳送;
  3. 當內部電腦想要連接到 PC1 或 Router A 時,由 Linux router 的 eth1 負責接收;
  4. 當 Linux Router 要傳送的資料為 192.168.1.0/24 ,但並非 PC2~PC4 時,需由 eth0 傳送。

上列的步驟與圖示內的線條上的順序相符合呦!得要對照著看看。其中的 (1) 與 (3) 就是透過 ARP Proxy (代理) 的功能啦! 那啥是 ARP Proxy 呢?簡單的說,就是讓我的某張介面卡的 MAC 代理其他主機的 IP 對應,讓想要連接到這個 IP 的 MAC 封包由我幫他接下來的意思。舉我們圖 8.4-1 的例子來說,就是在 Linux Router 的 eth0 介面上,規定 192.168.1.20, 192.168.1.30, 192.168.1.40 這三個 IP 都對應到 eth0 的 MAC 上,所以三個 IP 的封包就會由 eth0 代為收下,因此才叫做 ARP 代理人嘛!所以啦,每一部在 eth0 那端的主機都會『誤判』那三個 IP 是 Linux Router 所擁有,這樣就能夠讓封包傳給 Linux Router 啦!

再接下來,咱們的 Linux Router 必須要額外指定路由,設定情況為:

  • 若目標是 PC2 ~ PC4 時,該路由必須要由內部的 eth1 發送出去才行,
  • 若目標不為 PC2 ~ PC4 ,且目標在 192.168.1.0/24 的網域時,需由 eth0 發送出去才行。

也就是說,你必須要指定路由規則當中,那個 PC2~PC4 具有優先選擇權,然後其他的同網域封包才由 eth0 來傳送。 這樣就能夠達成我們所想要的結局啦!^_^!看樣子似乎很難,其實設定方面還挺簡單的,你可以透過 arp 以及 route 這兩個指令來達成喔!

  • 外部介面 eth0:00:E0:81:71:7C:D6
  • 內部介面 eth1:00:E0:4C:F0:B5:5B
# 1. 先設定外部 eth0 的 ARP Proxy,讓三個 IP 對應到自己的 MAC
[root@www ~]# arp -i eth0 -s 192.168.1.20 00:E0:81:71:7C:D6 pub
[root@www ~]# arp -i eth0 -s 192.168.1.30 00:E0:81:71:7C:D6 pub
[root@www ~]# arp -i eth0 -s 192.168.1.40 00:E0:81:71:7C:D6 pub
[root@www ~]# arp -n
Address             HWtype  HWaddress      Flags Mask       Iface
192.168.1.30        *       *              MP               eth0
192.168.1.40        *       *              MP               eth0
192.168.1.20        *       *              MP               eth0
# 首先需要讓外部介面擁有三個 IP 的操控權,透過這三個指令來建立 ARP 對應!

# 2. 開始處理路由,增加 PC2~PC4 的單機路由經過內部的 eth1 來傳遞
[root@www ~]# route add -host 192.168.1.20 eth1
[root@www ~]# route add -host 192.168.1.30 eth1
[root@www ~]# route add -host 192.168.1.40 eth1
[root@www ~]# route -n
Kernel IP routing table
Destination    Gateway        Genmask         Flags Metric Ref  Use Iface
192.168.1.40   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.20   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
169.254.0.0    0.0.0.0        255.255.0.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
# 的網域,兩個介面都可以傳送!因此,等一下第四個步驟得要將他刪除才行!

3. 設定一下內部的 ARP Proxy 工作 (綁在 eth1 上頭囉)!
[root@www ~]# arp -i eth1 -s 192.168.1.10  00:E0:4C:F0:B5:5B pub
[root@www ~]# arp -i eth1 -s 192.168.1.254 00:E0:4C:F0:B5:5B 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 , 同時每次重新啟動網路後,就得要重新執行一次該腳本,即可達到你的需求囉!

透過這個案例你也可以清楚的知道,能不能連線其實與路由的關係才大哩! 而路由是雙向的,你必須要考量到這個封包如何回來的問題喔!

重點回顧

  • 網路卡的代號為 eth0, eth1, eth2...,而第一張網路卡的第一個虛擬介面為 eth0:0 ...
  • 網路卡的參數可使用 ifconfig 直接設定,亦可使用設定檔如 /etc/sysconfig/network-scripts/ifcfg-ethn 來設定;
  • 路由是雙向的,所以由網路封包發送處發送到目標的路由規劃,必須要考慮回程時是否具有相對的路由, 否則該封包可能會『遺失』;
  • 每部主機都有自己的路由表,此路由表 (routing table) 是作為封包傳送時的路徑依據;
  • 每部可對外 Internet 傳送封包的主機,其路由資訊中應有一個預設路由 (default gateway);
  • 要讓 Linux 作為 Router 最重要的是啟動核心的 IP Forward 功能;
  • 重複路由可能會讓你的網路封包傳遞到錯誤的方向;
  • 動態路由通常是用在兩個 Router 之間溝通彼此的路由規則用的,常見的 Linux 上的動態路由套件為 zebra ;
  • arp proxy 可以透過 arp 與 route 的功能,讓路由器兩端都在同一個網段內;
  • 一般來說,路由器上都會有兩個以上的網路介面
  • 事實上,Router 除了作為路由轉換之外,在 Router 上面架設防火牆,亦可在企業內部再分隔出多個需要安全 (Security) 的單位資料的區隔!

本章習題

  • 請問你如何將你的 eth0 這個介面修改成為 192.168.100.2 在網域 192.168.100.0/25 之內的網路參數內容?
    因為 192.168.100.0/25 的 netmask 為 255.255.255.128 ,所以可以這樣做:
    ifconfig eth0 192.168.100.2 netmask 255.255.255.128 up
    這樣即可!如果尚須其他的參數,則需要以檔案形式來下達,如 vi /etc/sysconfig/network-scripts/ifcfg-eth0,並修改為:
    DEVICE=eth0
    ONBOOT=yes
    BOOTPROTO=static
    IPADDR=192.168.100.2
    NETMASK=255.255.255.128
    NETWORK=192.168.100.0
    BROADCAST=192.168.100.127
  • 請手動設定 eth0:1 這個虛擬介面,使成為網路參數: 192.168.200.2, 網域在 192.168.200.0/24。
    ifconfig eth0:1 192.168.200.2 up
  • 如何觀察路由表?
    route -n 即可查閱!注意到 0.0.0.0 那個目標(default gateway)。
  • 如何啟動 Linux 的 IP Forward 功能?
    直接以『echo "1" > /proc/sys/net/ipv4/ip_forward 』即可!
  • 假設你是一個學校單位的資訊管理員,學校內有 200 部電腦,奉上面大頭的旨意,必須要將 200 部電腦分為 4 個 Subnet ,請問你應該如何佈線(請畫出示意圖)?而這 4 個 Subnet 的網路參數如何選擇(請自行選擇)?而是否需要 Router ?如果需要的話,假設每個 Router 僅能有兩個網路實體介面,那麼該如何佈線?(註:不要使用虛擬介面)
  • 假設你想要連接到 168.95.1.1 ,那麼你該如何判斷你經過『多少個』節點?
    可以使用 traceroute 168.95.1.1 來分析每個節點的傳送資訊,也可以透過 ping 168.95.1.1 所回傳的那個 ttl 值判斷節點數量。
  • 萬一你的網路有點停頓,發現可能是網路上某個節點出現問題,你應該如何確認是哪一部 Router 出問題?
    就利用 traceroute 吧!

參考資料與延伸閱讀

修改歷史:
2002/08/09:第一次完成日期!
2003/08/22:重新編輯文章,並增加重點回顧與課後練習
2006/08/21:將舊的文章移動到 此處
2006/08/30:加入了 zebra 以及 ARP Proxy 等與 Router 比較相關的議題!
2010/09/23:將舊的基於 CentOS 4.x 的版本移動到 此處
2010/10/26:修訂了部分資料,尤其是 ARP 的說明部分!不過,重點於題目都還沒有更新!
其他連結
環境工程模式篇
鳥園討論區
鳥哥舊站

今日 人數統計
昨日 人數統計
本月 人數統計
上月 人數統計