Для начала расскажу, как у нас организована сеть. Если не вдаваться в подробности, то развешены точки доступа HP MSM430(J9651), управление через HP MSM760(J9420A) и шлюз HP F1000-EI (JG214A). Выбор оборудования не удачен, но работаем с тем, что имеем.
Так сложилось, что по жизни я больше полюбил Windows системы, но получив задачу, начитавшись кучу статей, пришел к выводу, что для этой цели лучше всего подойдет *nix система. Выбор пал на Ubuntu сервер 16.04. Дальше было несколько дней мучений, но в итоге все получилось.
Эта статья для тех, кто любит Windows, смотрит на Ubuntu и ставит с нуля кучу софта.
Как я решил все организовать:
Имеется открытая сеть, назовем ее Free. Пользователь при подключении переадресуется на хотспот со страницей авторизации. Там ему выдается код доступа к интернету и номер телефона, на которое он должен отправить сообщение (немного необычно, но стояла задача экономии, в том числе и на смс). Как только сообщение приходит к нам, доступ в интернет сразу открывается. Оговорюсь, симку и номер в модеме лучше использовать МТС (не реклама), так как только у них не нашел возможности отправить СМС с сайта без указания левого номера (хотя это проблема, но в процессе решения).
Что нам потребуется:
- лошадка Ubuntu Server 16.04
- прокси Squid в прозрачном режиме
- Mysql (MariaDB)
- Nginx
- PHP FPM
- USB redirector (виртуальная машинка под HyperV)
- модем Huawei E153 МТС
- SMS tools для чтения смс
- и тд. и тп.
Начнем.
Установка Ubuntu Server 16.04
Здесь все довольно банально:
- Создаем виртуальную машинку (2 ядра, 4 Гб памяти, 2 сетевых интерфейса, 30 Гб диск)
- Качаем последний дистрибутив, подключаем, ставим...
- Настраиваем сетевые интерфейсы, один смотрит в vlan сети wifi, второй в сторону шлюза
Настройка сети и форвардинг пакетов
Редактируем файл настройки сетевых интерфейсов:
nano /etc/network/interfaces
auto eth0
iface eth0 inet static
# в сторону интернет шлюза
address 10.66.66.6
netmask 255.255.255.240
network 10.66.66.0
broadcast 10.66.66.15
gateway 10.66.66.1
dns-nameservers 10.66.66.1
auto eth1
iface eth1 inet static
# в сторону wifi пользователей
address 10.0.87.254
netmask 255.255.248.0
network 10.0.80.0
broadcast 10.0.87.255
Убедимся в том, что в системе действительно присутствуют IPv6 интерфейсы:
ip a | grep inet
Также можно увидеть, что некоторые приложения вывешивают TCP прослушиватели на интерфейсах IPv6. Посмотреть все прослушиваемые в системе порты можно командой:
sudo ss -lnptu | sort
Чтобы выключить поддержку IPv6 на всех сетевых интерфейсах сразу, открываем на редактирование файл sysctl.conf
sudo nano -Y sh /etc/sysctl.conf
В конец файла добавляем строки для включения форвардинга и отключения IPv6:
net.ipv4.ip_forward=1
net.ipv6.conf.all.disable_ipv6 = 1
Для проверки того, что наша опция сможет быть прочитана sysctl во время загрузки выполним:
sudo sysctl -p
/etc/init.d/networking restart
Установка MySQL
В качестве сервера баз данных, выбрал MaridDB. По функционалу в чем-то даже лучше MySQL, но статья не об этом.
apt-get install mariadb-server
#настраиваем пароли на доступ
mysql_secure_installation
#запускаем mysql и сбрасываем привилегии
mysql -u root
use mysql;
update user set plugin='' where User='root';
flush privileges;
Проверяем, все ли хорошо у нас запустилось:
service mysql status
Установка Squid с поддержкой SSL и отключением IPv6
Есть много статей, как собирать и устанавливать прокси, но этот этап оказался наверное самый муторный. По умолчанию, в репозитарии убунты лежит Squid без поддержки SSL. Решил пересобрать, и так прошло 2 дня… В итоге получился свой мануал, как собрать под x64 последнюю версию 3.5.20.
Ставим необходимый софт для сборки:
apt-get install git fakeroot checkinstall build-essential devscripts patch libssl-dev libgnutls28-dev
apt-cache policy squid3
apt-get build-dep squid3
Расcкомментируем репозитарии исходников и добавим новый:
nano /etc/apt/sources.list
deb-src http://ftp.de.debian.org/debian/ testing main contrib non-free
Новый репозитарий, будет ругаться на ключи, поэтому сразу их получим:
gpg --keyserver keyserver.ubuntu.com --recv 8B48AD6246925553
gpg --export --armor 8B48AD6246925553 | sudo apt-key add -
gpg --keyserver keyserver.ubuntu.com --recv 7638D0442B90D010
gpg --export --armor 7638D0442B90D010 | sudo apt-key add -
Не забываем обновить информацию о репозитариях:
apt-get update
Чтобы не захламить рабочую папку, переходим в tmp и скачиваем из testing последнюю версию squid с правилами для сборки под debian
cd /tmp/
apt-get source squid3
Текущая версия 3.5.19, обновляемся до последней 3.5.20
wget http://www.squid-cache.org/Versions/v3/3.5/squid-3.5.20.tar.gz
tar -xf squid-3.5.20.tar.gz
mkdir ./squid-3.5.20/debian/
cp -r ./squid3-3.5.19/debian/* ./squid-3.5.20/debian/
cd squid-3.5.20/
nano debian/rules
Добавляем строчки (не забываем указать путь к openssl.cnf, у меня это /etc/ssl)
--disable-ipv6 --enable-icap-client --enable-ssl-crtd --with-openssl=/etc/ssl \
Подтверждаем патч и собираем (ждем примерно 10-15 минут)
dpkg-source --commit
#patch update to squid 3.5.20
debuild
Смотрим, какие пакеты у нас собрались:
ls -l /tmp/ | grep .deb$
И начинаем установку Squid:
apt-get install squid-langpack libdbi-perl
dpkg -i squid-common_3.5.19-1_all.deb
dpkg -i squid_3.5.19-1_amd64.deb
dpkg -i squid3_3.5.19-1_all.deb
dpkg -i squidclient_3.5.19-1_amd64.deb
если по каким-либо причинам, подвис установщик, то сбрасываем блокировку:
fuser -vki /var/lib/dpkg/lock
запускаем и проверяем статус
service squid start
systemctl status -l squid
в ответ должны увидеть что-то похожее
squid.service - LSB: Squid HTTP Proxy version 3.x
Loaded: loaded (/etc/init.d/squid; bad; vendor preset: enabled)
Active: active (running)
Теперь займемся его настройкой, для начала создадим SSL сертификат и сохраним конфиг по умолчанию:
cd /etc/squid
openssl req -new -newkey rsa:1024 -days 365 -nodes -x509 -keyout squidCA.pem -out squidCA.pem
mv ./squid.conf ./squid.conf.default
nano ./squid.conf
Файл конфигурации, почти без изменений взят из статьи.
acl localnet src 10.0.80.0/21
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
dns_nameservers 10.66.66.1
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
http_access allow localnet
http_access allow localhost
http_access deny all
#http_port 3128
#прозрачный порт указывается опцией intercept
http_port 10.0.87.254:3128 intercept options=NO_SSLv3:NO_SSLv2
#также нужно указать непрозрачный порт, ибо если захотите вручную указать адрес
#прокси в браузере, указав прозрачный порт, вы получите ошибку доступа, поэтому нужно
#указывать непрозрачный порт в браузере, если конечно такое желание будет, к тому же в логах #сыпятся ошибки о том, что непрохрачный порт не указан=)
http_port 10.0.87.254:3130 options=NO_SSLv3:NO_SSLv2
#и наконец, указываем HTTPS порт с нужными опциями
https_port 10.0.87.254:3129 intercept ssl-bump options=ALL:NO_SSLv3:NO_SSLv2 connection-auth=off cert=/etc/squid/squidCA.pem
always_direct allow all
sslproxy_cert_error allow all
sslproxy_flags DONT_VERIFY_PEER
#укажем правило со списком блокируемых ресурсов (в файле домены вида .domain.com)
acl blocked ssl::server_name "/etc/squid/blocked_https.txt"
acl step1 at_step SslBump1
ssl_bump peek step1
#терминируем соединение, если клиент заходит на запрещенный ресурс
ssl_bump terminate blocked
ssl_bump splice all
sslcrtd_program /usr/lib/squid/ssl_crtd -s /var/lib/ssl_db -M 4MB
coredump_dir /var/spool/squid
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
cache_dir aufs /var/spool/squid 2048 49 256
maximum_object_size 61440 KB
minimum_object_size 3 KB
cache_swap_low 90
cache_swap_high 95
maximum_object_size_in_memory 512 KB
memory_replacement_policy lru
#logfile_rotate 31
logfile_daemon /usr/lib/squid/log_db_daemon
access_log daemon:/127.0.0.1:3306/base/table/user/password squid
Создаем файл со списком блокируемых ресурсов
nano ./blocked_https.txt
Обращаю внимание, что логи будем писать в базу данных. Для этого создаем таблицу:
CREATE TABLE `access_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`time_since_epoch` decimal(15,3) DEFAULT NULL,
`time_response` int(11) DEFAULT NULL,
`ip_client` char(15) DEFAULT NULL,
`ip_server` char(15) DEFAULT NULL,
`http_status_code` varchar(10) DEFAULT NULL,
`http_reply_size` int(11) DEFAULT NULL,
`http_method` varchar(20) DEFAULT NULL,
`http_url` varchar(500) DEFAULT NULL,
`http_username` varchar(20) DEFAULT NULL,
`http_mime_type` varchar(50) DEFAULT NULL,
`squid_request_status` varchar(50) DEFAULT NULL,
`squid_hier_status` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
запускаем и проверяем статус
service squid start
systemctl status -l squid
в ответ должны увидеть что-то похожее
squid.service - LSB: Squid HTTP Proxy version 3.x
Loaded: loaded (/etc/init.d/squid; bad; vendor preset: enabled)
Active: active (running)
Проверяем используемые порты и версию установленного squid
sudo ss -lnptu | grep :3128
sudo ss -lnptu | grep :3129
sudo ss -lnptu | grep :3130
squid -version
Squid Cache: Version 3.5.20
Ставим USB-Redirector и модем
Так как, используется кластер под HyperV 2012R2, то возникает проблема, а именно как нам воткнуть модем. В нашей организации довольно успешно используется: USB-Redirector. Ставим его под Ubuntu
cd /tmp/
wget http://www.incentivespro.com/usb-redirector-linux-x86_64.tar.gz
tar -xf usb-redirector-linux-x86_64.tar.gz
./usb-redirector-linux-x86_64/installer.sh install-client
подключаемся к серверу, куда подключили модем
usbclnt -addserver 10.X.X.X:32032
usbclnt -autoconnect on 1
смотрим перечень всех usb устройств
usbclnt -l
================= USB CLIENT OPERATION SUCCESSFUL ===============
List of USB servers and devices:
1: USB server at 10.X.X.X:32032
Mode: auto-connect Status: connected
- 7: HUAWEI Mobile
Vid: 12d1 Pid: 1001 Port: 3-2
Mode: manual-connect Status: disconnected
устанавливаем драйверы модема
apt-get install usb-modeswitch usb-modeswitch-data
подключаемся и проверяем, установлен ли модем
usbclnt -connect 1-7
ls /dev | grep ttyUSB
в ответ должны увидеть:
ttyUSB0
ttyUSB1
ttyUSB2
Устанавливаем SMS-tools
Информацию о пакеты можно найти на сайте разработчика.
Устанавливаем и настраиваем:
apt-get install smstools
nano /etc/smsd.conf
находим строчку [GSM1]
[GSM1]
device = /dev/ttyUSB0
incoming = yes
baudrate = 9600
eventhandler = /var/www/sms_recieve.php
создаем файл обработчика входящих смс и делаем его исполняемым
nano /var/www/sms_recieve.php
chmod 755 /var/www/sms_recieve.php
service smstools restart
Настраиваем DHCP сервер
apt-get install isc-dhcp-server
nano /etc/default/isc-dhcp-server
#указываем, на каком интерфейсе будет слушать dhcp сервер
INTERFACES="eth1"
sudo nano /etc/dhcp/dhcpd.conf
# указываем
authoritative;
subnet 10.0.80.0 netmask 255.255.248.0 {
range 10.0.80.1 10.0.86.254;
option domain-name-servers 10.0.87.254;
option domain-name "wifi-free";
option subnet-mask 255.255.248.0;
option routers 10.0.87.254;
option broadcast-address 10.0.87.255;
default-lease-time 7200; #2h
max-lease-time 72000; #20h
}
/etc/init.d/isc-dhcp-server restart
Настраиваем Nginx и PHP 5.6 FPM
Так как php обновилось до 7 версии и во всех репозитариях ubuntu уже лежит php7, то добавляем новый и ставим:
add-apt-repository ppa:ondrej/php
apt-get install php5.6-cli php5.6-common php5.6-mysql php5.6-gd php5.6-fpm php5.6-cgi php-pear
останавливаем установленный сервис и редактируем файлы настройки
service php5.6-fpm stop
nano /etc/php/5.6/fpm/php.ini
cgi.fix_pathinfo = 0
post_max_size = 200M
upload_max_filesize = 200M
nano /etc/php/5.6/fpm/pool.d/www.conf
security.limit_extensions = .php .php3 .php4 .php5
listen = /run/php/php5.6-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
service php5.6-fpm start
Можно убедится в том, что права доступа к сокету установлены верно:
ls -la /run/php/php5.6-fpm.sock
#srw-rw---- 1 www-data www-data 0 May 2 16:36 /run/php/php5.6-fpm.sock
Проверяем:
php -v
PHP 5.6.23-2+deb.sury.org~xenial+1 (cli)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
Переходим к Nginx
apt-get install nginx nginx-extras
Основные настройки Nginx хранятся в файле /etc/nginx/nginx.conf.
Настройки базового сайта хранятся в файле /etc/nginx/sites-available/default.
Базовый конфигурационный файл сайта принято помещать в папку /etc/nginx/sites-available/ и затем включить его путём добавления символической ссылки на этот файл в папке /etc/nginx/sites-enabled/.
touch /etc/nginx/sites-available/hotspot.domain.com
ln -s /etc/nginx/sites-available/hotspot.domain.com /etc/nginx/sites-enabled/
mkdir /etc/nginx/common
Дальше буду краток, так как пояснения можно почитать по ссылке. Создаем общие файлы настройки сервера, в которых описываем настройки безопасности, сжатия, кэширования и php.
touch /etc/nginx/common/upstream
nano /etc/nginx/common/upstream
upstream php-fpm
{
# PHP5.6-FPM сервер
server unix:/run/php/php5.6-fpm.sock;
}
touch /etc/nginx/common/security
nano /etc/nginx/common/security
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
touch /etc/nginx/common/gzip
nano /etc/nginx/common/gzip
gzip on;
gzip_disable "msie6";
gzip_comp_level 6;
gzip_min_length 1100;
gzip_buffers 16 8k;
gzip_proxied any;
gzip_types text/plain application/xml text/css text/js text/xml application/x-javascript text/javascript application/javascript application/json application/xml+rss;
touch /etc/nginx/common/php-fpm
nano /etc/nginx/common/php-fpm
# Настройки порта или сокета PHP-FPM производятся в файле "/etc/php/5.6/fpm/pool.d/www.conf"
fastcgi_pass php-fpm;
# Порядок важен - строчка "include fastcgi_params" должна быть первой
include fastcgi_params;
fastcgi_split_path_info ^(.+?\.php)(/.*)?$;
# Вместо переменной "$document_root" можно указать адрес к корневому каталогу сервера и это желательно (см. http://wiki.nginx.org/Pitfalls)
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
# См. http://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
# Additional variables
fastcgi_param SERVER_ADMIN email@example.com;
fastcgi_param SERVER_SIGNATURE nginx/$nginx_version;
fastcgi_index index.php;
touch /etc/nginx/common/cache
nano /etc/nginx/common/cache
location ~* ".+\.(?:ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|css|swf|js|atom|jpe?g|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$"
{
access_log off;
log_not_found off;
expires max;
}
В моем случаи, у меня был публичный wildcard сертификат для моего домена. Распаковываю файл сертификата и устанавливаю права доступа
openssl pkcs12 -in certname.pfx -nocerts -out /etc/nginx/ssl/key.pem -nodes
openssl pkcs12 -in certname.pfx -nokeys -out /etc/nginx/ssl/cert.pem
openssl rsa -in /etc/nginx/ssl/key.pem -out /etc/nginx/ssl/domain.key
cd /etc/nginx/ssl/
chown www-data:www-data domain.key
chmod 400 domain.key
touch /etc/nginx/common/ssl
nano /etc/nginx/common/ssl
ssl_certificate /etc/nginx/ssl/domain.crt;
ssl_certificate_key /etc/nginx/ssl/domain.key;
ssl_session_timeout 20m; # время 20 минут
ssl_session_cache shared:SSL:20m; # размер кеша 20МБ
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AE$
Настраиваем наш сервер:
nano /etc/nginx/sites-available/hotspot.domain.com
include common/upstream;
server
{
listen 80;
server_name hotspot.domain.com;
root /var/www;
index index.php index.html index.htm;
client_max_body_size 200m; # увеличение максимального объема файла для загрузки до 200МБ
# Buffers
fastcgi_buffers 64 4K;
include common/security;
include common/gzip;
location "/"
{
index index.php index.html index.htm; # варианты индексных файлов если имя файла в запросе не задано
try_files $uri $uri/ =404; # проверить есть ли файл из запроса на диске, иначе - вернуть ошибку 404
include common/deny;
include common/cache;
include common/php-fpm;
}
}
и делаем редирект с сервера по умолчанию (не забываем, что DNS сервер должен резолвить имя hotspot.domain.com):
nano /etc/nginx/sites-available/default
server {
listen 80 default_server;
#listen [::]:80 default_server;
listen 443 ssl default_server;
#listen [::]:443 ssl default_server;
include common/ssl;
rewrite ^ http://hotspot.domain.com?url=$scheme://$host$request_uri? redirect;
...
}
Настраиваем phpmyadmin
Для более удобной работы с базой данных, устанавливаем phpmyadmin.
apt-get install phpmyadmin
apt-get install mcrypt php5.6-mcrypt php-gettext
touch /etc/nginx/common/phpmyadmin
nano /etc/nginx/common/phpmyadmin
location /phpmyadmin {
root /usr/share/;
index index.htm index.html index.php;
location ~ ^/phpmyadmin/(.+.php)$ {
try_files $uri = 404;
root /usr/share/;
fastcgi_pass unix:/run/php/php5.6-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $request_filename;
include /etc/nginx/fastcgi_params;
}
location ~* ^/phpmyadmin/(.+.(html|ico|xml|css|jpg|png|js|txt|gif|jpeg))$ {
root /usr/share/;
}
}
location /phpMyAdmin {
rewrite ^/* /phpmyadmin last;
}
и аналогично подключаем к nginx
nano /etc/nginx/sites-available/hotspot.domain.com
include common/phpmyadmin;
перезапускаемся
service nginx restart
service php5.6-fpm restart
Настройка фаервола iptables
В данном разделе, нам требуется ограничить доступ к серверу и завернуть трафик на прокси. Для начала, настроим сохранение всех правил после перезагрузки:
apt-get install iptables-persistent ipset
так как в нашей задаче, нам необходимо, чтобы сохранялись и таблицы ipset, то немного правим следующий файл:
nano /usr/share/netfilter-persistent/plugins.d/15-ip4tables
#в функцию save_rules()
touch /etc/iptables/rules.v4
touch /etc/iptables/ipset.rules
chmod 0640 /etc/iptables/ipset.rules
chmod 0640 /etc/iptables/rules.v4
iptables-save > /etc/iptables/rules.v4
ipset save > /etc/iptables/ipset.rules
#в функцию load_rules()
ipset restore < /etc/iptables/ipset.rules
iptables-restore < /etc/iptables/rules.v4 2> /dev/null
Для сохранения правил на фаерволе используем команду:
netfilter-persistent save
Для отслеживания и сброса установленных соединений используем conntrack
apt-get install conntrack
Настраиваем правила iptables
#создаем таблицу авторизованных mac-ip
ipset --create authorized macipmap --network 10.0.80.0/21
ipset -L authorized
#создаем дополнительные цепочки обработки правил
iptables -t nat -N toSQUID
iptables -t nat -N toHOTSPOT
#очищаем все ранее созданные правила
iptables -t nat -F PREROUTING
#пробрасываем DNS на наш сервер
iptables -t nat -A PREROUTING -i eth1 -p udp --dport 53 -j DNAT --to 10.66.66.1
#если ip,mac авторизован, то перенаправляем на squid
iptables -t nat -A PREROUTING -i eth1 -m set --match-set authorized src,src -j toSQUID
#если ip,mac не авторизован, то перенаправляем на заглушку
iptables -t nat -A PREROUTING -i eth1 -j toHOTSPOT
iptables -t nat -F toHOTSPOT
# в заглушке, все запросы перенаправляем на наш сервер nginx
iptables -t nat -A toHOTSPOT -p tcp -m multiport --dports 80,8080 -j DNAT --to-destination 10.0.87.254:80
iptables -t nat -A toHOTSPOT -p tcp -m multiport --dports 443 -j DNAT --to-destination 10.0.87.254:443
iptables -t nat -A toHOTSPOT -j RETURN
iptables -t nat -F toSQUID
# перенаправляем разрешенные порты на прокси
#создаем обход хотспота для telegram (так и не смог заставить работать через squid)
iptables -t nat -A toSQUID -p tcp -d 149.154.164.0/22 --dport 443 -j ACCEPT
#аналогично для whatsapp
iptables -t nat -A toSQUID -p tcp -m multiport --dport 4244,5242,5228,5223,5222 -j ACCEPT
iptables -t nat -A toSQUID -p tcp -m multiport --dports 80,25,465,110,995,119,563,8080 -j REDIRECT --to-ports 3128
iptables -t nat -A toSQUID -p tcp -m multiport --dports 443 -j REDIRECT --to-ports 3129
iptables -t nat -A toSQUID -j RETURN
#Включаем NAT для прошедших пакетов
iptables -t nat -A POSTROUTING -s 10.0.80.0/21 -o eth0 -j MASQUERADE
#политика по умолчанию для входящих пакетов
iptables -P INPUT ACCEPT
iptables -F INPUT
#разрешаем траффик на lo
iptables -A INPUT -i lo -j ACCEPT
#разрешаем доступ к портам управления из вышестоящей сети
iptables -A INPUT -i eth0 -p tcp -m multiport --dports 22,80,443 -j ACCEPT
#разрешаем пинг и трасерт
iptables -A INPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT
iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
#разрешаем работу уже открытых соединений
iptables -A INPUT -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p UDP -m state --state ESTABLISHED,RELATED -j ACCEPT
#разрешаем доступ на прокси
iptables -A INPUT -i eth1 -p tcp -m multiport --dport 3128,3129,3130 -j ACCEPT
iptables -A INPUT -i eth1 -p udp -m multiport --dport 3128,3129,3130 -j ACCEPT
№разрешаем доступ на заглушку
iptables -A INPUT -i eth1 -p tcp -m multiport --dports 80,443 -j ACCEPT
#политика по умолчанию для входящих пакетов
iptables -P INPUT DROP
#создаем цепочку для проблемных сервисов, которым разрешена пересылка
iptables -N FORWARD_AUTHORIZED
iptables -F FORWARD_AUTHORIZED
# разрешаем пересылку telegram
iptables -A FORWARD_AUTHORIZED -p tcp -d 149.154.164.0/22 --dport 443 -j ACCEPT
# разрешаем пересылку whatsapp
iptables -A FORWARD_AUTHORIZED -p tcp -m multiport --dport 4244,5242,5228,5223,5222 -j ACCEPT
iptables -A FORWARD_AUTHORIZED -j RETURN
#политика по умолчанию для пересылаемых пакетов
iptables -P FORWARD ACCEPT
iptables -F FORWARD
#разрешаем пересылку на dns
iptables -A FORWARD -i eth1 -p udp --dport 53 -d 10.66.66.1 -j ACCEPT
#разрешаем работу уже открытых соединений
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
#перенаправляем авторизованных клиентов на проверку в цепочку FORWARD_AUTHORIZED
iptables -A FORWARD -i eth1 -m set --match-set authorized src,src -j FORWARD_AUTHORIZED
#политика по умолчанию для пересылаемых пакетов
iptables -P FORWARD DROP
Для отлавливания проблем используем следующие команды
#сброс установленных соединений с заданного ip
conntrack -D conntrack --orig-src 10.0.8X.XXX
#просмотр новых записей в логе
tail -f /var/log/firewall | grep 10.0.8X.XXX
Настраиваем php файлы обработки запросов и скрипты
Создаем таблицы в нашей базе данных:
SET FOREIGN_KEY_CHECKS=0;
CREATE TABLE IF NOT EXISTS `mac-auth` (
`mac` char(17) NOT NULL COMMENT 'мак адрес устройства',
`code` int(6) NOT NULL COMMENT 'код авторизации',
`phone` varchar(15) NOT NULL DEFAULT '' COMMENT 'телефонный номер с которого пришло смс',
`updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'дата последнего изменения',
`created` datetime DEFAULT CURRENT_TIMESTAMP COMMENT 'дата создания',
UNIQUE KEY `mac` (`mac`),
KEY `code` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `mac-ip` (
`mac` char(17) NOT NULL COMMENT 'мак адрес устройства',
`ip` varchar(15) NOT NULL COMMENT 'ip адрес устройства',
`date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'дата изменения',
KEY `mac` (`mac`),
KEY `ip` (`ip`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `mac-phone` (
`mac` char(17) NOT NULL COMMENT 'мак адрес устройства',
`phone` varchar(15) NOT NULL COMMENT 'номер телефона',
`date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'дата изменения',
KEY `mac` (`mac`),
KEY `ip` (`phone`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `mac-ip`
ADD CONSTRAINT `mac` FOREIGN KEY (`mac`) REFERENCES `mac-auth` (`mac`) ON DELETE CASCADE ON UPDATE CASCADE;
SET FOREIGN_KEY_CHECKS=1;
создаем скрипт, при входе в систему, для проверки работы всех служб:
nano /var/www/check_services.sh
#!/bin/bash
function check {
printf %-30s "check $1"
if (( $(ps -ef | grep -v grep | grep $1 | wc -l) > 0 ))
then
echo -e "[\033[32;1m OK \033[0m]"
else
echo -e "[\033[31;1m ERROR \033[0m]"
fi
}
check dhcpd
check nginx
check mysql
check php-fpm
check smstools
check squid
check usbsrvd
устанавливаем права запуска и добавляем на старт
chmod 755 /var/www/check_services.sh
nano ~/.profile
/var/www/check_services.sh
а теперь исходники php файлов:
nano /var/www/sms_recieve.php
#!/usr/bin/php
<?php
require_once 'hotspot/connect.php';
$sms_type = $argv[1];
$sms_file = $argv[2];
$sms_file_content = file_get_contents($sms_file);
$i = strpos($sms_file_content, "\n\n");
$sms_headers_part = substr($sms_file_content, 0, $i);
$sms_message_body = substr($sms_file_content, $i + 2);
$sms_header_lines = split("\n", $sms_headers_part);
$sms_headers = array();
foreach ($sms_header_lines as $header)
{
$i = strpos($header, ":");
if ($i !== false)
$sms_headers[substr($header, 0, $i)] = substr($header, $i + 2);
}
$phone = (float)$sms_headers['From'];
$code = (int)$sms_message_body;
//проверяем базу на старые записи
$interval = '30 DAY';
//$interval = '1 MINUTE';
$macs = sql_getRows('SELECT `mac` FROM `mac-auth` WHERE `code` = 1 AND `created` < DATE_SUB(NOW(),INTERVAL '.$interval .')');
if (!empty($macs)){
$data = sql_getColumn('SELECT DISTINCT(`ip`) as `ip`,`mac` FROM `mac-ip` WHERE `mac` IN ("'.implode('","',$macs).'") ORDER BY `date` DESC','mac');
foreach ($data as $mac=>$ip){
sql_query('UPDATE `mac-auth` SET `code` = "0" WHERE `mac` IN ("'.implode('","',$macs).'")');
//удаляем авторизацию на фаерволе
shell_exec('sudo ipset -D authorized '.$ip .','.$mac);
//сбрасываем все подключения данного ip
shell_exec('sudo conntrack -D conntrack --orig-src '.$ip);
}
shell_exec('ipset save > /etc/iptables/ipset.rules');
}
echo $phone.'-'.$code;
$mac = sql_getValue('SELECT `mac` FROM `mac-auth` WHERE `code` = '.$code);
if ($mac){
$ip = sql_getValue('SELECT DISTINCT(`ip`) FROM `mac-ip` WHERE `mac` = "'.$mac.'" ORDER BY `date` DESC');
echo '-'.$mac.'-'.$ip;
//вносим в базу информацию о номере телефона
sql_query('INSERT `mac-phone` (`mac`,`phone`) VALUES("'.$mac.'","'.$phone.'")');
sql_query('UPDATE `mac-auth` SET `phone` = "'.$phone.'", `code` = "1" WHERE `mac` = "'.$mac.'"');
//разрешаем доступ на фаерволе
shell_exec('sudo ipset -A authorized '.$ip .','.$mac);
shell_exec('ipset save > /etc/iptables/ipset.rules');
shell_exec('sudo conntrack -D conntrack --orig-src '.$ip);
}
//удаляем сообщение
unlink($sms_file);
?>
nano /var/www/hotspot/index.php
<?php
//устанавливаем подключение с базой данных
require_once 'connect.php';
//определяем ip адрес
$ip = '';
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
if (empty($ip)) $ip = $_SERVER['REMOTE_ADDR'];
//проверяем правильность ip адреса
if (!preg_match('/^10\.0\.8[0-7]\.\d{1,3}$/', $ip)) {
$ip = false;
}
//определяем мак адрес
if ($ip) $mac = trim(shell_exec("arp -a ".$ip." | awk '{print $4}'"));
if (!isset($mac) || $mac == "entries") $mac = false;
//определяем адрес по которому обращался пользователь
$url = $_GET['url'];
//if (strpos($url, 'gstatic.com')!==false) $url = 'http://www.domain.ru';
//выключаем кэширование браузером
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Дата в прошлом
// строка ошибки
$error = false;
if (!$mac){
$error = 'Ошибка с Вашей сетевой картой. <br/>Доступ в интернет не может быть предоставлен.<br/><font class="eng error">Error with your network card. Internet access can not be granted</font>';
} else {
//проверяем, не изменился ли ip адрес у абонента
$base_ip = sql_getValue('SELECT DISTINCT(`ip`) FROM `mac-ip` WHERE `mac` = "'.$mac.'" ORDER BY `date` DESC');
if ($base_ip != $ip){
sql_query('INSERT INTO `mac-ip` (`mac`,`ip`) VALUES ("'.$mac.'","'.$ip.'")');
}
//проверяем авторизацию мак адреса
$code = sql_getValue('SELECT `code` FROM `mac-auth` WHERE `mac` = "'.$mac.'"');
switch ($code){
case '1':
//абонент авторизован
shell_exec('sudo ipset -A authorized '.$ip .','.$mac);
shell_exec('ipset save > /etc/iptables/ipset.rules');
header('Location: '.$url);
//shell_exec('sudo conntrack -D conntrack -p tcp --dport 80 --state ESTABLISHED --src '.$ip.' --dst 10.0.87.254');
die;
break;
case '':
//новый абонент
sql_query('INSERT INTO `mac-auth` (`mac`,`code`) VALUES ("'.$mac.'",0)');
case '0':
//абонент без авторизации и без кода доступа
//генерируем код
do {
$code = rand(10000,99999);
} while(sql_getValue('SELECT `mac` FROM `mac-auth` WHERE `code` = "'.$code.'"'));
sql_query('UPDATE `mac-auth` SET `code` = '.$code.' WHERE `mac` = "'.$mac.'"');
default:
//абонент без авторизации, но с генерированным кодом
break;
}
}
?>
<!DOCTYPE HTML>
<html>
<head>
<title>Хотспот</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<meta name="viewport" content="width=device-width, initial-scale=0.8, maximum-scale=1" />
</head>
<body>
<style type="text/css">
html, body {
width: auto;
margin: 0px;
padding: 0px;
}
* {
font-family: "Tahoma", sans-serif;
font-size: 14px;
text-align:center;
font-style: normal;
font-variant: normal;
font-weight: normal;
color: #000;
}
.center {
width: 400px;
padding: 10px;
margin: auto;
}
.logo {
background-image: url("/logo2.gif");
width: 177px;
height: 209px;
margin: auto;
}
.header {
font-size: 16px;
padding: 10px;
}
.repeat {
padding: 10px;
}
.sms {
font-size: 11px;
color: #4c4b4b;
padding: 10px;
}
.law {
font-size: 11px;
color: #4c4b4b;
padding: 10px;
}
.code {
font-size: 16px;
font-weight: bold;
}
.num {
font-size: 16px;
font-weight: bold;
}
.internet {
background-color: #3e315f;
#border: none;
color: white;
padding: 7px 20px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
border: 2px solid #ffffff;
border-radius: 4px;
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);
}
.internet:hover {
background-color: #ffffff;
color: #3e315f;
border: 2px solid #3e315f;
box-shadow: 0 12px 16px 0 rgba(0,0,0,0.24), 0 17px 50px 0 rgba(0,0,0,0.19);
}
.eng {
font-size: 12px;
line-height: 12px;
}
.error {
color: #d11313;
}
</style>
<div class="center">
<div class="logo"></div>
<div class="header">Добро пожаловать в открытую сеть <br/><font class="eng">Welcome to the open network</font></div>
<?php if ($error) { echo '<div class="error">'.$error.'</div>';} else { ?>
<div>Для получения доступа в интернет, Вам необходимо c Вашего телефона отправить смс с кодом: <font class="code"><?php echo $code;?></font> на номер: <font class="num">+7 917 XXX-XX-XX.</font><br/><font class="eng">To get access to the Internet, you need to send SMS with code <b><?php echo $code;?></b> to number <b>+7 917 XXX-XX-XX.</b></font></div>
<div class="repeat">Если Вы уже отправили смс с кодом, то нажмите на кнопку: <br/><font class="eng">If you have to send SMS with the code, then click on the button:</font></div>
<a target="_self" href="<?php echo $url;?>" class="internet">перейти в интернет</a>
<div class="repeat">Задержка предоставления доступа в интернет зависит от скорости доставки нам Вашего смс сообщения.<br/><font class="eng">Delayed access to the Internet depends on the speed of delivery of SMS messages to us.</font></div>
<div class="sms">Стоимость SMS-сообщений тарифицируется согласно вашему тарифному плану.<br/>Cost of SMS-messages is charged according to your tariff plan.</div>
<div class="law">Согласно постановлению Правительства №758 от 31 июля 2014г. и №801 от 12 августа 2014 г. - все публичные WIFI сети обязаны производить идентификацию пользователей.<br/>According to the decree №758 of the Government dated 31 July 2014. and №801 from 12 August 2014 - all public WIFI network required to make user authentication.</div>
<?php } ?>
</div>
</body>
</html>
nano /var/www/hotspot/connect.php
# mysql login params
$mysql_host = '';
$mysql_db = '';
$mysql_login = '';
$mysql_password = '';
$sql_link = mysqli_connect($mysql_host, $mysql_login, $mysql_password, $mysql_db) or die(mysql_error());
function sql_query($sql, $unbuffered = false){
global $sql_link;
$resource = $unbuffered ? mysqli_real_query($sql_link, $sql) : mysqli_query($sql_link, $sql);
if (mysqli_errno($sql_link) === 1016) {
if (preg_match("/'(\S*)\.MYD'\. \(errno\: 145\)/", mysqli_error($sql_link), $m)) {
mysqli_unbuffered_query("REPAIR TABLE ".$m[1]);
$resource = $unbuffered ? mysqli_unbuffered_query($sql_link, $sql) : mysqli_query($sql_link, $sql);
}
}
return $resource;
}
function sql_getValue($sql, $unbuffered = false){
$resource = sql_query($sql, $unbuffered);
$ret = false;
if (is_resource($resource) || is_object($resource)) {
$row = mysqli_fetch_row($resource);
$ret = $row[0];
}
return $ret;
}
function sql_getRows($sql, $use_key = false, $unbuffered = false){
$resource = sql_query($sql, $unbuffered);
$ret = false;
if (is_resource($resource) || is_object($resource)) {
$row = true;
while ($row) {
$row = mysqli_fetch_array($resource, MYSQLI_ASSOC);
if (!$row) continue;
$_row = $row;
if ($use_key) {
if (isset($_row[$use_key])) {
$link = &$ret[$_row[$use_key]];
$link = $_row;
}
} else {
$link = &$ret[];
$link = (count($_row) == 1) ? array_shift($_row) : $_row;
}
}
}
return $ret;
}
function sql_getColumn($sql, $id_field = 'id', $unbuffered = false){
$resource = sql_query($sql, $unbuffered);
$ret = false;
if (is_resource($resource) || is_object($resource)) {
$row = true;
while ($row) {
$row = mysqli_fetch_array($resource, MYSQLI_ASSOC);
if (!$row) continue;
$_row = $row;
$id = $_row[$id_field];
unset($_row[$id_field]);
$value = current($_row);
$ret[$id] = $value;
}
}
return $ret;
}
function sql_getRow($sql, $unbuffered = false){
$resource = sql_query($sql, $unbuffered);
$ret = false;
if (is_resource($resource) || is_object($resource)) {
$ret = mysqli_fetch_assoc($resource);
}
return $ret;
}
Ну а теперь, добавим в sudoers права для управления iptables из php
nano /etc/sudoers
smsd ALL=(ALL) NOPASSWD: /sbin/ipset
smsd ALL=(ALL) NOPASSWD: /sbin/iptables
www-data ALL=(ALL) NOPASSWD: /sbin/ipset
www-data ALL=(ALL) NOPASSWD: /sbin/iptables
smsd ALL=(ALL) NOPASSWD: /usr/sbin/conntrack
www-data ALL=(ALL) NOPASSWD: /usr/sbin/conntrack
На этом вроде всё. Система в работе уже месяц, полёт нормальный. Спасибо за внимание!
Комментарии (30)
vikarti
08.08.2016 14:12я правильно понимаю что:
— все авторизованные юзеры идут на transparent proxy, и пробуете заблокировать часть https-сайтов используя SNI (и подделку сертификата ведь в /etc/squid/squidCA.pem лежит сертификат легитимного subCA). а если не секрет — что таким образом блокируется и почему?
— вы намеренно ломаете механизм определения «а не стоит ли у нас captive portal» Android'а(иначе зачем игры с gstatic.com?vetal-pro
08.08.2016 14:44На первый вопрос очень хорошо разжевано в статье , на которую и опирался при настройке squid. Подмены сертификата не происходит.
Насчет gstatic.com, согласен, не стоит. Похоже осталось с тестирования. Если оставитьif (strpos($url, 'gstatic.com')!==false) $url = 'http://www.domain.ru';
то начинается последовательность редиректов, авторизация проходит, но выглядит не эстетично.
lopatoid
08.08.2016 14:21>Согласно постановлению Правительства №758 от 31 июля 2014г. и №801 от 12 августа 2014 г.
А есть у кого-нибудь ссылки на описание человеческим языком, что это такое, и чем это грозит? Потому что прочитал эти постановления, но всё равно ничего не понял :( Может какие статьи, или форумы?
1) Если у меня дома Wi-Fi без пароля, я попадаю под закон?
2) А кто это будет проверять? Что, уже есть «медиаполицейский», который ищет AP без пароля? Или какие другие контролирующие органы?
3) Если в кафе Wi-Fi с паролём, но пароль выдают любому по запросу? Проверочные органы будут совершать «контрольную закупку» пароля?
4) А если назвать точку доступа AndroidAP и говорить, что это не я, это кто-то с телефона интернет шарит?
5) А если я приду во время проверки (см пункт 3) в офис к компании «ВЕКТОР», и подниму там мобильную точку доступа ООО_VECTOR_FREE, их оштрафуют?martin74ua
08.08.2016 14:37Зачем кого то штрафовать. Вот если товарищ майор получит команду, выяснить — кто это с ип X.X.X.X написал плохое сообщение — то товарищ майор найдет владельца этого ип и назначит виноватым. И ваши отмазки — это кто то с моей АП написал, потому что там пароля нет — никого интересовать не будут. А в случае смс авторизации у владельцев кафе есть хоть какой то шанс отвести вопросы от себя, сославшись на то, что в это время вот владелец вот этого телефона сидел у нас на фривифи ;)
vetal-pro
08.08.2016 14:49У нас так и начало происходить, начали сыпаться запросы. Вообще, есть маленькая тонкость. По закону, это необходимо делать провайдерам, а не организациям, которые используют. Но предоставляя доступ в интернет, посредством своей точки доступа, мы фактически, делать это не можем, так как не обладаем лицензией на предоставление телематических услуг.
RicoX
08.08.2016 15:34Провайдер скажет, кафе такое-то, на этом роль провайдера заканчивается, а дальше владелец кафе уже заинтересован перевести стрелки, чтоб не отвечать за действия анонимусов. К тому же лицензия на оказание телематических услуг НЕ требуется, если услуга оказывается безвозмездно.
Taragolis
08.08.2016 15:43+3>Настройка фаервола iptables
так как в нашей задаче, нам необходимо, чтобы сохранялись и таблицы ipset, то немного правим следующий файл:
nano /usr/share/netfilter-persistent/plugins.d/15-ip4tables
Лучше создать отдельный плагин, назвав его 20-ipset. В таком случае:
1. Можно не переживать, что при обновлении пакета случайно перезатрут/перепишут 15-ip4tables
2. Можно будет отдельно выполнять load / start / flush правил независимо от iptablesTaragolis
08.08.2016 20:28+1Заметил, неточность.
Конечно же надо грузить ipset правила до iptables, поэтому файл надо назвать не 20-ipset, а к примеру 14-ipset.
Быстренько набросал скрипт: http://pastebin.com/ixwzB6fJ
antoo
08.08.2016 22:56+4if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])){ $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; } if (empty($ip)) $ip = $_SERVER['REMOTE_ADDR']; //определяем мак адрес $mac = trim(shell_exec("arp -a ".$ip." | awk '{print $4}'"));
Не рекомендовал бы так делать, потому что результат при изменении заголовка на:
X-Forwarded-For: | rm -rf /*
может быть печальным.vetal-pro
09.08.2016 09:43Добавил проверку ip адреса регулярным выражением, а именно:
//проверяем правильность ip адреса if (!preg_match('/^10\.0\.8[0-7]\.\d{1,3}$/', $ip)) $ip = false; //определяем мак адрес if ($ip) $mac = trim(shell_exec("arp -a ".$ip." | awk '{print $4}'")); if (!isset($mac) || $mac == "entries") $mac = false;
vvpoloskin
09.08.2016 01:19Есть пара вопросов…
1) Зачем в этой схеме использовать прокси? Вы же реализовали всю логику на iptables? Только для красивых логов?
2) Зачем писать логи в БД? Ведь логи — это вещь, которую не надо активно изменять, вставлять посередине. Почему не в файл?
3) Почему решили ограничивать доступ неавторизованных пользователей через iptables, а не через squid?
4) Почему выбрали именно схему, когда пользователь отправляет sms, а не вы пользователю?vetal-pro
09.08.2016 09:491) Потому что задача стоит «перевести стрелки» на виновника. Если брать логи iptables, то получим только ip адреса источника и назначения. Нам же интересно, на какие сайты ходил пользователь и что там делал.
2) Для быстрого поиска, проще и правильнее использовать базу данных
3) Все-таки для каждой задачи, правильнее использовать инструмент для нее предназначенный. Squid это прокси, iptables фаервол.
4) Цена вопроса. Входящие смс бесплатные.vvpoloskin
09.08.2016 17:00Однако в вашей схеме возникнут проблемы, когда решение нужно масштабировать на несколько офисов. В каждом из них придется держать отдельный такой сервер с iptables.
Openname
09.08.2016 12:06У нас 10 залов для мероприятий (от 30 до 400 человек), а в день в среднем проходит от 4 до 12, плюс постоянная текучка народа и капризные пользователи.
Авторизация через смс выгодна обоим сторонам если имеется договоренность с оператором(ами), это вид авторизации реклама операторам сотовой связи
Frankenstine
09.08.2016 13:42Всё это зело интересно, но как по мне это сизифов труд. В случае обращения «органов», «подозреваемый» может запросто сказать «логи подделаны, я не ходил в тырнет» или даже «меня там не было, это подстава».
selivanov_pavel
09.08.2016 14:58+1Задача не посадить подозреваемого, а не попасть под раздачу самим.
Frankenstine
09.08.2016 16:31+1Я к тому, что этого может оказаться недостаточно. Следует проконсультироваться с юристом. Возможно, без чего-то типа журнала подключений под роспись, эта система окажется юридически ничтожна и всё равно попадёте под раздачу, например, если окажется что найти «подозреваемого» по вашим данным не удаётся (неизвестный/незарегистрированный номер, подменённый МАС-адрес), то на вас же и повесят «подделка логов для ухода от ответственности» или как-то так. Это не сертифицированная железка типа СОРМа, которая как-то защищена от вмешательства с вашей стороны. Один ручной update блаблабла set ляляля where тополя, и вы сами не сможете сказать — было ли это вмешательство, например, злобными хакерами которые кого-то решили подставить (включая вас самих) или всё чисто.
bagiroff777
09.08.2016 18:21В Украине в библиотеках, в которых предоставляется бесплатный доступ к Wi-Fi, записывают паспортные данные, а потом только дают пароль. Но полученные данные никак не связываются с устройством (или я не заметил).
На мой взгляд, — если госучреждение использует такую схему, то можно и всем. Но есть «но» — нужны паспортные данные или данные иного документа, удостоверяющего личность пользователя.
selivanov_pavel
09.08.2016 20:08Хороший вопрос. В наших реалиях это зависит не столько от буквы закона, сколько от принятой в полиции практики его применения. Кто-нибудь сталкивался с запросами правоохранительных органов про бесплатный Wi-Fi?
bougakov
09.08.2016 18:18+4Пожалуйста, вычитывайте тексты для пользователей. Это традиционная беда у программистов, в результате рождаются толковые, но страхолюдные продукты :(
Для получения доступа в интернет, Вам необходимо c Вашего телефона отправить смс с кодом
Для получения доступа в интернет вам необходимо отправить SMS с кодом
To get access to the Internet, you need to send SMS with code to number
To access Internet, text this code: XXX to number YYY
Если Вы уже отправили смс с кодом, то нажмите на кнопку:
После отправки SMS нажмите на кнопку
If you have to send SMS with the code, then click on the button
After you've sent SMS with code, please click this button
Задержка предоставления доступа в интернет зависит от скорости доставки нам Вашего смс сообщения.
Доставка и обработка вашего SMS может занять некоторое время. Пожалуйста, выждите несколько секунд.
Delayed access to the Internet depends on the speed of delivery of SMS messages to us.
Please allow a minor delay in providing you access — delivery and processing of your SMS might take a few moments. Thank you for your patience.
According to the decree №758 of the Government dated 31 July 2014. and №801 from 12 August 2014 — all public WIFI network required to make user authentication.
We require our WiFi users to authenticate following the provisions of the Russian law, stated by enactments 758 of 31st July 2014 and 801 of 12th August 2014.
sgrudnyakov
Спасибо!
Очень полезная статья. Сами в прошлом году пытались настроить подобное, но не вышло.