Dhcp + Radius 3: відмінності між версіями
Sv (обговорення | внесок) мНемає опису редагування |
(Немає відмінностей)
|
Поточна версія на 17:31, 22 червня 2023
Выдача ip может быть основана на разных критериях, например:
- авторизация по мак-адресу клиента (преимущественно используется в неуправляемых сетях)
- по комбинации мак клиента, мак свича, порт свича
- по номеру vlan
- по имени nas, vlan свича, vlan клиента
- по имени nas, маку и vlan клиента
Вариантов может быть множество, в зависимости от того, что придумает админ. Но суть везде одна: на radius приходят параметры, с которыми подключается клиент, а radius возвращает обычно ip и/или любое множество иных параметров.
В данном документе будет описан самый простой вариант: авторизация по мак-адресу клиента. Потом сложнее.
Мы настраиваем Radius так, чтобы он "принимал" любого, в том числе неизвестного, клиента, поскольку неизвестным клиентам будет выдан ip из пула динамических адресов. После чего у клиента появится возможность через личный кабинет зарегистрировать свое подключение и данный мак-адрес перестанет быть неизвестным.
Установка Radius
Поскольку понадобится radius с модулем mysql, установим его не из бинарных пакетов (pkg install freeradius), а из портов:
cd /usr/ports/net/freeradius3 && make install clean
Обязательно поставим галку напротив опции MYSQL
Автозапуск:
sysrc radiusd_enable="yes"
Конфигурирование
cp /usr/local/nodeny/etc/raddb/* /usr/local/etc/raddb/
rm /usr/local/etc/raddb/sites-enabled/default
ee /usr/local/etc/raddb/sites-enabled/nodeny
Вставляем следующий текст:
server default {
listen {
type = auth
ipaddr = *
port = 1812
}
listen {
type = acct
ipaddr = *
port = 0
}
authorize {
sql
update control {
Auth-Type := Accept
}
}
authenticate {
}
preacct {
acct_unique
preprocess
}
accounting {
sql
}
session {
radutmp
sql
}
post-auth {
sql
}
Post-Auth-Type ACCEPT {
sql
}
}
Sql конфиг
В консоли:
ee /usr/local/etc/raddb/mods-enabled/sql
Вставляем следующий текст:
sql {
driver = "rlm_sql_mysql"
mysql {
warnings = auto
}
server = "localhost"
port = 3306
login = "nodeny"
password = "hardpass"
radius_db = "nodeny"
read_groups = no
authorize_reply_query = "call radreply('%{User-Name}')"
accounting {
reference = "%{tolower:type.%{Acct-Status-Type}.query}"
type {
start {
query = "call radupdate('%{User-Name}','%{Framed-IP-Address}',\
'user=%{Calling-Station-Id};nas=%{NAS-IP-Address};ses=%{Acct-Session-Id}')"
}
interim-update {
query = "${..start.query}"
}
stop {
query = "call radstop('%{User-Name}', '%{Framed-IP-Address}')"
}
}
}
post-auth {
query = "call radupdate('%{User-Name}','%{reply:Framed-IP-Address}',\
'user=%{Calling-Station-Id};nas=%{NAS-IP-Address};ses=%{Acct-Session-Id}')"
}
}
Mysql процедуры
ALTER DATABASE nodeny CHARACTER SET utf8 COLLATE utf8_general_ci;
DROP PROCEDURE IF EXISTS `radreply`;
DELIMITER $$
CREATE PROCEDURE `radreply`(IN login VARCHAR(64))
BEGIN
DECLARE usr_mac VARCHAR(12);
DECLARE usr_ip VARCHAR(15);
DECLARE usr_id INT;
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(usr_id) 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
WHERE uid=0 AND type='dynamic' AND `release` < UNIX_TIMESTAMP()
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=IF(ip>0,ip,INET_ATON(usr_ip)), time=UNIX_TIMESTAMP();
COMMIT;
SELECT INET_NTOA(ip) INTO usr_ip FROM mac_uid WHERE mac=usr_mac;
UPDATE ip_pool SET `release` = UNIX_TIMESTAMP() + 3600
WHERE ip = INET_ATON(usr_ip);
END IF;
SELECT NULL, login, 'Framed-IP-Address', usr_ip, '=';
SELECT NULL, login, 'Session-Timeout', '600', '=';
END$$
DELIMITER ;
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 ;
Проверим:
CALL radreply('00:11:22:33:44:55');
Если получаем ошибку:
- ERROR 1146 (42S02): Table 'nodeny.mac_uid' doesn't exist - не установлен модуль dhcp
- ERROR 1048 (23000): Column 'ip' cannot be null - забыли создать пул ip адресов типа "динамический"
- ERROR 1267 (HY000): Illegal mix of collations (utf8_general_ci,IMPLICIT) and (utf8_unicode_ci,IMPLICIT) for operation '=' - выполним:
ALTER DATABASE nodeny CHARACTER SET utf8 COLLATE utf8_general_ci;
и пересоздаем процедуры