Dhcp

Матеріал з NoDeny
Перейти до навігації Перейти до пошуку

NoDeny+ предоставляет 2 принципиально разных варианта работы Dhcp-модуля:

  • С Radius: dhcp-сервер получает ip от NoDeny+ и выдает клиенту
  • Без Radius: dhcp-сервер выдает клиенту ip на свое усмотрение и информирует NoDeny+

Если вы не можете определиться какой из вариантов использовать - рекомендуем без Radius - он проще в настройке. Прицип работы обоих вариантов:

Без Radius

Dhcp-сервер работает автономно от NoDeny. Т.е. выдает ip адреса на свое усмотрение! Dhcp-сервер запоминает какому мак-адресу выдавал какой ip, т.е одно устройства скорее всего будет получать постоянно один и тот же ip. Тем не менее, это не гарантируется и вообще неважно для NoDeny.

Как выглядит сам процесс:

  • Абонент включает компьютер и получает ip от dhcp-сервера. При этом посылается сигнал в NoDeny через скрипт modules/dhcp/events.pl.
  • NoDeny смотрит какому абоненту принадлежит мак-адрес (либо же комбинация мак+свич+порт) и привязывает ip, который выдал dhcpd, к его учетке. Абонент получает доступ в интернет.
  • В первый раз абонент, естественно, не будет найден, поэтому ip не привязывается. Абонент, открыв браузер и введя любой адрес, попадает на заглушку, на которой ему сообщается "для получения доступа в интернет введите логин и пароль".
  • После ввода логина и пароля, NoDeny запоминает, что мак-адрес (либо же комбинация мак+свич+порт) принадлежит такому-то абоненту.
  • При последующих подключениях логин и пароль запрашиваться не будут пока не будет сменено устройство либо точка подключения (в случае использования option 82).

Комментарий по Option 82

Без использования управляемого оборудования, dhcp не достаточно безопасно т.к. злоумышленник может подделать мак-адрес. Option 82 заставляет свичи информировать dhcp-сервер о том, с какого свича и какого порта пришел запрос. Поэтому подделка мака не приведет к успеху, поскольку мак свича и номер порта, злоумышленник не сможет подделать (если он подключен к свичу с option 82, естественно).

Через Radius (например, accel-ppp)

Dhcp-сервер работает с NoDeny через Radius аналогично pppoe. Клиент включает компьютер, который шлет запрос на dhcp-сервер. Тот в свою очередь шлет запрос в Radius. Радиус запускает NoDeny mysql-процедуру получения ip по мак адресу (комбинации мак+свич+порт). В ответ получает гостевой ip (в админке помечаются тегом guest в пуле ip) ...


Вариант без Radius

Ставим dhcp-сервер cd /usr/ports/net/isc-dhcp42-server make install clean Автозапуск и логирование

  1. echo dhcpd_enable=YES >> /etc/rc.conf

echo /usr/local/etc/rc.d/isc-dhcpd forcestart >> /etc/rc.local echo dhcpd_withuser=root >> /etc/rc.conf echo '!dhcpd' >> /etc/syslog.conf echo 'local7.* /var/log/dhcpd.log' >> /etc/syslog.conf touch /var/log/dhcpd.log killall -HUP syslogd Настраиваем dhcp-сервер: /usr/local/etc/dhcpd.conf log-facility local7; option domain-name-servers 1.1.1.1;

