Предыдущая версия справа и слева
Предыдущая версия
Следующая версия
|
Предыдущая версия
|
wifiadmin [2012/02/23 15:42] metallic [Реализация] |
wifiadmin [2012/02/24 17:51] test |
| |
Теперь, как уже говорилось выше, точка доступа переводится в режим сетевого моста. | Теперь, как уже говорилось выше, точка доступа переводится в режим сетевого моста. |
Далее нужно установить весь сопутствующий софт: nginx, uwsgi, pip (/usr/ports/devel/py-pip), isc-dhcpd, python. Плюс на свой вкус надо выбрать СУБД, в которой будут храниться данные, самый простой вариант – это sqlite3, для этого надо поставить py-sqlite3. Как это делается, описывать не буду, думаю и так понятно. Заключительным этапом ставим фреймворк django и проверяем, что все установлено корректно: | Далее нужно установить весь сопутствующий софт: nginx, uwsgi, pip (/usr/ports/devel/py-pip), isc-dhcpd, python, sudo. Плюс на свой вкус надо выбрать СУБД, в которой будут храниться данные, самый простой вариант – это sqlite3, для этого надо поставить py-sqlite3. Как это делается, описывать не буду, думаю и так понятно. Заключительным этапом ставим фреймворк django и проверяем, что все установлено корректно: |
| |
<konsole> | <konsole> |
</konsole> | </konsole> |
| |
Переходим к самому сервису авторизации. Скачиваем архив {{:wifiadmin.zip|}} и распаковываем его в /www, должно получиться следующее: | Переходим к самому сервису авторизации. Скачиваем архив {{:wifiadmin.tar|}} и распаковываем его в /www, должно получиться следующее: |
<konsole> | <konsole> |
<nowiki> | <nowiki> |
| |
и запускаем | и запускаем |
# /usr/local/etc/rc.d/uwsgi start | <konsole> |
| <nowiki> |
| # /usr/local/etc/rc.d/uwsgi start |
| </nowiki> |
| </konsole> |
| |
Теперь надо скомпилировать небольшую программку(wificmd), которая будет добавлять/удалять IP-адреса клиентов из таблицы пакетного фильтра. Она принимает два аргумента, действие add/delete и сам IP-адрес. Написана программа на языке Си, на самом деле это не важно, главное то, что она должна быть бинарной, т.к. ее будет вызывать сервис авторизации, который работает через nginx, у которого в свою очередь ограничены права, а для того, чтобы внести изменения в пакетный фильтр требуются права суперпользователя. Получается у нас два варианта как разрешить веб-серверу запускать wificmd, либо установить sticky bit, либо настроить sudo. Ни первый не второй вариант мы не можем реализовать со скриптом, поэтому пришлось сделать небольшую отдельную программу, очень ограниченную в возможностях, которая только умеет добавлять и удалять адреса из жестко прописанной в коде таблицы. | Теперь надо скомпилировать небольшую программку(wificmd), которая будет добавлять/удалять IP-адреса клиентов из таблицы пакетного фильтра. Она принимает два аргумента, действие add/delete и сам IP-адрес. Написана программа на языке Си, на самом деле это не важно, главное то, что она должна быть бинарной, т.к. ее будет вызывать сервис авторизации, который работает через nginx, у которого в свою очередь ограничены права, а для того, чтобы внести изменения в пакетный фильтр требуются права суперпользователя. Получается у нас два варианта как разрешить веб-серверу запускать wificmd, либо установить sticky bit, либо настроить sudo. Ни первый ни второй вариант мы не можем реализовать со скриптом, поэтому пришлось сделать небольшую отдельную программу, очень ограниченную в возможностях, которая только умеет добавлять и удалять адреса из жестко прописанной в коде таблицы. |
Итак, выполняем команду: | Итак, выполняем команду: |
# gcc /www/wifiadmin/wificmd.c -o /www/wifiadmin/wificmd | |
| <konsole> |
| <nowiki> |
| # gcc /www/wifiadmin/wificmd.c -o /www/wifiadmin/wificmd |
| </nowiki> |
| </konsole> |
| |
Второй вариант с sudo более красивый, т.к. выполнять wificmd смогут не все непривилегированные пользователи, а только один - www, поэтому я использовал именно его. Ставим sudo и в sudoers прописываем wificmd так, чтобы пользователь www мог выполнять ее от имени суперпользователя без запроса пароля: | Второй вариант с sudo более красивый, т.к. выполнять wificmd смогут не все непривилегированные пользователи, а только один - www, поэтому я использовал именно его. Ставим sudo и в sudoers прописываем wificmd так, чтобы пользователь www мог выполнять ее от имени суперпользователя без запроса пароля: |
| |
openwifi_net="192.168.40.0/24" | openwifi_net="192.168.40.0/24" |
| ext_if="em0" |
| int_if="em1" |
wifi_if="em2" | wifi_if="em2" |
| |
| # Заставляем пакетный фильтр создать пустую таблицу |
table <openwifi> persist | table <openwifi> persist |
| |
| # Наши локальные сети |
| table <not_routable> { 10.0.0.0/8, 192.168.0.0/16 } |
| |
scrub in all fragment reassemble | scrub in all fragment reassemble |
scrub out all random-id max-mss 1400 | scrub out all random-id max-mss 1400 |
| |
set skip on default | set skip on $int_if |
set skip on lo | set skip on lo |
| |
nat from <openwifi> to any -> ng0 | # Разрешаем нат от клиентов из таблицы openwifi |
| nat from <openwifi> to any -> $ext_if |
| # Но если клиент не в таблице openwifi, то перенаправляем его на сервис авторизации |
rdr pass on $wifi_if proto tcp from ! <openwifi> to any port 80 -> 127.0.0.1 port 444 | rdr pass on $wifi_if proto tcp from ! <openwifi> to any port 80 -> 127.0.0.1 port 444 |
| |
# Это если у вас нет своего DNS-сервера | # Это если у вас нет своего DNS-сервера |
nat proto udp from $openwifi_net to { 8.8.8.8, 8.8.4.4 } port 53 -> ng0 | nat proto udp from $openwifi_net to { 8.8.8.8, 8.8.4.4 } port 53 -> $ext_if |
| |
block in | block in |
pass in proto tcp from $openwifi_net to $wifi_if port 443 | pass in proto tcp from $openwifi_net to $wifi_if port 443 |
| |
pass in proto { tcp udp icmp } from <openwifi> to any | # Ну и разрешаем доступ в интернет |
| pass in proto { tcp udp icmp } from <openwifi> to { !<not_routable> } |
| |
| В заключении нужно прописать в crontab скрипт, который будет выполняться каждые 10 минут и закрывать истекшие сесии: |
| |
| . */10 * * * * www /www/wifiadmin/wifiadmin/cron.py |
| |
| <note>Также не забудьте дать права на выполнение файлу cron.py</note> |
| |
| На этом настройка закончена, теперь, если все было настроено корректно, при попытке входа на любой сайт через wifi, пользователя будет перекидывать на страничку авторизации. |
| |
| ===== Скриншоты ===== |
| {{:wifiadmin_1.png?direct&200|}} {{:wifiadmin_2.png?direct&200|}} {{:wifiadmin_3.png?direct&200|}} {{:wifiadmin_4.png?direct&200|}} {{:wifiadmin_5.png?direct&200|}} {{:wifiadmin_6.png?direct&200|}} |
| |
| ===== Как работает wifiadmin ===== |
| Принцип работы следующий: клиенты подключаются к открытой wifi-сети, автоматически получают сетевые настройки и при первой попытке открыть любой веб-узел перенаправляются на страницу авторизации. После успешной авторизации адрес клиента добавляется в специальную таблицу в фаерволе, в БД добавляется информация в таблицу сессий и пользователю предоставляется доступ в интернет. Специальный скрипт cron.py выполняется каждые 10 минут и проверяет активные сессии, если есть сессии время которых превышает максимальное время сессии, указанное в конфиге, то она закрывается. Если пользователь, сессия которого активна, авторизуется с другого компьютера с другим IP-адресом, то его старая сессия закроется и откроется новая для текущего компьютера. |
| |
| <note tip> |
| Просматривать список адресов в таблице маршрутизации в текущий момент можно с помощью команды: |
| |
| pfctl -t openwifi -T show |
| </note> |
| |
| В админке в wifiadmin есть несколько разделов: Auth и Main. В первом разделе создаются пользователи и группы, это стандартный раздел django admin, по большому счету там можно создавать только пользователей и давать им права суперпользователя, эти акаунты нужны только для входа в админку. Второй раздел main относится к wifi, там как раз создаются пользователи для доступа в интернет. У пользователей есть несколько параметров, такие как срок действия акаунта, активен он или нет и т.д. В журнал в обычном режиме пишутся события безопасности, а в режиме отладки подробный отчет о всех выполненных действиях на каждом этапе. Ну и наконец раздел "сессии" содержит информацию о подключениях, дата подключения, активна ли сессия и с какого адреса было открыто подключение. Тут же есть функция ручного отключения пользователя, если сессия активна. |
| |
| ===== Известные проблемы ===== |
| * В некоторых браузерах, например firefox кеширует перенаправление на сервис авторизации и даже после успешной авторизации, при попытке входа на тот сайт, с которого было выполнено перенаправление, пользователь все равно попадает на сервис авторизации. Лечится очисткой кеша для данного сайта. |
| |
| ===== План работ ===== |
| * Возможно, стоит сделать еще один cron-скрипт, который будет каждый час или каждые сутки проверять, нет ли в таблице openwifi адресов, которые не числятся в БД в таблице сессий как активные, таким образом, они никогда не будут удалены из таблицы маршрутизации. Такая ситуация маловероятна, но теоретически возможна из-за какого-либо сбоя. |
| |
| |
| ~~DISCUSSION~~ |
| |
| |