分类 wifidog原理 下的文章

原版wifidog一个接口(gw_message)上的问题

这个借口实际上用的比较少:
http://auth_server:port/gw_message.php?message=xxx
这个是原版wifidog于其他4个接口风格很不一致的地方,导致了使用其他非php服务器端的问题
并且如果采php的CI框架,也有访问上的问题(其他框架就不知道了)
只能通过特殊的url重定向规则等外部配置才能实现该接口的访问.

如果是其他平台呢服务器平台呢?
只需将gw_message.php?修改成其他script 路径就行了

本文章由http://www.wifidog.pro/2014/12/26/wifidog-gw-message%E9%97%AE%E9%A2%98.html整理编辑,转载请注明出处

如何理解wifidog 认证有效时间 - timeout

在wifidog.conf 里有两个参数是比较重要的:
CheckInterval 60 单位秒
ClientTimeout 5

这两个参数主要是用来检查接入网关的客户端是否超时,具体值根据需要自定义,这里以60 和 5 做讲解。
这里先说下一个知识点:
我们知道wifidog是起线程来实现不同的功能,比如监听http 请求,超时检查, ping协议,wdctl 控制wifidog 进程的线程等,这里加入我们不需要ping 协议,那么我们就可以把ping 协议的线程注释掉:

    /* Start heartbeat thread */
    result = pthread_create(&tid_ping, NULL, (void *)thread_ping, NULL);
    if (result != 0) {
        debug(LOG_ERR, "FATAL: Failed to create a new thread (ping) - exiting");
            termination_handler(0);
    }
    pthread_detach(tid_ping);

