2012年10月31日 星期三

(9) NIC bridging concepts

What is a bridge?


不管是鄉間優美的Richmond古橋,或是雪梨南北的重要命脈Hobour Bridge,或者是通往祖靈的彩虹橋,他們最重要的特點就是"溝通兩端的交通"。作為一個溝通管道,他不在乎上面要載運什麼樣的交通工具,也不在乎要實行何種交通規則--他就只是橋樑。

我們延續這樣的觀念:一個bridge裝置就是能連接兩個(或以上)網路的設備。這個裝置不需要非常有智慧,他只要能傳送封包就好(layer 2);他就像是一個port數有限的switch,負責作為多個網路裝置的通道;而事實上,他就是switch的前身。從現在開始把bridge在腦海中替換成switch邏輯上幾乎是安全的。

首先,switch只負責利用廣播以及ARP table來負責封包傳輸,因此bridge(就是switch)是不懂得IP位置的。假設有兩段獨立的網路想要溝通,除了買switch之外,也可以用Linux作為bridge來達成。

Bridge是IEEE 802.1d,在Linux裡是透過brtcl這個工具來控制bridge裝置,請先確定Linux系統有安裝bridge-utils這個套件。接上一張有2 ports以上的NIC,事情就便得很簡單:

brctl addbr br0 #新增一個bridge裝置
brctl addif br0 eth0 #把eth0加到br0裡
brctl addif br0 eth1 #把eth1加到br0裡
剛剛說過,eth0/eth1作為br0的兩端界面,是不需要也不可以有ip位置的。請把位置拿掉並確定裝置有起來:
ip l set eth0 up
ip a add 0.0.0.0 dev eth0
ip l set eth1 up
ip a add 0.0.0.0 dev eth1
ip l set br0 up
就是如此不可置信的容易。網路上有些中文文章寫bridge需要有ip_forwarding,這顯然是錯誤的說法;traffic都跑在Layer 2又如何懂得ip呢?
雖然eth0/eth1上不可設定位置,但是不代表br0不可以。設定br0的ip純粹只是為了與這台Linux連線,就像是你為switch設定management port的IP位置一樣。
ip a add 192.168.10.100/24 dev br0
ip r add default via 192.168.10.1 dev br0
記得在寫個DNS資訊到/etc/resolv.conf,這台switch就可以上網啦(聽起來很怪異吧!)

brctl還能幫我們作些什麼?

其實敲個brctl就可以知道還有哪些東西好玩,這裡僅列出一些些:
  • addbr <bridge> :新增一個bridge
  • brctl addbr br1
  • delbr <bridge> :刪除一個bridge
  • brctl delbr br1
  • addif <bridge> <device> :從一個bridge裡增加一個interface
  • brctl addif br0 eth2
  • delif <bridge> <device> :從一個bridge裡刪除一個interface
  • brctl delif br0 eth2
  • show [ <bridge> ] :顯示所有的bridge資訊
  • brctl show
    大概會看到這樣的訊息:
    bridge name bridge id  STP enabled interfaces
    br0  8000.f46d047bbe13 no  eth0
    virbr0  8000.000000000000 yes
  • showmacs <bridge> :顯示mac欄位
  • brctl showmacs br0
    port no mac addr  is local? ageing timer
      1 00:12:0e:39:37:48 no     0.71
      1 00:26:18:63:62:70 no     0.02
      1 40:6c:8f:02:e5:3a no     2.32
      1 f4:6d:04:7b:be:13 yes     0.00
  • showstp <bridge> :顯示Spanning Tree的狀態
  • brctl showstp
    br0
     bridge id  8000.f46d047bbe13
     designated root 8000.f46d047bbe13
     root port     0   path cost     0
     max age    12.00   bridge max age    12.00
     hello time     2.00   bridge hello time    2.00
     forward delay     9.00   bridge forward delay    9.00
     ageing time   300.01
     hello timer     0.50   tcn timer     0.00
     topology change timer    0.00   gc timer   171.86
     flags   
    
    
    eth0 (1)
     port id  8001   state       forwarding
     designated root 8000.f46d047bbe13 path cost    19
     designated bridge 8000.f46d047bbe13 message age timer    0.00
     designated port 8001   forward delay timer    0.00
     designated cost    0   hold timer     0.00
     flags
  • stp <bridge> {on|off} :啟用/停用STP
  • brctl stp br0 on

Bridge可以『只』連接一個port嗎?

答案是可以的,只是比較難以想像。假設一個bridge只連接一個裝置,那麼這個bridge的角色更像是router,而且是『分享實體網路』的功能給虛擬機器。最常見的例子就是KVM/XEN的環境了:KVM跟XEN總是會幫我們自動產生一個virbr0的裝置,這個virbr0裝置其實就是連接hypervisor以及虛擬NIC的通道,這個通道不僅能溝通虛擬機器以及實體機器,他還兼有DHCP+NAT的功能,因此我們的Linux bridge瞬間變成了router。但是如果要讓虛擬機器跟實體機器處於同一網段,我們則必須手動再建立一個bridge,讓實體的eth0與虛擬的NIC建立起通道:
brctl addbr br0
brctl addif br0 eth0
dhclient br0
此時你的bridge的角色是router,他必須持有一個ip才能夠把虛擬機器的封包往外繞送。有了這些基本觀念,就不會覺得為什麼有些人要在bridge上設定IP,有些則不用。唯有了解這個裝置真正的角色,我們的設定才具有意義。
網路上關於bridge的參考文章不少,但截至目前為止有用的只有這篇;精讀了這篇其餘的時間就省下來了:

Share

3 則留言:

Oni Lin 提到...

通常在玩這個的時候會遇到不知道當了bridge的這台機器連接的是哪些機器,這些機器又個別被DHCP發派哪些IP,尤其這些機器還都是沒有接螢幕的時候更蛋疼…

這時候可以用brctl + nmap兩邊結合來得到結果。

首先用brctl showmacs [br號碼] 產生mac列表,列表最前方port即可知道port所掃描到的macs有哪些,除了對外那個port其他port應只有其對應的一組mac,除非你後面還有在繼續串連這樣,到這邊可以獲取到機器的mac數值。

之後用nmap -sP [區網例如192.168.0.0/24] 來掃描區網的ip與mac對照表,但是表好長真是太難看了,用grep來篩選一下,假設我的mac是11:22:33:44:55:66,就可以用nmap -sP 192.168.0.0/24 | grep -i -n2 --color "11:22:33:44:55:66"來找到這組mac的ip是多少了,之後就可以ssh過去ooxx啦~

P.S. nmap是雙面刃,很多情形下都會被判斷為功擊行為,請慎用……沒辦法它太強大了XDDD

匿名 提到...

嗨:

這段似乎 eth <-> br 位置寫反了
##
brctl addif eth0 br0 #把eth0加到br0裡
brctl addif eth1 br0 #把eth1加到br0裡
##

感謝您的文章 幫助很大 ~

Jim T. Tang 提到...

已修正,非常感恩~~