在 OpenWRT 上架設 VLAN

在 OpenWRT 上針對有線網路設定 VLAN

VLAN 的介紹

除了 OVS 之外,另一個常用的網路虛擬化稱為 VLAN (Virtual Local Area Network),顧名思義,VLAN 的主要功能就是組件一個虛擬的 LAN,換句話說,所有廣播的封包,都會被限制於同一個 VLAN 裡面,在其他 VLAN 則無法得知廣播的訊息。透過適當的 VLAN 設計,一方面可以增加網路的安全性,另一方面,也可以讓封包的廣播更有效率。

VLAN 通訊協定對應到 802.1Q,其基本的想法是在原本的 ethernet 封包中,增加一個欄位,來標記一個虛擬的網路 (VLAN)。因此,只有在同一個 VLAN 下的裝置,也就是擁有相同標記的裝置,才能夠解析彼此的封包。由於在 VLAN 中傳輸的封包和一般乙太網路的封包不同,因此,必須是支援 VLAN 通訊協定的裝置,才能夠解析 VLAN 中的標記。在一般 Windows 作業系統中, VLAN 的設定是被關閉的,因此,一般的個人電腦應被視為一個不支援 VLAN 的裝置,此類裝置和 VLAN 的關聯性,藉由上層的 Switch 以及 WLAN 的 SSID 來確認。VLAN和傳統以太網路封包的差別,如下圖所示:

對於 VLAN 而言,按照不同的設定框架,又可以分成以下三種:

  • 實體層 VLAN: 將不同的埠 (也就是有線網路的插孔) 作為用以識別 VLAN 的方法。此方法最為簡單,但也缺乏彈性,適合小區域的網路設定。

  • MAC 層 VLAN: 將不同的 MAC 位址作為用以識別 VLAN 的方法。此方法需要一個額外的 VMPS 伺服器 (VLAN Management Policy Server) 讓 Switch 處理 MAC 位址和 LAN 的對應。

  • 網路層 VLAN: 將不同的 IP 位址作為用以識別 VLAN 的方法。考慮到原本 Switch 只有 MAC 層的解析能力,在此架構下,Switch 必須特殊設計,並會拖類原有的網路效能。

對於一般 Switch 裝置而言,通常預設切成 2 個 VALN,也就是: WAN 和 LAN,用以服務對外和對內的網路,VLAN 設定如下:

在上述設定中,可以看到 LAN 和 WAN 所包含的實體埠是分開的,因此,封包在 LAN 和 WAN 並無法藉由廣播傳輸,同時, LAN 和 WAN 可以使用不同的子網域,例如: 192.168.1.x 以及 192.168.3.x,用以對應對內和對外的網路設定。

在 VLAN 設定中,如果通訊埠狀態為 "untagged",即該通訊埠作為 VLAN 成員,但會把 VLAN 的 tag 標記去除,用以連接一般的電腦裝置。 若標記為 "tagged",則代表體實體埠只能接收相同 VLAN 的封包,同時,也必須連接支援 VLAN 的裝置。

因此,在設定時,下行 (downstream) 的設定都是 untagged,用以服務一般的網路裝置 (不支援 VLAN),而上行 (upstream) 的設定則是 tagged,因為這些封包將傳送到 Switch 晶片的 driver (支援 VLAN)。在 VLAN 設定中,要注意每一個實體埠,都只能連上一個 untagged 的 VLAN。

在 OpenWRT 上設置 VLAN

對於 OpenWRT 來說,網路可以分成兩部分,有線網路也就是實體的乙太網路部分,以及無線網路的部分,這兩個網路都可以針對 VLAN 作一些設定,我們先從有線網路部分開始。

首先,先確認一下網路的配置:

#  ls -l /sys/class/net
lrwxrwxrwx    1 root     root             0 Mar 29 15:46 br-lan -> ../../devices/virtual/net/br-lan
lrwxrwxrwx    1 root     root             0 Apr  3 06:50 br0 -> ../../devices/virtual/net/br0
lrwxrwxrwx    1 root     root             0 Jan  1  1970 eth0 -> ../../devices/platform/ag71xx.0/net/eth0
lrwxrwxrwx    1 root     root             0 Mar 29 15:46 eth0.1 -> ../../devices/virtual/net/eth0.1
lrwxrwxrwx    1 root     root             0 Mar 29 15:46 eth0.2 -> ../../devices/virtual/net/eth0.2
lrwxrwxrwx    1 root     root             0 Jan  1  1970 lo -> ../../devices/virtual/net/lo
lrwxrwxrwx    1 root     root             0 Apr  3 06:50 ovs-system -> ../../devices/virtual/net/ovs-system

