2015年4月

wifidog用php实现验证流程

步骤
1.首先简单说说wifidog认证的过程
客户端首次连接到wifi后,浏览器请求将会被重定向到:

login/?gw_address=%s&gw_port=%d&gw_id=%s&url=%s

验证通过后,客户端被重定向到网关,url格式如下:
http://网关地址:网关端口/wifidog/auth?token=
wifidong会启动一个线程周期性地报告每一个用户的状态信息,并通过如下地址发送给认证
服务器:

auth_server:/auth/?stage=
ip=
mac=
token=
incoming=
outgoing=

认证服务器根据该状态信息决定是否允许该用户继续连接,并回复网关,回复格式为:Auth:状态码,
如:Auth:1
常用状态码:
0:AUTH_DENIED,表示拒绝
1:AUTH_ALLOWED,验证通过
验证通过后,将重定向到如下地址:
portal/?gw_id=%s
wifidog的ping协议
wifidog通过ping协议将当前状态信息发送给认证服务器,发送地址为:

http://auth_sever/ping/?
gw_id=%s
sys_uptime=%lu
sys_memfree=%u
sys_load=%.2f
wifidog_uptime=%lu

认证服务器须返回一个“Pong”作为回应。
具体php实现代码如下

public function auth()
    {
        //响应客户端的定时认证,可在此处做各种统计、计费等等
        /*
            wifidog 会通过这个接口传递连接客户端的信息,然后根据返回,对客户端做开通、断开等处理,具体返回值可以看wifidog的文档
        wifidog主要提交如下参数
        1.ip
        2. mac
        3. token(login页面下发的token)
        4.incoming 下载流量
        5.outgoing 上传流量
        6.stage  认证阶段,就两种 login 和 counters
        */


        $stage = $_GET['stage'] == 'counters'?'counters':'login';
        if($stage == 'login')
        {
            //XXXX跳过login 阶段的处理XXXX不能随便跳过的
            //默认返回 允许
            echo "Auth: 1";
        }
        else if($stage == 'counters')
        {

            //做一个简单的流量判断验证,下载流量超值时,返回下线通知,否则保持在线
            if(!empty($_GET['incoming']) and $_GET['incoming'] > 10000000)
            {
                echo "Auth: 0";
            }else{
                echo "Auth: 1\n";
            }
        }
        else
            echo "Auth: 0"; //其他情况都返回拒绝


        /*
            返回值:主要有这两种就够了
        0 - 拒绝
        1 - 放行

        官方文档如下
        0 - AUTH_DENIED - User firewall users are deleted and the user removed.
        6 - AUTH_VALIDATION_FAILED - User email validation timeout has occured and user/firewall is deleted(用户邮件验证超时,防火墙关闭该用户)
        1 - AUTH_ALLOWED - User was valid, add firewall rules if not present
        5 - AUTH_VALIDATION - Permit user access to email to get validation email under default rules (用户邮件验证时,向用户开放email)
        -1 - AUTH_ERROR - An error occurred during the validation process
        */
    }
    public function portal()
    {
        /*
         wifidog 带过来的参数 如下
        1. gw_id
        */
        //重定到指定网站 或者 显示splash广告页面
        redirect('http://www.baidu.com', 'location', 302);

    }
    public function ping()
    {
        //url请求 "gw_id=$gw_id&sys_uptime=$sys_uptime&sys_memfree=$sys_memfree&sys_load=$sys_load&wifidog_uptime=$wifidog_uptime";
        //log_message($this->config->item('MY_log_threshold'), __CLASS__.':'.__FUNCTION__.':'.debug_printarray($_GET));

        //判断各种参数是否为空
        if( !(isset($_GET['gw_id']) and isset($_GET['sys_uptime']) and isset($_GET['sys_memfree']) and isset($_GET['sys_load']) and isset($_GET['wifidog_uptime']) ) )
        {
            echo '{"error":"2"}';
            return;
        }
        //添加心跳日志处理功能
        /*
            此处可获取 wififog提供的 如下参数
        1.gw_id  来自wifidog 配置文件中,用来区分不同的路由设备
        2.sys_uptime 路由器的系统启动时间
        3.sys_memfree 系统内存使用百分比
        4.wifidog_uptime wifidog持续运行时间(这个数据经常会有问题)
        */

        //返回值
        echo 'Pong';
    }
    /**
     * wifidog 的gw_message 接口,信息提示页面
     */
    function gw_message()
    {
        if (isset($_REQUEST["message"])) {
            switch ($_REQUEST["message"]) {
                case 'failed_validation':
                    //auth的stage为login时,被服务器返回AUTH_VALIDATION_FAILED时,来到该处处理
                    //认证失败,请重新认证
                    break;
                case 'denied':
                    //auth的stage为login时,被服务器返回AUTH_DENIED时,来到该处处理
                    //认证被拒
                    break;
                case 'activate':
                    //auth的stage为login时,被服务器返回AUTH_VALIDATION时,来到该处处理
                    //待激活
                    break;
                default:
                    break;
            }
        }else{
            //不回显任何信息
        }
    }

