分类 wifidog源码 下的文章

wifidog认证

前段时间使用wifidog进行wifi强制认证,现在做个小结。

  1. 首先简单说说wifidog认证的过程
    客户端首次连接到wifi后,浏览器请求将会被重定向到:
    login/?gw_address=%s&gw_port=%d&gw_id=%s&url=%s
    验证通过后,客户端被重定向到网关,url格式如下:
    http://网关地址:网关端口/wifidog/auth?token=xxx
    wifidong会启动一个线程周期性地报告每一个用户的状态信息,并通过如下地址发送给认证服务器:
    auth_server:/auth/?stage=
    ip=
    mac=
    token=
    incoming=
    outgoing=
    认证服务器根据该状态信息决定是否允许该用户继续连接,并回复网关,回复格式为:Auth:状态码,
    如:Auth:1
    常用状态码:
    0:AUTH_DENIED,表示拒绝
    1:AUTH_ALLOWED,验证通过
    验证通过后,将重定向到如下地址:
    portal/?gw_id=%s
    wifidog的ping协议
    wifidog通过ping协议将当前状态信息发送给认证服务器,发送地址为:
    http://auth_sever/ping/?
    gw_id=%s
    sys_uptime=%lu
    sys_memfree=%u
    sys_load=%.2f
    wifidog_uptime=%lu
    认证服务器须返回一个“Pong”作为回应。
  2. 实战应用
    struts配置文件:



    /Login/index.jsp
    /error.jsp






Action方法

