Название: Теги в пуле ip адресов. Показываю
Отправлено: Efendy от 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, но и его имя или какой-нить еще нужный параметр, тогда можно было его указать в теге. Сейчас я не имею возможности это проверить. Поэтому кому не лень - отпишитесь
Название: Re: Теги в пуле ip адресов. Показываю
Отправлено: Groov от 14 Октября 2013, 16:51:56
А если надо что бы на всех NAS серверах эта под сеть ?
Название: Re: Теги в пуле ip адресов. Показываю
Отправлено: VitalVas от 16 Октября 2013, 19:24:20
А если надо что бы на всех NAS серверах эта под сеть ?
Поставить вместо "%{NAS-IP-Address}" свой общий тег
Название: Re: Теги в пуле ip адресов. Показываю
Отправлено: SeMant от 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 ?
Название: Re: Теги в пуле ip адресов. Показываю
Отправлено: Efendy от 28 Июля 2014, 11:46:17
Изменил первое сообщение - добавил недостающее
Название: Re: Теги в пуле ip адресов. Показываю
Отправлено: SeMant от 28 Июля 2014, 12:24:01
Всё сделал. SELECT get_ip_by_tag(1,'10.1.0.1') Ипы из пула выдаёт правильно. В админке не показывает авторизованых и пропадает инет. Что не так ?
Название: Re: Теги в пуле ip адресов. Показываю
Отправлено: Efendy от 28 Июля 2014, 13:00:45
что выдает CALL radreply('логин клиента', 'ip сервера'); не возвращает ли ошибку: CALL radupdate('логин клиента', 'ip клиента', '', 'ip сервера'); если запустить radiusd -X выдает ошибки?
Название: Re: Теги в пуле ip адресов. Показываю
Отправлено: SeMant от 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
Название: Re: Теги в пуле ip адресов. Показываю
Отправлено: 0xbad0c0d3 от 28 Июля 2014, 23:06:18
Ну наверно нужно стопнуть уже запущеный радиус... А вообще, откройте для себя radmin, radsniff - полезно для дебага в боевых условиях, только нужно в radiusd.conf добавить или разрешить инклюд sites-available/control-socket listen { type = control socket = "/var/run/radiusd/radiusd.sock" mode = rw }
Название: Re: Теги в пуле ip адресов. Показываю
Отправлено: fet4 от 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 работает. Подскажите что еще нужно менять.
Название: Re: Теги в пуле ip адресов. Показываю
Отправлено: Pa4ka от 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;
Название: Re: Теги в пуле ip адресов. Показываю
Отправлено: fet4 от 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 т.к. там прям в этой процедуре происходит выборка из пула.
Название: Re: Теги в пуле ip адресов. Показываю
Отправлено: Pa4ka от 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 только с того пула с тем тегом который Вы указывает? Я просто не могу понять что именно у Вас не получаеться.
Название: Re: Теги в пуле ip адресов. Показываю
Отправлено: fet4 от 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')
и проскакивают с других пулов.
Название: Re: Теги в пуле ip адресов. Показываю
Отправлено: Efendy от 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; типа такого
Название: Re: Теги в пуле ip адресов. Показываю
Отправлено: fet4 от 08 Декабря 2016, 11:35:55
Внес Ваши изменения. Работает. Выполнил с десяток CALL radreply_dhcp('74:e5:43:8f:c1:17', 'accel-ppp-ipoe')
Все выдавало в рамках нужного пула. Скажите а radupdate нужного редактировать в данном случае? Он у меня такого вида 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 ;
updНаверно нужно так как радиус сыпит такое [sql] expand: call radupdate_dhcp('%{User-Name}','%{reply:Framed-IP-Address}','nas=%{NAS-IP-Address}', '%{NAS-Identifier}') -> call radupdate_dhcp('8c:1a:bf:26:a6:5d','10.194.6.231','nas=172.20.0.2', 'accel-ppp-ipoe') rlm_sql (sql) in sql_postauth: query is call radupdate_dhcp('8c:1a:bf:26:a6:5d','10.194.6.231','nas=172.20.0.2', 'accel-ppp-ipoe') rlm_sql (sql): Reserving sql socket id: 26 rlm_sql_mysql: MYSQL check_error: 1318 received rlm_sql (sql) in sql_postauth: Database query error - Incorrect number of arguments for PROCEDURE nodeny.radupdate_dhcp; expected 3, got 4 rlm_sql (sql): Released sql socket id: 26 ++[sql] = fail +} # group post-auth = fail
sql.conf привел к такому виду authorize_check_query = "call radcheck_dhcp('%{User-Name}')" authorize_reply_query = "call radreply_dhcp('%{User-Name}', '%{NAS-Identifier}')" postauth_query = "call radupdate_dhcp('%{User-Name}','%{reply:Framed-IP-Address}','nas=%{NAS-IP-Address}', '%{NAS-Identifier}')" accounting_update_query = "call radupdate_dhcp('%{User-Name}','%{Framed-IP-Address}','nas=%{NAS-IP-Address}', '%{NAS-Identifier}')"
Название: Re: Теги в пуле ip адресов. Показываю
Отправлено: fet4 от 08 Декабря 2016, 18:10:43
Добавил в процедуру radupdate "tag VARCHAR(64)" заработало. Спасибо.
|