<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="uk">
	<id>https:///index.php?action=history&amp;feed=atom&amp;title=Undernet_Radius</id>
	<title>Undernet Radius - Історія редагувань</title>
	<link rel="self" type="application/atom+xml" href="https:///index.php?action=history&amp;feed=atom&amp;title=Undernet_Radius"/>
	<link rel="alternate" type="text/html" href=""/>
	<updated>2026-05-05T12:22:19Z</updated>
	<subtitle>Історія редагувань цієї сторінки в вікі</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id></id>
		<title>Sv в 15:26, 29 вересня 2024</title>
		<link rel="alternate" type="text/html" href=""/>
		<updated>2024-09-29T15:26:55Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Нова сторінка&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==Добавить в пул ip поле для гостевых подключений==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
alter table ip_pool add guest varchar(60) not null default '';&lt;br /&gt;
alter table ip_pool add key (guest);&lt;br /&gt;
alter table ip_pool add last_session varchar(64) not null default '';&lt;br /&gt;
alter table ip_pool change `type` `type` enum(&lt;br /&gt;
   'static','dynamic','reserved',&lt;br /&gt;
   'pool_0', 'pool_1', 'pool_2', 'pool_3', 'pool_4',&lt;br /&gt;
   'pool_5', 'pool_6', 'pool_7', 'pool_8', 'pool_9'&lt;br /&gt;
) NOT NULL;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE `pod_queue` (&lt;br /&gt;
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `usr_ip` varchar(16) NOT NULL DEFAULT '',&lt;br /&gt;
  `nas_ip` varchar(16) NOT NULL DEFAULT '',&lt;br /&gt;
  `session` varchar(128) NOT NULL DEFAULT '',&lt;br /&gt;
  `created_at` int(10) unsigned NOT NULL DEFAULT 0,&lt;br /&gt;
  PRIMARY KEY (`id`),&lt;br /&gt;
  KEY `created_at` (`created_at`)&lt;br /&gt;
) ENGINE=InnoDB AUTO_INCREMENT=1;&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE `rad_log` (&lt;br /&gt;
  `id` int(11) NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `created_at` DATETIME DEFAULT NOW(),&lt;br /&gt;
  `username` varchar(127) NULL,&lt;br /&gt;
  `nas_name` varchar(32) NULL,&lt;br /&gt;
  `svlan` varchar(32) NULL,&lt;br /&gt;
  `cvlan` varchar(32) NULL,&lt;br /&gt;
  `user_id` int(11) NULL,&lt;br /&gt;
  `user_ip` varchar(15) NULL,&lt;br /&gt;
  PRIMARY KEY (`id`)&lt;br /&gt;
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Настройка NoDeny==&lt;br /&gt;
&lt;br /&gt;
Установить модуль radius атрибутов&lt;br /&gt;
&lt;br /&gt;
Создать тариф 1Мбит, параметр radius установить в:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ERX-Service-Activate:1+= &amp;quot;svc-global-ipoe(128000, 128000)&amp;quot;&lt;br /&gt;
ERX-Virtual-Router-Name = &amp;quot;brs&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Создать группу===&lt;br /&gt;
* имя: switch&lt;br /&gt;
* галки только на:&lt;br /&gt;
** К учетным записям подключаются ip, имеют трафик&lt;br /&gt;
** Учетные записи имеют сущность «Порты»&lt;br /&gt;
&lt;br /&gt;
===Дополнительные поля===&lt;br /&gt;
&lt;br /&gt;
* Имя поля: BRAS&lt;br /&gt;
* Имя поля в бд: _bras&lt;br /&gt;
* Тип поля: выпадающий список&lt;br /&gt;
* Галки по усмотрению&lt;br /&gt;
* Тип объекта: bras&lt;br /&gt;
* Группы: switch&lt;br /&gt;
----&lt;br /&gt;
* Имя поля: Service VLAN&lt;br /&gt;
* Имя поля в бд: _svlan&lt;br /&gt;
* Тип поля: целое положительное&lt;br /&gt;
* Группы: switch&lt;br /&gt;
----&lt;br /&gt;
* Имя поля: Client VLAN&lt;br /&gt;
* Имя поля в бд: _cvlan&lt;br /&gt;
* Тип поля: целое положительное&lt;br /&gt;
* Группы: switch&lt;br /&gt;
----&lt;br /&gt;
* Имя поля: MAC адрес&lt;br /&gt;
* Имя поля в бд: _mac&lt;br /&gt;
* Тип поля: мак&lt;br /&gt;
* Группы: switch&lt;br /&gt;
&lt;br /&gt;
==В Настроках-Dhcp/оборудование==&lt;br /&gt;
Имя дополнительного поля, в котором хранится мак-адрес свича установить в _mac&lt;br /&gt;
&lt;br /&gt;
==Тестовые данные==&lt;br /&gt;
&lt;br /&gt;
Создаем switch:&lt;br /&gt;
* MAC адрес: 001122334455&lt;br /&gt;
* BRAS: lesnoy&lt;br /&gt;
* SVLAN: 3571&lt;br /&gt;
&lt;br /&gt;
Создаем клиента. Данные неважны.&lt;br /&gt;
Добавляем услугу: 1 Мбит&lt;br /&gt;
Добавляем ip: 10.0.0.5&lt;br /&gt;
&lt;br /&gt;
Добавляем подключение:&lt;br /&gt;
* мак: e89a8f2db9f3&lt;br /&gt;
* Мак или идентификатор устройства - выбираем созданный switch&lt;br /&gt;
* Порт устройства или vlan: 3019&lt;br /&gt;
* ip: 10.0.0.5&lt;br /&gt;
&lt;br /&gt;
==Установка Radius==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apt install freeradius freeradius-mysql&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
rm /etc/freeradius/3.0/sites-enabled/default&lt;br /&gt;
cp /usr/local/nodeny/etc/raddb/clients.conf /etc/freeradius/3.0/&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Конфигурирование===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /etc/freeradius/3.0/sites-enabled/nodeny&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вставляем следующий текст:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
server default {&lt;br /&gt;
    listen {&lt;br /&gt;
        type = auth&lt;br /&gt;
        ipaddr = *&lt;br /&gt;
        port = 1812&lt;br /&gt;
    }&lt;br /&gt;
    listen {&lt;br /&gt;
        type = acct&lt;br /&gt;
        ipaddr = *&lt;br /&gt;
        port = 0&lt;br /&gt;
    }&lt;br /&gt;
    authorize {&lt;br /&gt;
        sql&lt;br /&gt;
        update control {&lt;br /&gt;
          Auth-Type := Accept&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    authenticate {&lt;br /&gt;
    }&lt;br /&gt;
    preacct {&lt;br /&gt;
        acct_unique&lt;br /&gt;
        preprocess&lt;br /&gt;
    }&lt;br /&gt;
    accounting {&lt;br /&gt;
        sql&lt;br /&gt;
        ok&lt;br /&gt;
    }&lt;br /&gt;
    session {&lt;br /&gt;
        radutmp&lt;br /&gt;
        sql&lt;br /&gt;
    }&lt;br /&gt;
    post-auth {&lt;br /&gt;
        sql&lt;br /&gt;
        ok&lt;br /&gt;
    }&lt;br /&gt;
    Post-Auth-Type ACCEPT {&lt;br /&gt;
        sql&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Sql конфиг===&lt;br /&gt;
В консоли:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
nano /etc/freeradius/3.0/mods-enabled/sql&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вставляем следующий текст:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sql {&lt;br /&gt;
    driver = &amp;quot;rlm_sql_mysql&amp;quot;&lt;br /&gt;
    mysql {&lt;br /&gt;
        warnings = auto&lt;br /&gt;
    }&lt;br /&gt;
    server = &amp;quot;91.193.33.65&amp;quot;&lt;br /&gt;
    port = 3306&lt;br /&gt;
    login = &amp;quot;nodeny-radius&amp;quot;&lt;br /&gt;
    password = &amp;quot;hardpass&amp;quot;&lt;br /&gt;
    radius_db = &amp;quot;nodeny&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    read_groups = no&lt;br /&gt;
    authorize_reply_query = &amp;quot;call radreply('%{User-Name}', '%{NAS-IP-Address}')&amp;quot;&lt;br /&gt;
    accounting {&lt;br /&gt;
        reference = &amp;quot;%{tolower:type.%{Acct-Status-Type}.query}&amp;quot;&lt;br /&gt;
        type {&lt;br /&gt;
            start {&lt;br /&gt;
                query = &amp;quot;call radupdate(\&lt;br /&gt;
                  '%{ERX-Dhcp-Mac-Addr}', '%{Framed-IP-Address}',\&lt;br /&gt;
                  '%{NAS-IP-Address}', '%{Acct-Session-Id}', '',\&lt;br /&gt;
                  (%{%{Acct-Input-Gigawords}:-0} * POWER(2, 32)) + %{%{Acct-Input-Octets}:-0},\&lt;br /&gt;
                  (%{%{Acct-Output-Gigawords}:-0} * POWER(2, 32)) + %{%{Acct-Output-Octets}:-0})&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
            interim-update {&lt;br /&gt;
                query = &amp;quot;${..start.query}&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
            stop {&lt;br /&gt;
                query = &amp;quot;call radstop('%{Framed-IP-Address}', '%{NAS-IP-Address}')&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    post-auth {&lt;br /&gt;
        query = &amp;quot;call radupdate(\&lt;br /&gt;
                '%{ERX-Dhcp-Mac-Addr}', '%{reply:Framed-IP-Address}',\&lt;br /&gt;
                '%{NAS-IP-Address}', '%{Acct-Session-Id}', ';first_response=1',\&lt;br /&gt;
                0, 0)&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
    pool {&lt;br /&gt;
      start = 5&lt;br /&gt;
      min = 5&lt;br /&gt;
      max = 130&lt;br /&gt;
      spare = 30&lt;br /&gt;
      uses = 0&lt;br /&gt;
      retry_delay = 30&lt;br /&gt;
      lifetime = 0&lt;br /&gt;
      idle_timeout = 60&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Логика radreply==&lt;br /&gt;
&lt;br /&gt;
В БД у свичей есть параметры:&lt;br /&gt;
* svlan - vlan свича&lt;br /&gt;
* cvlan - vlan, с которого начинается отсчет клиентских vlan. Клиентский vlan = cvlan + № порта&lt;br /&gt;
&lt;br /&gt;
Например, если клиент подключен к порту 5 свича с cvlan=3000, то у клиента vlan будет 3005&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
На Radius UserName приходит в закодированном виде: lesnoy|e89a.8f2d.b9f3|ps50:3571-3019&lt;br /&gt;
&lt;br /&gt;
Здесь:&lt;br /&gt;
* lesnoy - имя BRAS&lt;br /&gt;
* e89a.8f2d.b9f3 - мак клиента&lt;br /&gt;
* ps50:3571-3019 - параметры подключения, могут иметь формат:&lt;br /&gt;
** aaa:bbb-ccc (bbb - vlan свича,  ccc - vlan клиента)&lt;br /&gt;
** aaa:bbb (bbb - vlan свича)&lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
* В зависимости от формата подключения:&lt;br /&gt;
** Если aaa:bbb-ccc, то из базы выбираем подключение где: BRAS.name=lesnoy, BRAS.svlan=bbb, USER.port=ccc-BRAS.cvlan&lt;br /&gt;
** Если aaa:bbb, то из базы выбираем подключение где: USER.mac=e89a.8f2d.b9f3&lt;br /&gt;
* Если подключение не найдено, то&lt;br /&gt;
** Находим в базе NAS (группа 6) по ip из атрибута NAS-IP-Address&lt;br /&gt;
** В данных NAS в параметре _ip_pool содержится номер пула. Далее мы обрабатываем записи в ip_pool только с типом = 'pool_№пула'&lt;br /&gt;
** Сначала смотрим выдавался ли ранее данному клиенту какой либо ip. И если выдавался, выдадим его. Как определяем какой ip выдавался:&lt;br /&gt;
*** в поле guest хранится полный UserName клиента&lt;br /&gt;
*** поле release указывает когда ip можно освободить&lt;br /&gt;
** Если не выдавался, то выдаем рандомный ip из пула&lt;br /&gt;
** Устанавливаем release = now + 1 час&lt;br /&gt;
** return svc-guest-ipoe(svc-filter-notregistered)&lt;br /&gt;
* Если не подвязан ip, то return svc-guest-ipoe(svc-filter-disable)&lt;br /&gt;
* В ответ добавляем строку: Framed-IP-Address = хх.хх.хх.хх&lt;br /&gt;
* Если не подвязана услуга типа &amp;quot;интернет&amp;quot;, то return svc-guest-ipoe(svc-filter-disable)&lt;br /&gt;
* Если баланс меньше 0, то return svc-guest-ipoe(svc-filter-nomoney)&lt;br /&gt;
* В ответ добавляем атрибуты из услуги&lt;br /&gt;
&lt;br /&gt;
==Mysql процедуры==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ALTER DATABASE nodeny CHARACTER SET utf8 COLLATE utf8_general_ci;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DELIMITER $$&lt;br /&gt;
CREATE FUNCTION `strSplit`(x MEDIUMTEXT, delim MEDIUMTEXT, pos int) RETURNS mediumtext CHARSET utf8&lt;br /&gt;
    DETERMINISTIC&lt;br /&gt;
RETURN &lt;br /&gt;
    TRIM(BOTH '\r' FROM TRIM(&lt;br /&gt;
        REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos), LENGTH(SUBSTRING_INDEX(x, delim, pos - 1)) + 1), delim, '')&lt;br /&gt;
    ))$$&lt;br /&gt;
DELIMITER ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===radreply===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DROP PROCEDURE IF EXISTS `radreply`;&lt;br /&gt;
DELIMITER $$&lt;br /&gt;
CREATE PROCEDURE `radreply`(IN encoded_user_name VARCHAR(60), IN nas_ip VARCHAR(15))&lt;br /&gt;
BEGIN&lt;br /&gt;
    DECLARE nas_name VARCHAR(32);&lt;br /&gt;
    DECLARE usr_mac VARCHAR(12);&lt;br /&gt;
    DECLARE vlans VARCHAR(50);&lt;br /&gt;
    DECLARE svlan VARCHAR(6);&lt;br /&gt;
    DECLARE cvlan VARCHAR(6);&lt;br /&gt;
    DECLARE usr_id INT;&lt;br /&gt;
    DECLARE usr_ip VARCHAR(15) DEFAULT NULL;&lt;br /&gt;
    DECLARE usr_state VARCHAR(10);&lt;br /&gt;
    DECLARE usr_balance FLOAT(10,2);&lt;br /&gt;
    DECLARE add_attr MEDIUMTEXT;&lt;br /&gt;
    DECLARE line MEDIUMTEXT;&lt;br /&gt;
    DECLARE i INT DEFAULT 1;&lt;br /&gt;
    DECLARE ip_pool INT;&lt;br /&gt;
&lt;br /&gt;
    SELECT strSplit(encoded_user_name, '=7C', 1) INTO nas_name;&lt;br /&gt;
    SELECT REPLACE(strSplit(encoded_user_name, '=7C', 2), '.', '') INTO usr_mac;&lt;br /&gt;
    SELECT strSplit(encoded_user_name, '=7C', 3) INTO vlans;&lt;br /&gt;
    SELECT strSplit(vlans, ':', 2) INTO vlans;&lt;br /&gt;
    SELECT strSplit(vlans, '-', 1) INTO svlan;&lt;br /&gt;
    SELECT strSplit(vlans, '-', 2) INTO cvlan;&lt;br /&gt;
&lt;br /&gt;
    IF( LENGTH(cvlan) &amp;gt; 0 ) THEN&lt;br /&gt;
        SELECT m.uid, INET_NTOA(m.ip) INTO usr_id, usr_ip&lt;br /&gt;
          FROM mac_uid m&lt;br /&gt;
          JOIN data0 d ON m.device_mac=d._mac&lt;br /&gt;
          WHERE d._bras=nas_name&lt;br /&gt;
            AND d._svlan=svlan&lt;br /&gt;
            AND m.device_port=cvlan-d._cvlan&lt;br /&gt;
          LIMIT 1;&lt;br /&gt;
    ELSE&lt;br /&gt;
        SELECT m.uid, INET_NTOA(m.ip) INTO usr_id, usr_ip&lt;br /&gt;
          FROM mac_uid m&lt;br /&gt;
          WHERE m.mac=usr_mac;&lt;br /&gt;
    END IF;&lt;br /&gt;
&lt;br /&gt;
    INSERT INTO rad_log&lt;br /&gt;
      SET username=encoded_user_name,&lt;br /&gt;
          nas_name=nas_name,&lt;br /&gt;
          svlan=svlan,&lt;br /&gt;
          cvlan=cvlan,&lt;br /&gt;
          user_id=usr_id,&lt;br /&gt;
          user_ip=usr_ip;&lt;br /&gt;
&lt;br /&gt;
    SELECT NULL,encoded_user_name,'ERX-Virtual-Router-Name','&amp;quot;brs&amp;quot;','=';&lt;br /&gt;
&lt;br /&gt;
    IF( usr_id IS NULL OR usr_id=0 ) THEN&lt;br /&gt;
&lt;br /&gt;
      SELECT d._ip_pool INTO ip_pool&lt;br /&gt;
        FROM data0 d JOIN users u ON d.uid=u.id&lt;br /&gt;
        WHERE u.grp=6&lt;br /&gt;
          AND d._nas_ip=nas_ip&lt;br /&gt;
        LIMIT 1;&lt;br /&gt;
&lt;br /&gt;
      UPDATE ip_pool&lt;br /&gt;
        SET `release`=UNIX_TIMESTAMP()+3600&lt;br /&gt;
        WHERE type=CONCAT('pool_', ip_pool) &lt;br /&gt;
          AND guest=encoded_user_name&lt;br /&gt;
        LIMIT 1;&lt;br /&gt;
&lt;br /&gt;
      IF( ROW_COUNT() &amp;lt; 1 ) THEN&lt;br /&gt;
        UPDATE ip_pool SET guest='', `release`=0&lt;br /&gt;
          WHERE `release`&amp;gt;0 AND `release`&amp;lt;UNIX_TIMESTAMP();&lt;br /&gt;
&lt;br /&gt;
        UPDATE ip_pool&lt;br /&gt;
          SET `release`=UNIX_TIMESTAMP()+3600,&lt;br /&gt;
              guest=encoded_user_name&lt;br /&gt;
          WHERE type=CONCAT('pool_', ip_pool)&lt;br /&gt;
            AND guest=''&lt;br /&gt;
        LIMIT 1;&lt;br /&gt;
      END IF;&lt;br /&gt;
&lt;br /&gt;
      SELECT INET_NTOA(ip) INTO usr_ip&lt;br /&gt;
        FROM ip_pool&lt;br /&gt;
        WHERE type=CONCAT('pool_', ip_pool)&lt;br /&gt;
          AND guest=encoded_user_name&lt;br /&gt;
      LIMIT 1;&lt;br /&gt;
&lt;br /&gt;
      SELECT NULL,encoded_user_name,'Framed-IP-Address',usr_ip,'=';&lt;br /&gt;
      SELECT NULL,encoded_user_name,'ERX-Service-Activate:1',&lt;br /&gt;
        'svc-guest-ipoe-new(svc-filter-notregistered)','+=';&lt;br /&gt;
&lt;br /&gt;
    ELSE&lt;br /&gt;
&lt;br /&gt;
      SELECT NULL,encoded_user_name,'Callback-Number',usr_id,'=';&lt;br /&gt;
      SELECT INET_NTOA(ip) INTO usr_ip FROM ip_pool&lt;br /&gt;
          WHERE uid=usr_id AND type='static'&lt;br /&gt;
          ORDER BY INET_NTOA(ip)=usr_ip DESC LIMIT 1;&lt;br /&gt;
&lt;br /&gt;
      IF( usr_ip IS NOT NULL ) THEN&lt;br /&gt;
          SELECT NULL,encoded_user_name,'Framed-IP-Address',usr_ip,'=';&lt;br /&gt;
      END IF;&lt;br /&gt;
&lt;br /&gt;
      SELECT radius_attr INTO add_attr FROM users_services&lt;br /&gt;
        WHERE uid=usr_id AND tags LIKE '%,inet,%' LIMIT 1;&lt;br /&gt;
      SELECT balance, state INTO usr_balance, usr_state FROM users&lt;br /&gt;
        WHERE id=usr_id LIMIT 1;&lt;br /&gt;
&lt;br /&gt;
      IF( add_attr IS NULL OR usr_ip IS NULL ) THEN&lt;br /&gt;
          SELECT NULL,encoded_user_name,'ERX-Service-Activate:1','svc-guest-ipoe-new(svc-filter-disable)','+=';&lt;br /&gt;
      ELSEIF( usr_state = 'off' AND usr_balance &amp;lt; 0 ) THEN&lt;br /&gt;
          SELECT NULL,encoded_user_name,'ERX-Service-Activate:1','svc-guest-ipoe-new(svc-filter-nomoney)','+=';&lt;br /&gt;
      ELSEIF( usr_state = 'off' ) THEN&lt;br /&gt;
          SELECT NULL,encoded_user_name,'ERX-Service-Activate:1','svc-guest-ipoe-new(svc-filter-disable)','+=';&lt;br /&gt;
      ELSE&lt;br /&gt;
          attr_loop: WHILE TRUE DO&lt;br /&gt;
            SELECT strSplit(add_attr, '\n', i) INTO line;&lt;br /&gt;
            IF LENGTH(line) = 0 OR i &amp;gt; 20 THEN LEAVE attr_loop; END IF;&lt;br /&gt;
            IF line LIKE '%+=%' THEN&lt;br /&gt;
                SELECT NULL,encoded_user_name,strSplit(line, '+=', 1),strSplit(line, '+=', 2),'+=';&lt;br /&gt;
            ELSEIF line LIKE '%=%' THEN&lt;br /&gt;
                SELECT NULL,encoded_user_name,strSplit(line, '=', 1),strSplit(line, '=', 2),'=';&lt;br /&gt;
            END IF;&lt;br /&gt;
            SET i = i + 1;&lt;br /&gt;
          END WHILE;&lt;br /&gt;
      END IF;&lt;br /&gt;
&lt;br /&gt;
    END IF;&lt;br /&gt;
END$$&lt;br /&gt;
DELIMITER ;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===radupdate===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DROP PROCEDURE IF EXISTS `radupdate`;&lt;br /&gt;
DELIMITER $$&lt;br /&gt;
CREATE PROCEDURE `radupdate`(&lt;br /&gt;
    IN usr_mac VARCHAR(20),&lt;br /&gt;
    IN usr_ip VARCHAR(16),&lt;br /&gt;
    IN nas_ip VARCHAR(16),&lt;br /&gt;
    IN ses VARCHAR(64),&lt;br /&gt;
    IN properties VARCHAR(64),&lt;br /&gt;
    IN trafin BIGINT(20),&lt;br /&gt;
    IN trafout BIGINT(20)&lt;br /&gt;
)&lt;br /&gt;
BEGIN&lt;br /&gt;
    DECLARE user_id INT UNSIGNED;&lt;br /&gt;
    SELECT uid INTO user_id FROM ip_pool WHERE ip=INET_ATON(usr_ip);&lt;br /&gt;
    IF( user_id IS NOT NULL AND user_id &amp;gt; 0 ) THEN&lt;br /&gt;
       INSERT INTO ses_traf&lt;br /&gt;
         SET ses_id=ses, traf_in=trafin, traf_out=trafout, time=UNIX_TIMESTAMP(), uid=user_id;&lt;br /&gt;
    END IF;&lt;br /&gt;
    CALL set_auth(usr_ip, CONCAT(&lt;br /&gt;
        'nas=', nas_ip, ';ses=', ses, properties, ';mod=dhcp;user=', REPLACE(usr_mac, '.', '')&lt;br /&gt;
    ));&lt;br /&gt;
    UPDATE mac_uid SET time=UNIX_TIMESTAMP() WHERE ip=INET_ATON(usr_ip) LIMIT 1;&lt;br /&gt;
    UPDATE ip_pool&lt;br /&gt;
        SET `release`=UNIX_TIMESTAMP()+3600,&lt;br /&gt;
            last_session=CONCAT(nas_ip, ' ', ses)&lt;br /&gt;
        WHERE ip=INET_ATON(usr_ip) AND type LIKE 'pool_%';&lt;br /&gt;
END$$&lt;br /&gt;
DELIMITER ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===radstop===&lt;br /&gt;
Авторизация завершается только если radstop послал bras, который последним делал аккаунтинг. Это ситуация от заказчика: bras1 становится недоступным, клиент переключается на bras2, bras1 возвращается и посылает radstop. Этот radstop мы игнорируем т.к. клиент подключен через bras1&lt;br /&gt;
&lt;br /&gt;
Обратить внимание, что ip bras-а сохраняем в поле properties первым параметром, чтобы работал LIKE CONCAT('nas=', nas_ipa, '%'). Поэтому:&lt;br /&gt;
&lt;br /&gt;
# mods-enabled/sql в параметре 'nas=%{NAS-IP-Address};...;...' nas на первом месте&lt;br /&gt;
# в radupdate переменная properties идет на первом месте при вызове set_auth &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DROP PROCEDURE IF EXISTS `radstop`;&lt;br /&gt;
DELIMITER $$&lt;br /&gt;
CREATE PROCEDURE `radstop`(IN user_ipa VARCHAR(16), IN nas_ipa VARCHAR(16))&lt;br /&gt;
BEGIN&lt;br /&gt;
    DECLARE auth_prop VARCHAR(255);&lt;br /&gt;
    DECLARE user_id INT UNSIGNED;&lt;br /&gt;
    DECLARE start_auth INT UNSIGNED;&lt;br /&gt;
    SELECT a.properties, a.start, i.uid INTO auth_prop, start_auth, user_id&lt;br /&gt;
        FROM ip_pool i&lt;br /&gt;
        JOIN auth_now a ON i.ip = INET_ATON(user_ipa)&lt;br /&gt;
        JOIN users u ON i.uid=u.id&lt;br /&gt;
        WHERE a.ip=user_ipa;&lt;br /&gt;
    IF( user_id&amp;lt;&amp;gt;0 AND auth_prop IS NOT NULL AND auth_prop LIKE CONCAT('nas=', nas_ipa, '%') ) THEN&lt;br /&gt;
        INSERT INTO auth_log (uid, ip, start, end, properties) VALUES&lt;br /&gt;
            (user_id, INET_ATON(user_ipa), start_auth, UNIX_TIMESTAMP(), auth_prop);&lt;br /&gt;
        DELETE FROM auth_now WHERE ip=user_ipa LIMIT 1;&lt;br /&gt;
    END IF;&lt;br /&gt;
END$$&lt;br /&gt;
DELIMITER ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Тестирование==&lt;br /&gt;
&lt;br /&gt;
Запускаем радиус в режиме вывода в консоль:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
freeradius -X&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В соседней консоли тестовый запрос:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
echo &amp;quot;User-Name=\&amp;quot;test|0855.31fa.d608|ps20:1002-1284\&amp;quot;,User-Password=\&amp;quot;\&amp;quot;,Acct-Session-Id=\&amp;quot;1\&amp;quot;,NAS-IP-Address=\&amp;quot;172.16.66.249\&amp;quot;&amp;quot; | radclient -x localhost:1812 auth hardpass5&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В ответ должны получить следующее:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	Callback-Number = &amp;quot;14192&amp;quot;&lt;br /&gt;
	Framed-IP-Address = 100.66.56.104&lt;br /&gt;
	ERX-Virtual-Router-Name = &amp;quot;brs&amp;quot;&lt;br /&gt;
	ERX-Service-Activate:1 = &amp;quot;svc-global-ipoe(32000000,32000000)&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В админ интерфейсе в данных абонента напротив его ip должен появиться зеленый ключик.&lt;br /&gt;
&lt;br /&gt;
==Разное==&lt;br /&gt;
В /etc/mysql/mariadb.conf.d/50-server.cnf:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
max_connections        = 250&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Было 150. Однако, необходимость под вопросом&lt;br /&gt;
&lt;br /&gt;
==як працює регістрація ip==&lt;br /&gt;
&lt;br /&gt;
1) перевіряється чи існує ip в пулі ip (таблиця ip_pool). Якщо ні, значить ip був виданий некоректно (хтось зломав логіку білінгу, доналаштувавши на свій погляд) В цьому випадку клієнту виводиться месадж: 'Регистрация невозможна из-за неправильной настройки вашего подключения (неизвестный ip)'&lt;br /&gt;
&lt;br /&gt;
2) якщо тип ip static - це означає, що клієнту був виданий ip не з пулу дінамічних, а зі статичних. Виводиться месадж 'Вероятно вы уже прошли регистрацию (static ip type)'&lt;br /&gt;
&lt;br /&gt;
3) якщо тип НЕ починається з префіксу pool (а ми робили цей префікс чиспо під андернет), то виводиться месадж 'Регистрация невозможна, обратитесь к администрации (incorrect ip type)'&lt;br /&gt;
&lt;br /&gt;
4) у ip в пулі є параметр release, який означає, коли буде ця дінамічна адреса вважатися вільною. При отриманні ip, release встановлюється на деЯкий час в майбутньому. Якщо release переступив поточний час, то клієнт отримує месадж 'Прошло много времени с момента подключения, необходимо перезагрузить компьютер'&lt;br /&gt;
&lt;br /&gt;
5) В полі guest запису в пулі ip зберігаються параметри, при яких клієнт отримав ip. В випадку андернета це UserName в радіус-пакеті. Нагадаю формат:&lt;br /&gt;
lesnoy|e89a.8f2d.b9f3|ps50:3571-3019&lt;br /&gt;
Якщо структура не відповідає, то месадж 'Регистрация невозможна, обратитесь к администрации (incorrect connection data)'&lt;br /&gt;
&lt;br /&gt;
6) Шукається свіч по параметрам підключення:&lt;br /&gt;
- свіч повинен бути у групі 2&lt;br /&gt;
- в допаних поле _bras='lesnoy'&lt;br /&gt;
- _svlan, _cvlan&lt;br /&gt;
&lt;br /&gt;
Ще в налаштуваннях коректно повино бути вказаним $cfg::device_mac_field - поле, в якому зберігається мак свіча&lt;br /&gt;
&lt;br /&gt;
Свіч не знайдений - месадж 'Регистрация невозможна, обратитесь к администрации (switch not found)'&lt;br /&gt;
&lt;br /&gt;
7) якщо в таблиці mac_uid існує запис з device_mac=мак свіча AND device_port=cvlan, то у цій зв'язки встановлюється id абонета, інакше така зв'язка створюється&lt;br /&gt;
в таблицю  pod_queue вставляється запис що треба відрубити юзера з такою сесією&lt;br /&gt;
&lt;br /&gt;
месадж 'Ваш компьютер зарегистрирован'&lt;/div&gt;</summary>
		<author><name>Sv</name></author>
	</entry>
</feed>