Привязка ip к login: відмінності між версіями
Sv (обговорення | внесок) (Новая страница: «Если к учетной записи подключено несколько ip адресов и есть необходимость выдавать ip в з…») |
Sv (обговорення | внесок) Немає опису редагування |
||
(Не показані 4 проміжні версії цього користувача) | |||
Рядок 3: | Рядок 3: | ||
<youtube>A2yx5TcQzpQ</youtube> | <youtube>A2yx5TcQzpQ</youtube> | ||
Это число будет являться частью логина. Например, у абонента существует учетная запись ivanov и подключены 3 ip | Это число будет являться частью логина. Например, у абонента существует учетная запись ivanov и подключены 3 ip и для каждого ip выбрано число (как в видео выше): | ||
<pre> | <pre> | ||
10.0.0.205 - 0 | 10.0.0.205 - 1 | ||
10.0.0. | 10.0.0.206 - 3 | ||
10.0.0.207 - | 10.0.0.207 - 4 | ||
</pre> | |||
Чтобы при авторизации по pppoe ему был выдан адрес 10.0.0.206 необходимо в качестве логина использовать '''ivanov+3''', для 10.0.0.207 - '''ivanov+4''' | |||
Чтобы эта схема заработала, необходимо создать mysql-процедуру, которая будет выдавать ip в зависимости от числа в фрагменте логина: | |||
<pre> | <pre> | ||
DROP FUNCTION IF EXISTS `get_ip_by_num`; | |||
DELIMITER $$ | |||
CREATE FUNCTION `get_ip_by_num` ( user_id INTEGER UNSIGNED, num INTEGER ) | |||
RETURNS VARCHAR(15) NO SQL | |||
BEGIN | |||
DECLARE user_ip VARCHAR(15); | |||
DECLARE real_ip VARCHAR(15); | |||
SELECT INET_NTOA(ip) INTO user_ip FROM ip_pool | |||
WHERE uid = user_id AND type = 'static' | |||
AND tags LIKE CONCAT('%,', num, ',%') LIMIT 1; | |||
IF( user_ip IS NOT NULL ) THEN RETURN user_ip; END IF; | |||
SELECT INET_NTOA(ip) INTO user_ip FROM ip_pool | |||
WHERE uid = user_id AND type='static' LIMIT 1; | |||
IF( user_ip IS NOT NULL ) THEN RETURN user_ip; END IF; | |||
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) | |||
LIMIT 1 | |||
) UNION ( | |||
SELECT id, uid FROM ip_pool | |||
WHERE uid = user_id AND type = 'dynamic' AND realip = IF(real_ip>0,1,0) | |||
LIMIT 1 | |||
) | |||
) AS tbl ORDER BY uid DESC LIMIT 1); | |||
SELECT INET_NTOA(ip) INTO user_ip FROM ip_pool | |||
WHERE uid = user_id LIMIT 1; | |||
RETURN user_ip; | |||
END$$ | |||
DELIMITER ; | |||
</pre> | |||
Проверим ее работоспособность: | |||
<pre> | |||
SELECT get_ip_by_num(357, 3); | |||
</pre> | |||
<p>При условии, что id абонента ivanov = 357, должно выдать:</p> | |||
<pre> | |||
+-----------------------+ | |||
| get_ip_by_num(357, 3) | | |||
+-----------------------+ | |||
| 10.0.0.206 | | |||
+-----------------------+ | |||
</pre> | |||
Так же необходимо изменить radius-процедуры: | |||
<pre> | |||
DROP PROCEDURE IF EXISTS `radcheck`; | |||
DELIMITER $$ | |||
CREATE PROCEDURE `radcheck` (IN login VARCHAR(64)) | |||
BEGIN | |||
DECLARE real_login VARCHAR(64) DEFAULT NULL; | |||
SELECT SUBSTRING_INDEX(login, '+', 1) INTO real_login; | |||
SELECT id, name, 'Password' AS Attribute, AES_DECRYPT(passwd,'hardpass') AS Value,'==' | |||
FROM users WHERE name=real_login; | |||
END$$ | |||
DELIMITER ; | |||
</pre> | |||
<pre> | |||
DROP PROCEDURE IF EXISTS `radreply`; | |||
DELIMITER $$ | |||
CREATE PROCEDURE `radreply`(IN login VARCHAR(64)) | |||
BEGIN | |||
DECLARE usr_id INT; | |||
DECLARE ip_index INT; | |||
DECLARE usr_ip VARCHAR(15) DEFAULT NULL; | |||
DECLARE real_login VARCHAR(64) DEFAULT NULL; | |||
SELECT SUBSTRING_INDEX(login, '+', 1) INTO real_login; | |||
SELECT CAST(REPLACE(login, real_login, '') AS UNSIGNED) INTO ip_index; | |||
SELECT id INTO usr_id FROM users WHERE name=real_login LIMIT 1; | |||
SELECT get_ip_by_num(usr_id, ip_index) 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 ; | |||
</pre> | |||
<pre> | |||
DROP PROCEDURE IF EXISTS `radupdate`; | |||
DELIMITER $$ | |||
CREATE PROCEDURE `radupdate`(IN login VARCHAR(64), IN ip VARCHAR(16), IN properties VARCHAR(255)) | |||
BEGIN | |||
DECLARE usr_id INT; | |||
DECLARE ip_index INT; | |||
DECLARE usr_ip VARCHAR(15) DEFAULT NULL; | |||
DECLARE real_login VARCHAR(64) DEFAULT NULL; | |||
SELECT SUBSTRING_INDEX(login, '+', 1) INTO real_login; | |||
SELECT CAST(REPLACE(login, real_login, '') AS UNSIGNED) INTO ip_index; | |||
SELECT id INTO usr_id FROM users WHERE name=real_login LIMIT 1; | |||
SELECT get_ip_by_num(usr_id, ip_index) INTO usr_ip; | |||
CALL set_auth(usr_ip, CONCAT('mod=pppoe;',REPLACE(properties,':',''))); | |||
END$$ | |||
DELIMITER ; | |||
</pre> | |||
Также необходимо настроить радиус так, чтобы он не экранировал знак плюса в логине, в sql.conf добавьте: | |||
<pre> | |||
safe-characters = "@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.+-_: /" | |||
</pre> |
Поточна версія на 10:06, 17 жовтня 2018
Если к учетной записи подключено несколько ip адресов и есть необходимость выдавать ip в зависимости от логина - этот модуль для вас. В админке напротив ip адреса появится выпадающий список, где можно выбрать число, связанное с данным ip.
Это число будет являться частью логина. Например, у абонента существует учетная запись ivanov и подключены 3 ip и для каждого ip выбрано число (как в видео выше):
10.0.0.205 - 1 10.0.0.206 - 3 10.0.0.207 - 4
Чтобы при авторизации по pppoe ему был выдан адрес 10.0.0.206 необходимо в качестве логина использовать ivanov+3, для 10.0.0.207 - ivanov+4
Чтобы эта схема заработала, необходимо создать mysql-процедуру, которая будет выдавать ip в зависимости от числа в фрагменте логина:
DROP FUNCTION IF EXISTS `get_ip_by_num`; DELIMITER $$ CREATE FUNCTION `get_ip_by_num` ( user_id INTEGER UNSIGNED, num INTEGER ) RETURNS VARCHAR(15) NO SQL BEGIN DECLARE user_ip VARCHAR(15); DECLARE real_ip VARCHAR(15); SELECT INET_NTOA(ip) INTO user_ip FROM ip_pool WHERE uid = user_id AND type = 'static' AND tags LIKE CONCAT('%,', num, ',%') LIMIT 1; IF( user_ip IS NOT NULL ) THEN RETURN user_ip; END IF; SELECT INET_NTOA(ip) INTO user_ip FROM ip_pool WHERE uid = user_id AND type='static' LIMIT 1; IF( user_ip IS NOT NULL ) THEN RETURN user_ip; END IF; 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) LIMIT 1 ) UNION ( SELECT id, uid FROM ip_pool WHERE uid = user_id AND type = 'dynamic' AND realip = IF(real_ip>0,1,0) LIMIT 1 ) ) AS tbl ORDER BY uid DESC LIMIT 1); SELECT INET_NTOA(ip) INTO user_ip FROM ip_pool WHERE uid = user_id LIMIT 1; RETURN user_ip; END$$ DELIMITER ;
Проверим ее работоспособность:
SELECT get_ip_by_num(357, 3);
При условии, что id абонента ivanov = 357, должно выдать:
+-----------------------+ | get_ip_by_num(357, 3) | +-----------------------+ | 10.0.0.206 | +-----------------------+
Так же необходимо изменить radius-процедуры:
DROP PROCEDURE IF EXISTS `radcheck`; DELIMITER $$ CREATE PROCEDURE `radcheck` (IN login VARCHAR(64)) BEGIN DECLARE real_login VARCHAR(64) DEFAULT NULL; SELECT SUBSTRING_INDEX(login, '+', 1) INTO real_login; SELECT id, name, 'Password' AS Attribute, AES_DECRYPT(passwd,'hardpass') AS Value,'==' FROM users WHERE name=real_login; END$$ DELIMITER ;
DROP PROCEDURE IF EXISTS `radreply`; DELIMITER $$ CREATE PROCEDURE `radreply`(IN login VARCHAR(64)) BEGIN DECLARE usr_id INT; DECLARE ip_index INT; DECLARE usr_ip VARCHAR(15) DEFAULT NULL; DECLARE real_login VARCHAR(64) DEFAULT NULL; SELECT SUBSTRING_INDEX(login, '+', 1) INTO real_login; SELECT CAST(REPLACE(login, real_login, '') AS UNSIGNED) INTO ip_index; SELECT id INTO usr_id FROM users WHERE name=real_login LIMIT 1; SELECT get_ip_by_num(usr_id, ip_index) 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)) BEGIN DECLARE usr_id INT; DECLARE ip_index INT; DECLARE usr_ip VARCHAR(15) DEFAULT NULL; DECLARE real_login VARCHAR(64) DEFAULT NULL; SELECT SUBSTRING_INDEX(login, '+', 1) INTO real_login; SELECT CAST(REPLACE(login, real_login, '') AS UNSIGNED) INTO ip_index; SELECT id INTO usr_id FROM users WHERE name=real_login LIMIT 1; SELECT get_ip_by_num(usr_id, ip_index) INTO usr_ip; CALL set_auth(usr_ip, CONCAT('mod=pppoe;',REPLACE(properties,':',''))); END$$ DELIMITER ;
Также необходимо настроить радиус так, чтобы он не экранировал знак плюса в логине, в sql.conf добавьте:
safe-characters = "@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.+-_: /"