wifidog

wifidog开源模块,通过iptable对报文进行重定向到端口2060接口,对报文进行拦截,利用iptable实现用户上网行为管理功能,目前市面上的无线多采用此模块进行portale认真。 本文章对wifidog的源码进行了分析,希望有所帮助。

1 main

1.1 config_init();初始化全局变量,设置默认值

1.2 parse_commandline(argc,

argv);读取命令行参数

(1). -h 打印命令参数信息;

(2). -c 指定使用的wifidog配置文件;

(3). -f  wifidog前台运行;

(4). -d 设置调试等级;

(5). -s  将日志信息输入到log日志;

(6). -w 与Wdctl通信域socket路径;

(7). -v  打印wifidog版本信息;

(8). -x  父进程id;

(9).  -i   Internal socket path used when re-starting self.;

(10). -a  Path to /proc/net/arp replacement - mainly useful for debugging.;

(11) -p    Save pid to file;

1.3 config_read(config->configfile);读取wifidog.conf文件,并将其内容保存到全局变量

1.4 config_validate();检验是否配置gatewayinterface和authserver

1.5client_list_init();初始化client链表

1.6 init_signals();初始化信号

1.7 append_x_restartargv(),保存传入参数和进程id。

1.8 执行main_loop循环

2 main_loop循环

2.1 设置wifidog启动时间started_time

2.2 存放进程id到指定文件save_pid_file(config->pidfile);

2.3 获取gateway的ip地址config->gw_address

2.4 获取gateway id即mac地址config->gw_id

2.5 调用函数httpdCreate()创建web server(建立tcp,socket监听默认端口2060)

2.6 函数register_fd_cleanup_on_fork(webserver->serverSock);初始化socket表

2.7 web server注册调用函数

httpdAddCContent(webserver, "/", "wifidog", 0, NULL, http_callback_wifidog);

httpdAddCContent(webserver, "/wifidog", "", 0, NULL, http_callback_wifidog);

httpdAddCContent(webserver, "/wifidog", "about", 0, NULL, http_callback_about);

httpdAddCContent(webserver, "/wifidog", "status", 0, NULL, http_callback_status);

httpdAddCContent(webserver, "/wifidog", "auth", 0, NULL, http_callback_auth);

httpdAddCContent(webserver, "/wifidog", "disconnect", 0, NULL, http_callback_disconnect);

httpdSetErrorFunction(webserver, 404, http_callback_404);

2.8 清空防火墙规则fw_destroy();

2.9 初始化防火墙规则fw_init();

2.10 创建线程,检测client超时;thread_client_timeout_check

2.11 创建线程,处理wdctl发送的控制信息;thread_wdctl

2.12 创建线程,检测认证server是否在线;thread_ping

2.13 进入while循环;获取client连接,为每个client创建线程,处理http请求.

2.1 fw_init()

2.1.1 在mangle表创建新的链表和规则

1).在mangle表中创建新的链表。

("-t mangle -N " CHAIN_TRUSTED);

("-t mangle -N " CHAIN_OUTGOING);

("-t mangle -N " CHAIN_INCOMING);

("-t mangle -N " CHAIN_AUTH_IS_DOWN);

2).在挂载点为PREROUTING ,输入接口为gw_interface,执行相应的链表。

("-t mangle -I PREROUTING 1 -i %s -j " CHAIN_OUTGOING, config->gw_interface);

("-t mangle -I PREROUTING 1 -i %s -j " CHAIN_TRUSTED, config->gw_interface);

("-t mangle -I PREROUTING 1 -i %s -j " CHAIN_AUTH_IS_DOWN, config->gw_interface);

3).在挂载点为POSTROUTING  ,输出接口为gw_interface,执行相应的链表。

("-t mangle -I POSTROUTING 1 -o %s -j " CHAIN_INCOMING, config->gw_interface);

4).链表CHAIN_TRUSTED,匹配mac地址为白名单中设置的mac,则设置mark标记为FW_MARK_KNOWN = 2,对此mac不进行拦截。

("-t mangle -A " CHAIN_TRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", p->mac,FW_MARK_KNOWN);

2.1.2 在nat表中创建新的链表和规则

1). 在nat表中创建新的链表。

("-t nat -N " CHAIN_OUTGOING);

("-t nat -N " CHAIN_TO_ROUTER);

("-t nat -N " CHAIN_TO_INTERNET);

("-t nat -N " CHAIN_GLOBAL);

("-t nat -N " CHAIN_UNKNOWN);

("-t nat -N " CHAIN_AUTHSERVERS);

("-t nat -N " CHAIN_AUTH_IS_DOWN);

2).在挂载点PREROUTING,输入接口gw_interface,执行表CHAIN_OUTGOING

("-t nat -A PREROUTING -i %s -j " CHAIN_OUTGOING, config->gw_interface);

3).在链表CHAIN_OUTGOING,目的地址为gw_address,则执行链表 CHAIN_TO_ROUTER。

("-t nat -A " CHAIN_OUTGOING " -d %s -j " CHAIN_TO_ROUTER, config->gw_address);

("-t nat -A " CHAIN_TO_ROUTER " -j ACCEPT");

4).在链表CHAIN_OUTGOING,执行表CHAIN_TO_INTERNET。

("-t nat -A " CHAIN_OUTGOING " -j " CHAIN_TO_INTERNET);

5).表CHAIN_TO_INTERNET添加规则,tcp协议,目的端口80,匹配mark标记,并重定向到端口proxy_port.

("-t nat -A " CHAIN_TO_INTERNET" -p tcp --dport 80 -m mark --mark 0x%u -j REDIRECT --to-port %u",FW_MARK_KNOWN, proxy_port);

("-t nat -A " CHAIN_TO_INTERNET " -p tcp --dport 80 -m mark --mark 0x%u -j REDIRECT --to-port %u",FW_MARK_PROBATION, proxy_port);

6).表CHAIN_TO_INTERNET添加规则,匹配mark标记,返回ACCEPT.

("-t nat -A " CHAIN_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_KNOWN);

("-t nat -A " CHAIN_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_PROBATION);

7).在链表CHAIN_TO_INTERNET,执行表CHAIN_UNKNOWN。

iptables_do_command("-t nat -A " CHAIN_TO_INTERNET " -j " CHAIN_UNKNOWN);

8).在链表CHAIN_UNKNOWN,执行表CHAIN_AUTHSERVERS、CHAIN_GLOBAL、CHAIN_AUTH_IS_DOWN。

("-t nat -A " CHAIN_UNKNOWN " -j " CHAIN_AUTHSERVERS);

("-t nat -A " CHAIN_UNKNOWN " -j " CHAIN_GLOBAL);

("-t nat -A " CHAIN_UNKNOWN " -j " CHAIN_AUTH_IS_DOWN);

9). 在链表CHAIN_AUTH_IS_DOWN,添加规则,匹配mark标记,返回ACCEPT

("-t nat -A " CHAIN_AUTH_IS_DOWN " -m mark --mark 0x%u  -j ACCEPT",

FW_MARK_AUTH_IS_DOWN);

10). 在链表CHAIN_UNKNOWN,添加规则,tcp协议,目的端口80,重定向到端口gw_port。

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

2.1.3 在fliter表中创建新的链表和规则

1). 在flitert表中创建新的链表

("-t filter -N " CHAIN_TO_INTERNET);

("-t filter -N " CHAIN_AUTHSERVERS);

("-t filter -N " CHAIN_LOCKED);

("-t filter -N " CHAIN_GLOBAL);

("-t filter -N " CHAIN_VALIDATE);

("-t filter -N " CHAIN_KNOWN);

("-t filter -N " CHAIN_UNKNOWN);

("-t filter -N " CHAIN_AUTH_IS_DOWN);

2). filter表中在forword挂载点,输入接口config->gw_interface,执行链表CHAIN_TO_INTERNET

("-t filter -I FORWARD -i %s -j " CHAIN_TO_INTERNET, config->gw_interface);

3). filter中添加链表CHAIN_TO_INTERNET,匹配状态INVALID,则DROP

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

4). 在链表中CHAIN_TO_INTERNET添加规则,输出口ext_interface, tcp协议,则执行TCPMSS ,--clamp-mss-to-pmtu根据mtu调整MSS的值

