помогли на LOR и fido7.ru.linux:
------------
man dhcp-eval несколько прояснил ситуацию, но не до конца.
В общем, задавать ловлю MAC можно вот так
class "blocked-macs"
{
match if pick-first-value (option dhcp-client-identifier, hardware) = 1:11:22:33:44:55:66;
}
(правило сработает по первому встреченному совпадению ClientID или MAC addr)
или так
class "blocked-macs"
{
match if hardware = 1:11:22:33:44:55:66;
}
Но так и не получилось построить конструкцию из ловли нескольких MAC-адресов в одном классе, нечто вроде этого:
class "blocked-macs"
{
match if hardware = 1:11:22:33:44:55:10
elsif hardware = 1:11:22:33:44:55:20
elsif hardware = 1:11:22:33:44:55:30;
}
dhcpd ругается на неверный синтаксис, то ему требуется точка с запятой после строчки (при поставлении который он начинает ожидать "expecting a parameter or declaration"). Различные модификации синтаксиса не помогли (правда я не долго разбирался).
Так как в man dhcpd.conf рекомендуют использовать конструкцию subclass-ов для ускорения поиска совпадений, вернулся к ней, т.е. тому, что и предложил spirit:
class "blocked-macs"
{
match pick-first-value (option dhcp-client-identifier, hardware);
}
subclass "blocked-macs" 1:11:22:33:44:55:10;
subclass "blocked-macs" 1:11:22:33:44:55:20;
subclass "blocked-macs" 1:11:22:33:44:55:30;
Единичка в начале MAC-адреса задает тип интерфейса (ethernet)
(из man dhcp-eval)
The hardware operator returns a data string whose first element is the type of network interface indicated in packet being considered, and whose subsequent elements are client's link-layer address. If there is no packet, or if the RFC2131 hlen field is invalid, then
the result is null. Hardware types include ethernet (1) <...>
2jackill: я пробовал в правилах iptables задавать только MAC (и более никаких других фильтров), это не помогает, вне зависимости от того, в какой цепочке или таблице это правило было (в т.ч. и в -t mangle PREROUTING)
Вот развернутое объяснение от Eugene B. Berdnikov, почему не срабатывает iptables (тоже самое, что сказал mky, только более развернуто):
-------------
Таким образом, dhcp-сервер должен уметь получать "сырой" пакет вместе с изернетовским хедером. Очевидно, API сокетов IPv4 этого дать не может, просто потому что он относится к другому уровню стэка протоколов. Следовательно, эта информация может быть добыта лишь в обход IP-стэка. Стандартный способ в линуксе - через PF_PACKET. Пакеты, вычитываемые таким образом, попадают в программу ДО пакетного фильтра (поэтому, например, их видят tcpdump и вообще все pcap-based снифферы). То, что пакетник сработает потом - на результат повлиять уже не может.
-------------
------------