Биллинговая система Nodeny
14 Мая 2024, 01:43:58 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
Новости: Прекращена поддержка версии Nodeny 49
 
   Начало   Помощь Поиск Войти Регистрация  
Страниц: [1] 2 3 4
  Печать  
Автор Тема: mikrotik+dhcp+динамика+radius+много вланов  (Прочитано 15333 раз)
Cell
NoDeny
Спец
*

Карма: 52
Offline Offline

Сообщений: 1407



Просмотр профиля
« : 19 Января 2017, 12:13:14 »

Сабж темы заслуживает внимания т.к. данная связка описана в разных местах и с разными допущениями и требует довольно долгого курения всяких процедур, чтобы понять что именно необходимо, поэтому собираю все до кучи в этой теме.
Если кто-то хочет вникать самостоятельно, то вот ссылки для облегчения поисков:
http://forum.nodeny.com.ua/index.php?topic=2703.75
http://forum.nodeny.com.ua/index.php?topic=2374.0
http://nodeny.com.ua/wiki/index.php/Dhcp%2BRadius
Итак. Что мы имеем? При нескольких вланах, обслуживаемых одним микротиком настройка ДХЦП сводится к поднятию и настройке DHCP сервера для каждого из вланов (со своим интерфейсом, пулом и т.п.) Тут самое важное понимать, что ДХЦП сервер  микротика присылает запрос на радиус-сервер с радиус-атрибутом Called-Station-Id равным параметру Name в настройках дхцп микротика.

Раз мы все это поняли, то остается передавать в биллиг этот параметр и пометить необходимые динамические пулы тегом равным параметру Name (имени) дхцп для каждого из вланов.

Даллее  sql.conf необходимо внести изменения чтобы было так:

Код:
        authorize_check_query = "call radcheck('%{User-Name}')"
        authorize_reply_query = "call radreply('%{User-Name}', '%{Called-Station-Id}')"
        postauth_query = "call radupdate('%{User-Name}','%{reply:Framed-IP-Address}','nas=%{NAS-IP-Address}', '%{Called-Station-Id}')"
        accounting_update_query = "call radupdate('%{User-Name}','%{Framed-IP-Address}','nas=%{NAS-IP-Address}', '%{Called-Station-Id}')"
Не забыть ребутнуть после этого радиус-сервер.

Ну  и внести в базу данных изменения в процедуры и функции:

Цитировать
DROP FUNCTION IF EXISTS `get_ip_by_tag`;
DELIMITER $$
CREATE FUNCTION `get_ip_by_tag` ( user_id INTEGER UNSIGNED, tag VARCHAR(64) )
    RETURNS VARCHAR(15) NO SQL
BEGIN
    DECLARE user_ip VARCHAR(15);
    DECLARE real_ip VARCHAR(15);

    SELECT 1 INTO real_ip FROM users_services WHERE uid = user_id AND tags LIKE '%,realip,%';
    UPDATE ip_pool SET uid = user_id, `release` = UNIX_TIMESTAMP() + 300
        WHERE (uid = 0 OR uid = user_id)
            AND type = 'dynamic'
            AND realip = IF(real_ip>0,1,0)
            AND tags LIKE CONCAT('%,', tag, ',%')
        ORDER BY uid DESC, id ASC LIMIT 1;

    SELECT INET_NTOA(ip) INTO user_ip FROM ip_pool
        WHERE uid = user_id LIMIT 1;
    RETURN user_ip;
END$$
DELIMITER ;


DROP PROCEDURE IF EXISTS `radreply`;
DELIMITER $$
CREATE PROCEDURE `radreply`(IN login VARCHAR(64), tag VARCHAR(64))
    BEGIN
    DECLARE usr_mac VARCHAR(12);
    DECLARE usr_ip VARCHAR(15);
    DECLARE usr_id INT;
    DECLARE add_attr MEDIUMTEXT;
    DECLARE line MEDIUMTEXT;
    DECLARE i INT DEFAULT 1;
    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_by_tag(usr_id, tag) 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
        START TRANSACTION;
            SELECT INET_NTOA(ip) INTO usr_ip FROM ip_pool p WHERE uid=0 AND type='dynamic' AND tags  LIKE CONCAT('%,', tag ,',%')
            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), IN tag VARCHAR(64))
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 ;