本文章由 http://www.wifidog.pro/2015/04/09/wifidog-php-2.html 整理编辑,转载请注明出处

wifidog认证wifidog流程auth server简单配置

前段时间使用wifidog进行wifi强制认证,现在做个小结。
1.首先简单说说wifidog认证的过程
客户端首次连接到wifi后,浏览器请求将会被重定向到:

login/?gw_address=%s&gw_port=%d&gw_id=%s&url=%s

验证通过后,客户端被重定向到网关,url格式如下:
http://网关地址:网关端口/wifidog/auth?token=
wifidong会启动一个线程周期性地报告每一个用户的状态信息,并通过如下地址发送给认证
服务器:

auth_server:/auth/?stage=
ip=
mac=
token=
incoming=
outgoing=

认证服务器根据该状态信息决定是否允许该用户继续连接,并回复网关,回复格式为:Auth:状态码,
如:Auth:1
常用状态码:
0:AUTH_DENIED,表示拒绝
1:AUTH_ALLOWED,验证通过
验证通过后,将重定向到如下地址:
portal/?gw_id=%s
wifidog的ping协议
wifidog通过ping协议将当前状态信息发送给认证服务器,发送地址为:

http://auth_sever/ping/?
gw_id=%s
sys_uptime=%lu
sys_memfree=%u
sys_load=%.2f
wifidog_uptime=%lu

认证服务器须返回一个“Pong”作为回应。
2.实战应用
struts配置文件:

<package name="index" namespace="/" extends="interceptorMy,struts-default">
<action name="login/" class="goodsAction" method="login">
<result name="success" type="redirect">/Login/index.jsp</result>
<result name="input">/error.jsp</result>
</action>
<action name="ping/" class="goodsAction" method="ping">
</action>
 <action name="auth/" class="goodsAction" method="auth">
</action>
<action name="portal/" class="goodsAction" method="portal">
</action>
</package>

Action方法

public String login() {
    try{
        System.out.println("login start!");
                System.out.println("gw_port:"+gw_port);
        System.out.println("login end!");

     }
    catch(Exception e)
    {
        e.printStackTrace();
        return INPUT;
    }
    return "success";
}
public void ping() {
    try{
        System.out.println("ping start!");
        System.out.println(gw_id);
        ServletActionContext.getResponse().getWriter().write("Pong");
        System.out.println("ping end!");
         }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}
public void portal() {
    try{
        System.out.println("portal start");
        System.out.println("protal"+token);
    ServletActionContext.getResponse().sendRedirect("/demo/listAction");
        System.out.println("portal end");
     }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}
public void auth() {
    try{
        System.out.println("auth start!");
        System.out.println("mac"+mac);
        System.out.println("stage"+stage);
        System.out.println("token"+token);
        ServletActionContext.getResponse().getWriter().write("Auth: 1");
        System.out.println("auth end!");

     }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}

/Login/index.jsp代码:

<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    DateFormat format=new SimpleDateFormat("yyMMddHHmmss");
    String formatData=format.format(new Date());
    int ramdom=new Random().nextInt(1000);
    String token=formatData+ramdom;
    if(session.getAttribute("token")==null)
       session.setAttribute("token",token);

%>
<form method="GET" action='http://192.168.1.1:2060/wifidog/auth'>
<input type='hidden' name='token' value="<s:property value="#session.token" />" />
<input type='submit' value='Welcome!'/>
</form>

上面的192.168.1.1为网关的ip,2060为网关端口。
当然,完全可以在处理完login后直接跳到该地址。我们这里为演示其认证流程,故跳到该页面
效果:
客户端连接到wifi后,打开任何连接均跳到上面的index.jsp中,点击"Welcome"后,跳到/demo/listAction,即我们的目标地址。此后点击其他连接将不再拦截。
提示:安装wifidog的路由器必须可以访问Internet,否则wifidog拦截失败,无法跳到我们设定的页面。

本文章由 http://www.wifidog.pro/2015/04/08/wifidog%E6%B5%81%E7%A8%8Bwifidog%E8%AE%A4%E8%AF%81.html 整理编辑,转载请注明出处

OpenWrt wifidog 实现收费提醒效果

需求场景

