利用Wifidog实现微信wifi连接以及自写认证服务器
前言
大家如果有用公共場合wifi的習慣,想必都有過如下的體驗。
這就是利用微信身份來進行wifi連接認證,主要目的是商家為了吸引顧客,推廣其公眾號。別的也不多說,下面就來講一講怎么實現這樣的wifi認證方式。
本篇文章要講的是portal型路由設備(具體就是OpenWrt路由)的改造實現。在進行改造之前請務必要看微信公眾平臺開發文檔的微信連wifi,后面提到的相關設涉及微信公眾平臺開發的相關術語、參數不再一一解釋。
Wifidog的原理
下圖是在Wifidog的wiki網站上截取的wifidog認證流程圖,網址為點擊打開鏈接。
wifidog由兩部分組成,一個是運行在路由器上的程序,另一部分是運行在認證服務器上的程序。
wifidog的認證流程大致是:
1.首先,用戶的終端可以連接上wifi,然后發起訪問網站的請求,如www.baidu.com;
2.網關根據防火墻規則,將用戶的請求重定向到本地端口(wifidog的監聽端口);
3.網關將用戶的訪問重定向到認證服務器上的認證頁面;
4.認證服務器返回登錄頁面至用戶;
5.用戶再向認證服務器提供憑據,如用戶名和密碼;
6.認證服務器根據用戶提供的憑據來確定用戶是否符合要求,是否可以上網;
7.如果符合要求,認證服務器將用戶的訪問重定向至路由器的網關并攜帶標識token;
8.網關向認證服務器確認用戶信息;
9.如果符合要求,服務器向用戶返回登錄成功頁面;
10.用戶就可以上網了。
WifiDog在openwrt上的安裝和配置
我的路由器型號是:TP-LINK的TL-941N V4/V5版。
安裝的openwrt是:openwrt-ar71xx-generic-tl-wr941nd-v4-squashfs-sysupgrade(先刷openwrt-ar71xx-generic-tl-wr941nd-v4-squashfs-factory)。
我是先裝了luci,然后查到了這個路由器的wifidog版本的下載地址,然后通過opkg?install安裝的(由于這款路由器的FLASH只有4M,裝了luci以后就不能裝wifidog了,所以又刷了一次系統,只安裝了wifidog,然后通過windows下的putty這個ssh工具來訪問openwrt路由器。)。
首次訪問路由時,可通過telnet工具,然后通過passwd,設置路由器的密碼,之后就可通過ssh訪問了。
Wifidog的配置如下所示:
[plain]?view plain?copy
這段代碼首先根據mac地址來判斷登錄用戶是否合法,如果合法則直接重定向至192.168.1.1:2060/wifidog/auth?token=XXX,如果是不合法,則重定向至歡迎頁面,引導用戶獲得認證。
Wifidog與AuthServer的交互
這里特別提一下,我發現在openwrt的download網站里,ar71xx有兩個版本的wifidog,所以請根據需要確定好opkg的源,一個是2009版的wifidog,一個是2013版本的wifidog,我用的源是http://downloads.openwrt.org/snapshots/trunk/ar71xx.nand/packages/packages/,這個源的wifidog版本是wifidog_20130917-440445db60b0c3aff528ea703a828b0567293387_ar71xx,它們在login處有一個區別,后面會提。
先介紹一下wifidog與Auth服務器的交互協議:
1.首先是重定向,在首次登陸時,用戶訪問的url會被重定向到如下的地址:
login/?gw_address=%s&gw_port=%d&gw_id=%s&url=%s(2009版本的wifidog)
login/?gw_address=%s&gw_port=%d&gw_id=%s&mac=%s&url=%s(2013版本的wifidog)
這里有一個版本的問題,即2009的wifidog在重定向時不會在鏈接中帶上mac參數,而2013版本的wifidog是會帶上的,所以這里需要根據自己的應用特別注意。在用戶首次連接路由上網時,它訪問的url會被定向到login頁面,并帶上如上所述的參數,我們可以利用這些參數做生成token或其它一些判斷等。而通常情況是在login中向用戶返回通過wifi認證的方法,如帶有用戶名和密碼的登錄頁面等。
2.用戶認證協議:
auth_server:/auth/auth.php?stage=%s&ip=%s&mac=%s&token=%s&incoming=%s&outgoing=%s
一般情況下,認證服務器auth_server會根據用戶輸入的信息生成一個token,然后將用戶重定向到wifidog的監聽端口上,這個端口的默認地址為:192.168.1.1:2060/wifidog/auth?token=%s,wifidog得到這個token后,將其發送到auth_server認證服務器上進行認證。如果認證通過,auth_server返回“Auth: 1”,認證未通過則返回“Auth: 0”。具體參數如下。
0 - AUTH_DENIED - User firewall users are deleted and the user removed.6 - AUTH_VALIDATION_FAILED - User email validation timeout has occured and user/firewall is deleted1 - AUTH_ALLOWED - User was valid, add firewall rules if not present5 - AUTH_VALIDATION - Permit user access to email to get validation email under default rules-1 - AUTH_ERROR - An error occurred during the validation process
認證服務器通過獲取以上鏈接的參數可以判斷這個用戶是否合法等。這個鏈接是認證服務器用來判斷首次登陸的用戶是否合法和正在連接的用戶是否可以繼續訪問鏈接的方法。每隔一段時間,wifidog會向認證服務器發送信息,即通過如上所示的鏈接發送信息,通過這些參數,可以看到某個客戶的上傳流量、下載流量、mac地址、ip地址、token和、ip和stage。stage可能是兩個參數,分別是counters或login。第一次登陸驗證時,stage=login,其它時候stage=counters。
3.Ping協議
http://auth_sever/ping/?gw_id=%s&sys_uptime=%lu&sys_memfree=%u&sys_load=%.2f&wifidog_uptime=%lu
wifidog會向認證服務器發送一些信息,來報告wifidog現在的情況,這些信息是通過Http協議發送的,如上的鏈接所示,參數大概如字面意思,沒仔細研究過,而作為認證服務器,auth_server應回應一個“Pong”。
4.認證成功后的跳轉
portal/?gw_id=%s
在認證成功后,wifidog會將用戶重定向至該頁面。
5.若驗證失敗,則會根據失敗原因跳轉至如下頁面
gw_message.php?message=denied
gw_message.php?message=activate
gw_message.php?message=failed_validation
注意一下,按照我對wifidog.conf的配置,在執行login時,相當于重定向至鏈接http://justyoung.com/wifidog/login.php?gw_id=XX....等等,其它執行的鏈接也是如此。
編寫自己的WifiDog認證服務器
這次我使用的是php來編寫auth_server服務器,因為這樣比較簡單。
1.首先是login.php
[php]?view plain?copy
2.ping.php
[php]?view plain?copy
這里沒有做額外的處理,只是簡單地向wifidog回應一個Pong。
3.auth.php
[php]?view plain?copy
這里根據一些參數來獲取$result,從而決定是否允許認證。
4.welcomePage.php以及Portal.html就不一一列舉了。
微信wifi認證用戶操作流程
簡單的講(無技術實現),通過微信連wifi的流程(手機端):
對于用戶而言,前面是TA要走的流程,對于開發者而言,要搞清楚每一步路由器、微信、認證服務器這三者到底做了什么,之間有什么關系。要想清楚這些,首先需要了解wifidog。
wifidog認證處理流程
wifidog的介紹就省略掉,相信看這篇文章的人都知道,直接進入正題。wifidog的認證有五種向認證服務器發送的協議,一種自己接受協議,雖說是協議,不過是不同的URL罷了。
例如:192.168.1.2:9408/login/?mac=xx&gw_id=**
| Login | login/? | 用于登錄時 |
| Auth | auth/? | 用于初次認證和心跳認證 |
| Ping | ping/? | 用于路由器心跳 |
| Portal | portal/? | 登錄成功跳轉 |
| Msg | gw_message.php? | 用于出錯時用于展示給用戶信息 |
PS:官方畫的這個圖真的好奇葩,委屈下看官的脖子。或者可以轉動屏幕,最好發到手機上看。
下面對這個流程圖做個解釋:
客戶端發送一個請求,請求被轉發到認證服務器(AuthServer)的Login協議的URL上。這個過程中,具體情況是當客戶端向路由器發送一個HTTP時,OpenWrt中的iptables預定義的規則(在wifidog啟動時寫入規則)將所有請求轉發到wifidog監聽的地址(默認端口是2060)。當然配置文件中可以設置白名單,保證白名單列表的正常連接。再接著wifidog將向客戶端返回302重定向,location的url如下,客戶端將請求這個地址。
| 12345 | http://auth_server/login/?gw_id=[GatewaylD, default: "default]&gw_address=[GatewayAddress, internal IP of router]&gw_port=[GatewayPort, port that wifidog Gateway is listening on]&ur1=[user requested url] |
在配置文件中如果不設GatewayID,wifidog會將GatewayInterface的mac地址去掉冒號當做GatewayID。
If none is supplied, the mac address of the GatewayInterface interface will be used,without the : separators
如圖前面流程圖所示,每個參數都給出了解釋,很清楚。當然url是沒有換行的。
服務器收到login請求后,返回一個登錄頁面,用戶提交表單(假如有的話)。
wifidog收到請求后取得token,并向AuthServer發送Auth請求,url如下所示,之后認證服務器取得參數并判斷是否認證通過。
| 1234567 | http://auth_server/auth/?stage=[login|counters]&ip=[client ip]&mac=[client mac]&token=[token]&incoming=[in data usage]&outgoing=[out data usage] |
- stage有兩個值login表示登錄認證,counters表示計數(心跳)認證。
-
incoming和outgoing是從連接開始到當前的總量,不是每次auth的值。
AuthServer返回是否認證成功時,若成功,返回Auth: 1,若不成功,返回Auth: 0
Ping協議:在每次wifidog啟動的時候都會首先通過ping協議判斷某認證服務器(可以有多個)是否在線,如果是Down狀態就會嘗試下一個。url如下:
| 123456 | http://auth_sever/ping/?gw_id=%s&sys_uptime=%lu&sys_memfree=%u&sys_load=%.2f&wifidog_uptime=%lu |
若驗證失敗,則會根據失敗原因跳轉至如下頁面
| 1 | gw_message.php?message=[denied|activate|failed_validation] |
加入微信認證的流程
要想比較容易的理解這個流程,需要仔細閱讀Wi-Fi硬件鑒權協議接口說明
結合微信的認證流程圖和前面wifidog的認證流程,我們應該會有一些如何結合兩者的想法。
注意此處有坑:
- 此portal非wifidog認證中的portal,在結合微信的認證中wifidog的portal不會用到。
- md5函數的結果中字母一定要是小寫
- 首先portal頁面中的js代碼會向微信服務器發送Ajax請求,就是把要獲取ticket的參數傳過去。
- 微信服務器驗證參數和sign匹配,返回喚起微信所需要的ticket。
- portal頁面將通過微信的Schema:weixin://connectToFreeWifi/ticket=xx呼起微信。(有的瀏覽器不支持打開外部應用,最好用系統自帶瀏覽器)
- 微信連接微信服務器,核對ticket,成功則返回給微信用戶的extend,openId,tid,然后微信會打開前置的連接wifi頁(如圖1中的連接前頁)。
對于關注公眾號可以聯網,取消關注斷網:
- 可以讓用戶提前關注公眾號,在第5步時判斷是否有粉絲關系,有即通過否則拒絕。這可以做到關注了公眾號可以聯網。
- 要想做到取消關注即斷網需要在認證成功之后的auth心跳時進行判斷,具體怎么判斷是否取消關注,是每次查詢微信接口還是用戶取消關注微信服務器會給你個回調,這個我還沒研究。
關于實現的簡單說明
把認證流程搞清楚之后,有開發能力的人基本就不用往下看了,本文也是針對于有一定開發能力的人,關于實現不會像教程一樣詳細,主要是提幾個關鍵點。
wifidog客戶端
安裝wifidog
首先在OpenWrt中安裝wifidog,如果是開發用的話安裝repository中的就可以了。如果是用于生產的話需要對wifidog進行一些修改然后編譯成自己需要的包,這里可以參考?WiFiDog 多線程優化思路。
| 12 | opkg updateopkg install wifidog |
開機自啟?/etc/init.d/wifidog enable
啟動服務?/etc/init.d/wifidog start
配置文件修改
wifidog默認配置文件在/etc/wifidog.conf,最好是要通讀整個配置文件,也不是很多。
修改GatewayID,位置大概在15行
GatewayID用來表示這個wifidog網關的,前面也提到過,注釋掉著一行的話wifidog會取GatewayInterface的mac地址去掉冒號(separators)作為網關ID,如果一個路由上只運行一個wifidog這樣做挺好,多個的話就需要自己設置。
GatewayAddress和GatewayInterface一般按照默認就行,如果有需要自行設置。
| 12 | # GatewayID default# 這里很大一個坑,每個去掉注釋的設置項一定要頂頭開始,不能有空格,當然設置項的子項是要有縮進的。 |
AuthServer項配置,位置大概在80行。
| 1234567 | AuthServer {Hostname 192.168.66.186 HTTPPort 9408SSLAvailable noPath / MsgScriptPathFragment gw_message/?} |
每項配置的具體作用和可選值在前面的注釋中有。
wifidog防火墻配置,在FirewallRuleSet中加入如下規則,位置大概在245行。
| 12345678910111213141516 | # 放行微信FirewallRule allow tcp to wifi.weixin.qq.comFirewallRule allow tcp to dns.weixin.qq.comFirewallRule allow tcp to short.weixin.qq.comFirewallRule allow tcp to long.weixin.qq.comFirewallRule allow tcp to szshort.weixin.qq.comFirewallRule allow tcp to mp.weixin.qq.comFirewallRule allow tcp to res.wx.qq.comFirewallRule allow tcp to wx.qlogo.cnFirewallRule allow tcp to minorshort.weixin.qq.comFirewallRule allow tcp to adfilter.imtt.qq.comFirewallRule allow tcp to log.tbs.qq.com# 放行Apple#FirewallRule allow tcp to apple.com#FirewallRule allow tcp to icloud.com |
最小化修改就是以上三個地方,其它配置項建議也要看看,如果有需要的時候知道改哪里。
通過?wifidog -h?命令查看用法,一般在開發的時候使用?wifidog -f -d 7即可。
認證服務器
認證服務器就是處理wifidog的五種協議,如果只是簡單的認證,用php、python或者其他的腳本語言會更容易實現。因為我需要別的一些處理,所以我選擇JAVA來處理。
代碼的話不準備在這里寫了,放在Github,不過現在代碼寫的太爛,完成度太低,還沒有push,先放鏈接?fliapingWifi-auth
參考文章
- [wifidog-gateway]-Github
- Wi-Fi硬件鑒權協議接口說明
- wifidog安裝以及自寫wifidog認證服務器
總結
以上是生活随笔為你收集整理的利用Wifidog实现微信wifi连接以及自写认证服务器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 佳学网络(建议多翻)
- 下一篇: 基于java网盘搜索的设计与实现