Проверяем следующим образом:

SELECT get_ip_by_tag(id_абонента,'тэг_dhcp_пула');
CALL radreply('11:22:33:44:55:66', 'тэг_dhcp_пула');

Если ошибок нет, то все сделано правильно.
Записан
fet4
Старожил
****

Карма: 2
Offline Offline

Сообщений: 324


Просмотр профиля Email
« Ответ #1 : 19 Января 2017, 13:01:15 »

Какой смысл авторизовывать по маку клиента?
Записан
Cell
NoDeny
Спец
*

Карма: 52
Offline Offline

Сообщений: 1407



Просмотр профиля
« Ответ #2 : 19 Января 2017, 16:39:30 »

Какой смысл авторизовывать по маку клиента?
прибор? 20! Что 20? А что прибор?
Записан
fet4
Старожил
****

Карма: 2
Offline Offline

Сообщений: 324


Просмотр профиля Email
« Ответ #3 : 19 Января 2017, 17:37:29 »

Какой смысл авторизовывать по маку клиента?
прибор? 20! Что 20? А что прибор?
микротик? а что такое микротик?
Записан
Cell
NoDeny
Спец
*

Карма: 52
Offline Offline

Сообщений: 1407



Просмотр профиля
« Ответ #4 : 19 Января 2017, 22:48:32 »

Дружище, микротик - это такой же nas как твой аксель любимый, только со своими прибабахами, отличными от других. Не то чтобы мне там сильно нравилась его RouterOS но появившиеся не так давно железяки с ней на борту а особенно соотношение их цены/качества заставляют меня обращать на них свое внимание. В данном конкретном случае рассматривается схема авторизации абонентов по дхцп при помощи радиуса и динамических ip пулов биллинга. Есть что сказать, дополнить - говори.
Записан
fet4
Старожил
****

Карма: 2
Offline Offline

Сообщений: 324


Просмотр профиля Email
« Ответ #5 : 20 Января 2017, 11:59:21 »

Дружище, если ты не понял это был стеб, как и в твоем предыдущем посте, я знаю что такое микротик.
Мне просто интересна эта схема дхцп+радиус и я ее реализовал так же, только на акселе с динамикой и застрял на том что я не могу прикрутить к ней еще опцию82, так как без нее смысла нет в этой схеме, тем более если клиенты по опции82 уже работают только через обычный модуль дхцп.

Потому я и задал вопрос.
Какой смысл авторизовывать по маку клиента в данной схеме?
Записан
Efendy
Администратор
Спец
*****

Карма: 138
Offline Offline

Сообщений: 4782



Просмотр профиля
« Ответ #6 : 20 Января 2017, 13:01:51 »

Кстати, get_ip иногда приводила к дедлокам, мускул иногда на простых запросах чудит, пришлось переделать ее, так что тоже самое надо сделать и для get_ip_by_tag,  типа такого:
Код:
UPDATE ip_pool SET uid = user_id, `release` = UNIX_TIMESTAMP() + 300
    WHERE id = (SELECT id FROM (
        (
          SELECT id, uid FROM ip_pool
          WHERE uid = 0 AND type = 'dynamic' AND realip = IF(real_ip>0,1,0)
          AND tags LIKE CONCAT('%,', tag, ',%')
          LIMIT 1
        ) UNION (
         SELECT id, uid FROM ip_pool
          WHERE uid = user_id AND type = 'dynamic' AND realip = IF(real_ip>0,1,0)
          AND tags LIKE CONCAT('%,', tag, ',%')
          LIMIT 1
        )
    ) AS tbl ORDER BY uid DESC LIMIT 1);