public String login() {
    try{
        System.out.println("login start!");
                System.out.println("gw_port:"+gw_port);
        System.out.println("login end!");

     }
    catch(Exception e)
    {
        e.printStackTrace();
        return INPUT;
    }
    return "success";
}
public void ping() {
    try{
        System.out.println("ping start!");
        System.out.println(gw_id);
        ServletActionContext.getResponse().getWriter().write("Pong");
        System.out.println("ping end!");
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}
public void portal() {
    try{
        System.out.println("portal start");
        System.out.println("protal"+token);
        ServletActionContext.getResponse().sendRedirect("/demo/listAction");
        System.out.println("portal end");
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}
public void auth() {
    try{
        System.out.println("auth start!");
        System.out.println("mac"+mac);
        System.out.println("stage"+stage);
        System.out.println("token"+token);
        ServletActionContext.getResponse().getWriter().write("Auth: 1");
        System.out.println("auth end!");                                                                                                                                                                                                                                                                                                                       
     }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}

/Login/index.jsp代码:

<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    DateFormat format=new SimpleDateFormat("yyMMddHHmmss");
    String formatData=format.format(new Date());
    int ramdom=new Random().nextInt(1000);
    String token=formatData+ramdom;
    if(session.getAttribute("token")==null)
       session.setAttribute("token",token);

%>
<form method="GET" action='http://192.168.1.1:2060/wifidog/auth'>
<input type='hidden' name='token' value="<s:property value="#session.token" />" />
<input type='submit' value='Welcome!'/>
</form>

上面的192.168.1.1为网关的ip,2060为网关端口。
当然,完全可以在处理完login后直接跳到该地址。我们这里为演示其认证流程,故跳到该页面。
效果:
客户端连接到wifi后,打开任何连接均跳到上面的index.jsp中,点击"Welcome"后,跳到/demo/listAction,即我们的目标地址。此后点击其他连接将不再拦截。
提示:安装wifidog的路由器必须可以访问Internet,否则wifidog拦截失败,无法跳到我们设定的页面。

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

WiFidog运行环境及及主要和认证服务器交互函数

0:WiFiDog运行环境

/wlan/portal/buildroot/etc # ps -w  
\  PID USER       VSZ STAT COMMAND  
    1 root       868 S    init         
    2 root         0 SW<  [kthreadd]  
    3 root         0 SW<  [ksoftirqd/0]  
    4 root         0 SW<  [events/0]  
    5 root         0 SW<  [khelper]  
    6 root         0 SW<  [async/mgr]  
    7 root         0 SW<  [kblockd/0]  
    8 root         0 SW   [pdflush]  
    9 root         0 SW   [pdflush]  
   10 root         0 SW<  [kswapd0]  
   11 root         0 SW<  [crypto/0]  
   32 root         0 SW<  [mtdblockd]  
   37 root         0 SWN  [jffs2_gcd_mtd3]  
  564 root       864 S    /usr/sbin/telnetd   
  566 root       864 S    /usr/sbin/httpd -h /usr/www/   
  568 root       888 R    -sh   
  881 nobody    1004 S    dnsmasq   
 2191 root       868 R    ps -w   
 2340 root       876 S    udhcpd -S /etc/udhcpd.conf   
 3877 root       884 S    udhcpc -i eth0 -p /var/run/udhcpc_wan.pid -s /etc/udhcpc.script   
 3892 root      1788 S    wifidog -c /etc/wifidog.conf   
 4059 root      1788 S    wifidog -c /etc/wifidog.conf   
 4060 root      1788 S    wifidog -c /etc/wifidog.conf   
 4061 root      1788 S    wifidog -c /etc/wifidog.conf   
 4062 root      1788 S    wifidog -c /etc/wifidog.conf   
 /etc # ifconfig   
ath0      Link encap:Ethernet  HWaddr 00:0B:6B:B4:01:63    
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1  
          RX packets:1036165 errors:0 dropped:0 overruns:0 frame:0  
          TX packets:902768 errors:0 dropped:181 overruns:0 carrier:0  
          collisions:0 txqueuelen:0   
          RX bytes:173265983 (165.2 MiB)  TX bytes:472405245 (450.5 MiB)  

br0       Link encap:Ethernet  HWaddr 00:0B:6B:B4:01:63    
          inet addr:192.168.100.10  Bcast:192.168.100.255  Mask:255.255.255.0  
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1  
          RX packets:1038127 errors:0 dropped:0 overruns:0 frame:0  
          TX packets:895866 errors:0 dropped:0 overruns:0 carrier:0  
          collisions:0 txqueuelen:0   
          RX bytes:136852412 (130.5 MiB)  TX bytes:451119780 (430.2 MiB)  

eth0      Link encap:Ethernet  HWaddr 00:03:7F:FF:FF:FF    
          inet addr:192.168.0.143  Bcast:192.168.0.255  Mask:255.255.255.0  
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1  
          RX packets:100545 errors:0 dropped:0 overruns:0 frame:0  
          TX packets:83617 errors:0 dropped:0 overruns:0 carrier:0  
          collisions:0 txqueuelen:1000   
          RX bytes:94237206 (89.8 MiB)  TX bytes:9617979 (9.1 MiB)  

lo        Link encap:Local Loopback    
          inet addr:127.0.0.1  Mask:255.0.0.0  
          UP LOOPBACK RUNNING  MTU:16436  Metric:1  
          RX packets:50 errors:0 dropped:0 overruns:0 frame:0  
          TX packets:50 errors:0 dropped:0 overruns:0 carrier:0  
          collisions:0 txqueuelen:0   
          RX bytes:5181 (5.0 KiB)  TX bytes:5181 (5.0 KiB)  

wifi1     Link encap:UNSPEC  HWaddr 00-0B-6B-B4-01-63-00-00-00-00-00-00-00-00-00-00    
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1  
          RX packets:2682769 errors:0 dropped:0 overruns:0 frame:0  
          TX packets:3642860 errors:8464 dropped:0 overruns:0 carrier:0  
          collisions:0 txqueuelen:511   
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)  
          Interrupt:64 Memory:b0000000-b0020000   

/etc # brctl show  
bridge name bridge id       STP enabled interfaces  
br0     8000.000b6bb40163   no      ath0  
/etc #   
/etc # route  
Kernel IP routing table  
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface  
192.168.100.0   *               255.255.255.0   U     0      0        0 br0  
192.168.0.0     *               255.255.255.0   U     0      0        0 eth0  
default         192.168.0.1     0.0.0.0         UG    0      0        0 eth0  
/etc # iptables -t nat -L  
Chain PREROUTING (policy ACCEPT)  
target     prot opt source               destination           

Chain POSTROUTING (policy ACCEPT)  
target     prot opt source               destination           
MASQUERADE  all  --  anywhere             anywhere              

Chain OUTPUT (policy ACCEPT)  
target     prot opt source               destination      

1: 用户,WiFiDog,Authpuppy交互过程
1.png

具体细节部分可以参考:http://dev.wifidog.org/wiki/doc/developer/FlowDiagram

2:wifidog与authpuppy交互数据包
1) 当用户首次访问一个网址的时候:wifidog会将用户的请求重定义到登陆认证界面:
http://192.168.0.142:80/authpuppy/web/login/?gw_address=192.168.100.10&gw_port=2060&gw_id=123456789&mac=90:7a:28:01:20:26&url=www.baidu.com
2) authpuppy就回复一个包给运行wifidog的路由器的用户客户端浏览器,浏览器重定向到路由器:
http://GatewayIP:GatewayPort/wifidog/auth?token=[auth token]
3) 路由器与authpuppy之间的登陆认证数据:
http://192.168.0.142:80/authpuppy/web/auth/?stage=login&ip=192.168.100.11&mac=90:7a:28:01:20:26&token=9941ed0bc138c12c6edc4b1ed8358bd4516b86f2&incoming=0&outgoing=0&gw_id=123456789
4) authpuppy 回复一个auth code给路由器,表明token 正确与否
5) 路由器收到auth code:1,重定向浏览器:
http://192.168.0.142/portal/?gw_id=123456789

wifidog的路由器更新traffic counters到authpuppy
http://192.168.0.142:80/authpuppy/web/auth/?stage=counters&ip=192.168.100.11&mac=90:7a:28:01:20:26&token=9941ed0bc138c12c6edc4b1ed8358bd4516b86f2&incoming=1161884&outgoing=81646&gw_id=123456789

用户超时下线:
http://192.168.0.142:80/authpuppy/web/auth/?stage=logout&ip=192.168.100.11&mac=90:7a:28:01:20:26&token=9941ed0bc138c12c6edc4b1ed8358bd4516b86f2&incoming=0&outgoing=0&gw_id=123456789

3:wifidog代码主要函数执行顺序
http_send_redirect_to_auth()函数是WiFidog路由器发送数据给用户的接口。
流程1:httpdGetConnection()-->thread_httpd()-->httpdReadRequest()-->httpdProcessRequest()-->http_callback_404()-->http_send_redirect_to_auth()

流程2:httpdGetConnection()-->thread_httpd()-->httpdReadRequest()-->httpdProcessRequest()-->http_callback_auth-->authenticate_client()-->
auth_server_request(&auth_response, REQUEST_TYPE_LOGIN, r->clientAddr, mac, token, 0, 0)-->fw_allow()-->iptables_fw_access()-->iptables_do_command()--->http_send_redirect_to_auth(r, urlFragment, "Redirect to portal");

本文章由 http://www.wifidog.pro/2014/12/16/WiFidog%E8%BF%90%E8%A1%8C%E7%8E%AF%E5%A2%83.html 整理编辑,转载请注明出处

wifidog+authpuppy搭建WiFi 认证平台

0:前提
其实搭建认证环境都是基础,重要的是要对WiFidog的代码进行详细的研究,了解清楚wifidog与authpuppy之间进行了哪些数据交互,WiFidog的程序框架及iptables的建立及生效规则,这才是重点。WiFidog和之前nodogsplash的代码90%是一样的,只是之前没有研究nodogsplash的外部认证机制。
WiFidog可以通过外部认证来控制用户的上网行为,此处的外部认证接口就是:authpuppy。

1:authpuppy安装之前准备
在安装authpuppy的过程遇到很多问题,但是都能根据网上其他朋友的提示可以搞定,我将自己想要的配置文件copy上来。

[root@localhost /etc]$cat host.conf   
multi on  
order hosts,bind  
[root@localhost /etc]$cat hosts  
127.0.0.1       localhost.localdomain   localhost  
127.0.0.1       authpuppy.localhost  


::1         localhost6 localhost6.localdomain localhost6 localhost6.localdomain6

之后就是 httpd相关的配置文件:
/etc/httpd/conf]$cat httpd.conf
同时常用的命令如下:
service httpd restart,service mysqld restart等