这里需要注意一下,注释掉这个线程之后可能会引起一个问题,auth server不能访问了!这是因为默认wifidog 在刚启动时会把auth server 的iptables 放通:
fw_init->iptables_fw_init->iptables_fw_set_authservers, 我们需要来看下这个函数做了些什么事:

    void iptables_fw_set_authservers(void)
    {
        const s_config *config;
        t_auth_serv *auth_server;

        config = config_get_config();

        for (auth_server = config->auth_servers; auth_server != NULL; auth_server = auth_server->next)                
        {
                if (auth_server->last_ip && strcmp(auth_server->last_ip, "0.0.0.0") != 0) 
                {
                        iptables_do_command("-t filter -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->last_ip);
                        iptables_do_command("-t nat -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->last_ip);
                }
        }

    }

我们看到把auth server的last ip放通了,last ip是什么?last ip实际上是在连接auth server之前用dns 包得到的auth server 最新的IP地址(详见函数_connect_auth_server),那么问题就在这,last ip 是在连接server时才会更新的,但在iptables初始化时,并没有做连接的动作,不过在ping 协议里却是有的,ping 协议会在刚启动时连接auth server,所以关于auth server的iptables 会生效,如果单纯把ping 协议关了,有可能存在不能访问auth server 页面的情况,这里需要注意一下。

同理不需要wdctl 线程,也可以注释掉:

    /* Start control thread */
    result = pthread_create(&tid, NULL, (void *)thread_wdctl, (void *)safe_strdup(config->wdctl_sock));
    if (result != 0) {
            debug(LOG_ERR, "FATAL: Failed to create a new thread (wdctl) - exiting");
            termination_handler(0);
    }
    pthread_detach(tid);

了解了线程的作用,我们重点讲解下超时检查的这个线程:

    result = pthread_create(&tid_fw_counter, NULL, (void *)thread_client_timeout_check, NULL);
    if (result != 0) {
        debug(LOG_ERR, "FATAL: Failed to create a new thread (fw_counter) - exiting");
        termination_handler(0);
    }
    pthread_detach(tid_fw_counter);

这个线程做什么的? 咋一看是用来更新流量的,其实就是更新流量,同时把一段时间没流量更新的客户端踢掉,注意重点,是一段时间没有流量更新的客户端,而不是不管你有没有上网过一段时间都把你踢掉!这个是很重要的条件,因为前者需要和auth server接口做交互,后者可以直接在网关里实现。下面我们来看下代码:
thread_client_timeout_check,这个函数会在每CheckInterval 时间做一次事情,做什么呢?fw_sync_with_authserver:
先去调用iptables_fw_counters_update,这个函数会把每一个客户端的incoming 和outgoing 也就是上下行流量更新下,也会更新一个last_uodated的东西,这个变量其实就是最后一个更新客户端outgoing 流量的时间,更新条件就是客户端记录的流量比iptables 看到的流量小了,换句话说这个客户端还在上网。更新完这些变量之后回到fw_sync_with_authserver:
接着就是把每一个客户端的流量情况上报给auth server,同时对于客户端p1(p1是所有客户端中的一个)
if (p1->counters.last_updated +(config->checkinterval * config->clienttimeout) <= current_time)
下线处理:iptables 设置阻拦此客户端,从客户端列表中删除此客户端,通知auth server该客户端下线。
last_updated变量的作用就在这,结合前面讲的,last_updated是最后有访问外网流量行为即outgoing有变化时的时间,如果最后一次访问外网时间 + 检查流量间隔时间(CheckInterval 60 单位秒 * ClientTimeout 5)不大于当前时间,也就是说,已经有CheckInterval 60 单位秒 * ClientTimeout 5 时间没上网了,那么就做下线处理。
这里为什么是(CheckInterval 60 单位秒 * ClientTimeout 5)? 可以这么理解,网关每CheckInterval 60检查一次流量,检查了ClientTimeout 5 次发现有个客户端都没有访问外网没有outgoing 增加,那网关就认为该客户端已经下线了。

那么要是我想实现不管客户端上不上网,过了(CheckInterval 60 单位秒 * ClientTimeout 5)时间我就是要让客户端重新认证怎么做? 很简单:
在client 的结构体里添加个online_time 的字段,在append client时把online_time 字段更新到当前时间(time(NULL)),然后在fw_sync_with_authserver检查时间时,把if条件换成,如果online_time + (CheckInterval 60 单位秒 * ClientTimeout 5) 大于等于当前时间time(NULL),就踢掉,两个当前时间一个是添加客户端时的时间,一个是超时验证时的时间,所以不会相同。

本文章由 http://www.wifidog.pro/2014/12/26/wifidog-%E8%B6%85%E6%97%B6%E6%A3%80%E6%9F%A5.html 整理编辑,转载请注明出处

WiFidog简介

WIFIdog是一种新的认证方式,这种认证方式的优势在于安全性高,不容易被破解验证。
客户端发出初始化请求,比如访问www.baidu.com
网关的防火墙规则将这个请求重定向到本地网关的端口上。这个端口是Wifidog监听的端口。
Wfidog提供一个HTTP重定向回复,重定向到Web认证页面,重定向的Url的Querystring中包含了Gateway的ID,Gateway的FQDN以及其他的信息。
用户向认证服务器发出认证请求。
网关返回一个(可以是自定义的)splash(也称作“登录”)页面。
用户提供他的凭据信息,比如用户名和密码。
成功认证的话,客户端将会被重定向到网关的自己的web页面上,并且带有一个认证凭据(一个一次性的token)
用户就是用获取到的凭据访问网关。
网关去认证服务器询问token的有效性。
认证服务器确认token的有效性。
网关发送重定向给客户端,以从认证服务器上获取 成功提示页面,重定向到 http://portal_server:port/portal_script 这个位置。
认证服务器通知客户请求成功,可以上网了。
整个过程如下图所示:
1.jpg

本文章由http://www.wifidog.pro/2014/12/25/wifidog%E7%AE%80%E4%BB%8B.html 整理编辑,转载请注明出处

wifidog 移植到MIPS平台

使用的是一款Broadcom的芯片,现在上面运行wifidog实现认证上网的功能。由于不是openwrt平台,所以就没了make menuconfig 勾选就能自动编译到版本中的。所以想使用交叉编译的方法将wifidog移植到该平台上。

下面写下步骤吧,不是很复杂,但是开始也破费周折。下载源码到http://dev.wifidog.org 下载就可以了。

./configure CC=/opt/toolchains/crosstools-mips-gcc-4.6-linux-3.4-uclibc-0.9.32-binutils-2.21/usr/bin/mips-linux-gcc CXX=/opt/toolchains/crosstools-mips-gcc-4.6-linux-3.4-uclibc-0.9.32-binutils-2.21/usr/bin/mips-linux-g++ LD=/opt/toolchains/crosstools-mips-gcc-4.6-linux-3.4-uclibc-0.9.32-binutils-2.21/usr/bin/mips-linux-ld RANLIB=/opt/toolchains/crosstools-mips-gcc-4.6-linux-3.4-uclibc-0.9.32-binutils-2.21/usr/bin/mips-linux-ranlib AR=/opt/toolchains/crosstools-mips-gcc-4.6-linux-3.4-uclibc-0.9.32-binutils-2.21/usr/bin/mips-linux-ar --build=i686-pc-linux-gnu --host=mips-wrs-linux-gnu --target=mips-wrs-linux-gnu --prefix=/home/wifidog_install/

使用configure 配置。这里我的平台只使用 ./configure --host=mips-linux-gcc 的方式可以编译成功,但是放在板子上运行会报错"mips-linux-gcc " not found。很莫名其妙的。所以采用上面的配置方法,配置生成Makefile文件后,make ,make install,将/home/wifidog_install/下的lib 与 bin中的文件放到板子上。这里可能遇到执行wifidog 缺少libnsl.so.0这个库,查找交叉编译工具器中是否存在?如果没有就去下载源码,交叉编译一个了。

还有一个就是将wifidog 源码中的wifidog.conf 和wifidog-msg.html 两个文件拷贝到板子上。wifidog.conf 是wifidog运行需要解析的配置文件,而wifidog-msg.html 也是一个必须的框架。这个路径在wifidog.conf中指定。

本文章由 http://www.wifidog.pro/2014/12/25/wifidog-mips%E5%B9%B3%E5%8F%B0.html 整理编辑,转载请注明出处