("-t filter -A " CHAIN_TO_INTERNET " -o %s -p tcp --tcp-flags SYN,RST SYN

-j TCPMSS --clamp-mss-to-pmtu", ext_interface);

5). 在链表CHAIN_TO_INTERNET添加规则CHAIN_AUTHSERVERS,对于目的ip为authserverip地址的报文放行

("-t filter -A " CHAIN_TO_INTERNET " -j " CHAIN_AUTHSERVERS);

iptables_fw_set_authservers();

6). 从配置文件中读取相应的规则,并配置防火墙

iptables_load_ruleset

2.2 while循环;获取client连接,为每个client创建线程,处理http请求.

2.2.1. 获取client连接 r = httpdGetConnection(webserver, NULL);

2.2.2. 为每个client创建线程,处理http请求;thread_httpd

2.2.1 thread_httpd

1). 读取http请求httpdReadRequest();

2). 查找访问目录,如果dir= NULL,则调用函数http_callback_404

dir = _httpd_findContentDir(server, dirName, HTTP_FALSE);

3). 根据dir和entryName查找entry路径

entry = _httpd_findContentEntry(r, dir, entryName);

4).调用注册的entry函数

(entry->function) (server, r);

即:

httpdAddCContent(webserver, "/", "wifidog", 0, NULL, http_callback_wifidog);

httpdAddCContent(webserver, "/wifidog", "", 0, NULL, http_callback_wifidog);

httpdAddCContent(webserver, "/wifidog", "about", 0, NULL, http_callback_about);

httpdAddCContent(webserver, "/wifidog", "status", 0, NULL, http_callback_status);

httpdAddCContent(webserver, "/wifidog", "auth", 0, NULL, http_callback_auth);

httpdAddCContent(webserver, "/wifidog", "disconnect", 0, NULL, http_callback_disconnect);

2.2.1.1 http_callback_404

1). 检测网络是否连接,否,则返回提示页面

send_http_page(r, "Uh oh! Internet access unavailable!", buf);

2). 检测认证server是否在线,否,则返回提示页面

send_http_page(r, "Uh oh! Login screen unavailable!", buf);

3).检测域名白名单,存在,放行!

get_ruleset("global");

fw_allow_host(r->request.host);

4). 返回302重定向报文

http_send_redirect_to_auth(r, urlFragment, "Redirect to login page");

2.2.1.2 http_callback_auth

当client接收到302重定向报文后,访问认证server,并返回认证界面, 输入用户名密码后,向authserver返回,并获取到authserver为它分配的token值,执行redirect url跳转,向wifidog模块发送auth报文,携带token值,请求认证。

1.向client链表中添加client信息

client_list_add(r->clientAddr, mac, token->value);

2.对client进行认证处理

authenticate_client(r);

1). 获取token值;

httpdGetVariableByName(r, "token"))

2). 向认证服务器发送认证请求

auth_server_request();

3). 根据认证结果,放行或拦截client

fw_allow(client, FW_MARK_PROBATION);

fw_deny(client);

2.3 thread_ping

函数ping(void)

1). 建立tcp连接

2). 发送ping包

res = https_get(sockfd, request, auth_server->authserv_hostname);

res = http_get(sockfd, request);

3)标记认证服务器状态,如果服务器down,设置防火墙规则,放行所有client。

fw_set_authdown();

fw_set_authup();

2.4 thread_client_timeout_check

1)每隔一段时间,检测client是否在线, 根据流量统计,来判断client是否在线

2)与认证服务器进行client同步

3)针对client进行相关处理。

2.2 thread_wdctl

1). 创建unix

wdctl_socket_server = create_unix_socket(sock_name);

2). 监听wdctl发送的命令

status、stop、reset、restart