在比較新型的 WiFi AP 架構中,通常只有一張實體的乙太網路硬體 (eth0),而其他孔位網路則是由支持 VLAN 的硬體來管理,也就是上面看到的: eth0.1、eth0.2。在此架構下,由於硬體已支援 VLAN,因此 VLAN 的設定較為簡單,直接更改 /etc/config/network的設定就可以了。

~# cat /etc/config/network
[...]
config switch
        option name 'switch0'
        option reset '1'
        option enable_vlan '1'

config switch_vlan
        option device 'switch0'
        option vlan '1'
        option ports '2 3 0t'

config switch_vlan
        option device 'switch0'
        option vlan '2'
        option ports '1 0t'

/etc/config/network的設定中,我們僅列出和 Switch 相關的部分,可以看到原本的 VLAN 設定。其中,switch0 為真實的硬體,可以看到 VLAN 功能已被開啟,switch_vlan 則是所設定的 VLAN,vlan 1 對應到實體埠 { 2, 3, 0t },也就是設定中作為 LAN 的有線網路。vlan 2 對應到實體埠 { 1, 0t },也就是原本作為 WAN 的有線網路。

關於eth0.x和 VLAN ID 的對應,可以參考官網的敘述: A driver-level VLAN could be created in theinterface section by adding a dot"."and the respective VLAN ID after the interface name (in the ifname option), like eth1.2 for VLAN ID 2 on eth1.

在上述設定中, '0t' 是一個比較特殊的通訊埠,對應於 CPU 裝置 (可以參考這篇文章),在旁邊的 't'則是標記為 tagged,其他沒有標記的數字,則為 untagged。關於此處的設定,請參考之前介紹 VLAN 的說明。

設定 VLAN 時,對於每一個 VLAN 一定要對應於至少一個實體埠,例如:ports '1 0t',但不能只綁'0t'這個通訊埠,否則會出現設定錯誤。

瞭解上述設定之後,我們就可以自定義 OpenWRT 上的 VLAN,例如,我想要增加一個 VLAN ,並把實體埠 2, 3 分開,設定檔就可以修改為:

~# cat /etc/config/network
[...]
config switch
        option name 'switch0'
        option reset '1'
        option enable_vlan '1'

config switch_vlan
        option device 'switch0'
        option vlan '1'
        option ports '2 0t'
        
config switch_vlan
        option device 'switch0'
        option vlan '3'
        option ports '3 0t'

config switch_vlan
        option device 'switch0'
        option vlan '2'
        option ports '1 0t'

此時,我們多一個新的 VLAN,其 ID 為 "3",對應到的 ifname 為 "eth0.3",我們要幫他加入網路的設定檔才可以使用。我們先參考原本 LAN 的網路設定檔:

~# cat /etc/config/network
[...]
config interface 'lan'
        option type 'bridge'
        option proto 'static'
        option netmask '255.255.255.0'
        option ifname 'eth0.1'
        option ipaddr '192.168.10.1'
[...]

可以看到其對應於 "eth0.1" 這張網卡,也就是 ID = 1 的 VLAN,參照上方設定,的確原本實體埠 2, 3 對應於 VLAN 1,且功能為 LAN。考慮到我們新的設定把實體埠 2, 3 分開,並加入一個新的 VLAN,我們增加一個新的 interface 如下:

[...]
config interface 'lan2'
        option type 'bridge'
        option proto 'static'
        option netmask '255.255.255.0'
        option ifname 'eth0.3'
        option ipaddr '192.168.9.1'
[...]

在設定中,我們把其 IP 位址設為: 192.168.9.1,因此,新虛擬的 VLAN 和舊有的不同,會使用 192.168.9.X 這一個網段進行通訊。接著,根據新的設定檔,重新啟動有線網路就可以了。

~# /etc/init.d/network restart
:~# ifconfig
[...]
br-lan    Link encap:Ethernet  HWaddr E4:95:6E:45:A0:FA
          inet addr:192.168.10.1  Bcast:192.168.10.255  Mask:255.255.255.0
          inet6 addr: fe80::e695:6eff:fe45:a0fa/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1310 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1129 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:163252 (159.4 KiB)  TX bytes:1098124 (1.0 MiB)

