Биллинговая система Nodeny
29 Апреля 2024, 06:10:22 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
Новости: Прекращена поддержка версии Nodeny 49
 
   Начало   Помощь Поиск Войти Регистрация  
Страниц: [1] 2
  Печать  
Автор Тема: Теги в пуле ip адресов. Показываю  (Прочитано 8435 раз)
Efendy
Администратор
Спец
*****

Карма: 138
Offline Offline

Сообщений: 4782



Просмотр профиля
« : 14 Октября 2013, 14:04:03 »

Внимание. Актуальная версия: http://forum.nodeny.com.ua/index.php?topic=2919.0

Недавно я добавил теги в пул ip. Наверное мало кто понимает зачем это нужно. Тег - это метка, которая может быть у ip адреса. Сделана для того, чтобы мы в разных ситуациях могли присваивать клиенту разные ip в зависимости от метки. Например, у нас есть несколько NAS, стоящих в разных районах. Клиенты подключаются по PPPoE и получают ip динамически. Мы хотим, чтобы в зависимости от района выдавался ip из определенной подсетки. Если бы ип был статический, то можно было написать в параметрах группы, что для этой группы выдавать ip из такого-то диапазона. Но в случае динамических ip, их выдает mysql  процедура, которая не умеет выполнять такие операции (по крайней мере я боюсь писать такую громадную процедуру). Поэтому мы поступим иначе. Мы создадим процедуру выдачи ip в зависимости от тега:

Код:
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 ;


В админке, в настройке пула ip, выберем какие-нибудь ip из середины диапазона или создадим новый и присвоим им тег, скажем, '10.0.0.1' (без кавычек). Также выберем другой диапазон и установим тег в '10.1.0.1'.  Проверяем, что get_ip_by_tag работает:

Код:
SELECT get_ip_by_tag(1,'10.1.0.1')

Здесь 1 - id существующего клиента, у которого не должно быть ни одного статического ip.  В mysql меняем процедуры для радиуса:
Код:
DROP PROCEDURE IF EXISTS `radreply`;
DELIMITER $$
CREATE PROCEDURE `radreply`(IN login VARCHAR(64), tag VARCHAR(64))
BEGIN
  DECLARE usr_id INT;
  DECLARE usr_ip VARCHAR(15) DEFAULT NULL;

  SELECT id INTO usr_id FROM users WHERE name=login LIMIT 1;
  SELECT get_ip_by_tag(usr_id, tag) INTO usr_ip;

  SELECT NULL,login,'Framed-IP-Address',usr_ip,'=';
  SELECT NULL,login,'Framed-IP-Netmask','255.255.255.255','=';
  SELECT NULL,login,'Framed-Protocol','PPP','=';
END$$
DELIMITER ;


DROP PROCEDURE IF EXISTS `radupdate`;
DELIMITER $$
CREATE PROCEDURE `radupdate`(IN login VARCHAR(64), IN ip VARCHAR(16), IN properties VARCHAR(255), IN tag VARCHAR(64))
BEGIN
  DECLARE usr_id INT;
  DECLARE usr_ip VARCHAR(15) DEFAULT NULL;
  SELECT id INTO usr_id FROM users WHERE name=login LIMIT 1;
  SELECT get_ip_by_tag(usr_id, tag) INTO usr_ip;
  CALL set_auth(usr_ip, CONCAT('mod=pppoe;',REPLACE(properties,':','')));
END$$
DELIMITER ;


Меняем sql.conf радиуса:

Код:
authorize_reply_query = "call radreply('%{User-Name}', '%{NAS-IP-Address}')"
postauth_query = "call radupdate('%{User-Name}','%{Framed-IP-Address}',\
                'user=%{Calling-Station-Id};nas=%{NAS-IP-Address}', '%{NAS-IP-Address}')"
accounting_update_query = "call radupdate('%{User-Name}','%{Framed-IP-Address}',\
                'user=%{Calling-Station-Id};nas=%{NAS-IP-Address}', '%{NAS-IP-Address}')"

