--- title: 'Captive portal' date: '22:22 26-11-2014' publish_date: '22:22 26-11-2014' taxonomy: category: - Blog tag: - Linux - gelonet.ru --- Собираю инфу по реализации Captive порталов для WiFI сетей. Вот, первая пташка. [Captive portal собственными руками](https://habr.com/ru/sandbox/79059/) > Каждый из нас подключался к беспроводной сети (аэропорты, кафе и тд) где необходимо согласится с некоторыми условиями или пройти авторизации прежде чем начинать пользоваться интернетом. Такая технология называется captive portal. > > В мою задачу входило создать captive portal где каждому пользователю раз в 30 минут будет показываться определенный сайт (реклама), и пока он не нажмет «кнопочку» «далее» интернета не будет. > > Для создания нам понадобится: > Wifi-точка доступа любая (на практике можно использовать и проводной интернет) > Маршрутизатор на любой *nix системе (в моем случае это debian wheezy) > > > Краткое описание принципа работы > Любой пакет пришедший на маршрутизатор маркируем > Любой запрос на 80 порт (пакеты уж маркированны) перенаправляем на нужную нам страницу > При «авторизации»(нажатии кнопки далее) пользователя добавляем его мак в исключения и разрешаем доступ в интернет > Скрипт вычисляет у кого прошел лимит времени и удаляет данного клиента. > > > > У нас имеется маршрутизатор на базе debian, где eth0 — локальная сеть в моем случае (192.168.11.0/24), eth0:1 — интерфейс который смотрит в интернет. > > Настройку интерфейсов мы пропустим, это каждый выполнит сам. Сразу перейдем к настройке iptables, я обычно прописываю iptables в rc.local: > /etc/rc.local > IPTABLES="/sbin/iptables" > EBTABLES="/sbin/ebtables" > DHCP="67:68" > SSH="22" > WWW="80" > > $IPTABLES -t mangle -F > $IPTABLES -F > > $IPTABLES -A INPUT -i lo -j ACCEPT > #ssh > $IPTABLES -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT > # разрешаем серверу и клиентам dns гугла > $IPTABLES -A INPUT -s 8.8.8.8 -j ACCEPT > $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT > > # создаем правило интернет > $IPTABLES -N internet -t mangle > $IPTABLES -t mangle -A PREROUTING -j internet > #добавляем разрешенные маки в исключения путем добавления их в Return > awk 'BEGIN { FS="\t"; } { system("$IPTABLES -t mangle -A internet -m mac --mac-source "$4" -j RETURN"); }' /var/lib/users > #маркируем все пакеты > $IPTABLES -t mangle -A internet -j MARK --set-mark 99 > # все маркированные пакеты которые идут на 80 порт отправляем на наш сервер > $IPTABLES -t nat -A PREROUTING -m mark --mark 99 -p tcp --dport 80 -j DNAT --to-destination 192.168.11.38 > #дроппаем все маркированное > #$IPTABLES -t filter -A FORWARD -m mark --mark 99 -j DROP > #dns > $IPTABLES -t filter -A INPUT -s 8.8.8.8 -j ACCEPT > #http > $IPTABLES -t filter -A INPUT -p tcp --dport 80 -j ACCEPT > #port dns > $IPTABLES -t filter -A INPUT -p udp --dport 53 -j ACCEPT > #drop > $IPTABLES -t filter -A INPUT -m mark --mark 99 -j DROP > echo "1" > /proc/sys/net/ipv4/ip_forward > #настройка нат > $IPTABLES -A FORWARD -i eth0 -o eth0:1 -m state --state ESTABLISHED,RELATED -j ACCEPT > $IPTABLES -A FORWARD -i eth0:1 -o eth0 -j ACCEPT > $IPTABLES -t nat -A POSTROUTING -o eth0 -j MASQUERADE > > На этом конфигурация iptables заканчивается и переходим к странице которую получает пользователь: /var/lib/index.php > > $server_name = "192"; > $domain_name = "168.11.38"; > $site_name = "Wireless Network"; > > // arp > $arp = "/usr/sbin/arp"; > > // файл где хранятся текущие пользователи > $users = "/var/lib/users"; > > // Check if we've been redirected by firewall to here. > // If so redirect to registration address > if ($_SERVER['SERVER_NAME']!="$server_name.$domain_name") { > header("location:http://$server_name.$domain_name/index.php?add=" > .urlencode($_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'])); > exit; > } > > // получаем и добавляем мак пользователя > $mac = shell_exec("$arp -a ".$_SERVER['REMOTE_ADDR']); > preg_match('/..:..:..:..:..:../',$mac , $matches); > @$mac = $matches[0]; > if (!isset($mac)) { exit; } > > if (!isset($_POST['email']) || !isset($_POST['name'])) { > // Name or email address not entered therefore display form > ?> >