mportant;">Introduction
本文的研究成果是在 Captive Portal Using PHP and iptables Firewall on Linux 的基础上完成的。适用于任何使用 iptables 来共享上网的 Linux 软路由,因此,本迷你 Portal 也支援在树莓派上搭建。使用的原料:一台认证服务器(装有 PHP + MySQL),一台 Linux 接入路由。
Improvements on original plan
提供多帐号认证功能与用户数据库认证方案
认证端与接入端隔离(当然,如果搭建在树莓派等迷你平台上,不需要这样麻烦)
在原方案中,认证代码直接调用系统 shell,具有一定危险性,本方案改进为使用回调接口来通知上下线功能
更友好的 UI
原方案仅仅重定向 80 端口用于验证,在登录验证之前,其他端口依然畅通无阻,可以上网通信。在本方案中,未认证用户无法上网。
支持多个接入端统一共享一个认证端认证上网
Basic Concepts
警告:本文章操作具有一定危险性,您的电脑极有可能因为网络操作而断开连接。因此请您后果自负。请将本文章仅仅用在实验或教学目的,因为本文只是用以探讨 Captive Portal 的工作原理,而不是开发和搭建一个可以生产和公开使用的认证系统。如果您觉得本文对您有所帮助,我会非常感激
首先,我们介绍几点 Wi-Fi Portal 认证工作的基本原理:
本文假定每位无线用户连接到一个可以访问互联网的网关热点。
本文假定您已使用 iptables 做好 NAT 网络分享,接入设备的用户现在可以直接访问互联网。
本文在 Debian 系列系统上测试通过,其他发行版暂未测试。
用户的接入点本身就是网关。
每个未认证用户发给互联网的 HTTP 数据包都被使防火墙(iptables)用特殊的代码标记以便我们进一步处理将其重定向到 Portal 页面。
Portal Web 服务器透明地给每位接入用户提供认证页面并识别他们电脑的 MAC 地址。
通过认证的用户的设备 MAC 将被加入防火墙(iptables)的白名单,因此可以无限制地上网,他们的数据包不会被继续做标记。
Set-up a captive portal
1. 安装 conntrack
sudo apt-get install conntrack
2. 新建并编辑文件 /usr/bin/rmtrack (用于删除用户连接跟踪轨迹),并设置权限
nano /usr/bin/rmtrack #!/bin/bash /usr/sbin/conntrack -L |grep $1 |grep ESTAB |grep 'dport=80' |awk"{ system("conntrack -D --orig-src $1 --orig-dst " substr($6,5) " -p tcp --orig-port-src " substr($7,7) " --orig-port-dst 80"); }" chmod 755 /usr/bin/rmtrack
3. 为 Web 服务器的执行用户开放免密码 sudo 权限
sudo visudo 插入以下内容并保存(假定 www-data 为 Web 服务器的执行用户) www-data ALL=NOPASSWD: /usr/sbin/arp www-data ALL=NOPASSWD: /sbin/iptables www-data ALL=NOPASSWD: /usr/bin/rmtrack [0-9]*.[0-9]*.[0-9]*.[0-9]*
4. 实现开机自动设置 iptables 规则,插入如下代码(假定 100.64.0.1 为接入端,172.31.254.100 为 Web Portal 认证端,eth0 为 LAN 网卡接口名称,如果不需要将认证端与接入端分离,请直接将认证端 IP 与接入端 IP 设置为相同内容)
################################################################### #增加 iptables 规则,创建 portal 认证链 /sbin/iptables -t mangle -N portal /sbin/iptables -t mangle -A PREROUTING -i eth0 -p tcp -m tcp --dport 1:65534 -j portal /sbin/iptables -t mangle -A PREROUTING -i eth0 -p udp -m udp --dport 1:65534 -j portal /sbin/iptables -t nat -A PREROUTING -i eth0 -p tcp -m mark --mark 99 -m tcp --dport 1:65534 -j DNAT --to-destination 100.64.0.1 /sbin/iptables -t mangle -A portal -j MARK --set-mark 99 /sbin/iptables -t mangle -I portal 1 -d 172.31.254.100 -p tcp -m tcp -j RETURN /sbin/iptables -t mangle -I portal 1 -d 100.64.0.1 -p tcp -m tcp -j RETURN /sbin/iptables -t mangle -I portal 1 -d 100.64.0.1 -p udp --dport 1:52 -j DROP /sbin/iptables -t mangle -I portal 1 -d 100.64.0.1 -p udp --dport 54:65534 -j DROP #未验证用户禁止上网,但排除第三方认证 portal(在 FORWARD 链进行) /sbin/iptables -t filter -A FORWARD -m mark --mark 99 -j DROP /sbin/iptables -t filter -A FORWARD -m mark --mark 99 -d 172.31.254.100 -j ACCEPT #未验证用户禁止上网,但排除第三方认证 portal(在 INPUT 链进行,以防用户使用 squid 等代理上网) /sbin/iptables -t filter -A INPUT -p tcp --dport 80 -j ACCEPT /sbin/iptables -t filter -A INPUT -p udp --dport 53 -j ACCEPT /sbin/iptables -t filter -A INPUT -m mark --mark 99 -j DROP /sbin/iptables -t filter -A INPUT -m mark --mark 99 -d 172.31.254.100 -j ACCEPT ###################################################################
5. 搭建好 Web 服务器与 PHP 运行环境 ,这里假定使用 nginx。注意 Web 服务器应该仅保留一个默认网站,建议不使用虚拟主机与多站点。因为在用户未认证前,他们的各式各色的 HTTP 请求将会被本 Web 服务器接管。如果仅绑定一个域名,那么其他域名可能会发生 400 Bad Request 错误)在 nginx 的配置文件中,加入一个 URL 重写规则,以将所有页面的请求重写至 index.php 处理。
################################# 核心 URL 重写规则 ##################################### # 将所有 Web 请求都强行重写给 index.php 处理,导向到 Web Portal,并排除 Web Portal 的地址 if ( $remote_addr != "172.31.254.100" ) { rewrite /. /index.php last; } ########################################################################################
6. 分别部署好认证端与接入端的 PHP 页面,如果想让认证与接入同时在一个设备进行,请将认证端页面与接入端页面部署在同一台服务器上。修改 config.php 中的配置:
接入端:
<?php /* iEdon Mini Portal System */ // 定义 Web Portal 认证端URL define('PORTAL_URL', 'http://xxxx'); // 定义本接入端ID define('NAS_ID', 'iedon-net-access-point'); ?>
认证端:
<?php /* iEdon Mini Portal System */ // 定义 portal 站点名称 define('PORTAL_NAME', 'iEdon-Net'); // 定义底部文字 define('FOOTER_TEXT', '使用 Internet 前请先验证身份'); // 底部版权信息 define('COPYRIGHT', '© 2012-2017 iEdon'); // 定义默认的跳转URL define('DEFAULT_REDIRECT_URL', 'http://iedon.com'); // MySQL define('MYSQL_SERVER', '127.0.0.1'); define('MYSQL_USERNAME', 'root'); define('MYSQL_PASSWORD', 'root'); define('MYSQL_DATABASE_NAME', 'iedon_mini_portal'); // 分支接入路由器配置,支持多分支机构。不同的分支机构调用不同的回调接口。 /* eg: define('传递过来的nas参数_URL', '接入分支路由的回调URL'); define('传递过来的nas参数_NAME', '接入分支路由的友好描述'); */ define('iedon-net-access-point_URL', 'http://接入端地址/callback.php'); define('iedon-net-access-point_NAME', '办公室网'); ?>
7. 导入认证端中的 sql 文件至 MySQL 数据库。确认接入端 config.php 中的连接信息正确无误。
Previews
GitHub
https://github.com/iedon/mini-iptables-wifi-portal
本文链接:https://www.kinber.cn/post/2000.html 转载需授权!
推荐本站淘宝优惠价购买喜欢的宝贝: