wifidog 源码初分析(1)-转

wifidog 的核心还是依赖于 iptables 防火墙过滤规则来实现的,所以建议对 iptables 有了了解后再去阅读 wifidog 的源码。

在路由器上启动 wifidog 之后,wifidog 在启动时会初始化一堆的防火墙规则,如下:

[cpp] view plaincopy

  1. /** Initialize the firewall rules

  2. */
  3. int iptables_fw_init(void)  
  4. {  
  5. … …  
  6. /*
  7. *
  8. * Everything in the NAT table
  9. *
  10. */
  11. /* Create new chains */
  12. iptables_do_command("-t nat -N " TABLE_WIFIDOG_OUTGOING);  
  13. iptables_do_command("-t nat -N " TABLE_WIFIDOG_WIFI_TO_ROUTER);  
  14. iptables_do_command("-t nat -N " TABLE_WIFIDOG_WIFI_TO_INTERNET);  
  15. iptables_do_command("-t nat -N " TABLE_WIFIDOG_GLOBAL);  
  16. iptables_do_command("-t nat -N " TABLE_WIFIDOG_UNKNOWN);  
  17. iptables_do_command("-t nat -N " TABLE_WIFIDOG_AUTHSERVERS);  
  18. /* Assign links and rules to these new chains */
  19. iptables_do_command("-t nat -A PREROUTING -i %s -j " TABLE_WIFIDOG_OUTGOING, config->gw_interface);  
  20. iptables_do_command("-t nat -A " TABLE_WIFIDOG_OUTGOING " -d %s -j " TABLE_WIFIDOG_WIFI_TO_ROUTER, config->gw_address);  
  21. iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_ROUTER " -j ACCEPT");  
  22. iptables_do_command("-t nat -A " TABLE_WIFIDOG_OUTGOING " -j " TABLE_WIFIDOG_WIFI_TO_INTERNET);  
  23. iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_KNOWN);  
  24. iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_PROBATION);  
  25. iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN);  
  26. iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_AUTHSERVERS);  
  27. iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_GLOBAL);  
  28. // 将 80 端口的访问重定向(REDIRECT)到 (本路由)网关web服务器的监听端口
  29. iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -p tcp --dport 80 -j REDIRECT --to-ports %d", gw_port);  
  30. /*
  31. *
  32. * Everything in the FILTER table
  33. *
  34. */
  35. /* Create new chains */
  36. iptables_do_command("-t filter -N " TABLE_WIFIDOG_WIFI_TO_INTERNET);  
  37. iptables_do_command("-t filter -N " TABLE_WIFIDOG_AUTHSERVERS);  
  38. iptables_do_command("-t filter -N " TABLE_WIFIDOG_LOCKED);  
  39. iptables_do_command("-t filter -N " TABLE_WIFIDOG_GLOBAL);  
  40. iptables_do_command("-t filter -N " TABLE_WIFIDOG_VALIDATE);  
  41. iptables_do_command("-t filter -N " TABLE_WIFIDOG_KNOWN);  
  42. iptables_do_command("-t filter -N " TABLE_WIFIDOG_UNKNOWN);  
  43. /* Assign links and rules to these new chains */
  44. /* Insert at the beginning */
  45. iptables_do_command("-t filter -I FORWARD -i %s -j " TABLE_WIFIDOG_WIFI_TO_INTERNET, config->gw_interface);  
  46. iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m state --state INVALID -j DROP");  
  47. /* TCPMSS rule for PPPoE */

  48. 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);  
  49. iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_AUTHSERVERS);  
  50. iptables_fw_set_authservers();  
  51. iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_LOCKED, FW_MARK_LOCKED);  
  52. iptables_load_ruleset("filter", "locked-users", TABLE_WIFIDOG_LOCKED);  
  53. iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_GLOBAL);  
  54. iptables_load_ruleset("filter", "global", TABLE_WIFIDOG_GLOBAL);  
  55. iptables_load_ruleset("nat", "global", TABLE_WIFIDOG_GLOBAL);  
  56. iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_VALIDATE, FW_MARK_PROBATION);  
  57. iptables_load_ruleset("filter", "validating-users", TABLE_WIFIDOG_VALIDATE);  
  58. iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_KNOWN, FW_MARK_KNOWN);  
  59. iptables_load_ruleset("filter", "known-users", TABLE_WIFIDOG_KNOWN);  
  60. iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN);  
  61. iptables_load_ruleset("filter", "unknown-users", TABLE_WIFIDOG_UNKNOWN);  
  62. iptables_do_command("-t filter -A " TABLE_WIFIDOG_UNKNOWN " -j REJECT --reject-with icmp-port-unreachable");  
  63. UNLOCK_CONFIG();  
  64. return 1;  
  65. }

在该 防火墙规则的初始化过程中,会首先清除掉已有的防火墙规则,重新创建新的过滤链,另外,除了通过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) 的防火墙规则:

