iptables:
*nat
-A PREROUTING -d 10.100.0.220/32 -p tcp -m tcp --dport 80 -j ACCEPT
-A PREROUTING -p tcp -m tcp --dport 80 -m set ! --match-set mac-allowed src -j DNAT --to-destination 10.100.0.220
*filter
-A FORWARD -i vlan1+ -j macallowed
-A macallowed -d DNS-сервер -p udp -m udp --dport 53 -j ACCEPT
-A macallowed -m set --match-set mac-allowed src -j ACCEPT
-A macallowed -j DROP
ipset:
create mac-allowed hash:mac hashsize 1024 maxelem 65536
add mac-allowed A0:4E:A7:55:44:33
Примерно так.
В nat prerouting трафик не из ipset разрешенных MAC-адресов заворачивается на хост с порталом.
И на портале надо в заголовке указать код 511, чтобы captive portal detection понимал, что это песочница и сам
открывал окно для дополнительных действий для подключения( хотя это не точно):
header('HTTP/1.1 511 Network Authentication Required', TRUE, 511);
header("Location: http://10.100.0.220/portal/index.php?step=1");
PS. Можно обойтись и без ipset, но с ним быстрее, когда записей станет много.