И в radupdate параметр tag не используется у тебя.

И, походу у себя мелкий косяк заметил: в REPLACE(properties,':','') надо не двоеточие, а точку с запятой - это защита от того, что в параметре появится разделитель в виде точки запятой
Записан
Cell
NoDeny
Спец
*

Карма: 52
Offline Offline

Сообщений: 1407



Просмотр профиля
« Ответ #7 : 20 Января 2017, 14:26:24 »

Проверю как работает и исправлю в описании.
Записан
k291
Старожил
****

Карма: -10
Offline Offline

Сообщений: 455


Просмотр профиля
« Ответ #8 : 20 Января 2017, 22:41:20 »

С конфигом из первого поста, на первый взглад, работает все как надо. Mikrotik выдает IP из нужного pool`а согласно тегу в билинге в нужном pool`е и названию DHCP сервера в Mikrotik`е.
Из замеченного:
Если в Mikrotik`е /ip dhcp-server add disabled=no interface=ether1 name=dhcp_15(соответственно в билинге в нужном pool`е ТЕГ=dhcp_15), клиент получает IP 10.0.15...
Код:
mysql> SELECT *, INET_NTOA(ip) FROM mac_uid;
+----+--------------+-----------+-----+------------+------------+-------------+------------+---------------+
| id | mac          | ip        | uid | time       | device_mac | device_port | oneconnect | INET_NTOA(ip) |
+----+--------------+-----------+-----+------------+------------+-------------+------------+---------------+
|  1 | 005533007766 | 167776091 |   0 | 1484942137 | 0          |           0 |          0 | 10.0.15.91    |
+----+--------------+-----------+-----+------------+------------+-------------+------------+---------------+
Если потом сменить название DHCP на /ip dhcp-server add disabled=no interface=ether1 name=dhcp_1,
то IP из нового назначенного pool`а не выдается, а остается тот что прописан в БД(10.0.15.91).
Записан
Cell
NoDeny
Спец
*

Карма: 52
Offline Offline

Сообщений: 1407



Просмотр профиля
« Ответ #9 : 20 Января 2017, 23:33:45 »

Это нормально. Этот ип минут через 5 удаляется ядром и все начинает фунциклировать как надо.
Записан
Efendy
Администратор
Спец
*****

Карма: 138
Offline Offline

Сообщений: 4782



Просмотр профиля
« Ответ #10 : 21 Января 2017, 00:23:27 »

По идее можно изменить в get_ip_by_tag:

Код:
    SELECT INET_NTOA(ip) INTO user_ip FROM ip_pool
        WHERE uid = user_id LIMIT 1;

на

Код:
    SELECT INET_NTOA(ip) INTO user_ip FROM ip_pool
        WHERE uid = user_id AND tags LIKE CONCAT('%,', tag, ',%') LIMIT 1;
Записан
k291
Старожил
****

Карма: -10
Offline Offline

Сообщений: 455


Просмотр профиля
« Ответ #11 : 21 Января 2017, 00:39:09 »

Хочу выдать клиенту реальный IP из pool`а 217.55.66.240/28

1) Создал pool.
В личном кабинете, статически назначаю адрес 217.55.66.251
2) В Mikrotik`е:
/ip firewall nat add chain=dstnat dst-address=217.55.66.240/28 action=netmap to-addresses=10.0.1.2-10.0.1.254
/ip firewall nat add chain=srcnat src-address=10.0.1.2/24 action=netmap to-addresses=217.55.66.240/28
Добавил второй шлюз 217.55.66.240 к 10.0.1.1()

Mikrotik назначает новый адрес, но с маской /24 вместо /28
Чтото надо в процедуре изменить?
Записан
k291
Старожил
****

Карма: -10
Offline Offline

Сообщений: 455


Просмотр профиля
« Ответ #12 : 21 Января 2017, 01:02:54 »

По идее можно изменить в get_ip_by_tag:

Код:
    SELECT INET_NTOA(ip) INTO user_ip FROM ip_pool
        WHERE uid = user_id LIMIT 1;

на

Код:
    SELECT INET_NTOA(ip) INTO user_ip FROM ip_pool
        WHERE uid = user_id AND tags LIKE CONCAT('%,', tag, ',%') LIMIT 1;

Работает! Автоматически обновляет адрес в течении 5-ти минут. Или после перезагрузки компа клиента.
Записан
Cell
NoDeny
Спец
*

Карма: 52
Offline Offline

Сообщений: 1407



Просмотр профиля
« Ответ #13 : 21 Января 2017, 10:12:35 »

Mikrotik назначает новый адрес, но с маской /24 вместо /28
Чтото надо в процедуре изменить?
добавить реальный пул в дхцп и описать сеть соотв. образом.
Записан
Cell
NoDeny
Спец
*

Карма: 52
Offline Offline

Сообщений: 1407



Просмотр профиля
« Ответ #14 : 21 Января 2017, 15:22:47 »

К сожалению не могу изменить первый пост т.к. нет прав на это, поэтому пишу здесь, может модератор перенесет.
В результате последних тестирований дополнений и обновлений конфигурация выглядит следующим образом:
sql.conf

Цитировать
        authorize_check_query = "call radcheck('%{User-Name}')"
        authorize_reply_query = "call radreply('%{User-Name}', '%{Called-Station-Id}')"
        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}')"