subnet 10.100.0.0 netmask 255.255.0.0 {

   range 10.100.64.0 10.100.80.255;
   interface igb0;
   option routers 10.100.0.1;
   default-lease-time 2400;
   max-lease-time 1800;
   on commit {
       set ClientIP  = binary-to-ascii(10, 8, ".", leased-address);
       set ClientMac = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6));
       set SwitchMac = "";
       set SwitchPort ="";
       if exists agent.circuit-id
       {
           set SwitchMac = binary-to-ascii(16, 8, ":", suffix(option agent.remote-id, 6));
           set SwitchPort = binary-to-ascii(10, 8, ":", suffix(option agent.circuit-id, 1));
       }
       execute("/usr/bin/perl", "/usr/local/nodeny/modules/dhcp/events.pl", "commit",
               ClientIP, ClientMac, SwitchMac, SwitchPort);
   }
   on expiry {
       set ClientIP  = binary-to-ascii(10, 8, ".", leased-address);
       execute("/usr/bin/perl", "/usr/local/nodeny/modules/dhcp/events.pl", "expiry", ClientIP);
   }
   on release {
       set ClientIP  = binary-to-ascii(10, 8, ".", leased-address);
       execute("/usr/bin/perl", "/usr/local/nodeny/modules/dhcp/events.pl", "release", ClientIP);
   }

} interface igb0 - интерфейс, к которому подключены клиенты option routers 10.100.0.1 - ip вашего сервера на интерфейсе igb0, т.е. gateway для клиентов subnet - клиентская сеть range - диапазон ip адресов, которые выдает dhcp сервер клиентам. Должен попадать в subnet. Желательно взять диапазон с запасом: ip должно быть в несколько раз больше чем ваших клиентов. В админке NoDeny в настройках в разделе «ip pool» создаем ту же сеть, какая указана в конфиге в параметре range, при этом тип ip должен быть «динамический».

В разделе «Кабинет клиента» добавляем модуль dhcp.

Для того чтобы фаервол перенаправлял клиентов на веб-заглушку:

Компилируем ядро сервера с опцией «options IPFIREWALL_FORWARD»


В файле /usr/local/nodeny/cfg/noserver.cfg.pm устанавливаем в 1 параметр $forward_enabled = 1; Перезапускаем noserver.pl kill -9 `ps axu | grep noserver | grep -v grep | awk '{ print $2 }'` perl /usr/local/nodeny/noserver.pl -d & Смотрим, появилась ли команда fwd в правилах фаервола ipfw show | grep fwd Если не появилась, пробуем: ipfw add 65534 fwd 127.0.0.1,8080 tcp from any to any 80 Если ошибка - ядро не скомпилировалось с опцией форварда, может забыли ребутнуть сервер после перекомпиляции?

Если web-заглушка (модуль cap) не запускается по умолчанию, то либо в ее конфиге ставим параметр run => 1 либо (рекомендуется) запускаем отдельным процессом (и ставим автозапуск в /etc/rc.local):

Запускаем web-заглушку /usr/bin/perl /usr/local/nodeny/nokernel.pl -m=cap -d & Также запускаем модуль dhcp, но его не обязательно запускать отдельным процессом как в примере:

Запуск модуля dhcp отдельным процессом /usr/bin/perl /usr/local/nodeny/nokernel.pl -m=dhcp -d & Тестируем

Запускаем dhcp-сервер и смотрим лог NoDeny /usr/local/etc/rc.d/isc-dhcpd forcestart tail -f /usr/local/nodeny/logs/dhcp.events.log Включаем клиентский компьютер и убеждаемся, что он получил ip по dhcp.

В логе должно отобразиться подобное [commit] ip=10.100.65.98, mac=0:1d:2a:ff:22:88, mac_ok=001d2aff2288 | Необходима регистрация мака Это означает, что клиенту выдан ip, но мак пока не известен NoDeny. Если есть желание (или у вас что-то не получается), вы можете посмотреть в БД таблицу mac_uid - там будет зарегистрирован данный мак, ip, время, а uid = 0:

Команда mysql SELECT *, INET_NTOA(ip) FROM mac_uid; Если с клиентского компьютера открыть любую страницу, то запрос будет перехвачен заглушкой и выведено сообщение, что необходимо ввести логин и пароль. После их ввода, мак адрес должен быть привязан к id клиента - это можно проверить той же mysql командой, указанной выше.

Вы должны ввести логин и пароль не позднее чем через 10 минут от момента получения ip - это защита от ситуации, когда кто-то вручную пропишет ip и попытается его зарегистрировать.