有一个免认证的 Wifi SSID,比如叫:OpenWrt,附近的同学可以随便连上这个 SSID,没有缴过费的同学不管访问什么地址,都会被跳转到收费提醒页面,而缴过费的同学就可以开心上网了。

解决办法

从需求上来说,这是一个非常标准的 WifiDog 效果,如果未来有很复杂的需求,可以直接通过 WifiDog 来实现跳转,然后再通过 AuthPuppy 来实现账户管理,不过想在 OpenWrt 上同时部署 WifiDog 与 AuthPuppy 也不是一件很容易的事情。

因此我们准备考虑直接通过 iptables 来实现这个需求,未来如果有复杂的扩展需求,也不影响扩展到 WifiDog 来实现。

实现流程

通过 SSH 登录到 OpenWrt,打开 /etc/config/uhttpd,在文件的最顶部增加以下配置

config uhttpd 'portal'
list listen_http '0.0.0.0:11990'
option home '/www/portal'
option error_page '/index.html'

然后在 /www/portal 下新建一个名为 index.html 的静态文件,文件内容可以如下

<html>
<head>
  <meta http-equiv="cache-control" content="no-cache">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Wifi</title>
</head>
<body>
  Email: xxxx@xxx.com
</bodu>
</html>

之后再打开 /etc/firewall.user 文件,在末尾添加如下配置:

iptables -t nat -A prerouting_lan_rule -p tcp -m tcp --dport 80 -m mark ! --mark 8 -j REDIRECT --to-ports 11990
iptables -t filter -A forwarding_lan_rule -m mark ! --mark 8 -j REJECT

保存后执行 /etc/init.d/firewall restart 重新载入 iptables 的配置
然后再执行 /etc/init.d/uhttpd restart 重新载入 uhttpd 的配置

然后用手机连接这个无线网络,你就会发现总是弹出这个提示页面了

用户授权

当有用户缴费了之后,向他要到他的MAC地址,同样打开 /etc/firewall.user 文件,比如这个用户有 2 个设备,MAC 地址分别是 00:00:00:00:BB:AA 与 00:00:00:00:BB:BB 则添加以下 2 条 规则,以后这 2 个设备就可以随便上网了!

iptables -t mangle -A fwmark -m mac --mac-source 00:00:00:00:BB:AA -j MARK --set-mark 8
iptables -t mangle -A fwmark -m mac --mac-source 00:00:00:00:BB:BB -j MARK --set-mark 8

添加后同样需要执行 /etc/init.d/firewall restart 以使配置生效

注意事项

如果通过以太网口访问 OpenWrt luci 管理界面也是那个收费提示,只需要把该机器的 MAC 地址同样授权一样即可

本文章由 http://www.wifidog.pro/2015/04/08/openwrt-wifidog-5.html 整理编辑,转载请注明出处

OpenWrt WifiDog + wiwiz 安装配置

wifidog

WifiDog是路由器的一种上网认证功能,如果开启此功能,所有通过路由器上网的设备都会跳转到指定的界面,需要通过某种方式认证才可以上网,这种认证方式的优势在于安全性高,不容易被破解验证。

WifiDog安装
登录到 OpenWrt luci 后台,打开 System / Software,然后查找 wifidog
NewImage1.png

再点击 Available packages (wifidog),选择安装
NewImage2.png

NewImage.png

WifiDog 安装后,还需要到 System / Startup 使用 WifiDog 服务自动启动
NewImage4.png

然后还要到 Network /Firewall 里,把 lan => wan 的默认 Forward 规则改为 reject
NewImage3.png

wiwiz 账号申请

Wifidog 使用时需要配合认证系统来使用,你可以部署一个 AuthPuppy,不过如果为了测试方便,可以直接申请一个 wiwiz 的账号。Wiwiz是一个有线/无线网络热点管理系统,利用它你可以为你的热点创建一个强制门户/强制认证页面(captive portal)。

申请好账号之后,需要在 Wiwiz 里创建一个热点,这个时候将得到你的 HotSpot ID,把这个 ID 记录下来,等下 WifiDog 配置的时候要用到。

WifiDog配置

使用 SSH 登录到你的 OpenWrt 上,编辑 /etc/wifidog.conf 文件,在文件末尾增加以下配置:

GatewayID 14BBB888BBB
AuthServer {
    Hostname cp.wiwiz.com
    Path /as/s/
}

最后直接重新启动一下路由器,然后用你的终端通过你的路由器访问互联网,就会弹出 Wiwiz 的认证页面

本文章由 http://www.wifidog.pro/2015/04/08/wifidog-openwrt-2.html 整理编辑,转载请注明出处