其配置文件中主要就是配置一个虚拟目录.其配置内容如下:

<VirtualHost *:80>  
    ServerAdmin webmaster@test  
    ServerName authpuppy.localhost  
    ServerAlias authpuppy.test  

    DocumentRoot "/var/www/"  
    DirectoryIndex index.php  

   <Directory /var/www/authpuppy/web/>  
          Options Indexes FollowSymLinks MultiViews  
          AllowOverride All  
          Order allow,deny  
          allow from all  
  </Directory>  


  Alias /sf /var/www/authpuppy/lib/vendor/symfony/data/web/sf  
  <Directory "/var/www/authpuppy/lib/vendor/symfony/data/web/sf">  
          AllowOverride All  
          Allow from All  
  </Directory>  



    ErrorLog /var/log/httpd/error.log  
    # Possible values include: debug, info, notice, warn, error,crit,  
    # alert, emerg.  
    LogLevel warn  

    CustomLog /var/log/httpd/access.log combined  

</VirtualHost>  
[root@localhost /etc/httpd/conf]$cat httpd.conf 

其中可以看出:

ServerName authpuppy.localhost
DocumentRoot "/var/www/"   #web的根目录
DirectoryIndex index.php   #访问的主页http://192.168.0.142/authpuppy/web/index.php
<Directory /var/www/authpuppy/web/> #authpuppy的目录位置
          Options Indexes FollowSymLinks MultiViews
          AllowOverride All
          Order allow,deny
          allow from all
</Directory>

authpuppy的目录位置及结构如下:
QQ截图20141216162755.png

建立好上面的环境之后,下面就要建立MySQL数据库。建立好的数据如下:

[root@localhost ~]$mysql  
Welcome to the MySQL monitor.  Commands end with ; or \g.  
Your MySQL connection id is 813  
Server version: 5.1.47 Source distribution  

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.  
This software comes with ABSOLUTELY NO WARRANTY. This is free software,  
and you are welcome to modify and redistribute it under the GPL v2 license  

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.  

mysql> show databases;  
+--------------------+  
| Database           |  
+--------------------+  
| information_schema |  
| authpuppy          |  
| mysql              |  
+--------------------+  
3 rows in set (0.01 sec)  

mysql> use authpuppy;  
Reading table information for completion of table and column names  
You can turn off this feature to get a quicker startup with -A  

Database changed  
mysql> show tables;  
+---------------------------+  
| Tables_in_authpuppy       |  
+---------------------------+  
| ap_applicable_policies    |  
| ap_connection_policies    |  
| ap_node_authenticators    |  
| ap_node_policies          |  
| ap_node_user_bypass       |  
| ap_plugin_config          |  
| ap_plugins_migrations     |  
| ap_user                   |  
| ap_user_remember_me       |  
| connections               |  
| migration_version         |  
| nodes                     |  
| sf_guard_forgot_password  |  
| sf_guard_group            |  
| sf_guard_group_permission |  
| sf_guard_permission       |  
| sf_guard_remember_key     |  
| sf_guard_user             |  
| sf_guard_user_group       |  
| sf_guard_user_permission  |  
+---------------------------+  
20 rows in set (0.00 sec)  

mysql> slect * from ap_user;  
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'slect * from ap_user' at line 1  
mysql> select * from ap_user;  
+----+----------+--------------------------+--------------------+---------------------+------------------------------------------+--------+----------------+  
| id | username | password                 | email              | registered_on       | validation_token                         | status | username_lower |  
+----+----------+--------------------------+--------------------+---------------------+------------------------------------------+--------+----------------+  
|  1 | suiyuan  | H9hK9mgDAXdJnkYghQczkQ== | suiyuan626@163.com | 2014-06-10 16:05:25 | eda2838b1543e16fcfd7da6064886be67c544042 |      5 | suiyuan        |  
|  4 | xue      | H9hK9mgDAXdJnkYghQczkQ== | xue626@163.com     | 2014-06-10 17:04:07 | 117b0cd467900c59b9e60bb52719ce3551d321ce |      5 | xue            |  
+----+----------+--------------------------+--------------------+---------------------+------------------------------------------+--------+----------------+  
2 rows in set (0.00 sec)  

