まず、ネットワークがどのように構成されているかを説明します。 詳細に入ることなく、HP MSM430アクセスポイント(J9651)、HP MSM760(J9420A)およびHP F1000-EIゲートウェイ(JG214A)を介した制御がハングアップします。 機器の選択は成功しませんが、私たちは持っているものを使って作業します。
人生で私はWindowsシステムにもっと夢中になりましたが、仕事を受けて、たくさんの記事を読んで、* nixシステムがこれに最適であるという結論に達しました。 選択はUbuntuサーバー16.04で行われました。 その後、数日間の苦しみがありましたが、最終的にはすべてがうまくいきました。
この記事は、Windowsを愛し、Ubuntuを見て、一からソフトウェアをインストールする人を対象としています。
すべてを整理することにしたので:
オープンなネットワークがあります。無料と呼びましょう。 接続すると、ユーザーは認証ページでホットスポットにリダイレクトされます。 そこで彼は、インターネットへのアクセスコードと、メッセージの送信先の電話番号を与えられます(少し変わっていますが、タスクはSMSを含めて保存することでした)。 メッセージが到着するとすぐに、インターネットアクセスがすぐに開きます。 予約します。左の番号を指定せずにサイトからSMSを送信する機能を見つけられなかったため、MTSとモデムの番号(広告ではない)を使用することをお勧めします(これは問題ですが、解決中です)。
必要なもの:
- Ubuntu Server 16.04の馬
- 透過モードのSquidプロキシ
- Mysql(MariaDB)
- Nginx
- PHP FPM
- USBリダイレクタ(HyperVの仮想マシン)
- モデムHuawei E153 MTS
- SMSを読むためのSMSツール
- などなど。 などなど。
始めましょう。
Ubuntu Server 16.04をインストールします
ここにあるものはすべて非常にありふれたものです。
- 仮想マシンを作成します(2コア、4 GBのメモリ、2つのネットワークインターフェイス、30 GBのディスク)
- 最新のディストリビューションをダウンロードし、接続し、インストールします...
- ネットワークインターフェイスを設定します。1つはvlanネットワークwifiで、2つ目はゲートウェイに向かっています
ネットワーク設定とパケット転送
使用しているネットワークカードと、それらに割り当てられている論理名を確認します。
cat /proc/net/dev
私の場合、これらはeth0とeth1です。
Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed lo: 632643353 3624368 0 0 0 0 0 0 632643353 3624368 0 0 0 0 0 0 eth1: 8789521059 30492824 0 0 0 0 0 0 65843784529 28992970 0 0 0 0 0 0 eth0: 65798728800 56063700 0 0 0 0 0 0 8382628950 29920038 0 0 0 0 0 0
ネットワークインターフェイスを構成するためのファイルを編集します。
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
また、IPv6インターフェースでTCPリスナーがハングしているアプリケーションもあります。 次のコマンドを使用して、システムでリッスンされているすべてのポートを表示できます。
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
SSLを使用してSquidをインストールし、IPv6を無効にする
プロキシの構築およびインストール方法に関する記事は多数ありますが、この段階はおそらく最も退屈なものでした。 デフォルトでは、ubuntuリポジトリにはSSLサポートなしのSquidが含まれています。 再構築することを決めたので、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 update apt-get build-dep squid3
ソースリポジトリにコメントして、新しいリポジトリを追加しましょう。
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に移動し、debianでのアセンブリのルールを使用して最新バージョンのsquidをテストしてダウンロードします
cd /tmp/ apt-get source squid3
現在のバージョン3.5.19、最新の3.5.21に更新
wget http://www.squid-cache.org/Versions/v3/3.5/squid-3.5.21.tar.gz tar -xf squid-3.5.21.tar.gz mkdir ./squid-3.5.21/debian/ cp -r ./squid3-3.5.19/debian/* ./squid-3.5.21/debian/ cd squid-3.5.21/ nano debian/rules
行を追加します(openssl.cnfへのパスを指定することを忘れないでください、/ etc / sslがあります)
--disable-ipv6 \ --enable-icap-client \ --enable-ssl-crtd \ --with-openssl=/etc/ssl \
エラー(ログ内の一定のメッセージ:セキュリティアラート:ローカルヘッダーで偽造が検出されました= ...:443リモート= ...:*)を修正し、すべてのセキュリティリスクを評価します。 (記事ではバージョン3.5.12について説明していますが、コードはここで少し変更されています)。
nano ./src/client_side_request.cc
hostHeaderIpVerify関数を探しており、そのコードをわずかに変更しています。
void ClientRequestContext::hostHeaderIpVerify(const ipcache_addrs* ia, const DnsLookupDetails &dns) { Comm::ConnectionPointer clientConn = http->getConn()->clientConnection; // note the DNS details for the transaction stats. http->request->recordLookup(dns); if (ia != NULL && ia->count > 0) { // Is the NAT destination IP in DNS? for (int i = 0; i < ia->count; ++i) { if (clientConn->local.matchIPAddr(ia->in_addrs[i]) == 0) { debugs(85, 3, HERE << "validate IP " << clientConn->local << " possible from Host:"); http->request->flags.hostVerified = true; http->doCallouts(); return; } debugs(85, 3, HERE << "validate IP " << clientConn->local << " non-match from Host: IP " << ia->in_addrs[i]); } } // patch for SECURITY ALERT: Host header forgery detected http->request->flags.hostVerified = true; http->doCallouts(); return; debugs(85, 3, HERE << "FAIL: validate IP " << clientConn->local << " possible from Host:"); hostHeaderVerifyFailed("local IP", "any domain IP"); }
パッチを確認して収集します(約10〜15分待ちます)
dpkg-source --commit #patch update to squid 3.5.20 debuild
収集したパッケージを確認します。
ls -l /tmp/ | grep .deb$
パッケージがない場合は、フォルダーを確認してください
ls -l /tmp/squid3-3.5.19/ | 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)
Squidのインストール済みバージョンの確認
/usr/sbin/squid -v Squid Cache: Version 3.5.21 Service Name: squid Ubuntu linux
それをセットアップして、最初に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リダイレクターとモデムを入れます
クラスターは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.XXX:32032 usbclnt -autoconnect on 1
すべてのUSBデバイスのリストを参照してください
usbclnt -l ================= USB CLIENT OPERATION SUCCESSFUL =============== List of USB servers and devices: 1: USB server at 10.XXX: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
USBデバイスをモデムモードに切り替える必要があります。これには、miniconプログラムを配置します。
apt-get install minicom
セットアップを開始します。
minicom -s
「シリアルポートを設定」を選択し、「シリアルポート」の項目にput / dev / ttyUSB0
設定で他の変更は行いません。 次のatコマンドは、Huaweiモデムの動作モードを切り替えるために使用されます。
AT ^ U2DIAG = 0-モデム専用モードのデバイス
AT ^ U2DIAG = 1モデムモードのデバイス+ CD-ROM
AT ^ U2DIAG = 255モデムモードのデバイス+ CD-ROM +カードリーダー
AT ^ U2DIAG = 256モデムデバイス+カードリーダー
モデムのみのモードをオンにします。
AT ^ U2DIAG = 0
応答として、「OK」を取得します。 プログラムを終了します。このためには、Ctrl + AおよびQを押します。
SMSツールをインストールする
パッケージに関する情報は、開発者のWebサイトで見つけることができます。
インストールと構成:
apt-get install smstools nano /etc/smsd.conf
行[GSM1]を見つけます
[GSM1] device = /dev/ttyUSB0 incoming = yes baudrate = 9600 eventhandler = /var/www/sms_recieve.php
受信SMSハンドラファイルを作成し、実行可能にします
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に更新されており、php7はすべてのubuntuリポジトリに既にあるため、新しいリポジトリを追加して設定します。
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; }
私の場合、ドメインのパブリックワイルドカード証明書がありました。 証明書ファイルを解凍し、アクセス権を設定します
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 php5.6-mbstring 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 0642 /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 `updated` < 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('sudo 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('sudo 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('sudo ipset save > /etc/iptables/ipset.rules'); // ip, TOO_MANY_REDIRECTS shell_exec('sudo conntrack -D conntrack --orig-src '.$ip); header('Location: '.$url); 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-disabled { background-color: #dadbdb; 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 { background-color: #3e315f; 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> <?php if (!$error) {?> <script type="text/javascript"> window.onload = function(){ window.htime = 60; check = function(){ if (window.htime <=0 ) { return true; } else { return false; } } window.htimer = window.setInterval(function(){ document.getElementById('button').innerHTML = ' ' + window.htime + ' .'; window.htime -= 1; if (window.htime <= 0) { window.clearInterval(window.htimer); document.getElementById('button').className = "internet"; document.getElementById('button').innerHTML = ' '; } }, 1000); } </script> <?php } ?> <div class="center"> <div class="logo"></div> <div class="header"> <br/> . <font class="eng">Welcome to the open network of the Civic Chamber of the Russian Federation.</font></div> <?php if ($error) { echo '<div class="error">'.$error.'</div>';} else { ?> <div> SMS : <font class="code"><?php echo $code;?></font> : <font class="num">+7 917 XXX-XX-XX.</font><br/><font class="eng">To access Internet, text this code <b><?php echo $code;?></b> to number <b>+7 917 XXX-XX-XX.</b></font></div> <div class="repeat"> SMS : <br/><font class="eng">After you've sent SMS with code, please click this button:</font></div> <a target="_self" href="<?php echo $url;?>" id="button" class="internet-disabled" onclick="return check();"> </a> <div class="repeat"> SMS . , .<br/><font class="eng">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.</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/>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. </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; }
さて、今度は、iptablesをphpからsudoersに制御する権限を追加します
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
それだけです このシステムは現在1か月稼働していますが、飛行は正常です。ご清聴ありがとうございました!