wifidog 源码初分析(一)

wifidog 的核心还是依赖于 iptables 防火墙过滤规则来实现的,所以建议对 iptables 有了了解后再去阅读 wifidog 的源码。
在路由器上启动 wifidog 之后,wifidog 在启动时会初始化一堆的防火墙规则,如下:

/** Initialize the firewall rules
*/
int iptables_fw_init(void)
{
    const s_config *config;
    char * ext_interface = NULL;
    int gw_port = 0;
    t_trusted_mac *p;

    fw_quiet = 0;

    LOCK_CONFIG();
    config = config_get_config();
    gw_port = config->gw_port;
    if (config->external_interface) {
            ext_interface = safe_strdup(config->external_interface);
    } else {
            ext_interface = get_ext_iface();
    }

    if (ext_interface == NULL) {
            UNLOCK_CONFIG();
            debug(LOG_ERR, "FATAL: no external interface");
            return 0;
    }
    /*
     *
     * Everything in the MANGLE table
     *
     */

    /* Create new chains */
    iptables_do_command("-t mangle -N " TABLE_WIFIDOG_TRUSTED);
    iptables_do_command("-t mangle -N " TABLE_WIFIDOG_OUTGOING);
    iptables_do_command("-t mangle -N " TABLE_WIFIDOG_INCOMING);

    /* Assign links and rules to these new chains */
    iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_OUTGOING, config->gw_interface);
    iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_TRUSTED, config->gw_interface);//this rule will be inserted before the prior one
    iptables_do_command("-t mangle -I POSTROUTING 1 -o %s -j " TABLE_WIFIDOG_INCOMING, config->gw_interface);

    for (p = config->trustedmaclist; p != NULL; p = p->next)
            iptables_do_command("-t mangle -A " TABLE_WIFIDOG_TRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", p->mac, FW_MARK_KNOWN);

    /*
     *
     * Everything in the NAT table
     *
     */

    /* Create new chains */
    iptables_do_command("-t nat -N " TABLE_WIFIDOG_OUTGOING);
    iptables_do_command("-t nat -N " TABLE_WIFIDOG_WIFI_TO_ROUTER);
    iptables_do_command("-t nat -N " TABLE_WIFIDOG_WIFI_TO_INTERNET);
    iptables_do_command("-t nat -N " TABLE_WIFIDOG_GLOBAL);
    iptables_do_command("-t nat -N " TABLE_WIFIDOG_UNKNOWN);
    iptables_do_command("-t nat -N " TABLE_WIFIDOG_AUTHSERVERS);

    /* Assign links and rules to these new chains */
    iptables_do_command("-t nat -A PREROUTING -i %s -j " TABLE_WIFIDOG_OUTGOING, config->gw_interface);

    iptables_do_command("-t nat -A " TABLE_WIFIDOG_OUTGOING " -d %s -j " TABLE_WIFIDOG_WIFI_TO_ROUTER, config->gw_address);
    iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_ROUTER " -j ACCEPT");

    iptables_do_command("-t nat -A " TABLE_WIFIDOG_OUTGOING " -j " TABLE_WIFIDOG_WIFI_TO_INTERNET);
    iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_KNOWN);
    iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_PROBATION);
    iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN);

    iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_AUTHSERVERS);
    iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_GLOBAL);
    iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -p tcp --dport 80 -j REDIRECT --to-ports %d", gw_port);


    /*
     *
     * Everything in the FILTER table
     *
     */

    /* Create new chains */
    iptables_do_command("-t filter -N " TABLE_WIFIDOG_WIFI_TO_INTERNET);
    iptables_do_command("-t filter -N " TABLE_WIFIDOG_AUTHSERVERS);
    iptables_do_command("-t filter -N " TABLE_WIFIDOG_LOCKED);
    iptables_do_command("-t filter -N " TABLE_WIFIDOG_GLOBAL);
    iptables_do_command("-t filter -N " TABLE_WIFIDOG_VALIDATE);
    iptables_do_command("-t filter -N " TABLE_WIFIDOG_KNOWN);
    iptables_do_command("-t filter -N " TABLE_WIFIDOG_UNKNOWN);

    /* Assign links and rules to these new chains */

    /* Insert at the beginning */
    iptables_do_command("-t filter -I FORWARD -i %s -j " TABLE_WIFIDOG_WIFI_TO_INTERNET, config->gw_interface);


    iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m state --state INVALID -j DROP");

    /* XXX: Why this? it means that connections setup after authentication
       stay open even after the connection is done... 
       iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m state --state RELATED,ESTABLISHED -j ACCEPT");*/

    //Won't this rule NEVER match anyway?!?!? benoitg, 2007-06-23
    //iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -i %s -m state --state NEW -j DROP", ext_interface);

    /* TCPMSS rule for PPPoE */
    iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -o %s -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu", ext_interface);

    iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_AUTHSERVERS);
    iptables_fw_set_authservers();

    iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_LOCKED, FW_MARK_LOCKED);
    iptables_load_ruleset("filter", "locked-users", TABLE_WIFIDOG_LOCKED);

    iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_GLOBAL);
    iptables_load_ruleset("filter", "global", TABLE_WIFIDOG_GLOBAL);
    iptables_load_ruleset("nat", "global", TABLE_WIFIDOG_GLOBAL);

    iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_VALIDATE, FW_MARK_PROBATION);
    iptables_load_ruleset("filter", "validating-users", TABLE_WIFIDOG_VALIDATE);

    iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_KNOWN, FW_MARK_KNOWN);
    iptables_load_ruleset("filter", "known-users", TABLE_WIFIDOG_KNOWN);

    iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN);
    iptables_load_ruleset("filter", "unknown-users", TABLE_WIFIDOG_UNKNOWN);
    iptables_do_command("-t filter -A " TABLE_WIFIDOG_UNKNOWN " -j REJECT --reject-with icmp-port-unreachable");

    UNLOCK_CONFIG();
    return 1;
}

