(iptables) 自制简单Wi-Fi Captive Portal(无线认证门户),支持树莓派
本文最后更新于 1560 天前,其中的信息可能已经有所发展或是发生改变。

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 认证工作的基本原理:

  1. 本文假定每位无线用户连接到一个可以访问互联网的网关热点。
  2. 本文假定您已使用 iptables 做好 NAT 网络分享,接入设备的用户现在可以直接访问互联网。
  3. 本文在 Debian 系列系统上测试通过,其他发行版暂未测试。
  4. 用户的接入点本身就是网关。
  5. 每个未认证用户发给互联网的 HTTP 数据包都被使防火墙(iptables)用特殊的代码标记以便我们进一步处理将其重定向到 Portal 页面。
  6. Portal Web 服务器透明地给每位接入用户提供认证页面并识别他们电脑的 MAC 地址。
  7. 通过认证的用户的设备 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', '&copy; 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

iEdon Mini Portal Preview

GitHub

https://github.com/iedon/mini-iptables-wifi-portal

CC-BY-NC-SA ー  無断転載はご遠慮下さい

评论

  1. FROYO
    Windows Chrome 48.0.2564.116
    4年前
    2017-10-18 22:45:40

    这么说来安卓手机也可以了,建个免费WiFi热点,打个广告,或者做点什么其他用途,貌似不错

    • iEdon 博主
      iPhone Safari 9.0
      4年前
      2017-10-19 14:50:01

      安卓上面可以使用 iptables?而且 iptables 有部分模块是需要加载到内核里面的。

  2. FROYO
    Windows Chrome 48.0.2564.116
    4年前
    2017-10-20 9:22:08

    可以使用哇,很早的时候,安卓2.x的时代好像就有了
    曾经在安卓机上搭过WordPress博客,这样的话条件都具备了

    • 老何
      Windows Chrome 62.0.3202.62
      4年前
      2017-10-25 9:59:24

      你的博客怎么打不开了

      • iEdon 博主
        Windows Chrome 61.0.3163.100
        4年前
        2017-10-25 16:00:47

        能打开呀?

  3. 何先生
    Windows Chrome 62.0.3202.62
    4年前
    2017-10-20 12:30:01

    我路由器用的老毛子的固件,也是很容易实现

  4. 老何
    Windows Chrome 61.0.3163.100
    4年前
    2017-10-22 10:19:29

    终于更新了

  5. 山野愚人居
    Windows Firefox 57.0
    4年前
    2017-11-29 13:00:51

    这个技术难度有点高,感觉搞不来……

  6. too
    Windows Chrome 64.0.3278.0
    4年前
    2017-12-05 0:06:37

    会不会存在折那么漏洞啊?

  7. 关竹
    Windows Chrome 80.0.3987.149
    2年前
    2020-3-31 9:10:47

    您好,您所用的接入端地址是否是eth0 LAN 网卡的地址?Web Server 所在的地址,是无线的地址?

    • iEdon 博主
      Windows Chrome 80.0.3987.149
      2年前
      2020-4-03 11:08:48

      您好,接入端地址为 LAN 网卡地址。Web Server 所在地址为 portal 地址,只要网络内部可以通达就行。

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