Измененные функции и процедуры по сравнению с документацией:
Цитировать
DROP FUNCTION IF EXISTS `get_ip_by_tag`;
DELIMITER $$
CREATE FUNCTION `get_ip_by_tag` ( user_id INTEGER UNSIGNED, tag VARCHAR(64) )
    RETURNS VARCHAR(15) NO SQL
BEGIN
    DECLARE user_ip VARCHAR(15);
    DECLARE real_ip VARCHAR(15);

    SELECT 1 INTO real_ip FROM users_services WHERE uid = user_id AND tags LIKE '%,realip,%';
    UPDATE ip_pool SET uid = user_id, `release` = UNIX_TIMESTAMP() + 300
    WHERE id = (SELECT id FROM (
        (
          SELECT id, uid FROM ip_pool
          WHERE uid = 0 AND type = 'dynamic' AND realip = IF(real_ip>0,1,0)
          AND tags LIKE CONCAT('%,', tag, ',%')
          LIMIT 1
        ) UNION (
         SELECT id, uid FROM ip_pool
          WHERE uid = user_id AND type = 'dynamic' AND realip = IF(real_ip>0,1,0)
          AND tags LIKE CONCAT('%,', tag, ',%')
          LIMIT 1
        )
    ) AS tbl ORDER BY uid DESC LIMIT 1);
        SELECT INET_NTOA(ip) INTO user_ip FROM ip_pool
        WHERE uid = user_id AND tags LIKE CONCAT('%,', tag, ',%') LIMIT 1;
    RETURN user_ip;
END$$
DELIMITER ;



DROP PROCEDURE IF EXISTS `radreply`;
DELIMITER $$
CREATE PROCEDURE `radreply`(IN login VARCHAR(64), tag VARCHAR(64))
    BEGIN
    DECLARE usr_mac VARCHAR(12);
    DECLARE usr_ip VARCHAR(15);
    DECLARE usr_id INT;
    DECLARE add_attr MEDIUMTEXT;
    DECLARE line MEDIUMTEXT;
    DECLARE i INT DEFAULT 1;
    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_by_tag(usr_id, tag) 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
        START TRANSACTION;
            SELECT INET_NTOA(ip) INTO usr_ip FROM ip_pool p WHERE uid=0 AND type='dynamic' AND tags  LIKE CONCAT('%,', tag ,',%')
            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 ;

Да, и модуль dhcp все-таки включать надо! Без него авторизация через 150 секунд идет курить.
Записан
Страниц: [1] 2 3 4
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.20 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!