Модуль dchp + Radius

В настройках админки в разделе «клиентская статистика» добавляем модуль dhcp.

Создаем пул ip адресов

   тип: динамические
   теги: guest

Это гостевые ip, с которых нельзя будет получить интернет. Количество ip должно превышать в несколько раз число устройств в сети, поскольку для каждого нового мак-адреса выделяется свой персональный гостевой ip (предусмотрено удаление старых записей, но запас должен быть).

Устанавливаем Radius (останавливаемся на создании mysql-процедур). Создаем:

Команды mysql DROP PROCEDURE IF EXISTS `radreply`; DELIMITER $$ CREATE PROCEDURE `radreply`(IN login VARCHAR(64)) BEGIN

   DECLARE usr_ip VARCHAR(15) DEFAULT NULL;
   INSERT INTO mac_uid (
       SELECT NULL, login, p.ip, 0, UNIX_TIMESTAMP(), 0, 0 ,0
       FROM ip_pool p WHERE uid=0 AND tags LIKE '%,guest,%'
           AND NOT EXISTS (SELECT ip FROM mac_uid WHERE ip=p.ip)
       LIMIT 1)
       ON DUPLICATE KEY UPDATE time=UNIX_TIMESTAMP();
   SELECT INET_NTOA(ip) INTO usr_ip FROM mac_uid WHERE mac=login;
   IF usr_ip IS NULL THEN
       DELETE FROM mac_uid WHERE uid=0 AND time<(UNIX_TIMESTAMP()-3600);
   END IF;
   SELECT NULL, login, 'Framed-IP-Address', usr_ip, '=';

END$$ DELIMITER ;

DROP PROCEDURE IF EXISTS `radupdate`; DELIMITER $$ CREATE PROCEDURE `radupdate`(IN login VARCHAR(64), IN ip VARCHAR(16), IN properties VARCHAR(255)) BEGIN

   CALL set_auth(ip, CONCAT('mod=dhcp;',REPLACE(properties,':',)));

END$$ DELIMITER ; Проверим:

Команды mysql call radreply('123'); select mac, inet_ntoa(ip) as ip, uid, time from mac_uid; Получаем в ответ +------+----------+-----+------------+ | mac | ip | uid | time | +------+----------+-----+------------+ | 123 | 10.0.0.2 | 0 | 1403783705 | +------+----------+-----+------------+ Здесь 10.0.0.2 - один из гостевых ip. При повторном выполнении call radreply('123') мы должны получать этот же ip, при этом должно изменяться поле time.

Команда bash ee /usr/local/etc/raddb/sql.conf Cтроку: authorize_reply_query = "call radreply('%{User-Name}')" меняем на

authorize_check_query = "SELECT NULL,'%{User-Name}','Auth-Type','Accept','='" Заметим, что User-Name - это не логин пользователя, а мак-адрес. Например в accel-ppp можно получить так:

function username(pkt)

       local interface = string.gsub(pkt:ifname(),'(eth%d+)%.(%d+)%.(%d+)$','%2-%3')               
       local mac = string.gsub(pkt:hdr("chaddr"),':',)                                           
       local username=mac..':'..string.gsub(interface,'-$',)                                     
       print(username)                                                                             
       return username                                                                             

end Здесь мы логин представили в виде мак:интерфейс.

В конфиге модуля dhcp меняем параметр run => 0 - этим мы отключили его запуск, поскольку он был предназначен для поддержания авторизации, а в случае Radius - он занимается этим.

Настраиваем NoDeny загрушку как это описано выше для работы с isc dhcpd.

Тестируем. Включаем клиентский компьютер и убеждаемся, что он получил гостевой ip по dhcp. Разлогиниваемся в админке, если до этого были в ней залогинены с тестируемого компьютера. Открываем в браузере любой url и попадаем на заглушку. После ввода логина и пароля должны получить сообщение, что компьютер зарегистрирован в системе. Необходимо получить новый не гостевой адрес (вкл/выкл соединение или передернуть кабель).