NoDeny+ предоставляет 2 принципиально разных варианта работы Dhcp-модуля:
Если вы не можете определиться какой из вариантов использовать - рекомендуем без Radius - он проще в настройке. Прицип работы обоих вариантов:
Комментарий по Option 82:
Без использования управляемого оборудования, dhcp не достаточно безопасно т.к. злоумышленник может подделать мак-адрес. Option 82 заставляет свичи информировать dhcp-сервер о том, с какого свича и какого порта пришел запрос. Поэтому подделка мака не приведет к успеху, поскольку мак свича и номер порта, злоумышленник не сможет подделать (если он подключен к свичу с option 82, естественно).
cd /usr/ports/net/isc-dhcp42-server make install clean
#echo dhcpd_enable=YES >> /etc/rc.conf echo /usr/local/etc/rc.d/isc-dhcpd forcestart >> /etc/rc.local echo dhcpd_withuser=root >> /etc/rc.conf echo '!dhcpd' >> /etc/syslog.conf echo 'local7.* /var/log/dhcpd.log' >> /etc/syslog.conf touch /var/log/dhcpd.log killall -HUP syslogd
log-facility local7; option domain-name-servers 1.1.1.1; subnet 10.100.0.0 netmask 255.255.0.0 { range 10.100.64.0 10.100.80.255; interface igb0; option routers 10.100.0.1; default-lease-time 2400; max-lease-time 1800; on commit { set ClientIP = binary-to-ascii(10, 8, ".", leased-address); set ClientMac = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6)); set SwitchMac = ""; set SwitchPort =""; if exists agent.circuit-id { set SwitchMac = binary-to-ascii(16, 8, ":", suffix(option agent.remote-id, 6)); set SwitchPort = binary-to-ascii(10, 8, ":", suffix(option agent.circuit-id, 1)); } execute("/usr/bin/perl", "/usr/local/nodeny/modules/dhcp/events.pl", "commit", ClientIP, ClientMac, SwitchMac, SwitchPort); } on expiry { set ClientIP = binary-to-ascii(10, 8, ".", leased-address); execute("/usr/bin/perl", "/usr/local/nodeny/modules/dhcp/events.pl", "expiry", ClientIP); } on release { set ClientIP = binary-to-ascii(10, 8, ".", leased-address); execute("/usr/bin/perl", "/usr/local/nodeny/modules/dhcp/events.pl", "release", ClientIP); } }
В админке NoDeny в настройках в разделе «ip pool» создаем ту же сеть, какая указана в конфиге в параметре range, при этом тип ip должен быть «динамический».
В разделе «Кабинет клиента» добавляем модуль dhcp.
Для версий FreeBSD < 10 компилируем ядро сервера с опцией «options IPFIREWALL_FORWARD»
$forward_enabled = 1;
kill -9 `ps axu | grep noserver | grep -v grep | awk '{ print $2 }'` perl /usr/local/nodeny/noserver.pl -d &
ipfw show | grep fwd
ipfw add 65534 fwd 127.0.0.1,8080 tcp from any to any 80
Если ошибка - ядро не скомпилировалось с опцией форварда, может забыли ребутнуть сервер после перекомпиляции?
Если web-заглушка (модуль cap) не запускается по умолчанию, то либо в ее конфиге ставим параметр run => 1 либо (рекомендуется) запускаем отдельным процессом (и ставим автозапуск в /etc/rc.local):
/usr/bin/perl /usr/local/nodeny/nokernel.pl -m=cap -d &
Также запускаем модуль dhcp, но его не обязательно запускать отдельным процессом как в примере:
/usr/bin/perl /usr/local/nodeny/nokernel.pl -m=dhcp -d &
/usr/local/etc/rc.d/isc-dhcpd forcestart tail -f /usr/local/nodeny/logs/dhcp.events.log
Включаем клиентский компьютер и убеждаемся, что он получил ip по dhcp.
[commit] ip=10.100.65.98, mac=0:1d:2a:ff:22:88, mac_ok=001d2aff2288 | Необходима регистрация мака
Это означает, что клиенту выдан ip, но мак пока не известен NoDeny. Если есть желание (или у вас что-то не получается), вы можете посмотреть в БД таблицу mac_uid - там будет зарегистрирован данный мак, ip, время, а uid = 0:
SELECT *, INET_NTOA(ip) FROM mac_uid;
Если с клиентского компьютера открыть любую страницу, то запрос будет перехвачен заглушкой и выведено сообщение, что необходимо ввести логин и пароль. После их ввода, мак адрес должен быть привязан к id клиента - это можно проверить той же mysql командой, указанной выше.
Вы должны ввести логин и пароль не позднее чем через 10 минут от момента получения ip - это защита от ситуации, когда кто-то вручную пропишет ip и попытается его зарегистрировать.
В настройках админки в разделе «клиентская статистика» добавляем модуль dhcp.
тип: динамические теги: guest
Это гостевые ip, с которых нельзя будет получить интернет. Количество ip должно превышать в несколько раз число устройств в сети, поскольку для каждого нового мак-адреса выделяется свой персональный гостевой ip (предусмотрено удаление старых записей, но запас должен быть).
Устанавливаем Radius (останавливаемся на создании mysql-процедур). Создаем:
DROP PROCEDURE IF EXISTS `radreply`; DELIMITER $$ CREATE PROCEDURE `radreply`(IN login VARCHAR(64)) BEGIN DECLARE usr_ip VARCHAR(15) DEFAULT NULL; INSERT INTO mac_uid ( SELECT NULL, login, p.ip, 0, UNIX_TIMESTAMP(), 0, 0 ,0 FROM ip_pool p WHERE uid=0 AND tags LIKE '%,guest,%' AND NOT EXISTS (SELECT ip FROM mac_uid WHERE ip=p.ip) LIMIT 1) ON DUPLICATE KEY UPDATE time=UNIX_TIMESTAMP(); SELECT INET_NTOA(ip) INTO usr_ip FROM mac_uid WHERE mac=login; IF usr_ip IS NULL THEN DELETE FROM mac_uid WHERE uid=0 AND time<(UNIX_TIMESTAMP()-3600); END IF; SELECT NULL, login, 'Framed-IP-Address', usr_ip, '='; END$$ DELIMITER ; DROP PROCEDURE IF EXISTS `radupdate`; DELIMITER $$ CREATE PROCEDURE `radupdate`(IN login VARCHAR(64), IN ip VARCHAR(16), IN properties VARCHAR(255)) BEGIN CALL set_auth(ip, CONCAT('mod=dhcp;',REPLACE(properties,':',''))); END$$ DELIMITER ;
Проверим:
call radreply('123'); select mac, inet_ntoa(ip) as ip, uid, time from mac_uid;
+------+----------+-----+------------+ | mac | ip | uid | time | +------+----------+-----+------------+ | 123 | 10.0.0.2 | 0 | 1403783705 | +------+----------+-----+------------+
Здесь 10.0.0.2 - один из гостевых ip. При повторном выполнении call radreply('123') мы должны получать этот же ip, при этом должно изменяться поле time.
ee /usr/local/etc/raddb/sql.conf
Cтроку: authorize_reply_query = "call radreply('%{User-Name}')" меняем на
authorize_check_query = "SELECT NULL,'%{User-Name}','Auth-Type','Accept','='"
Заметим, что User-Name - это не логин пользователя, а мак-адрес. Например в accel-ppp можно получить так:
function username(pkt) local interface = string.gsub(pkt:ifname(),'(eth%d+)%.(%d+)%.(%d+)$','%2-%3') local mac = string.gsub(pkt:hdr("chaddr"),':','') local username=mac..':'..string.gsub(interface,'-$','') print(username) return username end
Здесь мы логин представили в виде мак:интерфейс.
В конфиге модуля dhcp меняем параметр run => 0 - этим мы отключили его запуск, поскольку он был предназначен для поддержания авторизации, а в случае Radius - он занимается этим.
Настраиваем NoDeny загрушку как это описано выше для работы с isc dhcpd.
Тестируем. Включаем клиентский компьютер и убеждаемся, что он получил гостевой ip по dhcp. Разлогиниваемся в админке, если до этого были в ней залогинены с тестируемого компьютера. Открываем в браузере любой url и попадаем на заглушку. После ввода логина и пароля должны получить сообщение, что компьютер зарегистрирован в системе. Необходимо получить новый не гостевой адрес (вкл/выкл соединение или передернуть кабель).