mysql>   

其中上面是创建的俩个用户,是通过authpuppy的管理界面来创建的,用户在认证的时候只有输入正确的用户名及密码才能才算认证通过。同时如果不创建数据库,在启动authpuppy的时候会告诉缺少相应的文件目录。

3:安装过程
由于我们已经安装成功了,安装的过程中没有怎么抓图。

2.png

其中过一定要记住上面的用户名及密码,后面登陆的时候要用到,最好也写一个邮箱地址,如果忘记密码也可以找回来。
当安装成功之后访问:http://192.168.0.142/authpuppy/web/index.php
如下界面:
4.png

输入之前的用户名及密码(第二张图片上面的用户名及密码)。登陆之后的界面如下:
3.png

之后就可以安装插件,现在随便看看几个菜单。
6.png

上面就是数据库里面创建的用户suiyaun(用户已此用户名进行登陆认证的)的上网的一些信息。

wifidog运行时的配置文件,其实配置文件只需要几个关键的参数就可以运行。

# WiFiDog Configuration file  

GatewayID 123456789  

ExternalInterface eth0  

GatewayInterface br0  

HtmlMessageFile /opt/wifidog/etc/wifidog-.html  


AuthServer {  
    Hostname 192.168.0.142  
    SSLAvailable no  
    Path /authpuppy/web/  
}  

CheckInterval 60  

# The timeout will be INTERVAL * TIMEOUT  
ClientTimeout 5  

# Parameter: TrustedMACList  
# Comma separated list of MAC addresses who are allowed to pass  
# through without authentication  
#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D  


FirewallRuleSet validating-users {  
    FirewallRule allow to 0.0.0.0/0  
}  


FirewallRuleSet known-users {  
    FirewallRule allow to 0.0.0.0/0  
}  


FirewallRuleSet unknown-users {  
    FirewallRule allow udp port 53  
    FirewallRule allow tcp port 53  
    FirewallRule allow udp port 67  
    FirewallRule allow tcp port 67  
}  

FirewallRuleSet locked-users {  
    FirewallRule block to 0.0.0.0/0  
}  

本文章由 http://www.wifidog.pro/2014/12/16/wifidog-authpuppy%E6%90%AD%E5%BB%BA.html 整理编辑,转载请注明出处

OpenWRT使用Wifidog实现强制认证的WIFI热点

首先安装wifidog到OpenWRT的路由器:
opkg update
opkg install wifidog

wifidog依赖下面这些模块:
iptables-mod-extra
iptables-mod-ipopt
kmod-ipt-nat
iptables-mod-nat-extra
libpthread

由于trunk的固件更新会比较频繁,会导致直接opkg install wifidog安装不了,如果你凑巧又没有备份与固件对应的Packages的话,就需要到http://downloads.openwrt.org/snapshots/trunk升级固件,然后再安装wifidog。

如果你的路由器不是openwrt官方支持的版本的话,那就需要自己编译固件。make menuconfig后,在Network–>Captive Portals中选择wifidog.

wifidog1.png

安装完成后,
/etc/init.d/wifidog enable
/etc/init.d/wifidog start

这时会抛出一个错误,因为我们还没有设置AuthServer的信息。关于安装wifidog更多的信息可以参考:http://wiki.openwrt.org/doc/howto/wireless.hotspot.wifidog

下面安装Auth Server,按照官方的说法:
AuthPuppy is the next generation authentication server for Wifidog networks.
源文档 http://www.authpuppy.org/
不过貌似这wifidog和Authpuppy都已经N久没更新了。。。

AuthPutty是需要安装apache2, php5和MySQL。详细介绍在这里:http://www.authpuppy.org/doc/Getting_Started (Windows版点http://www.authpuppy.org/doc/Getting_Started_-_Windows)。

安装成功后,访问AuthPuppy会要求设置一些数据库信息,全部设置完成后能看到首页:
wifidog2.jpg

当然了,我们还需要设置管理员的账号。
进入Manage plugins,Install apAuthLocalUserPlugin,记得要enable这个插件。