在该 防火墙规则的初始化过程中,会首先清除掉已有的防火墙规则,重新创建新的过滤链,另外,除了通过iptables_do_command("-t nat -A "TABLE_WIFIDOG_UNKNOWN " -p tcp --dport 80 -j REDIRECT --to-ports %d",gw_port); 这个命令将 接入设备的 80 端口(HTTP)的访问重定向至网关自身的 HTTP 的端口之外,还通过iptables_fw_set_authservers(); 函数设置了 鉴权服务器(auth-server) 的防火墙规则:

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);
        }
    }
}

首先从上面的代码可以看出 wifidog 支持多个鉴权服务器,并且针对每一个鉴权服务器设置了如下两条规则:
1)在filter表中追加一条[任何访问鉴权服务器都被接受]的WiFiDog_$ID$AuthServers过滤链:iptables -t filter -A WiFiDog$ID$AuthServers -d auth-server地址 -j ACCEPT
2)在nat表中追加一条[任何访问鉴权服务器都被接受]的WiFiDog
$ID$AuthServers过滤链:iptables -t nat -A WiFiDog$ID$_AuthServers -d auth-server地址 -j ACCEPT
这样确保可以访问鉴权服务器,而不是拒绝所有的出口访问。

本文章由 http://www.wifidog.pro/2014/12/08/wifidog%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90.html整理编辑,转载请注明出处

linux 系统安装wifidog

  1. 下载源码:
    1) 从svn checkout https://dev.wifidog.org/svn/trunk/wifidog-auth下载最新的wifidog 网关源码
    2) 从http://sourceforge.net/projects/wifidog/files/wifidog-gateway/下载wifidog 网关源码
    我使用第二种下载方法下载wifidog-20090925.tar.gz 版本,这是目前最新的wifidog。

  2. 解压: tar -zxvf wifidog-20090925.tar.gz

  3. cd wifidog-20090925; ./configure; make; make install, /usr/local/bin/目录下会多一个wifidog

  4. 到这里我们需要配置下源码根目录下的wifidog.conf,并再修改后将文件拷贝至 /usr/local/etc/,

    GatewayID default #网关的ID,如果不设置默认是网关interface 的 mac地址

    GatewayInterface br0  #网关使用的LAN Interface,必须设置
    
    GatewayAddress 192.168.1.1  #网关LAN 的IP地址,不设置默认从interface拿IP
    
    AuthServer   #必须设置
    {
        Hostname                 (Mandatory; Default: NONE)  #认证server 的主机名
        SSLAvailable             (Optional; Default: no; Possible values: yes, no) #认证server是否使用ssl协议
        SSLPort                  (Optional; Default: 443)  #认证server ssl协议端口
        HTTPPort                 (Optional; Default: 80)   #http协议端口
        Path                     (Optional; Default: /wifidog/ Note:  The path must be both prefixed and suffixed by /.  Use a single / for server root.) 
        LoginScriptPathFragment  (Optional; Default: login/? Note:  This is the script the user will be sent to for login.) 
        PortalScriptPathFragment (Optional; Default: portal/? Note:  This is the script the user will be sent to after a successfull login.)
        MsgScriptPathFragment    (Optional; Default: gw_message.php? Note:  This is the script the user will be sent to upon error to read a readable message.)
        PingScriptPathFragment    (Optional; Default: ping/? Note:  This is the script the user will be sent to upon error to read a readable message.)
        AuthScriptPathFragment    (Optional; Default: auth/? Note:  This is the script the user will be sent to upon error to read a readable message.)
    }
    
    GatewayPort 2060  #wifidog监听的端口
    
    CheckInterval 60   #检查连接网关客户端的流量,主要是用于流量更新、超时重新认证
    ClientTimeout 5  #checkinterval的间隔数,这里要注意,实际流量更新遗迹超时、检查使用的时间是CheckInterval * ClientTimeout
    
    TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D #MAC地址白名单
    

    后面还有一些关于网段、port 的黑白名单规则,以及其他一些设置,这里就不一一列举了。

  5. 启动wifidog -c /usr/local/etc/wifidog.conf 就可以和auth server交互了,auth server可以参考http://www.authpuppy.org 安装authpuppy,这里就不详细解释了

本文章由 http://www.wifidog.pro/2014/12/08/linux%E5%AE%89%E8%A3%85wifidog.html 整理编辑,转载请注明出处

