Содержание статьи
При организации гостевого подключения к интернету в конференц-залах, публичных библиотеках и кафе особое внимание следует уделить обеспечению безопасности и максимально простой аутентификации. Технология под названием Captive Portal призвана в этом помочь.
WARNING
Администраторы точек доступа обычно разрешают все DNS-запросы из внутренней сети во внешнюю. Это можно использовать для несанкционированного выхода в интернет при помощи технологии DNS tunneling, реализованной в таких решениях, как Dnscat, Ozyman, NameServer Transfer Protocol (NSTX), Dns2tcp, и других.
Как работает Captive Portal
Все пользователи, которые хотят подключиться к публичной Wi-Fi-сети и выйти в интернет, вначале проходят через шлюз, который представляет собой комп с несколькими сетевыми интерфейсами. Шлюз действует как маршрутизатор и брандмауэр, а для возможности авторизации пользователя при помощи браузера он содержит еще и веб-сервер. Для аутентификации клиентов может использоваться внутренняя база данных или внешний RADIUS-сервер. Все пакеты от «неавторизованных» пользователей помечаются на брандмауэре, и посетитель переправляется на специальную веб-страницу (Captive Portal), где он может ознакомиться с условиями подключения и ввести логин/пароль (либо код доступа). После аутентификации пользователя производится идентификация компьютера, за которым он работает, его МАС- и IP-адреса заносятся в белый список брандмауэра. В самом простом случае пользователь может вообще не проходить аутентификацию, Captive Portal автоматически получает IP- и MAC-адреса компьютера, которые сразу подставляются в правилах брандмауэра. В последующем все пакеты проходят через маршрутизатор без ограничений. Дополнительно, в зависимости от роли, могут устанавливаться ограничения по скорости, времени, трафику или посещаемым ресурсам.
В настоящее время существует несколько проектов, позволяющих быстро развернуть Captive Portal: Wifidog, PacketFence, ChilliSpot и веб-интерфейс EasyHotspot, KATTIVE, PepperSpot и jkaptive. Выбор конкретного решения зависит от необходимых функций и поддерживаемых ОС. Например, ChilliSpot официально поддерживает несколько дистрибутивов Linux, FreeBSD, OpenBSD и OpenWRT. К слову, это единственное приложение, пакет которого доступен в официальном репозитории Ubuntu, и установить его просто:
$ sudo apt-get install chillispot
Для организации простого портала без поддержки внешних средств аутентификации хватит и решения вроде jkaptive, а вот чтобы разобраться со всеми возможностями, заложенными в PacketFence, потребуется некоторое время. Некоторые из представленных проектов уже прекратили свое развитие, но все наработки по-прежнему актуальны. Также можно найти модули для различных языков, позволяющие самостоятельно создать Captive Portal из подручных средств. Например, для Perl он так и называется — Captive::Portal, есть модуль для Python/Django tollgate.org.au.
Кроме этого, ряд дистрибутивов-роутеров предлагает возможность быстрого создания Captive Portal буквально парой щелчков мышки: Untangle, pfSense, Zeroshell, m0n0wall, ClearOS и Zentyal. Но при желании или если невозможно изменить текущую конфигурацию сети нужные скрипты легко создать самостоятельно. Этим мы и займемся.
Настраиваем Captive Portal в Linux
Разобравшись, как работает Captive Portal, легко реализовать его штатными средствами Linux. Причем доступно несколько способов — маркировка и блокировка пакетов, пришедших от неавторизованных пользователей, использование цепочки правил или шаманство с NAT. Дополнительно на лету можно перенастраивать правила прокcи-сервера Squid или контент-фильтра DansGuardian, что позволит управлять выходом в интернет на уровне групп пользователей, да и просто кешировать и фильтровать информацию, блокируя доступ к нежелательным ресурсам. И кстати, именно такой подход применяется в специализированных дистрибутивах.
Для примера разберем вариант использования отдельной цепочки и DansGuardian. Первым делом создаем правила пакетного фильтра:
# Очищаем правила
ebtables -t broute -F
ebtables -F
# Переправляем пакеты, идущие к 80-му порту на стек iptables
ebtables -t broute -A BROUTING -p IPV4 --ip-protocol 6 --ip-destination-port 80 -j redirect --redirect-target ACCEPT
Не забываем разрешить специфические низкоуровневые протоколы:
ebtables -A INPUT -p ARP -j ACCEPT
ebtables -A FORWARD -p ARP -j ACCEPT
ebtables -A OUTPUT -p ARP -j ACCEPT
То же пишем и для LENGTH, и IPv4. Теперь создаем правила для iptables:
iptables -N captive
iptables -F captive
iptables -P FORWARD DROP
# Переправляем пакеты, идущие к порту 80, на 8080, где работает DansGuardian
iptables -t nat -I PREROUTING -i br0 -p tcp --dport 80 -j REDIRECT --to-ports 8080
iptables -t nat -I PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-ports 8080
iptables -t nat -I PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-ports 8080
# Создаем цепочку для LAN
iptables -A FORWARD -s 192.168.1.0/24 -j captive
iptables -A FORWARD -d 192.168.1.0/24 -j captive
# Разрешаем локальный трафик (добавляем все необходимые сети)
iptables -I FORWARD -p tcp -s 192.168.1.0/24 -d 192.168.1.0/24 -j ACCEPT
iptables -I FORWARD -p udp -s 192.168.1.0/24 -d 192.168.1.0/24 -j ACCEPT
iptables -A captive -j RETURN
Не забываем разрешить ICMP, DNS, DHCP и прочие необходимые протоколы. Здесь, кстати, есть один важный момент: многие админы не заморачиваются и разрешают весь DNS-трафик. Этим пользуются некоторые юзвери для получения доступа в Сеть при помощи технологии DNS tunneling. Конечно, итоговая скорость небольшая, но вполне достаточная, чтобы сидеть в аське, писать в твиттер или отдавать команды по SSH. И главное — при этом везде засветится IP твоей сети, а в логах какие-либо записи о несанкционированной деятельности будут отсутствовать, ведь не каждый админ пишет все запросы в журнал DNS-сервера. Поэтому лучше строго указать разрешенные серверы.
Настраиваем Captive Portal в Zentyal
Если под Captive Portal выделяется новый сервер и все настройки нужно произвести в короткое время, то лучше обратиться к специализированным решениям, где все необходимое делается буквально парой нажатий клавиш. Яркий пример — серверный дистрибутив Zentyal, ориентированный на малые и средние корпоративные сети. Он может выступать в любой из четырех ролей сетевого шлюза, Office Server, сервера коммуникаций и инфраструктуры. Для поддержки Captive Portal следует во время установки активировать одноименный модуль (активируется роль Gateway и все сопутствующие пакеты). Затем в мастере первичной настройки правильно указываем на LAN-интерфейс. Создаем учетные записи пользователей и группы. Далее в интерфейсе настройки Zentyal переходим в меню Captive Portal и отмечаем в поле «Captive-интерфейсы» нужный, выбираем группу, участники которой будут иметь доступ, и указываем порт, на который будут перенаправляться пользователи. Вот и все. Теперь любой, кто желает подключиться к сети, вводит свои учетные данные, если аутентификация проходит успешно, появляется всплывающее окно, которое нужно держать открытым. Чтобы отключиться, достаточно нажать кнопку «Выйти» или просто закрыть окно браузера.
Если имеем шлюз, построенный на Ubuntu, то для установки связанных с Zentyal приложений проще использовать специальный репозиторий:
$ sudo add-apt-repository ppa:zentyal/3.0
$ sudo apt-get update
После чего команда sudo apt-cache search zentyal покажет более 20 модулей Zentyal.
iptables -I FORWARD -p tcp -s 192.168.1.0/24 -d 8.8.8.8/32 -j ACCEPT
iptables -I FORWARD -p udp -s 192.168.1.0/24 -d 8.8.8.8/32 -j ACCEPT
В принципе, на этот момент ничего особенного нет. Суть Captive Portal заключается в добавлении нужных правил на лету. Для этого понадобится скрипт, который будет получать IP/MAC и передавать их пакетному фильтру. Полностью HTML-страницу приводить здесь нет смысла, поэтому ограничимся ключевыми моментами с нужным функционалом. На странице, куда перенаправляется пользователь, должен быть следующий код, получающий IP- и MAC-адреса:
<?php $ip = $_SERVER['REMOTE_ADDR'];
$arp = "/usr/sbin/arp";
$mac = shell_exec("sudo $arp -an " . $ip);
preg_match('/..:..:..:..:..:../',$mac , $matches);
$mac = @$matches[0];
if( $mac === NULL) { echo "Access Denied."; exit; } ?>
<form method="post" action="action.php">
<input type="hidden" name="mac" value="<?php echo $mac; ?>" />
<input type="hidden" name="ip" value="<?php echo $ip; ?>" />
<input type="submit" value="OK" style="padding:10px 20px;" />
</form>
При необходимости добавляем поле для проверки логина и пароля, нужные примеры легко найти в интернете. Далее в этом же скрипте подставляем полученные данные в правила iptables и DansGuardian, после чего перезапускаем последний:
exec("sudo /sbin/iptables-bin -I captive -s {$_SERVER['REMOTE_ADDR']} -j captive");
exec("sudo /sbin/iptables-bin -I captive -d {$_SERVER['REMOTE_ADDR']} -j captive");
exec("touch /etc/dansguardian/lists/authplugins/ipgroups");
exec("echo \"{$_SERVER['REMOTE_ADDR']} = filter1\" >> /etc/dansguardian/lists/authplugins/ipgroups");
exec("sudo /sbin/service dansguardian reload");
После подключения клиента запись в /etc/dansguardian/lists/authplugins/ipgroups будет выглядеть так:
192.168.1.100 = filter1
Параметр filter1 указывает на группу фильтров, так мы можем устанавливать специфические настройки для всех пользователей, подключающихся посредством Captive Portal. При необходимости так же легко в DansGuardian подставляется и логин пользователя, для реализации индивидуальных правил. Не забываем разрешить фильтр IP в dansguardian.conf:
$ sudo nano /etc/dansguardian/dansguardian.conf
authplugin = '/etc/dansguardian/authplugins/ip.conf'
Так как используемые системные команды может выполнять только root, немного подправим sudoers, чтобы их мог запускать и веб-сервер:
$ sudo nano /etc/sudoers
...
www-data ALL=(root) NOPASSWD: /sbin/iptables-bin
www-data ALL=(root) NOPASSWD: /sbin/service
www-data ALL=(root) NOPASSWD: /sbin/arping
Вот мы и реализовали простейший Captive Portal. Если хотспот будет работать сутками, следует побеспокоиться, чтобы через некоторое время таблица очищалась. Здесь можно придумать несколько вариантов. Например, параллельно создавать задание для cron, которое будет срабатывать через определенное время, убирая правило. Другой вариант — прописывать данные сессии в отдельный файл, а затем при помощи cron или при каждом вызове PHP-скрипта анализировать время создания файла и удалять устаревшие записи. В Zentyal, например, после регистрации пользователя открывается отдельное окно, а в каталоге /var/lib/zentyal-captiveportal/sessions создается файл, содержащий все данные сессии (IP- и MAC-адрес). Как только пользователь закрывает Popup, вся информация и правила очищаются.
Настройка Captive Portal в FreeBSD
Понимая, как работает пакетный фильтр, и владея навыками разработки на языке, используемом в веб, легко организовать Captive Portal в любой ОС. И *BSD здесь не исключение, причем реализация при помощи IPFW выглядит даже проще. Принцип остается тем же, что и ранее. Все пакеты от неавторизованных пользователей блокируем и перенаправляем на веб-страницу. После того как гость подтверждает информацию, разрешаем выход в Сеть. Для удобства всю информацию об авторизованных IP будем сохранять в базу данных (в примере текстовый файл). Заносим в системный файл вроде /etc/rc.local (а лучше в отдельный, чтобы было легче искать) необходимые переменные:
# Файл с базой разрешенных IP
$db = "/tmp/session.db";
# IP-адрес и порт Apache
$gateway = "192.168.0.100,8080";
# Подсеть Wi-Fi
$wnet = "192.168.1.0/24";
# Проводная LAN
$pnet = "192.168.0.0/24";
# Список портов, которые необходимо блокировать и форвардить
$fwdports = "80,21,23,25,110,443";
# Группировка правил брандмауэра
$setnum = "set 5";
# Начальный номер правил для блокировки и форвардинга, желательно сделать число большим, чтобы не мешать текущим установкам
$fwdrulenum = "50000";
# Добавляем правило форвардинга
ipfw -q add $fwdrulenum $setnum fwd $gateway tcp from $wnet to any $fwdports
# Запрещаем выход с Wi-Fi в LAN (если нужно, конечно)
$denyrulenum = $fwdrulenum + 1;
ipfw -q add $denyrulenum $setnum deny all from $wnet to $pnet
В веб-страницу добавляем следующий код. В примере пользователь в чекбоксе просто подтверждает некие условия, результат отправляется Perl-скрипту access.pl.
index.html
<form name="form1" method="post" action="access.pl">
<div align="center">
<input name="submit" type="submit" id="submit" value="I Agree">
</div>
</form>
Здесь Perl выбран исключительно для разнообразия, при желании можно переработать PHP-код, показанный выше. Сам скрипт:
access.pl
#!/usr/bin/perl
require 5.004;
use Fcntl qw(:DEFAULT);
# Для доступа к файлу используем модуль (perldoc.perl.org/NDBM_File.html)
use NDBM_File;
# Получаем IP пользователя
$USERIP = $ENV{REMOTE_ADDR};
# Файл базы данных
$db = "/tmp/session.db";
# Заносим данные IP в файл и добавляем разрешающее правило
tie %hash, "NDBM_File", $db, O_RDWR|O_CREAT, 0644;
$hash{userip} = $USERIP;
$rulenum--;
system("ipfw -q add $rulenum $setnum allow all from $ip to any");
untie %hash;
print "Доступ разрешен\n";
При желании дополняем скрипт проверкой МАС-адреса и перестройкой правил прокси-сервера. Вызвав функцию time(), мы также можем сохранить время соединения (в секундах), которое затем использовать для сброса старых соединений.
access.pl
$TSTAMP = time();
# Добавляем в вызов tie
...
$hash{time} = $TSTAMP;
$hash{userip} = $USERIP;
...
# Проверяем, что время сессии вышло (примеры легко найти в интернете), и снимаем правило
if (время вышло) {
system("ipfw -q delete $setnum");
unlink("$db");
exit(0);
}
Captive Portal на Windows
Организовать Captive Portal на Windows штатными средствами проблематично из-за особенностей работы брандмауэра (который, кстати, начал контролировать исходящие соединения только с Vista), поэтому в любом случае придется обращаться к сторонним решениям. Выбор здесь не особенно велик — DNS Redirector, FirstSpot, PacketFence, myWIFIzone, работает под WinXP/2k), Wifidog и Antamedia HotSpot. Из них бесплатны PacketFence и Wifidog. Первый требует некоторой подготовки, а используемые во втором компоненты, такие как Apache, PHP, PostgreSQL, удобнее разворачивать на *nix-системе.
Из перечисленных наиболее функционален Antamedia HotSpot, который позволяет организовать свободный и предоплаченный доступ (по трафику, времени или скорости), управлять пропускной способностью, гарантируя нужную скорость разным клиентам, блокировать нежелательные сайты, получать статистику и многое другое. Развертывание Antamedia HotSpot не представляет особой сложности, в режиме простой установки все компоненты (хотспот, интерфейс оператора и база данных) устанавливаются на один компьютер. Разобраться с первоначальными установками помогает визард, интерфейсы настраиваются автоматически, пользователь может также выбрать внешний вид страницы регистрации. Дальнейшее управление производится при помощи понятного интерфейса.
Заключение
Организовать точку доступа с различными вариантами использования не так уж и сложно. Выбор конкретного решения зависит от наличия времени на подготовку и желания копаться в настройках. Все представленные схемы можно легко развить до требуемого уровня.