OpenWRT安装Wifidog实现Portal网页认证上网

天锦 发表于 码农也得有格调 分类,标签:

Portal认证上网多用于WiFi营销,通过接入一个开放的WiFi网络,进行Web认证登陆后放行上网,协会有百来号人,直接公开密码不合适,直接设置成一个开放网络更不合适,必须要做认证之后方能允许上网,Portal认证便是一个很好的选择。先前使用的是iKuai的软路由,iKuai提供了集成Portal认证,我也对协会的网站进行了iKuai认证集成,用户可以直接使用协会网站账号登录上网,但由于种种原因,如今不得不将iKuai撤下,换成OpenWRT路由系统。

OpenWRT安装Wifidog很简单,直接使用opkg安装就行

[root@openwrt ~]# opkg update
[root@openwrt ~]# opkg install wifidog

配置

网上有提到Web版的配置工具包也就是luci-app-wifidog,多为用户自行编译,我觉得Wifidog就一个conf文件,没有必要在专门去折腾这给luci-app,事实也证明我花了几个小时在这个包上,最后也没啥结果,还是直接vim /etc/wifidog.conf来的快,wifidog.conf文件只需关注一下几个参数就行了:

GatewayID default
GatewayInterface br-lan
GatewayAddress 10.10.16.1
AuthServer {
    Hostname auth.mydomain.com
    SSLAvailable no
    HTTPPort 80
    Path /wifidog/
    LoginScriptPathFragment login.php?
    PortalScriptPathFragment portal.php?
    MsgScriptPathFragment message.php?
    PingScriptPathFragment ping.php?
    AuthScriptPathFragment auth.php?
}

GatewayAddress wifidog所在路由的网关IP

Hostname: 提供验证服务的服务器

SSLAvailable, HTTPPort, Path 分别是验证服务对应的 是否可用https, 访问端口, 路径. 路径必须前后带'/'(如果是根目录则只有'/')

LoginScriptPathFragment 和上面的Path联合后得到的登录页地址

PortalScriptPathFragment 验证成功后的页面地址

MsgScriptPathFragment 消息页地址

PingScriptPathFragment 必须返回 Pong  --- 注意大小写一致

AuthScriptPathFragment 返回 Auth: 1 或 Auth: 0 代表验证通过/不通过

使用以下命令在前台启用wifidog, 可以看到详细的日志输出

[root@openwrt ~]# wifidog -f

wifidog启动后, 会主动访问验证服务器确认验证服务器在线

GET /wifidog/ping.php?gw_id=default&sys_uptime=1254&sys_memfree=80884&sys_load=0.54&wifidog_uptime=262 HTTP/1.0" 200 5 "-" "WiFiDog 1.3.0"

用户连接wifi后, 会被引导至登录页

GET /wifidog/login.php?gw_address=10.10.16.1&gw_port=2060&gw_id=default&ip=10.10.16.2&mac=aa:aa:aa:aa:aa:aa&url=http%3A%2F%2Fwww.tianjinkun.com%2F HTTP/1.1

用户登录成功后, 验证服务器生成Token并引导返回wifidog的验证页, 其域名, 端口来自于前面的参数, 而/wifidog/auth?token= 这个是固定的,通过URL传参的方式将Token传递给Wifidog。

GET http://10.10.16.1:2060/wifidog/auth.php?token=fa1a7f7ad3c87f21f6f89b3d474e8c0b

Wifidog拿到token后向验证服务器验证该Token的有效性

GET /wifidog/auth.php?stage=login&ip=10.10.16.2&mac=aa:aa:aa:aa:aa:aa&token=fa1a7f7ad3c87f21f6f89b3d474e8c0b&incoming=0&outgoing=0&gw_id=default HTTP/1.0

验证服务器返回“Auth: 1”表示验证成功,Wifidog引导用户跳转到PortalScriptPathFragment 指定的地址,并放行网络权限完成连接,如果返回“Auth: 0”表示验证失败,将引导用户到MsgScriptPathFragment指定的地址,并继续阻止用户上网。

GET /wifidog/portal.php?gw_id=default HTTP/1.1
GET /wifidog/message.php?message=denied HTTP/1.1

wifidog会定时去验证服务器验证访问有效性,当验证服务器返回“Auth: 0”时将会把用户踢下线,以此实现认证的解除。

GET /wifidog/auth.php?stage=counters&ip=10.10.16.2&mac=aa:aa:aa:aa:aa:aa&token=fa1a7f7ad3c87f21f6f89b3d474e8c0b&incoming=73838&outgoing=13952&gw_id=default HTTP/1.0

验证服务器例子

ping.php

<?php
echo "Pong";
?>

auth.php

<?php
echo "Auth: 1";
?>

portal.php

<?php
echo "Auth: 1";
$location = 'Location: http://www.tianjinkun.com';
header($location);
?>

message.php

<?php
echo "验证失败,你不能再上网了";
?>

login.php

<html>
<head>
  <title>Portal Login</title>
</head>
<body>
    <h2>Login</h2>
    <?php
    if (isset($_POST['user_name']) && isset($_POST['password'])) {
      $user_name = $_POST['user_name'];
      $password = $_POST['password'];
      if ($user_name == 'husky' && $password == '2233') {
        $location = 'Location: http://' . $_POST['gw_address'] . ':' . $_POST['gw_port'] .'/wifidog/auth?token='.md5(time());
        echo $location;
        header($location);
      } else {
        echo '<h1>账号错误!</h1><br>';
      }
    }
    ?>
    <form action="login.php" method="post">
    Username:<input type="text" name="user_name"/><br>
    Password:<input type="password" name="password"/><br>
    <?php
        echo '<input type="hidden" name="gw_address" value="'. $_GET['gw_address'] . '"><br>';
        echo '<input type="hidden" name="gw_port" value="'. $_GET['gw_port'] . '">';
    ?>
    <input type="submit">
    <pre>
        <?php var_dump($_GET);?>
    </pre>
</body>
</html>

只要根据自己已有的系统稍加修改便可实现Portal认证上网。