Pull to refresh

Динамическое ограничение доступа посредством web авторизации

Reading time 3 min
Views 1K
Зачастую возникает необходимость обеспечить доступом какой-то сегмент гостевой пользовательской сети ограниченный по времени.

Расскажу немного о задаче.
У нас есть wifi сеть или LAN в интернет кафе где нам необходимо обеспечивать повременной доступ к интернет. Желательно чтобы управление системой было — поставил и забыл, дать оператору генерилку паролей с принтером и вручить кассовый аппаратдля приёма денег.

Многие придумывают схемы авторизации, скрипты которые время от времени меняют системные таблицы firewall согласно необходимым задачам, а полностью динамической системы так никто и не написал. Поэтому предлагаю прототип который любой сисадмин адаптирует для своих задач.

Думаю администраторы Linux систем смогут реализовать этот механизм на основе своих любимых firewall, но мы будем использовать pf.
Почему pf спросите Вы?
Потому-что у него есть замечательная вещь называемая динамическими таблицами.
В конфигурационном файле pf таблицы описываются в виде:

table <wifiallow> persist

Содержимое таблиц можно динамически менять при помощи командной строки, а также утилиты pftabled. Утилита представляет собой udp сервер который принимает команды управления содержимым таблиц.
Через командную строку таблицами управлять очень просто:
pfctl -t tablename -T show - показать содержимое таблицы
pfctl -t tablename -T expire 3600 - удалить все элементы старше 1 часа
pfctl -t tablename -T add 10.10.10.10 - добавить с таблицу элемент
pfctl -t tablename -T delete 10.10.10.10 - удалить элемент из таблицы
pfctl -t tablename -T flush - очистить таблицу

pftabled позволяет делать операции add, delete и flush посредством udp пакетов. В последнем релизе pftabled 1.07 есть perl клиент для управления pftabled. Естественно все операции производятся только от авторизованных хостов имеющих такой-же ключ как и слушающий сервер.

Итак что нам необходимо?
apache с модулем mod_rewrite и желание реализации данной схемы.

Основной принцип работы схемы прост. Если адрес хоста пытающегося выйти в интернет хост отсутствует в таблице разрешений, то необходимо перебросить его на веб морду с просьбой ввести логин и пароль. Если хост в таблице присутствует, то его необходимо выпустить в инет.
в pf это решается следующим образом
$int_if = "xl0";
$ext_if = "xl1";
rdr on $int_if proto tcp from !<wifiallow> to any port 80 -> $int_if port 8081 # проброс всех запросов на порт apache с вебмордой
nat on $ext_if proto tcp from <wifiallow> to any -> ($ext_if) # nat всех кто разрешен в инет

В конфиге apache создаём виртуальный хост и прописываем rewrite правила для всех входящих запросов на наш скрипт.

<Directory "/usr/local/www/wifi-redir">
Options Indexes ExecCGI FollowSymLinks
Allow from all
RewriteEngine on
RewriteRule ^(.*)$ redirect.cgi?url=$1 [L]
RewriteRule ^redirect\.cgi$ - [L]
</Directory>

Скрипт принимает запрос и выдаёт авторизационную форму. В качестве параметра url будет передаваться запрошенный пользователем адрес. После submit и неверно введенных логине пароле внутри формы необходимо сделать редирект на реферер с которого была заполнена форма. Если пропустить эту операцию, то заполнение формы войдёт в бесконечный цикл.
Если логин и пароль верны, что при помощи куска из perl клиента Вы тут же в онлайн просто добавляете запись в таблицу wifiallow и где-то у себя журналируете, что данный логин и пароль уже использован(чтобы не было злоупотреблений)., а потом делаете редирект на url который изначально запросил пользователь. Таблицу логинов и паролей можно вести в mysql или в любом удобном для Вас виде. После того как форма заработала Вы добавляете в crontab строку

* * * * * /sbin/pfctl -t wifiallow -T expire 3600 > /dev/null

которая будет ежеминутно удалять из таблицы IP адреса со временем создания больше 1 часа. Единственной проблемой которая может возникнуть — это поддержка pf уже установленных соединений. Выход прост. Пишем маленький скрипт на shell+awk+grep, который будет раз в одну/пять минут делать pfctl -k hostip(удаление keepstate соединений) для хостов которых нет в таблице разрешенных адресов.

Данная схема опробирована и работает у нас в компании. Выкладывать содержимое скриптов и текущие настройки firewall я думаю смысла не имеет, ибо у каждого из админов своя ситуация с раздачей адресов dhcp, резолвом имён и т.д. Основная идея реализации описана выше.

Удачи Вам в реализации и эксплуатации этого решения.
Tags:
Hubs:
+3
Comments 1
Comments Comments 1

Articles