如何理解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安装 wifidog原理 wifidog分析 wifidog配置 wifidog流程 wifidog服务器 wifidog-ddwrt wifidog openwrt