linux wifi 源代码,Linux无线认证----wifidog源码分析相关推荐

  1. Linux中mknod命令实现原理以及源码分析

    本篇文章以mknod创建字符设备文件进行讲解 字符设备驱动的Demo例子可参考该篇文章 Linux 编写简单驱动并测试 1. mknod 命令 mknod /dev/hello c 520 0 该命令 ...

  2. linux的can通信busoff,socketCAN内核源码分析是否支持busoff自恢复--Apple的学习笔记

    大总结:诊断小系统搭建步骤总结--Apple的学习笔记的剩余问题2中,我说过要深入下socketCAN内核源码学习.因为这个小项目关于驱动开发太顺利了,导致学习不到什么东东.最主要我一开始走了捷径,看 ...

  3. Linux项目实战C++轻量级Web服务器源码分析TinyWebServer

    目录 文章简介 一. 先跑起来项目 二.再看项目核心 三.逐个击破!立下flag 文章简介 TinyWebServer是Linux下C++轻量级Web服务器,助力初学者快速实践网络编程,搭建属于自己的 ...

  4. 【分析笔记】Linux gpio_wdt.c 看门狗设备驱动源码分析

    基本原理 该看门狗的设备驱动实现原理很简单,比较主要的有两点: 一.定时器喂狗 通过定时器根据配置文件配置的喂狗方式(如脉冲切换.电平切换),对指定的 gpio 进行脉冲切换或电平切换实现喂狗. 脉冲 ...

  5. linux蓝牙源代码,Android 4.4 蓝牙源码部分分析

    最近GOOGLE发布了Android4.4,看了一下源码:4.4的蓝牙打开流程这一部分还是有些变化的,从界面上看蓝牙开关就是设置settings里那个switch开关,widget开关当然也可以,起点 ...

  6. 【Linux 内核 内存管理】mmap 系统调用源码分析 ④ ( do_mmap 函数执行流程 | do_mmap 函数源码 )

    文章目录 一.do_mmap 函数执行流程 二.do_mmap 函数源码 调用 mmap 系统调用 , 先检查 " 偏移 " 是否是 " 内存页大小 " 的 & ...

  7. Linux下存储多路径软件MultiPath源码分析

    2019独角兽企业重金招聘Python工程师标准>>> 全局概览 测试环境为CentOS 7 X64 从RPM获取源码 $ cd ~/rpmbuild/ $ yumdownloade ...

  8. Linux设备驱动简析—PC重启源码分析

    Linux在PC上的关机和重启可能由两种行为引发,一是通过用户编程,一是系统自己产生的消息.用户和系统进行交互的方式也有两个,一个是系统调用:sys_reboot,另一个就是apm或acpi的设备文件 ...

  9. wifidog源码分析 - 初始化阶段

    Wifidog是一个linux下开源的认证网关软件,它主要用于配合认证服务器实现无线路由器的认证放行功能. wifidog是一个后台的服务程序,可以通过wdctrl命令对wifidog主程序进行控制. ...

最新文章

  1. 融合基础设施会给私有云带来什么?
  2. AJAX 在Django 设置csrf_token
  3. 七、规则组织的衍生组织——菱形斜纹组织数学模型的建立
  4. windows下安装和使用scrapy
  5. java合并两个数组_「JAVA」两个数组的交集—力扣每日一题(一)
  6. iOS开发--xcode快捷键
  7. IOSday04 UIButton使用
  8. 关于显式量化和隐式量化的英文对照
  9. imx6q LINUX 启动时间优化
  10. win11找不到开启蓝牙开关,设备管理器也没有蓝牙
  11. EasyRecovery最新免费专业版数据恢复软件
  12. hdb3编码规则波形_(完整word版)AMI与HDB3码波形与功率谱密度实验
  13. 金蝶KIS专业版K3即时库存查询SQL语句SQLServer
  14. 中职计算机基础辅导书,中职计算机基础 (938)(16页)-原创力文档
  15. hashmap面试题,音视频学习指南来咯,社招面试心得
  16. 利用Python进行数据分析的学习笔记——chap9
  17. HDU 3265 - Posters
  18. 32种EMC标准电路 (共用)
  19. 零售转型之战,“富二代”平安银行胜算如何?
  20. 自动化立体仓库系统(Automated Storage and Retrieval System)

热门文章

  1. PMD (别向报信者开火)
  2. 冷暴力,是什么心理?
  3. 国产新冠口服药为什么是治艾滋病的药
  4. 不合格高校教师的自我总结(成绩统计和课程总结)
  5. 电竞游戏耳机哪个好用?和平精英吃鸡耳机排行榜
  6. python strftime函数_Python 常用函数time.strftime()简介
  7. 都江堰市建成区块链场景创新实验室!
  8. CSS 绝对定位 div 水平居中(两种)
  9. Nuxt3开发项目模版
  10. html锚点定位向下偏移,锚点偏移