原文:http://blog.csdn.net/dog250/article/details/7354590安全
提及IEEE 802.1q,都知道是VLAN,提及VLAN,基本上也沒有盲區,網絡基礎。然而說到配置,基本全部人都能順口溜同樣說出Cisco或者H3C設備的配置命令,對於Linux的VLAN配置卻存在大量的疑問。這些疑問之因此存在我以爲有兩點緣由:
1.對VLAN的本質仍是沒有理解。
無論你的Cisco/H3C命令敲得再熟練,若是看不懂Linux的vconfig,那麼也將沒法掩飾你對概念理解的淺顯;
2.對Linux實現虛擬網絡設備風格不熟悉
網絡
可能你已經十分理解802.1q了,也許還看過了IEEE的文檔,然而卻對Linux的Bridge,tap,bond等虛擬設備不是很理解,那麼也將沒法順利配置VLAN。函數
對於VLAN概念的理解,有幾點要強調:
1.VLAN分離了廣播域;
2.單獨的一個VLAN模擬了一個常規的交換以太網,所以VLAN將一個物理交換機分割成了一個或多個邏輯交換機;
3.不一樣VLAN之間通訊須要三層參與;
4.當多臺交換機級聯時,VLAN經過VID來識別,該ID插入到標準的以太幀中,被稱做tag;
5.大多數的tag都不是端到端的,通常在上行路上第一個VLAN交換機打tag,下行鏈路的最後一個VLAN交換機去除tag;
6.只有在一個數據幀不打tag就不能區分屬於哪一個VLAN時纔會打上tag,能去掉時儘早要去掉tag;
7.最終,IEEE 802.1q解決了VLAN的tag問題。除了IEEE 802.1q,其他的都是和實現相關的,雖然Cisco和H3C的實現很相似,Linux能夠和它們有大不一樣。
關 鍵看最後3點,也就是3,4,5。這是VLAN最難理解的部分,不過一旦理解了,VLAN也就不剩下什麼了。爲了使得敘述上以及配置上更加的方 便,Cisco以及其餘的廠商定義了不少的細節,而這些細節在IEEE 802.1q標準中並無被定義,這些細節包括但不侷限於如下幾點:
工具
我 們實則沒有必要去深究Cisco/H3C的命令以及到底那三類端口類型有何區別,之因此有三類端口類型徹底是爲了將VLAN的概念(最終的IEEE 802.1q標準)很方便的用起來。說白了,trunk端口的存在是由於不得已,由於有屬於多個VLAN的數據幀要經過單一的物理鏈路,不打tag是沒法 區分各自屬於哪一個VLAN的,因而就有了IEEE 802.1q這個標準,定義了一個tag插入到以太幀中,爲了使這個理論性的東西被使用起來,廠商便定義了一系列的概念性的東西,好比和tag相關的鏈路 就是trunk鏈路之類。
因而乎,咱們能夠徹底拋開任何的配置命令,拋開任何廠商定義的東西,徹底按照IEEE 802.1q標準以及咱們的需求來理解VLAN,這樣下來以後,你絕對能夠在Linux上完美實現任何VLAN配置了。首先咱們定義一下咱們的需求以及滿 足該需求的網絡拓撲,關鍵看如何接線。
spa
從 上述1.2能夠看出,爲了節省線纜和避免環路,兩個VLAN交換機的兩個端口之間的同一條鏈路須要承載不一樣的VLAN數據幀,爲了使彼此可以識別每一個數據 幀到底屬於哪一個VLAN,十分顯然的辦法就是爲數據幀打上tag,所以上述1.2中的端口J和端口K之間的鏈路上的數據幀須要打tag,端口J和端口K都 同屬於兩個VLAN,分別爲VLAN m和VLAN n。換句話說,只要一個端口須要傳輸和接收屬於多個VLAN的數據幀,那麼從該端口發出的數據幀就要打上tag,從該端口接收的數據幀能夠經過tag來識 別它屬於哪一個VLAN,用Cisco/H3C等廠商的術語來說,它就是trunk端口,兩個trunck端口之間的鏈路屬於trunk鏈路。
咱們知道,通常而言,咱們的PC機直接鏈接在常規二層交換機或者支持VLAN的交換機端口上,而咱們的PC機發出的通常都是常規的以太網數據幀,這些數據 幀是沒有tag的,它們可能根本不知道802.1q爲什麼物,然而VLAN存在的目的就是把一些PC機劃在一個VLAN中,而把另外一些PC機劃在另外一個 VLAN中從而實現隔離,那麼很顯然的一種辦法就是將支持VLAN的交換機的某些端口劃在一個VLAN,而另外一些端口劃在另外一個VLAN中,一個VLAN 的全部端口其實就造成了一個邏輯上的二層常規交換機,同屬於一個VLAN的PC機鏈接在劃在同一個VLAN的端口上,爲了擴展VLAN,鑑於單臺交換機端 口數量的限制,須要級聯交換機,那麼級聯鏈路上則同時承載着不一樣VLAN流量,所以級聯鏈路則成爲trunk鏈路,全部不是級聯鏈路的鏈路都是直接鏈路, 用廠商術語來說就是access鏈路(注意,這裏暫且不談hybrid),天然而然的,access鏈路兩端的端口都是和tag無關的,只須要作到「沒有 tag直通,有tag去掉便可」,所以它能夠鏈接PC機或者常規交換機以及VLAN交換機的非trunk端口。
VLAN的內容基本也就是以上那些了,分爲三部分:
.net
隔離廣播域,節省物理設備,隔離安全策略域
設計
爲擴展VLAN的級聯方案提供了一個標準的協議
blog
將某些端口劃爲一個VLAN,基於MAC地址什麼的...
其實,至於怎麼劃分VLAN,標準中並無給出什麼硬性的規定,只要可以保證屬於同一VLAN的端口徹底不然IEEE 802系列的標準便可,換句話說就是屬於同一VLAN的全部交換機的全部同一VLAN的端口徹底就是一個以太網便可,透傳以太幀。
到此爲止,咱們基本上已經忘了配置trunk,access,基於端口劃VLAN的命令了,腦子裏面留下的只是VLAN的核心概念,使用這些核心的概念, 咱們就能夠在Linux上配置完整的VLAN方案了,若是你去硬套Cisco的配置,那麼結果只是悲哀。好比若是你問:如何在Linux上配置端口爲 access,如何在Linux上將某些網卡劃到一個VLAN...
理解Linux Bridge的都知道,Linux自己就能夠實現多個Bridge設備,由於Linux的Bridge是軟的,因此一個Linux Box能夠配置多個邏輯意義的Bridge,而多個Bridge設備之間必須經過第三層進行通訊,加之第三層正是以太網的邊界,所以一個Linux Box也就能夠模擬多個以太網了,不一樣的Bridge設備就能夠表明不一樣的VLAN。
接口
Linux 上的VLAN和Cisco/H3C上的VLAN不一樣,後者的VLAN是現有了LAN,再有V,也就是說是先有一個大的LAN,再劃分爲不一樣的VLAN,而 Linux則正好相反,因爲Linux的Bridge設備是被建立出來的邏輯設備,所以Linux須要先建立VLAN,再建立一個Bridge關聯到該 VLAN,建立VLAN很簡單:
ifconfig eth0 0.0.0.0 up
vconfig eth0 10
ifconfig eth0.10 up
當 使用vconfig建立了eth0.10以後,它就是一個「真實意義」的虛擬網卡設備了,相似br0,tap0,bond0之類的,在這個虛擬網卡之下綁 定的是一個真實網卡eth0,也就是數據從eth0這塊真實網卡發出,eth0.10中的「.10」表示它能夠承載VLAN 10的數據幀,而且在經過eth0發出以前要打上tag。那麼打tag這件事天然而然就是經過eth0.10這個虛擬設備的hard_xmit來完成的, 在這個hard_xmit中,打上相應的tag後,再調用eth0的hard_xmit將數據真正發出,以下圖所示:
所以一個真實的物理網卡好比ethx,它能夠承載多個VLAN的數據幀,所以它就是trunk端口了,以下所示:
Linux 的VLAN工具vconfig採用ethx.y的方式以ethx爲trunk端口加入VLAN id爲y的VLAN中。類比Cisco/H3C,咱們已經建立了trunk,總結一下:使用vconfig建立一個ethx.y的虛擬設備,就建立了一個 trunk,其中ethx就是trunk口,而y表明該trunk口鏈接的trunk鏈路能夠承載的VLAN數據幀的id,咱們建立 ethx.a,ethx.b,ethx.c,ethx.d,就說明ethx能夠承載VLAN a,VLAN b,VLAN c,VLAN d的數據幀。
接下來,咱們看一下如何建立access端口。首先注意,因爲Linux的Bridge是虛擬的,邏輯意義的,所以能夠先建立了VLAN以後,再根據這個VLAN動態的建立Bridge,而不是「爲每個端口配置VLAN id」,咱們須要作的很簡單:
建立VLAN:
ifconfig eth0 0.0.0.0 up
vconfig eth0 10
ifconfig eth0.10 up
爲該VLAN建立Bridge:
brctl addbr brvlan10
brctl addif brvlan10 eth0.10
爲該VLAN添加網卡:
ifconfig eth1 0.0.0.0 up
brctl addif brvlan10 eth1
ifconfig eth2 0.0.0.0 up
brctl addif brvlan10 eth2
...
這 就完了。今後,eth1和eth2就是VLAN 10的access端口了,而eth0則是一個trunk端口,級聯VLAN的時候要用到,若是不須要級聯VLAN,而僅僅須要擴展VLAN 10,那麼你大可將eth1鏈接在一個二層常規交換機或者hub上...一樣的,你能夠再建立一個VLAN,一樣經過eth0來級聯上游VLAN交換機:
ifconfig eth0 0.0.0.0 up
vconfig eth0 20
ifconfig eth0.20 up
brctl addbr brvlan20
brctl addif brvlan20 eth0.20
ifconfig eth5 0.0.0.0 up
brctl addif brvlan20 eth5
以下圖所示:
這 下基本就搞定了Linux上VLAN的配置,接下來還有一個內容,那就是VLAN之間的通訊。這個知識點最簡單了,那就是使用路由,爲此不少人把支持 VLAN的三層交換機和路由器等同起來。既然使用路由就須要一個IP地址做爲網關,那麼如何能尋址到這個IP地址天然就是一個不可迴避的問題,咱們要把這 個IP配置在哪裏呢?能夠確定的是,必須配置在當前VLAN的某處,因而咱們有多個地方能夠配置這個IP:
ip
其中的1和2實際上沒有什麼差異,本質上就是找一個能配置IP地址的地方,大多數狀況下使用2,可是若是出現同一個VLAN在同一個Linux Box配置了兩個trunk端口,那麼就要使用Bridge的地址了,好比下面的配置:
brctl addbr brvlan10
brctl addif brvlan10 eth0.10
brctl addif brvlan10 eth1.10
ifconfig brvlan10 up
此 時有兩個ethx.y型的虛擬接口,爲了避免使路由衝突,只能配置一個IP,那麼此IP地址就只能配置在brvlan10上了。無論配置在Bridge上還 是配置在ethx.y上,都是要走IP路由的,只要MAC地址指向了本地的任意的一個接口,在netif_receive_skb調用 handle_bridge的時候都會將數據幀導向本地的IP路由來處理。Linux做爲一個軟件,其並無原生實現硬件cache轉發,所以對於 Linux而言,所謂的三層交換其實就是路由。
咱們看一下一個被打上tag的數據幀何時脫去這個tag,在定義上,它是從access端口發出時脫去的,然而在語義上,只要能保證access端口 發出的數據幀不帶有tag便可,所以對於什麼時候脫去tag並無什麼嚴格的要求。在Linux的VLAN實現上,packet_type的func做爲一個 第三層的處理函數來單獨處理802.1q數據幀,802.1q此時和IP協議處於一個同等的位置,VLAN的func函數vlan_skb_recv正如 IP的處理函數ip_rcv同樣。在Linux實現的VLAN中,只有當一個端口收到了一個數據幀,而且該數據幀是發往本地的時候,纔會到達第三層的 packet_type的func處理,不然只會被第二層處理,也就是Bridge邏輯處理,Linux的原生Bridge實現並不能處理802.1q數 據幀,甚至都不能識別它。整個trunk口收發數據幀,IEEE 802.1q幀處理,以及VLAN間通訊的示意圖以下:
到 此爲止,Linux的VLAN要點基本已經說完了,有了這些理解,我想設計一個單臂Linux Box就不是什麼難事了,單臂設備最大的優點就是節省物理設備,同時還能實現隔離。這個配置不復雜,若是不想用VLAN實現的話也能夠用ip addr add dev ...增長虛擬IP的方式來實現,然而用VLAN實現的好處在於能夠和既有的三層交換機進行聯動,也能夠直接插在支持標準的IEEE 802.1q的設備的trunk口上。
機制搭臺,策略唱戲。既然VLAN的實現機制已經瞭然於胸了,那麼它的缺點估計你也看到了,如何去克服呢?PVLAN說實在的是一個VLAN的替代方案。 解決了VLAN間的IP網段隔離問題,咱們在Linux上如何實現它呢?這倒也不難,無非就是在LAN上添加一些訪問控制策略罷了,徹底能夠用純軟件的方 式來實現,甚至均可以用ebtables/arptables/iptables來實現一個PVLAN。若是說VLAN是一個硬實現的VLAN的話,那麼 PVLAN純粹是一個軟實現的VLAN,甚至都不須要劃分什麼VLAN,你們都處於一個IP網段,只須要配置好訪問控制策略便可,使得同一IP子網的 Host只能和默認網關通訊,而之間不能通訊,因此說,即便你不知道「隔離VLAN」,「團體VLAN」之類的術語,實際上你已經實現了一個PVLAN 了。
1.你須要首先規劃出你的網絡拓撲而不是先去研究VLAN在Linux上如何配置以及如何實現;2.你須要深刻理解VLAN設計的初衷,該配置哪些東西;3.你須要知道對於VLAN哪些概念是核心,哪些概念並非必須的。4.無論基於什麼平臺配置VLAN,只有兩點是必須的:a.哪些端口屬於哪一個VLAN;b.哪一個端口是級聯端口,屬於多個VLAN。5.其它的都不用去死記硬背,都是浮雲...