Dhcp+Radius

Матеріал з NoDeny
Перейти до навігації Перейти до пошуку

Для работы по dhcp необходим модуль dhcp, который нужно приобрести дополнительно на главном сайте NoDeny. При использовании dhcp нам доступен механизм регистрации клиентского оборудования. Если мак-адрес компьютера абонента не известен - при открытии браузером любой страницы будет отображено окно с вводом логина и пароля, после заполнения которой, произойдет регистрация мака и в дальнейшей работе логин и пароль запрашиваться не будут пока пользователь не сменить свое оборудование (сетевую карту, роутер и т.д).

  • В админке NoDeny создадим пул ip адресов в количестве раз в 5-10 большим чем предполагаемое количество абонентов. Тип ip обязательно должен быть "динамический".
  • С главного сайта NoDeny скачаем модуль dhcp и установим его: perl install.pl -x

Установка Radius

Поскольку понадобится radius с модулем mysql, установим его не из бинарных пакетов (pkg install freeradius), а из портов:

cd /usr/ports/net/freeradius2 && make install clean

Обязательно поставим галку напротив опции MYSQL

rm /usr/local/etc/raddb/sites-enabled/default 
ee /usr/local/etc/raddb/sites-enabled/nodeny

Вставляем следующий текст:

authorize {
        sql
}
authenticate {
        Auth-Type PAP {
                pap
        }
}
preacct {
        acct_unique
        preprocess
}
accounting {
        detail
        sql
        exec
}
session {
        radutmp
        sql
}
post-auth {
        sql
}


cp /usr/local/nodeny/etc/raddb/* /usr/local/etc/raddb/
echo radiusd_enable=YES >> /etc/rc.conf
ee /usr/local/etc/raddb/radiusd.conf

Раскомментируем строку (найти проще всего так: ctrl+y, затем текст "sql.conf", затем enter):

$INCLUDE sql.conf
ee /usr/local/etc/raddb/sql.conf

Изменим postauth_query и accounting_update_query:

        postauth_query = "call radupdate('%{User-Name}','%{reply:Framed-IP-Address}',\
                'nas=%{NAS-IP-Address}')"
        accounting_update_query = "call radupdate('%{User-Name}','%{Framed-IP-Address}',\
                'nas=%{NAS-IP-Address}')"}

Mysql процедуры

ALTER DATABASE nodeny CHARACTER SET utf8 COLLATE utf8_general_ci;
DROP PROCEDURE IF EXISTS `radcheck`;
DELIMITER $$
CREATE PROCEDURE `radcheck` (IN login VARCHAR(64))
BEGIN
  SELECT Null, login, 'Cleartext-Password' AS Attribute, '' AS Value,':=';
END$$
DELIMITER ;
DROP PROCEDURE IF EXISTS `radreply`;
DELIMITER $$
CREATE PROCEDURE `radreply`(IN login VARCHAR(64))
BEGIN
    DECLARE usr_mac VARCHAR(12);
    DECLARE usr_ip VARCHAR(15);
    DECLARE usr_id INT;
    SELECT REPLACE(login, ':', '') INTO usr_mac;
    SELECT uid INTO usr_id FROM mac_uid WHERE mac=usr_mac;
    IF usr_id IS NOT NULL AND usr_id>0 THEN
        SELECT get_ip(usr_id) INTO usr_ip;
        UPDATE mac_uid SET ip=0 WHERE ip=INET_ATON(usr_ip) AND uid<>usr_id;
        UPDATE mac_uid SET ip=INET_ATON(usr_ip), time=UNIX_TIMESTAMP() WHERE uid=usr_id;
    ELSE
        UPDATE mac_uid SET ip=0 WHERE uid=0 AND time<(UNIX_TIMESTAMP()-3600);
        START TRANSACTION;
        SELECT INET_NTOA(ip) INTO usr_ip FROM ip_pool p WHERE uid=0 AND type='dynamic'
            AND NOT EXISTS (SELECT ip FROM mac_uid WHERE ip=p.ip)
            ORDER BY RAND() LIMIT 1 FOR UPDATE;
        INSERT INTO mac_uid VALUES(
            NULL, usr_mac, INET_ATON(usr_ip), 0, UNIX_TIMESTAMP(), 0, 0, 0)
        ON DUPLICATE KEY
            UPDATE ip=IF(ip>0,ip,INET_ATON(usr_ip)), time=UNIX_TIMESTAMP();
        COMMIT;
        SELECT INET_NTOA(ip) INTO usr_ip FROM mac_uid WHERE mac=usr_mac;
    END IF;
    SELECT NULL, login, 'Framed-IP-Address', usr_ip, '=';
    SELECT NULL, login, 'Session-Timeout', '600', '=';
END$$
DELIMITER ;
DROP PROCEDURE IF EXISTS `radupdate`;
DELIMITER $$
CREATE PROCEDURE `radupdate`(
    IN login VARCHAR(64), IN ipa VARCHAR(16), IN properties VARCHAR(255))
BEGIN
    DECLARE usr_mac VARCHAR(16);
    SELECT REPLACE(login, ':', '') INTO usr_mac;
    CALL set_auth(ipa, CONCAT('mod=dhcp;user=', usr_mac, ';', REPLACE(properties,':','')));
    UPDATE mac_uid SET time=UNIX_TIMESTAMP() WHERE ip=INET_ATON(ipa) LIMIT 1;
END$$
DELIMITER ;

Проверим:

CALL radreply('00:11:22:33:44:55');
Если получаем ошибку:
  • ERROR 1146 (42S02): Table 'nodeny.mac_uid' doesn't exist - не установлен модуль dhcp
  • ERROR 1048 (23000): Column 'ip' cannot be null - забыли создать пул ip адресов типа "динамический"
  • ERROR 1267 (HY000): Illegal mix of collations (utf8_general_ci,IMPLICIT) and (utf8_unicode_ci,IMPLICIT) for operation '=' - выполним:
ALTER DATABASE nodeny CHARACTER SET utf8 COLLATE utf8_general_ci;

и пересоздаем процедуры

Запускам Radius

/usr/local/etc/rc.d/radiusd start

Проверяем:

radtest 00:11:22:33:44:55 '' 127.0.0.1 0 hardpass5

Если получаем ошибку radclient:: Failed to find IP address for имя_нашего_сервера - в /etc/hosts не прописано имя нашего сервера.

Должны получить примерно такой ответ:

rad_recv: Access-Reject packet from host 127.0.0.1 port 1812, id=63, length=38
	Framed-IP-Address = 10.0.4.175
	Session-Timeout = 600
	Acct-Interim-Interval = 60

В ином случае тушим radius и запускаем в режиме детального вывода:

/usr/local/etc/rc.d/radiusd stop
radiusd -X

Продолжаем настройку. Добавим микротик (1.1.1.1) в настройки радиуса:

ee /usr/local/etc/raddb/clients.conf

Добавляем:

client 1.1.1.1 {
        secret      = hardpass5
        shortname   = Mikrotik
        nastype     = cisco
}

Проверим, что модуль dhcp запускается при старте nokernel:

cd /usr/local/nodeny
perl nokernel.pl -L

Обратите внимание, что после установки модуля dhcp необходимо перезапустить nokernel.

Включаем тестовый компьютер как абонента, подключенного к микротику. Должны получить ip адрес из пула динамических адресов NoDeny. Поскольку мак-адрес тестового компьютера не известен NoDeny, выданный ip нигде не будет фигурировать (на самом деле он появится в таблице mac_uid). Привязку мака к учетной записи выполняется через веб-заглушку, которую мы настроим позже.