Теперь в зависимости от ip NAS, будет выдаваться  ip либо из одного, либо с другого диапазона (в зависимости от того, в котором будет тег 10.0.0.1 или 10.1.0.1).

Лучше, конечно, чтобы теги были не ip сервера, а, например, NAS1 или NAS2. Но тогда нужно модифицировать конфиг радиуса, чтобы он конвертил ip NAS в уловное имя NAS1 (NAS2...). Скорее всего, в параметрах к радиусу передается не тока ип NAS, но и его имя или какой-нить еще нужный параметр, тогда можно было его указать в теге. Сейчас я не имею возможности это проверить. Поэтому кому не лень - отпишитесь
« Последнее редактирование: 28 Февраля 2017, 09:01:17 от Efendy » Записан
Groov
NoDeny
Постоялец
*

Карма: -3
Offline Offline

Сообщений: 100

102196993
Просмотр профиля
« Ответ #1 : 14 Октября 2013, 16:51:56 »

А если надо что бы на всех NAS серверах эта под сеть ?
Записан
VitalVas
NoDeny
Спец
*

Карма: 60
Offline Offline

Сообщений: 991



Просмотр профиля WWW
« Ответ #2 : 16 Октября 2013, 19:24:20 »

А если надо что бы на всех NAS серверах эта под сеть ?
Поставить вместо "%{NAS-IP-Address}"  свой общий тег
Записан
SeMant
NoDeny
Старожил
*

Карма: 4
Offline Offline

Сообщений: 266



Просмотр профиля Email
« Ответ #3 : 28 Июля 2014, 07:23:51 »

 Здравствуйте! Хочу всё уточнить, так чтобы точно всё получилось.
 
Добавляю функцию get_ip_by_tag
Меняю процедуру radreply (по примеру выше) и radupdate. Кстати как должна выглядеть radupdate, а то Я тут не совсем ... ?
Код:
DROP PROCEDURE IF EXISTS `radupdate`;
DELIMITER $$
CREATE PROCEDURE `radupdate`(IN login VARCHAR(64), IN ip VARCHAR(16), IN properties VARCHAR(255), tag VARCHAR(64))
BEGIN
  DECLARE usr_id INT;
  DECLARE usr_ip VARCHAR(15) DEFAULT NULL;
  SELECT id INTO usr_id FROM users WHERE name=login LIMIT 1;
  SELECT get_ip_by_tag(usr_id, tag) INTO usr_ip;
  CALL set_auth(usr_ip, CONCAT('mod=pppoe;',REPLACE(properties,':','')));
END$$
DELIMITER ;

В sql.conf вместо
Код:
authorize_reply_query = "call radreply('%{User-Name}')"
ставлю
Код:
authorize_reply_query = "call radreply('%{User-Name}', '%{NAS-IP-Address}')"

Добавляю пулы ип адресов, а в тегах указываю ипы Насов, как в clients.conf.

Нужно ли ещё что-то и правильная ли у меня процедура radupdate ?
Записан
Efendy
Администратор
Спец
*****

Карма: 138
Offline Offline

Сообщений: 4782



Просмотр профиля
« Ответ #4 : 28 Июля 2014, 11:46:17 »

Изменил первое сообщение - добавил недостающее
Записан
SeMant
NoDeny
Старожил
*

Карма: 4
Offline Offline

Сообщений: 266



Просмотр профиля Email
« Ответ #5 : 28 Июля 2014, 12:24:01 »

 Всё сделал.
Код:
SELECT get_ip_by_tag(1,'10.1.0.1')
Ипы из пула выдаёт правильно.
 В админке не показывает авторизованых и пропадает инет.
 Что не так ?
Записан
Efendy
Администратор
Спец
*****

Карма: 138
Offline Offline

Сообщений: 4782



Просмотр профиля
« Ответ #6 : 28 Июля 2014, 13:00:45 »

что выдает
Код:
CALL radreply('логин клиента', 'ip сервера');

