Микротик
Краткий обзор
Прочитайте внимательно это раздел - есть несколько вариантов работы с Микротиком.
Работа Микротика с NoDeny основана на radius-протоколе. Вам необходимо поставить на сервер биллинга программу radius-сервер (см. ниже). Эта программа будет принимать запросы от Микротика, проверять пароль абонента и возвращать Микротику ip адрес этого абонента. Схема примерно такая:
Микротик может предоставлять доступ в интернет по двум технологиям: посредством DCHP или PPPoE. Настройка радиус-сервера и процедур mysql отличаются для этих технологий - будте внимательны.
Микротик может выполнять все или часть следующих функций:
- dhcp
- pppoe
- dns
- перенаправлять на заглушку заблокированных и неизвестных абонентов
- предоставлять доступ в интернет незаблокированным абонентам
- управлять скоростью в интернет
Для dhcp сервера необходим модуль dhcp, который нужно приобрести дополнительно на главном сайте NoDeny. При использовании dhcp нам доступен механизм регистрации клиентского оборудования. Если мак-адрес компьютера абонента не известен - при открытии браузером любой страницы будет отображено окно с вводом логина и пароля, после заполнения которой, произойдет регистрация мака и в дальнейшей работе логин и пароль запрашиваться не будут пока пользователь не сменить свое оборудование (сетевую карту, роутер и т.д).
dhcp
- На сервере NoDeny создадим пул ip адресов в количестве раз в 5-10 большим чем предполагаемое количество абонентов. Тип ip обязательно должен быть "динамический".
- С главного сайта NoDeny скачаем модуль dhcp и установим его: perl install.pl -x
Настраиваем mikrotik
/ip dhcp-server add disabled=no interface=ether1 name=dhcp1 use-radius=yes /ip dhcp-server network add dns-server=10.1.0.11 gateway=10.1.0.11 netmask=16 /radius add address=10.1.0.1 secret=hardpass5 service=dhcp
Здесь:
- 10.1.0.1 - ip сервера NoDeny, где установлен Radius server
- 10.1.0.11 - ip микротика
- netmask=16 - маска подсети абонентов (число после слеша в сети, например: 10.1.0.0/16)
- ether1 - интерфейс микротика, подключенный к сети абонентов
В данной конфигурации считается, что dns сервер также запущен на микротике. Если нет, то
/ip dns set allow-remote-requests=yes servers=8.8.4.4,8.8.8.8
Установка Radius
Поскольку понадобится radius с модулем mysql, установим его не из бинарных пакетов (pkg install freeradius), а из портов:
cd /usr/ports/net/freeradius2 && make install clean
Обязательно поставим галку напротив опции MYSQL
rm /usr/local/etc/raddb/sites-enabled/default
ee /usr/local/etc/raddb/sites-enabled/nodeny
Вставляем следующий текст:
authorize { sql } authenticate { Auth-Type PAP { pap } } preacct { acct_unique preprocess } accounting { detail sql exec } session { radutmp sql } post-auth { sql }
cp /usr/local/nodeny/etc/raddb/* /usr/local/etc/raddb/
echo radiusd_enable=YES >> /etc/rc.conf
ee /usr/local/etc/raddb/radiusd.conf
Раскомментируем строку (найти проще всего так: ctrl+y, затем текст "sql.conf", затем enter):
$INCLUDE sql.conf
ee /usr/local/etc/raddb/sql.conf
Изменим postauth_query и accounting_update_query:
postauth_query = "call radupdate('%{User-Name}','%{reply:Framed-IP-Address}',\ 'nas=%{NAS-IP-Address}')" accounting_update_query = "call radupdate('%{User-Name}','%{Framed-IP-Address}',\ 'nas=%{NAS-IP-Address}')"}
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 UPDATE mac_uid SET ip=0 WHERE uid=0 AND time<(UNIX_TIMESTAMP()-3600); START TRANSACTION; SELECT INET_NTOA(ip) INTO usr_ip FROM ip_pool p WHERE uid=0 AND type='dynamic' AND NOT EXISTS (SELECT ip FROM mac_uid WHERE ip=p.ip) 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; 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;
и пересоздаем процедуры
Запускам Radius
/usr/local/etc/rc.d/radiusd start
Проверяем:
radtest 00:11:22:33:44:55 '' 127.0.0.1 0 hardpass5
Если получаем ошибку radclient:: Failed to find IP address for имя_нашего_сервера - в /etc/hosts не прописано имя нашего сервера.
Должны получить примерно такой ответ:
rad_recv: Access-Reject packet from host 127.0.0.1 port 1812, id=63, length=38 Framed-IP-Address = 10.0.4.175 Session-Timeout = 600 Acct-Interim-Interval = 60
В ином случае тушим radius и запускаем в режиме детального вывода:
/usr/local/etc/rc.d/radiusd stop
radiusd -X
Продолжаем настройку. Добавим микротик (10.1.0.11) в настройки радиуса:
ee /usr/local/etc/raddb/clients.conf
Добавляем:
client 10.1.0.11 { secret = hardpass5 shortname = Mikrotik nastype = cisco }
Проверим, что модуль dhcp запускается при старте nokernel:
cd /usr/local/nodeny
perl nokernel.pl -L
Обратите внимание, что после установки модуля dhcp необходимо перезапустить nokernel.
Включаем тестовый компьютер как абонента, подключенного к микротику. Должны получить ip адрес из пула динамических адресов NoDeny. Поскольку мак-адрес тестового компьютера не известен NoDeny, выданный ip нигде не будет фигурировать (на самом деле он появится в таблице mac_uid). Привязку мака к учетной записи выполняется через веб-заглушку, которую мы настроим позже.
Включение/выключение доступа в интернет
На микротик включаем NAT и разрешаем натить только те ip, которые будут в списке goodboys
/ip service enable api /ip firewall nat add action=masquerade chain=srcnat disabled=no out-interface=ether2 src-address=10.1.0.0/16 src-address-list=goodboys
Здесь:
- ether2 - интерфейс, который смотрит в интернет
- 10.1.0.0/16 - сеть абонентов
На сервере NoDeny:
cd /usr/local/nodeny/modules
cat mikrotik/create.cfg.mikrotik.cfg.pm >> MyNetwork/create.mikrotik1.cfg.pm
ee MyNetwork/create.mikrotik1.cfg.pm
В первой строке редактируемого файла добавим единичку в mikrotik.cfg.pm:
#<ACTION> file=>'cfg/mikrotik1.cfg.pm',hook=>'new'
А также изменим параметры подключения к Микротику:
$host = '10.1.0.11'; $user = 'admin'; $pass = '';
Установим новый конфиг:
cd /usr/local/nodeny/
perl install.pl -x
Запустим с выводом процесса управления микротиком на консоль:
perl noserver.pl -g=_mikrotik1.cfg.pm -v
Тестируем. Если все ок, то в автозагрузку:
echo '/usr/bin/perl /usr/local/nodeny/noserver.pl -g=_mikrotik1.cfg.pm -d &' >> /etc/rc.local
Заглушка
На микротике выполним команды:
/ip firewall nat add action=dst-nat chain=dstnat dst-address=!10.1.0.1 src-address=!10.1.0.1 dst-port=80 fragment=no protocol=tcp src-address-list=!goodboys to-addresses=10.1.0.1 to-ports=8080
Здесь 10.1.0.1 - ip сервера с админкой NoDeny
Поскольку сервер с админкой не предоставляет доступ в интернет абонентам, необходимо изменить фаервол на следующий:
#!/bin/sh - f='/sbin/ipfw' ${f} add 100 deny ip from any to not me in ${f} add 150 check-state ${f} add 200 allow ip from any to any via lo0 ${f} add 300 allow icmp from any to any in ${f} add 350 allow tcp from any to any 22,80,443,8080 in ${f} add 400 allow udp from any to any 53 in ${f} add 450 allow udp from 10.1.0.11 to any 1812,1813 in ${f} add 500 deny ip from any to any in ${f} add 600 fwd 10.1.0.11 tcp from any 8080 to any ${f} add 650 allow udp from any 53 to any ${f} add 700 allow tcp from any to any setup keep-state ${f} add 750 allow udp from any to any keep-state ${f} add 800 allow ip from any to any
Здесь 10.1.0.11 - ip микротика.
Если сервер с админкой NoDeny не выполняет функции DNS - удаляем правила 400 и 650.
Если заглушка не запущена (модуль cap), необходимо записать в автозагрузку (/etc/rc.local) и запустить с консоли:
/usr/bin/perl /usr/local/nodeny/nokernel.pl -m=cap -d &
Скорость по Radius
Более оптимальный вариант управления микротик:
- включение/выключение доступа по API
- скорость по Radius
Для этого необходимо установить модуль "Radius атрибуты" и изменить mysql-процедуры:
DROP FUNCTION strSplit; CREATE FUNCTION strSplit(x MEDIUMTEXT, delim MEDIUMTEXT, pos int) RETURNS MEDIUMTEXT RETURN TRIM(BOTH '\r' FROM TRIM( REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos), LENGTH(SUBSTRING_INDEX(x, delim, pos - 1)) + 1), delim, '') )); 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; DECLARE add_attr MEDIUMTEXT; DECLARE line MEDIUMTEXT; DECLARE i INT DEFAULT 1; 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 p WHERE uid=0 AND type='dynamic' AND NOT EXISTS (SELECT ip FROM mac_uid WHERE ip=p.ip) 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=INET_ATON(usr_ip), time=UNIX_TIMESTAMP(); COMMIT; SELECT INET_NTOA(ip) INTO usr_ip FROM mac_uid WHERE mac=usr_mac; END IF; SELECT NULL, login, 'Framed-IP-Address', usr_ip, '='; SELECT NULL, login, 'Session-Timeout', '600', '='; SELECT radius_attr INTO add_attr FROM users_services WHERE uid=usr_id AND tags LIKE '%,inet,%' LIMIT 1; 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 ;
Если что-то не получается
- Проверяем, что в настройках NoDeny есть пул ip адресов с типом "динамический". При этом ip, указанные в настройках микротика
dns-server=10.1.0.11 gateway=10.1.0.11 netmask=16
должны попадать в этот диапазон. Например, мы можем сделать пул ip: 10.1.2.100 ... 10.1.9.254 - они попадают в сеть 10.1.0.0/16 так же как и 10.1.0.11
- Запустите radiusd с ключем -X и включите абонентский компьютер. Если radiusd не получит никаких запросов:
- Запустите tcpdump -iem0 -p -n udp 1812. Если никакие запросы на приходят - что-то не так с настройкой микротик
- На время разрешите полностью фаервол (ipfw add 10 allow ip from any to any)
- Если запросы приходят на radius, но он выдает ошибки - обратите внимание на то, какого рода эти ошибки: в настройке radius или ошибки при выполнении sql-запросов