RasPiをVLAN毎にSSIDを分けるAPにする(hostapd)

モチベーション

家でVLAN毎にSSID分けたい。

予備知識

  • 複数のSSIDを吐く際には基本的に複数のBSSIDが必要となる
  • hostapdでは、あるMACアドレスに対して「base macaddr xor ssidのID」としてSSIDを分ける
  • ただし、xorをとるとき、マスク先のビットが1ではいけない。
  • このためbaseとなるmacaddrはマスクしたときにマスクできるmac addrである必要がある。
  • HW(=無線LAN NIC)によって、複数SSIDをサポートするものと、できないものがある
  • RasPiの内蔵WiFiは複数SSIDをサポート「できない」。このため、外付けWiFiNICは必須である。

構成

nand

 wlan0: 内蔵のWiFi 192.168.100.248 これは管理用
 wlan1: 外付けWiFi

だとする。

複数SSIDのおはなし

まず、Raspi内蔵のWLANチップは複数のSSIDに対応していない。

$iw phy0 info
...(snip)...
        valid interface combinations:
                 * #{ managed } <= 1, #{ P2P-device } <= 1, #{ P2P-client, P2P-GO } <= 1,
                   total <= 3, #channels <= 1
                 * #{ managed } <= 1, #{ AP } <= 1, #{ P2P-client } <= 1, #{ P2P-device } <= 1,
                   total <= 4, #channels <= 1

の通り、AP<=1 なので、APモードとしては1つのSSIDしか出せない。

...(snip)...
$iw phy1 info
#{ AP, mesh point } <= 8,

のように、wlan1としてAP1以上のNICを用意する。

例えば、wlan1自身のSSIDの第6オクテットが0x00だとすると、 2つめのSSID(1つめの他のSSID)は0x01が割り当てられる。 ただ、ここは、"+"ではなくて、xorでのマスクとなる。 0x01の場合、2つめのSSIDは0x02になるのではなく、0x01 xor 1としようとする。 この場合、LSBの1がすでに立っているので、errorとなる。

このため、必要があるのならば、wlan1のhwaddrを変更する。

sudo ifconfig wlan1 down
sudo ifconfig wlan1 hw ether 00:00:5e:00:53:00
sudo ifconfig wlan1 down
sudo ifconfig wlan1 up

hostapdの準備: SSIDを立てる

sudo apt-get hostapd
sudo vi /etc/hostapd/hostapd.conf
interface=wlan1
driver=nl80211
ssid=homenet
hw_mode=g
channel=7
wpa=2 # WPA2
wpa_passphrase=password
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
# hostapd_cliのためのconfig
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0

# ここがssidのセパレータ。bssの"_x"がaliasであり、macaddrはxor xされる
bss=wlan1_1
ssid=guest
wpa=2 # WPA2
# passwordは変えていい
wpa_passphrase=password100
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP

# 一緒
bss=wlan1_2
ssid=honeypot
wpa=2 # WPA2
wpa_passphrase=password666
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP

みたいに書く。

ドキュメント曰く、"bss"というキーワードはセパレータらしい。 ここで区切られて、それいかにそのssid固有のconfigをかく

bridgeの設定

ここまでで、

I/F: SSID
wlan1: homenet
wlan1_1: guest
wlan1_2: honeypot

というI/FとSSIDのマッピングができている。 あとは、eth0側とのbridgeを行う。

sudo apt install bridge-utils
# デバッグだったら以下みたいに立ち上げる
sudo /usr/sbin/hostapd -P /run/hostapd.pid /etc/hostapd/hostapd.conf
# debugじゃないなら、 service hostapd start
sudo vconfig add eth0 200
sudo vconfig add eth0 666
sudo brctl addbr br0
sudo brctl addif br0 wlan1_1
sudo brctl addif br0 eth0.200
sudo brctl addbr br1
sudo brctl addif br1 wlan1_2
sudo brctl addif br1 eth0.666
# 必要があればraspiにアドレスつけたりroutingするようにする
sudo sysctl -w net.ipv4.ip_forward=1
sudo ip addr change 192.168.202.1/24 dev eth0.200
sudo ip addr change 192.168.66.1/24 dev eth0.666

できた!

厄介なのは、↑でhostapdをrestartなどすると、wlan1_xは一度消えるので、 hostapdのscriptなどで上記を上手く呼んであげる必要がある。