не возвращает ли ошибку:
Код:
CALL radupdate('логин клиента', 'ip клиента', '', 'ip сервера');

если запустить radiusd -X выдает ошибки?
Записан
SeMant
NoDeny
Старожил
*

Карма: 4
Offline Offline

Сообщений: 266



Просмотр профиля Email
« Ответ #7 : 28 Июля 2014, 22:27:44 »

что выдает
Код:
CALL radreply('логин клиента', 'ip сервера');

не возвращает ли ошибку:
Код:
CALL radupdate('логин клиента', 'ip клиента', '', 'ip сервера');

если запустить radiusd -X выдает ошибки?
Я тупанул в sql.conf. Все авторизовываются, сесии не рвутся. Вот только авторизованым ипы по Насам не выдаёт, всё по порядку или 127.0.0.2.
Функцию get_ip_by_tag взял, как ты говорил, с forum.nodeny.com.ua/index.php?topic=2491.msg25814#msg25814. К стати пробовал функцию с этой темы, почему-то всем у кого статический реальный ип вешает ещё и динамический вторым.
На radiusd -X выдаёт из ошибок только
Код:
Failed binding to authentication address * port 1812: Address already in use
/usr/local/etc/raddb/radiusd.conf[240]: Error binding to port for 0.0.0.0 port 1812
Записан
0xbad0c0d3
гуру nodeny )
NoDeny
Спец
*

Карма: 116
Offline Offline

Сообщений: 1059



Просмотр профиля
« Ответ #8 : 28 Июля 2014, 23:06:18 »

Ну наверно нужно стопнуть уже запущеный радиус... А вообще, откройте для себя radmin, radsniff - полезно для дебага в боевых условиях, только нужно в radiusd.conf добавить или разрешить инклюд sites-available/control-socket
Код:
listen {
    type = control
    socket = "/var/run/radiusd/radiusd.sock"
    mode = rw
}
Записан
fet4
Старожил
****

Карма: 2
Offline Offline

Сообщений: 324


Просмотр профиля Email
« Ответ #9 : 06 Декабря 2016, 23:33:17 »

Ребят может кто изменял процедуры radreply и radupdate под dhcp поделитесь пожалуйста.
На сколько я понял меняется в них
Код:
SELECT get_ip(usr_id) INTO usr_ip;
на
Код:
SELECT get_ip_by_tag(usr_id, tag) INTO usr_ip;

И добавляется переменная tag VARCHAR(64).

Пытаюсь отредактировать процедуры с h__p://nodeny.com.ua:8080/wiki/index.php/Dhcp%2BRadius но что-то не получается, хотя функция get_ip_by_tag работает.
Подскажите что еще нужно менять.
Записан
Pa4ka
Старожил
****

Карма: 4
Offline Offline

Сообщений: 281

591884591
Просмотр профиля Email
« Ответ #10 : 07 Декабря 2016, 09:14:59 »

Ребят может кто изменял процедуры radreply и radupdate под dhcp поделитесь пожалуйста.
На сколько я понял меняется в них
Код:
SELECT get_ip(usr_id) INTO usr_ip;
на
Код:
SELECT get_ip_by_tag(usr_id, tag) INTO usr_ip;

И добавляется переменная tag VARCHAR(64).

Пытаюсь отредактировать процедуры с h__p://nodeny.com.ua:8080/wiki/index.php/Dhcp%2BRadius но что-то не получается, хотя функция get_ip_by_tag работает.
Подскажите что еще нужно менять.
покажите функцию
SHOW CREATE FUNCTION get_ip_by_tag;
Записан
fet4
Старожил
****

Карма: 2
Offline Offline

Сообщений: 324


Просмотр профиля Email
« Ответ #11 : 07 Декабря 2016, 10:24:06 »

