Linux

hostapd:將 MAC 地址映射到 VLAN ID(通過accept_mac_file 進行靜態映射)

  • March 24, 2021

我希望 hostapd 根據 MAC 地址為每個站分配一個給定的 VLAN。順便說一句,我的網路很小。使用 RADIUS 將是一個矯枉過正。

根據hostapd手冊

或者,可以使用本地 MAC ACL 列表 (accept_mac_file) 將靜態客戶端 MAC 地址設置為 VLAN ID 映射。

假設我只有 1 個站(使用 MAC DE:AD:BE:EF:CA:FE)。我使用以下方法創建了一個 VLAN:

sudo ip link add link wlan0 name vlan.100 type vlan id 100
sudo ip addr add 192.168.100.1/24 brd 192.168.100.255 dev vlan.100
sudo ip link set dev vlan.100 up

在 hostapd.conf 我正在使用:

#  Interface to use
interface=wlan0
#  Driver
driver=nl80211
#  Name of the network
ssid=YaddaYadda
#  Use the 2.4GHz band: g = IEEE 802.11g (2.4 GHz)
hw_mode=g
#  Use channel 6
channel=6
#  Enable 802.11n
ieee80211n=1
#  Enable 40MHz channels with 20ns guard interval
ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40]
#  Accept only known MAC addresses
macaddr_acl=1
accept_mac_file=/etc/hostapd/accept
#  Use WPA authentication
auth_algs=1
#  Send empty SSID in beacons and ignore probe request frames that do not specify full SSID
ignore_broadcast_ssid=1
#  Use WPA2
wpa=2
#  Use a pre-shared key
wpa_key_mgmt=WPA-PSK
#  Enable the wireless multimedia extensions
wmm_enabled=1
#  The network hashed passphrase
wpa_psk=786451648446NotReallyTheHashedPassphrase849989654651651651654564
#  Use AES, instead of TKIP
rsn_pairwise=CCMP
# Isolate Clients
ap_isolate=1

#  HOSTAPD event logger configuration
logger_syslog=-1
logger_syslog_level=2
logger_stdout=-1
logger_stdout_level=2

#  Country code
country_code=NO

在文件*/etc/hostapd/accept*中,我包含以下內容:

DE:AD:BE:EF:CA:FE vlan.100

hostapd 啟動沒有任何問題。但是,在將我的站與 MAC DE:AD:BE:EF:CA:FE 連接後,我仍然在 wlan0 而不是 vlan.100 上獲得所有流量…

hostapd 沒有過多說明文件 accept_mac_file 應該如何映射 MAC <-> VLAN ID。我試過逗號,有和沒有空格,但沒有運氣……

有沒有人能讓這個 MAC <-> VLAN 映射工作?

查看hostapd原始碼,我發現其中有一個hostapd_config_read_maclist()函式可以解析和配置值config_file.c引用的文件:accept_mac_filedeny_mac_file

static int hostapd_config_read_maclist(const char *fname,
                      struct mac_acl_entry **acl, int *num)
{
   FILE *f;
   char buf[128], *pos;
   int line = 0;
   u8 addr[ETH_ALEN];
   int vlan_id;

   f = fopen(fname, "r");
   if (!f) {
       wpa_printf(MSG_ERROR, "MAC list file '%s' not found.", fname);
       return -1;
   }

   while (fgets(buf, sizeof(buf), f)) {
       int rem = 0;

       line++;

       if (buf[0] == '#')
           continue;
       pos = buf;
       while (*pos != '\0') {
           if (*pos == '\n') {
               *pos = '\0';
               break;
           }
           pos++;
       }
       if (buf[0] == '\0')
           continue;
       pos = buf;
       if (buf[0] == '-') {
           rem = 1;
           pos++;
       }

       if (hwaddr_aton(pos, addr)) {
           wpa_printf(MSG_ERROR, "Invalid MAC address '%s' at "
                  "line %d in '%s'", pos, line, fname);
           fclose(f);
           return -1;
       }

       if (rem) {
           hostapd_remove_acl_mac(acl, num, addr);
           continue;
       }
       vlan_id = 0;
       pos = buf;
       while (*pos != '\0' && *pos != ' ' && *pos != '\t')
           pos++;
       while (*pos == ' ' || *pos == '\t')
           pos++;
       if (*pos != '\0')
           vlan_id = atoi(pos);

       if (hostapd_add_acl_maclist(acl, num, vlan_id, addr) &lt; 0) {
           fclose(f);
           return -1;
       }
   }

   fclose(f);

   if (*acl)
       qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp);

   return 0;
}

我還沒有(還)對此進行測試以確認,但根據上面的程式碼,*_mac_file文件的規則如下所示:

  1. 以 開頭#的行將被忽略。
  2. 空行被忽略。
  3. MAC 地址由 6 個十六進制的八位字節指定,每個八位字節用 . 分隔:
  • 可以選擇為 MAC 地址添加前綴,-以從列表中刪除所有出現的它。
  • 否則,可以選擇在 MAC 地址後跟空格和製表符的某種組合,然後跟一個指定 VLAN 的整數。如果 VLAN 是0、未指定或不是整數,則將其視為無 VLAN。

基於這些規則,我相信將 MAC 地址映射DE:AD:BE:EF:CA:FE到具有名稱vlan.100和 ID的 VLAN 的方法100是使用以下行:

DE:AD:BE:EF:CA:FE 100

也就是說,只有 VLAN IDhostapd與 VLAN 名稱無關。

引用自:https://serverfault.com/questions/937595