wifidog 认证流程

一. 用户上线

  1. 用户访问网络,通过iptables将未认证的用户dnat到wifidog进程,wifidog通过307报文将用户重定向到认证服务器
  2. 用户打开认证服务器登录页面,输入用户名密码,发送认证请求
  3. 认证成功的话服务器会发送302报文,携带token信息重定向到wifidog页面。认证失败的话会返回失败页面
  4. 用户携带token信息向wifidog发起认证请求,wifidog再向认证服务器发起请求,认证成功后授权,并将用户重定向到成功页面

1.jpg

二. 保活和下线

  1. wifidog会定时向认证服务器发送保活消息
  2. 当用户主动请求下线后,wifidog此时并没有下线
  3. 当wifidog再次发起保活请求时,认证服务器会告诉它用户已下线,此时wifidog会将用户下线

2.png

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

WiFiDog Project History

Wifidog was designed as a replacement to existing captive portal solutions which we felt didn't fit the needs of next generation community groups. Specifically, we wanted both personalized and community wide content for each hotspot, no pop ups, no client software and centralized management. Mainly as a replacement for portals currently using NoCat. A lot of other vendors use WiFiDog (especially the client) as a base for their solutions.
Wifidog’s Features
Main Features

Captive portal which lets hotspot owners communicate with their users (through the Content Distribution System).
Wifidog gateway was designed for and runs on GNU/Linux servers and embedded linux devices, e.g. Linksys WRT54G with OpenWRT. For a current list of supported devices and installation instructions please click Here.
Multilingual support (through browser detection and user selection) with the ability to add more languages using a .po editor (please see Language Translation for more details).Current implemented languages are:
    English
    French
    German
    Spanish
    Italian
    Greek
    Portuguese (also Brazilian)
    Swedish
    Bulgarian
    Japanese
    Catalan 
Maintain the client (hotspot users) connection by checking network activity through a ping command, instead of a javascript window (like used in NoCat). This allows PDAs and cellphones and other devices without javascript support to connect.
Support for differing types of hotspots:
    Splash Only mode: Users are redirected to the portal, but do not have to login in order to use services
    Normal Mode: Users are unique and must have a valid email address in order to open an account. 
Users are able to create a working account directly from any hotspot. New users sign on from any hotspot, create their account and are granted access for 15 minutes to confirm an email. If they don't, they are disconnected and have to sign up again.
Hotspot/node monitoring by two way heart beating, so the central server always knows which hotspots/nodes are up, regardless of dynamic DNS, firewalls, etc.
Reports and Statistics including:
    10 highest bandwidth consumers
    10 most frequent users
    10 most mobile users
    Anoymised SQL data export (for academic research)
    Breakdown of how many users actually use the network
    Connection log
    Content display and click through report
    Graph on network use (per hour, weekday and month)
    Individual user report, most popular nodes (by visit)
    Network status information
    Node status information
    Registration log
    User registration report 
Automatic node creation (if the person creating the node has the relevant permissions and the feature is enabled). 

Please see the Road Map for new features currently in development.
Most awaited features are:

User classes
Bandwidth limiting per class
Bandwidth limiting per router
Port blocking per class
Apply policies based on time of day 

Auth server (Current)

Node-specific content features. Wifidog-auth has a very cool local content architecture.
    RSS feed support (optional, with magpierss), one feed per node (url stored in the database, works great, but no gui to edit it yet) and one network-wide RSS feed. 
Configuration and integration
    No need to set any path in the web server config files
    All paths are editable from the config file
    Quick setup: the network name, url, default RSS, and similar data are set from the config file, and will be displayed as needed throughout the system.
    Can import all users and passwords from a NoCat password file [WWW] More info]. 
Development
    Demo page to let people to hack on it more easily
    Database abstraction layer with very nice debugging features (just append true at the end of the call and you'll see the query, the results, the query plan, and the number of affected rows. Porting to another database only requires porting one file. Currently uses Postgres.) 
User management (end user)
    Users can create and activate accounts without admin intervention. The user will be granted a 15 minute grace period after signing up in order to retrieve and validate his email.
    Users can request that the server re-send the validation email
    Users can change their passwords
    Users who forget their username can have it mailed to them.
    Users who lose their password can ask the system to generate a new one and mail it to them.
    Email must be valid but isn't displayed in order to preserve user privacy.
    Users can login using either email or username
    Enforces (politely) that duplicate email addresses are not allowed in the database 
Logging and monitoring
    MAC address logging (in case it is a legal requirement in your country)
    Sends the original url before redirecting to the central server in order to allow linking on the portal page
    Multi-language support
    Script and sql execution time breakdown. Already implemented, just needs to be packaged to be usable by the templates. 
Reports and Statistics 

Gateway (Current)

Supports using backup auth servers if the primary one doesn't respond.
Runtime query interface
One rule to jump in, one to jump out rejects, one to jump out accepts
Detects the IP address of a network interface automatically, instead of specifying it separately in the configuration file. 

Sourceforge
You can also take a look at Sourceforge Feature Requests page or add your own new requests.

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