вот такое показывает, она такая же как в первом посте, в ней ничего не менял
Код:
mysql> SHOW CREATE FUNCTION get_ip_by_tag;
+---------------+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
| Function      | sql_mode | Create Function                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | character_set_client | collation_connection | Database Collation |
+---------------+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
| get_ip_by_tag |          | CREATE DEFINER=`nodeny`@`%` FUNCTION `get_ip_by_tag`( user_id INTEGER UNSIGNED, tag VARCHAR(64) ) RETURNS varchar(15) CHARSET utf8
    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 | utf8mb4              | utf8mb4_general_ci   | utf8_general_ci    |
+---------------+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
1 row in set (0.00 sec)


Мне кажется проблема в radreply от dhcp т.к. там прям в этой процедуре происходит выборка из пула.
Записан
Pa4ka
Старожил
****

Карма: 4
Offline Offline

Сообщений: 281

591884591
Просмотр профиля Email
« Ответ #12 : 07 Декабря 2016, 10:49:01 »

вот такое показывает, она такая же как в первом посте, в ней ничего не менял
Код:
mysql> SHOW CREATE FUNCTION get_ip_by_tag;
+---------------+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
| Function      | sql_mode | Create Function                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | character_set_client | collation_connection | Database Collation |
+---------------+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
| get_ip_by_tag |          | CREATE DEFINER=`nodeny`@`%` FUNCTION `get_ip_by_tag`( user_id INTEGER UNSIGNED, tag VARCHAR(64) ) RETURNS varchar(15) CHARSET utf8
    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 | utf8mb4              | utf8mb4_general_ci   | utf8_general_ci    |
+---------------+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
1 row in set (0.00 sec)


Мне кажется проблема в radreply от dhcp т.к. там прям в этой процедуре происходит выборка из пула.
Эта функция точно выдает IP только с того пула с тем тегом который Вы указывает?
Я просто не могу понять что именно у Вас не получаеться.
Записан
fet4
Старожил
****

Карма: 2
Offline Offline

Сообщений: 324


Просмотр профиля Email
« Ответ #13 : 07 Декабря 2016, 11:06:10 »

SELECT get_ip_by_tag(1,'10.1.0.1') выполняю все ок, берется с нужного пула.

А вот radreply
Код:
| radreply_dhcp |          | CREATE DEFINER=`nodeny`@`%` PROCEDURE `radreply_dhcp`(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 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=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 radius_attr INTO add_attr FROM users_services
        WHERE uid=usr_id AND tags LIKE '%,inet,%' LIMIT 1;

    attr_loop: WHILE TRUE DO
        SELECT strSplit(add_attr, '\n', i) INTO line;
        IF LENGTH(line) = 0 OR i > 20 THEN LEAVE attr_loop; END IF;
        IF line LIKE '%+=%' THEN
            SELECT NULL,login,strSplit(line, '+=', 1),strSplit(line, '+=', 2),'+=';
        ELSEIF line LIKE '%=%' THEN
            SELECT NULL,login,strSplit(line, '=', 1),strSplit(line, '=', 2),'=';
        END IF;
        SET i = i + 1;
    END WHILE;
END

выполняю
Код:
CALL radreply_dhcp('74:e5:43:8f:c1:17', '172.20.0.2')

и проскакивают с других пулов.
Записан
Efendy
Администратор
Спец
*****

Карма: 138
Offline Offline

Сообщений: 4782



Просмотр профиля
« Ответ #14 : 07 Декабря 2016, 11:42:35 »

В пппое когда создается соединение, то у нас всегда есть id пользователя, которое мы получаем по логину. Если у тебя радиус для дхцп настроен так, чтобы выдавать ip для неизвестных мак, то естественно одно get_ip_by_tag не пожет - там первым параметром идет id абонента. Т.е. если в твоем случае '74:e5:43:8f:c1:17' не внесен в таблицу mac_uid, то в процедуре radreply_dhcp сработает ветка START TRANSACTION блаблабла COMMIT, где тег не принимается во внимание. Думаю, что нужно заменить

Код:
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;

на

Код:
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;

типа такого
Записан
Страниц: [1] 2
  Печать  
 
Перейти в:  

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