FreeRadius3 + Dhcp (Linux)
Установка FreeRaius версии 3
apt install freeradius
apt install freeradius-mysql
apt install freeradius-dhcp
Конфигурирование Radius
rm /etc/freeradius/3.0/sites-enabled/default
Создаем конфиг dhcp:
nano /etc/freeradius/3.0/sites-enabled/dhcp
server dhcp { listen { type = dhcp ipaddr = 0.0.0.0 port = 67 broadcast = yes } dhcp DHCP-Discover { update reply { DHCP-Message-Type = DHCP-Offer } update reply { DHCP-Domain-Name-Server = 0.0.0.0 DHCP-IP-Address-Lease-Time = 7200 DHCP-DHCP-Server-Identifier = 10.0.1.1 } sql.authorize ok } dhcp DHCP-Request { update reply { DHCP-Message-Type = DHCP-Ack } update reply { DHCP-Domain-Name-Server = 0.0.0.0 DHCP-IP-Address-Lease-Time = 7200 DHCP-DHCP-Server-Identifier = 10.0.1.1 } sql.authorize sql.post-auth ok } dhcp { reject } }
Здесь 10.0.1.1 - это ip интерфейса, на котором нам нужно dhcp.
Создаем конфиг sql:
nano /etc/freeradius/3.0/mods-enabled/sql
sql { database = "mysql" driver = "rlm_sql_mysql" server = "localhost" port = 3306 login = "nodeny" password = "hardpass" radius_db = "nodeny" delete_stale_sessions = yes sqltrace = no sqltracefile = ${logdir}/sqltrace.sql num_sql_socks = 5 connect_failure_retry_delay = 60 lifetime = 0 max_queries = 0 authorize_check_query = "call radcheck('%{DHCP-Client-Hardware-Address}')" authorize_reply_query = "call radreply('%{DHCP-Client-Hardware-Address}')" postauth_query = "call radupdate('%{DHCP-Client-Hardware-Address}','%{reply:Framed-IP-Address}',\ 'user=%{Calling-Station-Id};nas=%{NAS-IP-Address}')" accounting_update_query = "call radupdate('%{DHCP-Client-Hardware-Address}','%{Framed-IP-Address}',\ 'user=%{Calling-Station-Id};nas=%{NAS-IP-Address}')" }
Запуск с дебагом на экран:
freeradius -X
Mysql процедуры
ALTER DATABASE nodeny CHARACTER SET utf8 COLLATE utf8_general_ci;
DROP PROCEDURE IF EXISTS `radcheck`; DELIMITER $$ CREATE PROCEDURE `radcheck` (IN login VARCHAR(64)) BEGIN SELECT Null, login, 'Cleartext-Password' AS Attribute, '' AS Value,':='; END$$ DELIMITER ;
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, 'DHCP-Client-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');