[cpp] view plaincopy

  1. void iptables_fw_set_authservers(void)

  2. {  
  3. const s_config *config;  
  4. t_auth_serv *auth_server;  
  5. config = config_get_config();  
  6. for (auth_server = config->auth_servers; auth_server != NULL; auth_server = auth_server->next) {  
  7. if (auth_server->last_ip && strcmp(auth_server->last_ip, "0.0.0.0") != 0) {  
  8. iptables_do_command("-t filter -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->last_ip);  
  9. iptables_do_command("-t nat -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->last_ip);  
  10. }  
  11. }  
  12. }

首先从上面的代码可以看出 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

这样确保可以访问鉴权服务器,而不是拒绝所有的出口访问。

wifidog 源码初分析(1)-转

时间: 2024-10-08 18:34:10

wifidog 源码初分析(1)-转的相关文章

wifidog 源码初分析(4)-转

在上一篇<wifidog 源码处分析(3)>的流程结束后,接入设备的浏览器重定向至 路由器 上 wifidog 的 http 服务(端口 2060) /wifidog/auth 上(且携带了 认证服务器 为此接入设备分配的 token),本篇就是从 wifidog 接收到 /wifidog/auth 的访问后的 校验流程. - 根据<wifidog 源码初分析(2)>中描述的,在 wifidog 启动 http 服务前,注册了一个针对访问路径 /wifidog/auth 的回调,如

wifidog 源码初分析(3)-转

上一篇分析了 接入设备 在接入路由器,并发起首次 HTTP/80 请求到路由器上时,wifidog 是如何将此 HTTP 请求重定向至 auth-server 的流程. 之后 接入设备 的浏览器接收到 wifidog 返回的 302 重定向请求后,会将页面重定向至 auth-server 的 /login 页面,并且在此 URL 中会携带一些 路由器/网关 参数,以及 接入设备的 MAC 地址 和 客户端访问的源URL(如示例中的 baidu.com). 下面几个步骤就是 接入设备 到 auth

wifidog 源码初分析(2)-转

上一篇分析了接入设备的首次浏览器访问请求如何通过 防火墙过滤规则 重定向到 wifidog 的 HTTP 服务中,本篇主要分析了 wifidog 在接收到 接入设备的 HTTP 访问请求后,如何将此 HTTP 请求重定向到 认证服务器(auth-server) 上. 通过上面的防火墙规则,会将通过上面的防火墙规则,会将HTTP请求的外部IP地址和端口通过NAT方式重定向至本地wifidog内嵌HTTP服务器的地址和端口上,并由内嵌HTTP服务器进行服务,而内嵌HTTP服务器的路径和回调处理如下:

Hadoop学习笔记(9) ——源码初窥

Hadoop学习笔记(9) ——源码初窥 之前我们把Hadoop算是入了门,下载的源码,写了HelloWorld,简要分析了其编程要点,然后也编了个较复杂的示例.接下来其实就有两条路可走了,一条是继续深入研究其编程及部署等,让其功能使用的淋漓尽致.二是停下来,先看看其源码,研究下如何实现的.在这里我就选择第二条路. 研究源码,那我们就来先看一下整个目录里有点啥: 这个是刚下完代码后,目录列表中的内容. 目录/文件 说明 bin 下面存放着可执行的sh命名,所有操作都在这里 conf 配置文件所在

又是正版!Win下ffmpeg源码调试分析二(Step into ffmpeg from Opencv for bugs in debug mode with MSVC)

最近工作忙一直没时间写,但是看看网络上这方面的资源确实少,很多都是linux的(我更爱unix,哈哈),而且很多是直接引入上一篇文章的编译结果来做的.对于使用opencv但是又老是被ffmpeg库坑害的朋友们,可能又爱又恨,毕竟用它处理和分析视频是第一选择,不仅是因为俩者配合使用方便,而且ffmpeg几乎囊括了我所知道的所有解编码器,但是正是因为这个导致了一些bug很难定位,所以有必要考虑一下如何快速定位你的ffmpeg bug. sorry,废话多了.首先给个思路: 1.使opencv 的hi

uboot移植——uboot源码目录分析

uboot移植(一)--uboot源码目录分析 本文分析的uboot是九鼎官方提供的,是对应s5pv210开发板x210bv3的uboot 一:uboot的概念及移植的原理. uboot就是在内核运行前的一段小程序,用来初始化硬件设备,建立内存空间映射图.从而将系统的软硬件带到合适的状态,主要功能就是为了启动内核,它将内核从flash中拷贝到ddr中,然后跳转到内核入口中,交由内核控制权,uboot严重依赖硬件,因此一个通用的uboot不太可能. 移植原理:uboot中有很多平行代码,各自属于各

netty 源码简单分析一

周末简单看了下netty5的源码,只看懂了个大概,记录下成果,方便下次再看的时候回忆. 上服务端代码: public void run() throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.grou

MapReduce job在JobTracker初始化源码级分析

mapreduce job提交流程源码级分析(三)中已经说明用户最终调用JobTracker.submitJob方法来向JobTracker提交作业.而这个方法的核心提交方法是JobTracker.addJob(JobID jobId, JobInProgress job)方法,这个addJob方法会把Job提交到调度器(默认是JobQueueTaskScheduler)的监听器JobQueueJobInProgressListener和EagerTaskInitializationListen

OpenStack_Swift源码分析——创建Ring及添加设备源码详细分析

1 创建Ring 代码详细分析 在OpenStack_Swift--Ring组织架构中我们详细分析了Ring的具体工作过程,下面就Ring中增加设备,删除设备,已经重新平衡的实现过程作详细的介绍. 首先看RingBuilder类 def __init__(self, part_power, replicas, min_part_hours): #why 最大 2**32 if part_power > 32: raise ValueError("part_power must be at