wifidog3.png

然后,点击Manage Nodes,把默认节点的status改成deployed。这个GW(Gateway) ID default后面配置wifidog.conf的时候需要使用。

wifidog4.png

到这里,AuthPuppy就基本配置完毕了。
下面回到路由器,编辑wifidog.conf,一般情况下,我们之后配置ExternalInterface,GatewayInterface和AuthServer这三项就可以,其他默认。下面是我的配置:

GatewayID default           #注意这个ID必须跟AuthPuppy的GW ID一致
# Parameter: ExternalInterface
# Default: NONE
# Optional
#
# Set this to the external interface (the one going out to the Inernet or your larger LAN).
# Typically vlan1 for OpenWrt, and eth0 or ppp0 otherwise,
# Normally autodetected
ExternalInterface eth0      #路由器外网的物理接口

# Parameter: GatewayInterface
# Default: NONE
# Mandatory
#
# Set this to the internal interface (typically your wifi interface).
# Typically br-lan for OpenWrt, and eth1, wlan0, ath0, etc. otherwise
GatewayInterface wlan0      #路由器内网的物理接口
AuthServer {
    Hostname 192.170.1.104
    SSLAvailable no
    Path /
}

CheckInterval 60
ClientTimeout 5
FirewallRuleSet global {
}
FirewallRuleSet validating-users {
    FirewallRule allow to 0.0.0.0/0
}
FirewallRuleSet known-users {
    FirewallRule allow to 0.0.0.0/0
}
FirewallRuleSet unknown-users {
    FirewallRule allow udp port 53
    FirewallRule allow tcp port 53
    FirewallRule allow udp port 67
    FirewallRule allow tcp port 67
}
FirewallRuleSet locked-users {
    FirewallRule block to 0.0.0.0/0
}

注意这个Interface是物理接口,而不是下面OpenWRT web界面中看到的interface。注意不是下面这个:
wifidog5.png

可以看到我的Interface里面没有wlan0之类的选项,/etc/config/network里面也看不到。

root@OpenWrt:~# cat /etc/config/network
config interface ‘loopback’
    option ifname ‘lo’
    option proto ‘static’
    option ipaddr ‘127.0.0.1’
    option netmask ‘255.0.0.0’
config globals ‘globals’
    option ula_prefix ‘fd09:fd03:490d::/48′
config interface ‘lan’
    option proto ‘static’
    option ipaddr ‘192.168.1.1’
    option netmask ‘255.255.255.0’
    option ip6assign ’60’
    option _orig_ifname ‘eth0′
    option _orig_bridge ‘false’
config interface ‘WAN’
    option proto ‘dhcp’
    option _orig_ifname ‘gretap0′
    option _orig_bridge ‘false’
    option ifname ‘eth0′

之前我用gretap0和eth0设置ExternalInterface和GatewayInterface,不行。反着来也不行。网上搜了一圈,找到下面的方法来获取physical interface:

root@OpenWrt:~# ls -l /sys/class/net
lrwxrwxrwx    1 root     root             0 Jan  1  1970 eth0 ->../../devices/platform/ag71xx.0/net/eth0
lrwxrwxrwx    1 root     root             0 Jan  1  1970 lo -> ../../devices/virtual/net/lo
lrwxrwxrwx    1 root     root             0 Aug  2 15:58 wlan0 -> ../../devices/platform/ar933x_wmac/net/wlan0

源文档 http://unix.stackexchange.com/questions/57309/how-can-i-tell-whether-a-network-interface-is-physical-device-or-virtual-alia

OK,原来我这边也是有wlan0这个interface的,找到之后添加在wifidog.conf上。重启wifidog,成功。
另外:

You can also run wifidog in foreground/Debug mode:
wifidog -f -d 7
  -f means to run in foreground (do not become a background daemon)
  -d 7 increases Debug output level to the maximum

本文章由 http://www.wifidog.pro/2014/12/15/openwrt%E4%BD%BF%E7%94%A8wifidog%E5%AE%9E%E7%8E%B0%E8%AE%A4%E8%AF%81.html整理编辑,转载请注明出处