Radius атрибуты: відмінності між версіями

Матеріал з NoDeny
Перейти до навігації Перейти до пошуку
мНемає опису редагування
Рядок 19: Рядок 19:
<pre>
<pre>
DROP FUNCTION strSplit;
DROP FUNCTION strSplit;
CREATE FUNCTION strSplit(x MEDIUMTEXT, delim MEDIUMTEXT, pos int) RETURNS MEDIUMTEXT
CREATE FUNCTION strSplit(x MEDIUMTEXT, delim MEDIUMTEXT, pos int) RETURNS MEDIUMTEXT DETERMINISTIC
RETURN  
RETURN  
     TRIM(BOTH '\r' FROM TRIM(
     TRIM(BOTH '\r' FROM TRIM(

Версія за 15:01, 29 травня 2023

Модуль позволяет добавлять произвольные атрибуты в radreply пакет radius-сервера в зависимости от тарифа абонента. Это может быть альтернативой скрипту noserver, который управляет фаерволом или скоростями на mikrotik. В этом случае правила скорости (либо иные другие) будет устанавливать сам сервер PPPoE или DHCP. Например, необходимо чтобы radius отдавал следующее:

    Service-Type = Framed-User
    Framed-Protocol = PPP
    Framed-IP-Address = 192.168.100.5
    Framed-IP-Netmask = 255.255.255.255
    ERX-Service-Activate:1+= "pppoe_local(10m,10m,15m,15m)"
    ERX-Primary-Dns = 8.8.8.8

Здесь атрибут ERX-Service-Activate устанавливает скорость абоненту по разным направлениям.

После установки модуля, в безлимитных услугах появится параметр Radius, в который следует вписать дополнительные radius-атрибуты по-одному на каждую строку, например:

ERX-Service-Activate:1+= "pppoe_local(10m,10m,15m,15m)"
ERX-Primary-Dns = 8.8.8.8

В mysql необходимо выполнить

DROP FUNCTION strSplit;
CREATE FUNCTION strSplit(x MEDIUMTEXT, delim MEDIUMTEXT, pos int) RETURNS MEDIUMTEXT DETERMINISTIC
RETURN 
    TRIM(BOTH '\r' FROM TRIM(
    REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos), LENGTH(SUBSTRING_INDEX(x, delim, pos - 1)) + 1), delim, '')
    ));

Для Freeradius версии 2:

DROP PROCEDURE IF EXISTS `radreply`;
DELIMITER $$
CREATE PROCEDURE `radreply`(IN login VARCHAR(64))
BEGIN
  DECLARE usr_id INT;
  DECLARE usr_ip VARCHAR(15) DEFAULT NULL;
  DECLARE add_attr MEDIUMTEXT;
  DECLARE line MEDIUMTEXT;
  DECLARE i INT DEFAULT 1;

  SELECT id INTO usr_id FROM users WHERE name=login LIMIT 1;
  SELECT get_ip(usr_id) INTO usr_ip;
  SELECT radius_attr INTO add_attr FROM users_services
    WHERE uid=usr_id AND tags LIKE '%,inet,%' LIMIT 1;

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

  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$$
DELIMITER ;

Для Freeradius версии 3:

DROP PROCEDURE IF EXISTS `radreply`;
DELIMITER $$
CREATE PROCEDURE `radreply`(IN login VARCHAR(64), IN password VARCHAR(64))
BEGIN
    DECLARE usr_id INT;
    DECLARE usr_ip VARCHAR(15) DEFAULT NULL;
    DECLARE add_attr MEDIUMTEXT;
    DECLARE line MEDIUMTEXT;
    DECLARE i INT DEFAULT 1;

    SELECT id INTO usr_id FROM users WHERE name=login AND password=AES_DECRYPT(passwd, 'hardpass') LIMIT 1;
    IF( usr_id IS NOT NULL ) THEN
        SELECT get_ip(usr_id) INTO usr_ip;
        SELECT radius_attr INTO add_attr FROM users_services
          WHERE uid=usr_id AND tags LIKE '%,inet,%' LIMIT 1;

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

        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 IF;
END$$
DELIMITER ;

Проверяем в консоли mysql.

Для Freeradius версии 2:

call radreply('Test1');

Для Freeradius версии 3:

call radreply('Test1', 'Пароль');

Где Test1 - логин абонента.

Новое

DROP PROCEDURE IF EXISTS `rad_attr`;
DELIMITER $$
CREATE PROCEDURE `rad_attr`(IN login VARCHAR(64), IN state VARCHAR(3), IN add_attr MEDIUMTEXT)
BEGIN
  DECLARE line MEDIUMTEXT;
  DECLARE i INT DEFAULT 1;

  IF add_attr LIKE '%###%' THEN
      SELECT strSplit(add_attr, '###', IF(state='on', 1, 2)) INTO add_attr;
  END IF;

  attr_loop: WHILE TRUE DO
    SELECT strSplit(add_attr, '\n', i) INTO line;
    SET i = i + 1;
    IF i > 20 THEN LEAVE attr_loop; END IF;
    IF LENGTH(line) = 0 THEN ITERATE 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;
  END WHILE;
END$$
DELIMITER ;


DROP PROCEDURE IF EXISTS `radreply`;
DELIMITER $$
CREATE PROCEDURE `radreply`(IN login VARCHAR(64))
BEGIN
  DECLARE usr_id INT;
  DECLARE usr_state VARCHAR(3);
  DECLARE usr_ip VARCHAR(15) DEFAULT NULL;
  DECLARE add_attr MEDIUMTEXT;

  SELECT id,  state INTO usr_id, usr_state FROM users WHERE name=login LIMIT 1;
  SELECT get_ip(usr_id) INTO usr_ip;
  SELECT radius_attr INTO add_attr FROM users_services
    WHERE uid=usr_id AND tags LIKE '%,inet,%' LIMIT 1;

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

  CALL rad_attr(login, usr_state, add_attr);
END$$
DELIMITER ;

Если в блоке с радиус-атрибутами будут идти подряд 3 символа # - это будет означать, что до этих символов будут применены атрибуты если учетная запись в незаблокированном состоянии, а после - если в заблокированном. Например:

attr1=val1
attr2=val2
###
attr1=val3
attr8=val4