Приведу пример настройки переадресации клиентов без денег на captive portal при подключении к сети.
Допустим Nginx установлен, например как я описывал в статье Установка и настройка Nginx. На практике nginx использует меньше ресурсов системы и работает быстрее чем Apache2.
Сделаем файла конфигурации для клиентов у кого закончились деньги:
nano /etc/nginx/sites-enabled/page_credit
Добавим в новый файле следующее:
server {
allow 10.0.0.0/8;
allow 172.16.0.0/12;
deny all;
server_tokens off;
listen 81;
access_log off;
root /var/www/81;
index index.php;
server_name _;
location / {
if ( $http_user_agent ~ ^uTorrent ) {
return 404;
}
if ( $http_user_agent ~ Windows-Update-Agent ) {
return 404;
}
if ( $http_user_agent ~ "Microsoft NCSI" ) {
return 302 https://captive.ixnfo.com;
}
if ( $http_user_agent ~ "ESS Update" ) {
return 404;
}
if ( $http_user_agent ~ "Google Update" ) {
return 404;
}
if ( $http_user_agent ~ "Microsoft-CryptoAPI" ) {
return 404;
}
if ( $http_user_agent ~ "Microsoft BITS" ) {
return 404;
}
if ( $http_user_agent ~ MSDW ) {
return 404;
}
if ( $http_user_agent ~ ^SeaPort ) {
return 404;
}
if ( $http_user_agent ~ ^Windows-Media-Player ) {
return 404;
}
if ( $http_user_agent ~ "Google Update" ) {
return 404;
}
if ( $http_user_agent ~ ^GoogleEarth ) {
return 404;
}
if ( $http_user_agent ~ ^Skype ) {
return 404;
}
if ( $http_user_agent = "MailRuSputnik" ) {
return 404;
}
if ( $http_user_agent ~ ^Ya\.Online ) {
return 404;
}
if ( $http_user_agent ~ ^MRA ) {
return 404;
}
if ( $http_user_agent ~* ^MediaGet ) {
return 404;
}
if ( $http_user_agent ~ ^BTWebClient ) {
return 404;
}
if ( $http_user_agent ~ ^Syncer ) {
return 404;
}
if ( $http_user_agent = "TMUFE" ) {
return 404;
}
if ( $http_user_agent ~ ^Akamai\ NetSession\ Interface ) {
return 404;
}
if ( $http_user_agent ~ ^VKSaver ) {
return 404;
}
if ( $http_user_agent ~ DrWebUpdate ) {
return 404;
}
if ( $http_user_agent = "" ) {
return 404;
}
if ( $host ~ geo\.kaspersky\.com ) {
return 404;
}
if ( $host ~ (su|download|webrep).*\.avast\.com ) {
return 404;
}
if ( $host = wi2geo.mobile.yandex.net ) {
return 404;
}
if ( $host ~ bar.*\.yandex\.ru ) {
return 404;
}
if ( $host ~ (ping|master)\d*\.(dyngate|teamviewer)\.com ) {
return 404;
}
if ( $host ~ sitecheck\d*\.opera\.com ) {
return 404;
}
if ( $host ~ (xml\.my|mailsputnik|maps)\.mail\.ru ) {
return 404;
}
if ( $host = onlineconfigservice.ubi.com ) {
return 404;
}
if ( $host = com-services.pandonetworks.com ) {
return 404;
}
if ( $host ~ ticno\.com ) {
return 404;
}
if ( $host ~ conduit ) {
return 404;
}
if ( $host ~ cbox\.ws ) {
return 404;
}
if ( $host ~ (pricelist|metrics)\.skype\.com ) {
return 404;
}
if ( $host = weather.service.msn.com ) {
return 404;
}
if ( $host = advstat.letitbit.net ) {
return 404;
}
if ( $host = skymonk.net ) {
return 404;
}
if ( $host ~ counter ) {
return 404;
}
if ( $host ~ pluraserver ) {
return 404;
}
if ( $host ~ apps.bittorrent.com ) {
return 404;
}
if ( $host ~ tracker ) {
return 404;
}
if ( $request_uri ~* (update|feed|announce|rss|xml|json|oauth) ) {
return 404;
}
if ( $request_uri ~* (toolbar|suggest) ) {
return 404;
}
if ( $request_filename ~ \.(ico|gif|jpg|png) ) {
return 404;
}
if ( $request_filename ~ \.(css|xml|js|swf|flv) ) {
return 404;
}
if ( $request_filename ~ \.(crl|txt|cab|msi|jar) ) {
return 404;
}
if ( $host ~ norton ) {
return 404;
}
rewrite ^ https://captive.ixnfo.com/ redirect;
}
location ~ \.php$ {
try_files $uri =404;
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
}
Страничку с текстом я создал на другом сервере, а в файл /var/www/81/index.php я добавил содержимое:
<?php
header('Content-Type: text/html; charset=cp1251');
http_response_code(511);
?>
<html>
<head>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="Refresh" content="1;URL=https://captive.ixnfo.com">
</head>
No payment
</html>
Сделаем файла конфигурации для неизвестных клиентов:
nano /etc/nginx/sites-enabled/unknown_clients
Добавим в него:
server {
allow 10.0.0.0/8;
allow 10.55.56.0/24;
deny all;
server_tokens off;
listen 82;
access_log off;
#access_log /var/log/nginx/unknown.access.log;
root /var/www/82/;
index index.php;
server_name test_ixnfo;
add_header Cache-Control no-cache;
#expires 0;
location / {
if ( $http_user_agent ~ ^uTorrent ) {
return 404;
}
if ( $http_user_agent ~ Windows-Update-Agent ) {
return 404;
}
if ( $http_user_agent ~ "Microsoft NCSI" ) {
return 302 http://192.168.2.2:82/index.php;
}
if ( $http_user_agent ~ "ESS Update" ) {
return 404;
}
if ( $http_user_agent ~ "Google Update" ) {
return 404;
}
if ( $http_user_agent ~ "Microsoft-CryptoAPI" ) {
return 404;
}
if ( $http_user_agent ~ "Microsoft BITS" ) {
return 404;
}
if ( $http_user_agent ~ MSDW ) {
return 404;
}
if ( $http_user_agent ~ ^SeaPort ) {
return 404;
}
if ( $http_user_agent ~ ^Windows-Media-Player ) {
return 404;
}
if ( $http_user_agent ~ "Google Update" ) {
return 404;
}
if ( $http_user_agent ~ ^GoogleEarth ) {
return 404;
}
if ( $http_user_agent ~ ^Skype ) {
return 404;
}
if ( $http_user_agent = "MailRuSputnik" ) {
return 404;
}
if ( $http_user_agent ~ ^Ya\.Online ) {
return 404;
}
if ( $http_user_agent ~ ^MRA ) {
return 404;
}
if ( $http_user_agent ~* ^MediaGet ) {
return 404;
}
if ( $http_user_agent ~ ^BTWebClient ) {
return 404;
}
if ( $http_user_agent ~ ^Syncer ) {
return 404;
}
if ( $http_user_agent = "TMUFE" ) {
return 404;
}
if ( $http_user_agent ~ ^Akamai\ NetSession\ Interface ) {
return 404;
}
if ( $http_user_agent ~ ^VKSaver ) {
return 404;
}
if ( $http_user_agent ~ DrWebUpdate ) {
return 404;
}
if ( $http_user_agent = "" ) {
return 404;
}
if ( $host ~ geo\.kaspersky\.com ) {
return 404;
}
if ( $host ~ (su|download|webrep).*\.avast\.com ) {
return 404;
}
if ( $host = wi2geo.mobile.yandex.net ) {
return 404;
}
if ( $host ~ bar.*\.yandex\.ru ) {
return 404;
}
if ( $host ~ (ping|master)\d*\.(dyngate|teamviewer)\.com ) {
return 404;
}
if ( $host ~ sitecheck\d*\.opera\.com ) {
return 404;
}
if ( $host ~ (xml\.my|mailsputnik|maps)\.mail\.ru ) {
return 404;
}
if ( $host = onlineconfigservice.ubi.com ) {
return 404;
}
if ( $host = com-services.pandonetworks.com ) {
return 404;
}
if ( $host ~ ticno\.com ) {
return 404;
}
if ( $host ~ conduit ) {
return 404;
}
if ( $host ~ cbox\.ws ) {
return 404;
}
if ( $host ~ (pricelist|metrics)\.skype\.com ) {
return 404;
}
if ( $host = weather.service.msn.com ) {
return 404;
}
if ( $host = advstat.letitbit.net ) {
return 404;
}
if ( $host = skymonk.net ) {
return 404;
}
if ( $host ~ counter ) {
return 404;
}
if ( $host ~ pluraserver ) {
return 404;
}
if ( $host ~ apps.bittorrent.com ) {
return 404;
}
if ( $host ~ tracker ) {
return 404;
}
if ( $request_uri ~* (update|feed|announce|rss|xml|json|oauth) ) {
return 404;
}
if ( $request_uri ~* (toolbar|suggest) ) {
return 404;
}
if ( $request_filename ~ \.(ico|gif|jpg|png) ) {
return 404;
}
if ( $request_filename ~ \.(css|xml|js|swf|flv) ) {
return 404;
}
if ( $request_filename ~ \.(crl|txt|cab|msi|jar) ) {
return 404;
}
if ( $host ~ norton ) {
return 404;
}
rewrite ^ http://192.168.2.2:82/index.php redirect;
}
location ~ \.php$ {
try_files $uri =404;
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
}
Файл /var/www/82/index.php я создал такого типа:
<html>
<head>
...
<p class='alert-text' style='color:red;'>
Ваше устройство не зарегистрировано в системе<br>
и получило временный айпи адрес, при необходимости сообщите его оператору</p><br>
<b><p class='alert-text' style='color:red; font-size:140%;'><?php echo $_SERVER["REMOTE_ADDR"]; ?></b></p><br>
<a href='https://test.ixnfo.com/'>ЛИЧНЫЙ КАБИНЕТ</a><br>
<p class='alert-text'><b>Телефоны для справок:</b><br>
XX-XX-XX, ... <br>
<b>С уважением, Администрация ...</b><br><br></p>
...
Так как на сервере доступа я использовал для должников ipset, то для этого ipset переадресуем http запросы через iptables, разрешим доступ к серверу с nginx, биллингу и dns серверу, а все остальное запретим.
/sbin/ipset create denyip iphash
/sbin/iptables -t nat -A PREROUTING -p tcp -m multiport --dport 80 -m set --match-set denyip src -j DNAT --to-destination 192.168.5.5:81
/sbin/iptables -A FORWARD -m set --match-set denyip src -d 192.168.5.5 -p tcp --dport 81 -j ACCEPT
/sbin/iptables -A FORWARD -m set --match-set denyip src -d 192.168.5.5 -p tcp --dport 443 -j ACCEPT
/sbin/iptables -A FORWARD -m set --match-set denyip src -d 192.168.2.2 -p tcp --dport 9443 -j ACCEPT
/sbin/iptables -A FORWARD -m set --match-set denyip src -d 192.168.2.2 -p tcp --dport 53 -j ACCEPT
/sbin/iptables -A FORWARD -m set --match-set denyip src -d 192.168.2.2 -p udp --dport 53 -j ACCEPT
/sbin/iptables -A FORWARD -m set --match-set denyip src -j DROP
Либо если гостевым клиентам выдаются отдельные IP адреса, то вместо ipset укажем сеть:
iptables -t nat -A PREROUTING -s 10.0.56.0/24 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.5.5:81
Кратко опишу процесс:
Windows при подключении к сети под «http_user_agent=Microsoft NCSI» пытается открыть страницу http://www.msftncsi.com/ncsi.txt на которой содержится текст Microsoft NCSI и получает статус 200 ОК, а также проверяет DNS сервер — определяет IP адрес для dns.msftncsi.com, который должен быть 131.107.255.255.
Если ссылка открылась и DNS ответил верно, то система считает что есть подключение к интернет, если ссылка не доступна, а DNS ответил верно — система считает что нужно авторизоваться и открывает в браузере наш captive portal.
Все эти параметры хранятся в реестре HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NlaSvc\Parameters\Internet, а также можно отключить эту проверку указав 0 для EnableActiveProbing.
Apple при подключении к сети два раза пытается открыть http://captive.apple.com/hotspot-detect.html, в золовке и теле странице ожидает получить текст «Success». Первый раз пытается под «http_user_agent=CaptiveNetworkSupport…».
В логах nginx можно увидеть следующие записи:
«GET /connecttest.txt HTTP/1.1» 301 178 «-» «Microsoft NCSI»
«GET /ncsi.txt HTTP/1.1» 301 178 «-» «Microsoft NCSI»
«GET /hotspot-detect.html HTTP/1.0» 302 154 «-» «CaptiveNetworkSupport-355.260.2 wispr»
«GET /generate_204 HTTP/1.1» 301 178 «-» «Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36»
Подобным образом на Apache2 используя .htaccess можно сделать следующим образом:
RewriteEngine on
ErrorDocument 404 http://192.168.5.5:81/index.php
Также чтобы поисковики не индексировали страницу, можно создать файл robots.txt с содержимым:
User-agent: *
Disallow: /
Иногда в логах видел ошибки что нет файла favicon.ico, по этому можно его тоже добавить.
А также я рекомендую через iptables ограничить доступ к странице только для локальных сетей.
Смотрите также мою статью:
IPTables правила для веб-сервера
Настройка маскарадинга (NAT) в Ubuntu
Здравствуйте
понравилось решение, но есть несколько вопросов….
не все странички отрабатывает, допусти facebook microsoft
а так же странички допустим из закладок где помимо домена еще всякой белеберда из серии microsoft.com/en-us/software-download/windows10ISO
как нить можно решить?