br-lan2   Link encap:Ethernet  HWaddr E4:95:6E:45:A0:FA
          inet addr:192.168.9.1  Bcast:192.168.9.255  Mask:255.255.255.0
          inet6 addr: fe80::e695:6eff:fe45:a0fa/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:7 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:770 (770.0 B)

eth0.1    Link encap:Ethernet  HWaddr E4:95:6E:45:A0:FA
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:242 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:25966 (25.3 KiB)

eth0.3    Link encap:Ethernet  HWaddr E4:95:6E:45:A0:FA
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:880 (880.0 B)
[...]

在這裡我們列出和 LAN 相關的兩個網路: br-lan,br-lan2。可以看到他們相對於不同的子網路設定。當然,當透過有線網路連上 AP 裝置時,也必須按照不同的 IP 位址才能連上。以上就完成有線網路的基本 VLAN 設定了。

注意: 此部分的設定只是把實體埠和 VLAN 網路切開,對於新配置的 VLAN (也就是 br-lan2) 並未有有效的設定,像是: DHCP。因此,當使用此新開啟的 VLAN 時,必須手動設定 IP 位址至 19.168.9.x 子網域下,才能連到 AP 的 IP 位址 (192.168.9.1)。若是要有完整的網路服務,還須在 DHCP 以及防火牆那邊做出正確的設定。

interface 設定的說明

在上述的設定中,我們針對 /etc/config/network 進行設定,在設定檔中,定義了一個新的 LAN (lan2),並透過 ifname 的設定,讓 lan2 和 eth0.3,也就是新建立的 VLAN 相連,設定檔如下所示:

config interface 'lan2'
        option type 'bridge'
        option proto 'static'
        option netmask '255.255.255.0'
        option ifname 'eth0.3'
        option ipaddr '192.168.9.1'

當然,network interface 的設定和 VLAN 不一定要對應,舉例來說,localhost 也是一個 network interface,但是就沒有對應到 VLAN,其設定檔如下:

config interface 'loopback'
        option ifname 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

對於一個 network interface 而言,重要的是要代表一個子網域。因此,在無線網路、DHCP 以及 firewall 設定中,都必須表明所設定的目標,也就是在 network interface 中定義的一個子網域。我們列出 /etc/config/dhcp、/etc/config/firewall 以及 /etc/config/wireless 中的部分設定,表示如下:

~# cat /etc/config/dhcp
[...]
config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '150'
        option leasetime '12h'
        option force '1'
        option dhcpv6 'server'
        option ra 'server'
[...]
~# cat /etc/config/firewall
[...]
config zone
        option name 'lan'
        option network 'lan'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
[...]
~# cat /etc/config/wireless
[...]
config wifi-iface 'default_radioi1'
        option device 'radio1'
        option network 'lan'
        option mode 'ap'
        option encryption 'psk-mixed'
        option wds '1'
        option ifname 'wlan1'
        option ssid 'WiSDON-TEST'
        option key 'mbwcl711'
        option disabled '0'
[...]

在這些設定檔中,我們可以看到 interface 也就是子網域的設定是在 OpenWRT 網路中 (更精確地說,應該是在 OVS 網路中) 一個上位的概念,其定義一個子網路,並透過 VLAN 和實體通訊埠相連,或是透過 /etc/config/wireless 的設定與無線網路 (via SSID) 相連。而此子網路的功能,也就是 DHCP 和 firewall 的設定,則透過/etc/config/wireless/etc/config/firewall來定義。因此,當我們新設定一個 VLAN 之後,也必須對上述幾個檔案進行更新。

VLAN 和 SSID 的對應: 考慮到一個 SSID 對應到一個 logic LAN (可以是 VLAN),但是,對於一個 SSID 可否對應於多個 VLAN 呢? 這裡有兩種方法可以完成類似的設定: 第一、透過 MAC 位址設定 VLAN 的對應。在此環境下,使用者透過 802.1X 登入,讓系統可以取得其 MAC 位址,之後,就可以透過 MAC 位只來決定 VLAN 的從屬。第二、則是把 WiFi AP 分屬不同群集,每個群即屬於不同的 VLAN。此方法在設計上較為簡單,等於是照 AP 位置區分 VLAN,當 AP 可以分成互不相連的群集時,會是一個簡單的解決方案。詳細說明可以參考: https://community.cisco.com/t5/other-wireless-mobility-subjects/single-ssid-with-multiple-vlans/td-p/1496917

Last updated