我希望 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 映射正常工作吗?
答案1
看看hostapd
源代码,我发现有一个hostapd_config_read_maclist()
功能在config_file.c
其中解析accept_mac_file
和deny_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) < 0) {
fclose(f);
return -1;
}
}
fclose(f);
if (*acl)
qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp);
return 0;
}
我还没有测试过以确认,但根据上面的代码,*_mac_file
文件的规则看起来如下:
- 以 开头的行将
#
被忽略。 - 空行将被忽略。
- MAC 地址由六个十六进制八位字节指定,每个八位字节之间用 分隔
:
。
- 可以选择在 MAC 地址前加上前缀,
-
以便从列表中删除所有出现的地址。 - 否则,MAC 地址后面可以随意跟一些空格和制表符组合,后面跟着一个指定 VLAN 的整数。如果 VLAN 为
0
、未指定或不是整数,则视为无 VLAN。
根据这些规则,我相信将 MAC 地址映射到具有名称和 ID 的DE:AD:BE:EF:CA:FE
VLAN 的方法是使用以下行:vlan.100
100
DE:AD:BE:EF:CA:FE 100
也就是说,只有 VLAN ID 对 重要hostapd
,而 VLAN 名称则不重要。