要: 目前商用WiFi路由器已應用到多個領域,商家通過給用戶提供一個穩定免費WiFi熱點達到吸引客戶、提升服務的目標。傳統路由器自帶的Luci界面提供了工廠模式的Web界面,用戶可通過該界面配置路由器。Luci采用MVC模式(Model-View-Controller)構造網頁,能實現動態的程序設計,便于修改和擴展。本文主要針對OpenWrt系統的路由器,介紹如何使用Lua和JavaScript腳本語言添加用戶模式Web界面。此外,還介紹了工廠模式和用戶模式之間的切換、添加Web頁面的方法,給出了一些應用實例。
0 引言
基于OpenWrt系統的家用路由器作為免費WiFi以及廣告投放的解決方案,具有成本低、部署靈活的優點,被廣告商家以及大型連鎖門店以集中投放、集中管理的方式運用[1]。采用該方式需要解決以下問題:精簡配置管理界面,便于大規模投放部署;屏蔽認證頁、廣告頁投放等設置,避免路由器的經營價值受損。因此需要在路由器管理界面中設定工廠模式以及用戶模式,以便于設備的管理、調試、部署[2]。
本文首先介紹了OpenWrt系統網頁的工作原理,然后具體介紹了如何添加用戶模式以及用戶模式和工廠模式的切換原理,接下來分析了基于Luci編寫網頁的具體過程。文章的最后對下一步的改進工作提出展望。
1 Luci搭建網頁
要理解Luci是如何搭建網頁的,首先就要了解Luci、Uhttpd、CGI、MVC幾個概念。
Luci是OpenWrt上的Web管理界面,它提供給用戶UCI、API接口組件,用于用戶在Web界面上對路由器進行管理與設置。Luci由Lua編寫完成,Lua是一種擴展語言,幾乎在所有操作系統和平臺上都可以編譯、運行。實際上,Lua程序的工作流程是嵌入到其他的程序中運行的[3]。
Uhttpd是OpenWrt系統路由下的一個精簡的Web服務器,它具有非常低的內存開銷,CPU占用率低,效能好,通常用于輕量級的嵌入式設備[4]。Uhttpd是Luci默認的Web服務器,通過Web界面修改相關參數配置路由器。
CGI(Common Gateway Interface)是通用網關接口,它是外部應用程序與Web服務器之間的接口標準[5]。CGI規定了CGI程序和Web服務器之間傳遞信息的規則和流程[5]。通常Web服務器Uhttpd的功能并沒有強大到直接運行php、asp這樣的網頁文件,因此與第三方約定,把請求參數發送至第三方,然后接收第三方處理結果給客戶端。Lua語言編寫的Luci就是這個第三方。
用戶端與Web服務器Uhttpd使用CGI方式交互。Uhttpd服務器在工作過程中分叉出一個子進程,用于處理用戶的具體需求,然后傳遞給Luci,并在網頁中將子進程的結果進行顯示。
Luci、Uhttpd、CGI與網頁之間的關系如圖1所示。
Luci采用MVC(Model-View-Controller)模式搭建網頁。MVC模式把軟件系統分為三個基本部分:模型(Model)、視圖(View)和控制器(Controller)。
(1)控制器(Controller):負責轉發和處理請求。
(2)視圖(View):設計的網頁界面。
(3)模型(Model):數據模型,是客觀事物的抽象。
使用MVC模式的目的是實現一種動態的程序設計,使后續對程序的修改和擴展簡化,并且使程序某一部分的重復利用成為可能[6]。
Controller、View、Model三者之間的關系如圖2所示[7]。
2 用戶模式切換
2.1 MVC框架設計
Luci是一個單用戶框架,在/usr/lib/lua/luci/下有三個目錄,分別是model、view、controller,它們對應M、V、C[6]。公用的模塊放置在/usr/lib/lua/luci/controller/下面,各個用戶的模塊放置在該路徑下面對應的文件夾中。如路由器自帶的工廠模式就位于該目錄下的admin文件夾下。新增用戶模式需新添加文件夾mini,然后在該路徑下添加功能程序。這樣既有效地管理了不同管理員的權限,又有利于系統的拓展和維護。Controller、Model、View生成網頁的關系如圖3所示。
在controller目錄下,每個Lua程序都以index作為起始函數。在index函數中,通過調用entry函數創建子節點,并把它放在全局節點樹的相應位置。entry函數的參數規定了該節點的位置屬性。
2.2 利用控制器生成Target
Controller目錄下的子節點以Target的方式生成網頁。Target是由每個子節點的entry函數創建的,這是dispatch流程最后要執行的方法。Target主要有alise、firstchild、call、cbi、form和template 6種生成方式。總體上可以分成兩類,前兩種主要用于鏈接其他節點,后四種則是實現函數方法或頁面跳轉[7]。
鏈接節點:alias是網頁節點之間的鏈接。比如,當用戶登錄路由成功后,進入的網頁節點未定義內容,可以用alias的方法,自動鏈接到有內容的Web節點。
實現函數方法或頁面跳轉:這種方法一般用于一個路徑的葉節點leaf,執行相應的操作,并且動態生成頁面html文件,傳遞給用戶。在call、cbi、form、template四種方法中,call調用了自定義的功能函數,直接調用以實現特定的目標,如發送數據、讀取文件等。調用cbi函數能夠使用CBI模塊簡潔高效地生成網頁。函數template是直接鏈接到目錄view下面的htm頁面,實現網頁跳轉。
如果要添加用戶模式(Mini),就必須在Controller目錄下添加文件夾mini。這樣Luci就能夠直接從Controller目錄下讀取子節點的數目及名稱,以便生成對應的節點樹。在用戶模式的mini目錄下至少添加兩個文件。第一個是index.lua文件,index.lua程序是為了實現用戶名、密碼的認證和網頁節點的配置。第二個是要具體實現的功能網頁,該網頁定義了生成的Target。以顯示路由系統狀態為例,需要添加index.lua和system_state.lua文件。
添加的用戶模式(Mini)文件結構如圖4所示。
要說明的是,此處system_state.lua規定是用template的方式生成Target,直接跳轉到view/mini文件夾下的system_state.htm文件。
實際上,用戶模式和工廠模式都是使用Luci搭建網頁,二者之間的原理完全相同。不同的是,在用戶模式下,給用戶顯示的是更加貼近實際使用需求的頁面。此外,使用用戶模式,關閉工廠模式的部分功能,還能使路由器更加高效地運轉。
在成功添加了用戶模式后,就要考慮登錄認證的問題。只有輸入正確的用戶名和密碼之后,才能成功登錄用戶模式。用戶模式下的所有子節點是由上而下逐層索引的,因此只要有一個節點需要認證,在該節點下的所有子節點也需要認證。只要mini節點有sysauth值,它以下的所有子節點都需要認證才能查看、操作。
此外,OpenWrt的精簡內核是單用戶機制,路由器自動以root用戶登錄。也就是說,工廠模式和用戶模式使用的是同一個用戶名和密碼。通過認證后,服務器端會發給用戶端一個session值,該值以cookie的形式存在于請求報文中,供服務器識別用戶。
2.3 Footer頁腳標簽
用戶成功登錄路由后,要求能夠在工廠模式與用戶模式之間自由切換。這個任務就由Footer頁腳標簽來完成。Footer的工作原理是由Luci的主題決定的,主題包含兩個內容,分別是header.htm和footer.htm。header.htm能顯示每個頁面的菜單欄,footer.htm則會讀取Controller目錄下的節點,最終顯示在頁腳中,以鏈接的方式切換用戶。
Footer頁腳標簽的工作原理如圖5所示。
在成功添加頁腳之后,整個添加用戶模式和模式切換的工作就完成了。結果如圖6所示,其中footer.htm顯示在右下方,user model就是添加的用戶模式。
3 網頁設計
前面提到,為了在用戶模式下生成滿足特定功能的網頁,需要在controller/mini目錄下添加index.lua和system_state.lua兩個文件。在system_state.lua中,規定網頁是以template的方式鏈接到view/mini文件下的system_state.htm文件。這樣只要設計system_state.htm的內容,就可以實現對應的功能。
system_state.htm是將Lua和JavaScript兩種語言配合使用來完成相應的功能。如果編寫的功能模塊不需要訪問路由器的數據,則利用Lua和JavaScript可以比較輕松地實現[4]。特別地,還可以調用一些輔助性Shell script。在網頁中,利用Lua語言的luci.sys.exec函數,就可以調用shell腳本。
例如,要測試路由器與外網是否連通,可以簡單地通過ping命令,訪問某一主流網站即可。如果ping通,則返回值為1,否則返回0。該功能可以用shell腳本寫,在網頁中使用如下命令:
state=tonumber(luci.sys.exec("/shellfun/pingtest"))
這樣就能執行/shellfun文件夾下的pingtest.sh Shell腳本,返回是否連通的狀態,在網頁中顯示相應的內容。
如果編寫的功能模塊需要訪問路由器的數據,這就需要一個從Lua腳本到JavaScript腳本數據交互的過程。因為JavaScript不太適合直接訪問路由器的數據,一般都是由Lua腳本程序讀取路由器的數據。然后,用JSON(JavaScript Object Notation)這種輕量級的數據交換格式發送給JavaScript腳本,利用JavaScript腳本在網頁上顯示出傳遞的數據。
例如,當要在網頁中顯示某一端口的實時流量時,需要不斷地訪問路由器的端口流量數據。可以在/luci/controller/mini的system_state.lua中某一節點規定,通過Lua的函數不斷地訪問數據,然后用JSON數據格式輸出數據[5]。在JavaScript腳本中,利用XHR.poll函數每隔一段時間接收JSON數據,最后將數據以圖表的方式動態顯示。
最終實現的路由器連通測試和流量監控結果如圖7所示。
4 結論
本文深入地分析了路由器Web系統Luci搭建網頁的原理和實現細節。MVC模式是軟件工程實現網站搭建的核心,通過MVC模式,大大簡化了網站的開發和維護工作。在設計網頁的過程中,介紹了Lua和JavaScript如何進行數據交互,以及如何配合外部的shell腳本實現特定功能。
目前家用路由已經支持采用TF卡、U盤等外置存儲硬件,可以采用Luci搭建接口實現路由器本地存儲以及內容的投放,使之具有更高的運營價值和潛力。
參考文獻
[1] 海虎,李濤,韓俊剛,等.多態并行處理器的數據通信和路由器的設計[J].電子技術應用,2014,40(8):38-40,47.
[2] 朱云雷.基于互聯與認證的無線路由器關鍵技術[J].微型機與應用,2014,33(24):57-58,65.
[3] 張一弓.基于OpenWrt平臺的進程問通信[J].科技創新與應用,2014(21):62.
[4] KIM C G, KIM K J. Implementation of a cost-effective home lighting control system on embedded Linux with OpenWrt[J]. Personal & Ubiquitous Computing, 2014, 18(3):535-542.
[5] PALAZZI C E, BRUNATI M, ROCCETTI M. An OpenWrt solution for future wireless homes[C]. 2010 IEEE International Conference on Multimedia and Expo, IEEE Computer Society, 2010:1701-1706.
[6] 吵吵博客.LuCI界面開發之CBI模塊[EB/OL].(2011-09-04)[2015-06-30]http://www.chaochaoblog.com/archives/698.
[7] 吵吵博客.LuCI實現啟動應用程序等腳本命令2011[EB/OL].(2011-09-03)[2015-06-30]http://www.chaochaoblog.com/archives/691.
微笑]關鍵字:騰訊云、DDNS、動態域名、公網IP、群暉、軟路由、openwrt、lede
#奇妙知識季#
本文快速的教大家解決域名綁定動態公網IP的問題,幫助大家實現用域名登錄家里的設備。
首先您需要一臺支持騰訊云DDNS功能路由器,如openwrt、ikuai均可。
這里用openwrt做示范,openwrt具有眾多優勢,如插件安裝自如,相比任何路由固件。
1、安裝騰訊云DDNS插件
OpenWRT TencentDDNS插件是一款騰訊云研發的,自動映射動態公網IP至用戶指定的DNSPod域名解析記錄的官方插件。可在安裝了openwrt的軟路由上,將運營商分配的家庭寬帶公網IP動態關聯到指定的DNSPod域名解析記錄上。實現通過域名訪問家庭內網服務的目的。
標題 | 名稱 |
中文名稱 | 騰訊云DDNS插件 |
英文名稱 | luci-app-tencentddns |
最新版本 | 0.1.0 (2020.09.17) |
適用平臺 | Lean OpenWRT(opens new window) |
適用產品 | DNSPod(opens new window) |
GitHub項目 | tencentcloud-openwrt-plugin-ddns(opens new window) |
gitee項目 | tencentcloud-openwrt-plugin-ddns(opens new window) |
主創團隊 | 騰訊云中小企業產品中心(SMB Product Center of Tencent Cloud) |
推薦安裝方式如下:
登錄OpenWrt路由器,進入系統>軟件包>動作頁面,將下方軟件包的地址放入從網絡安裝的輸入框中,點擊確認完成安裝。 ipk安裝地址:https://openwrt-tencentddns-1301800460.cos.ap-guangzhou.myqcloud.com/luci-app-tencentddns_0.1.0-1_all.ipk
官方指導頁面如下:
https://openapp.qq.com/docs/OpenWRT/ddns.html
安裝完畢后,在過濾器里搜索:tencentddns,檢查搜索結果是否正確,顯示有結果,版本號對應上即可。
之后找到:網絡>騰訊云DDNS菜單,即可找到該插件的配置頁面,里面有密鑰ID、密鑰Token、主域名、子域名等配置需要配置。繼續往下看。
名詞解釋
啟用:是否開啟騰訊云DDNS
清除所有同名記錄:如果一個域名有多個A解析記錄,是否一并清除
密鑰ID:DNSPod后臺密鑰管理中的ID,獲取地址:DNSPod密鑰管理(opens new window)
密鑰Token:DNSPod后臺密鑰管理中的Token。獲取地址:DNSPod密鑰管理(opens new window)
主域名:主域名,如: github.com
子域名:子域名,如:www
檢查時間:后臺對域名解析檢查的時間間隔
2、申請騰訊云域名
有了騰訊云DDNS插件,我就需要一個域名,當然家里必須要是撥號的公網IP。這是前提。百度搜索騰訊云,點擊控制臺,經過一系列的認證申請,直到成功登錄騰訊云賬號。
接入輸入dnspod搜索dns業務
進入DNSPOD控制臺頁面后,點擊域名注冊,右側彈出頁面點擊立即注冊。
搜索框輸入你想注冊的域名,如:qazwsx.top,點擊查詢,尋找沒有注冊的域名即可注冊。
找一個性價比高的入手,加入購物車,點擊立即購買后,會有一個信息模板要求完善,按照要求完成每一步的信息填寫和實名認證即可。
注冊完畢后,就可以進入https://console.dnspod.cn/控制臺,DNS解析>我的域名菜單,就能看到新購買的域名了。
這里我們需要先手動添加基礎的解析條目,后面再由DDNS插件自動更新。
點擊藍色的域名名字,進入域名設置
點擊添加記錄,
記錄類型:選A
主機記錄:輸入域名前面名字,比如openwrt,域名組合后就是openwrt.qazwsx.top
IPV4地址:先隨便填,后面由DDNS插件自動更新為公網IP
權重:空
TTL:600
添加好后如下截圖。后面開始申請API綁定,實現自動更新公網IP
3、申請騰訊云DDNS POD API
在https://console.dnspod.cn/控制臺右上角頭像處,點擊頭像,彈出的菜單選擇API密鑰,點擊后進入API申請頁面,選擇DNSPod Token。
點擊創建密鑰,輸入密鑰名字,后面自動生成密鑰
密鑰只會展現一次完整,趕緊復制粘貼,接下來需要復制到DDNS插件里。
4、配置OpenWrt DDNS插件
返回本地openwrt配置頁面:網絡>騰訊云DDNS菜單。點擊啟用,填入對應信息。
其中openwrt作為旁路由的話,WAN-IP來源選擇internet即可,主域名填購買的域名,子域名填dnspod控制臺添加的解析記錄的“主機記錄“名字。這樣子域名+主域名+api token,ddns插件就能主動上傳動態IP到DDNS后臺進行綁定。騰訊無非就是將整個IP的獲取,上傳,解析更新實現自動化。
設置好后,返回dnspod控制臺,過一會添加的記錄就會更新。原來設置的192.168.100.2地址自動變成公網IP。
5、檢查DDNS更新信息
檢查DDNS插件日志,檢查dnspod控制臺解析記錄是否更新成功
這個時候,雖然看到解析成功了,域名成功綁定公網IP,但是你的路由器還沒有做端口映射,公網登錄后是沒有任何內容的,請繼續往下看。
6、端口映射
進入主路由,以我的ikuai為例,進入菜單:網絡設置>端口映射>添加菜單。
輸入需要映射的內網ip+port,協議選擇全部,映射類型選擇外網接口,外網端口設置大一點,減少掃描風險,允許訪問ip可以設置成你單位的公網IP,將進一步提高訪問安全。最后保存。之后就可以用你的域名進行公網登陸了。記得域名尾部加端口。
7、測試
以實現路由器功能的開源軟件很多,為什么只有OpenWrt成功了?OpenWrt軟件成功的關鍵在于3個方面:領導者、基礎設施以及實現軟件的技術。通常領導者是最重要的,因為領導者決定著社區的規則和技術方向,但是每個人都是獨特的而且是無法復制的,因此通常無法借鑒。基礎設施和實現軟件的技術則是可以借鑒的。
OpenWrt社區采用六大基礎設施工具支撐整個社區的運轉,這六大基礎設施工具分別是代碼管理工具Git、郵件列表、自動構建工具buildbot、文檔管理工具WiKi、Trac和技術論壇。
代碼管理工具Git可以跟蹤文件和目錄的歷史信息,包含4個W(Who、When、Why和What),即誰做了修改,什么時間做了修改,為什么修改以及修改的內容是什么。此外,Git還支持分布式代碼倉庫,適合開源軟件項目的跨地域開發,這個工具可以讓每個人看到代碼的變化過程。OpenWrt經過了12年的發展,代碼倉庫還保留了最初的提交記錄。
郵件列表是代碼審查及代碼提交集成的地方,開發人員將修改代碼生成補丁發送給所有的郵件訂閱者,每個人都可以進行代碼評審,核心開發人員看到后會將代碼集成到代碼倉庫中。郵件內容可以永久保存到郵件列表中。郵件列表和普通郵件的主要區別在于訂閱機制和存檔機制,每個人都可以自由訂閱并查看歷史郵件。
自動構建工具buildbot的核心是一個作業調度系統,它會將任務排隊,當提供了任務所需的資源時,執行任務并報告結果。buildbot不僅僅支持持續集成及自動化測試,還支持應用程序的自動化部署和軟件發布的管理。同時在多個平臺開發時,通常最后的編譯驗證都是重復的,編譯機器人(buildbot)將這一部分接管過來,每日自動下載代碼進行編譯驗證,并將安裝包上傳到文件服務器上,如果編譯失敗則將用郵件通知感興趣的人。
文檔管理工具WiKi的特點是具有開放性,可以讓任何參與人員非常方便地進行編輯、訪問和搜索。大多數軟件公司的軟件文檔均保存為二進制格式,在經過一段時間和人員流動之后,這些文檔就會成為固定的資料,因為它會被遺落在某個角落而無法找到,而OpenWrt社區的軟件開發文檔和使用手冊均保存到WiKi上。WiKi是一個協同寫作和分享平臺,允許所有人修改頁面。WiKi使用簡化的語法來代替復雜的HTML語言,降低了內容維護的門檻。
Trac是一個集成WiKi和問題跟蹤管理系統的項目管理平臺,可以幫助開發人員更好地管理軟件開發過程,從而開發出高質量的軟件。任何人都可以使用該系統來提交Bug并查詢當前的進展。Trac采用面向進度的項目管理模型,采用里程碑的方式來組織開發。里程碑是以ticket(問題)來組織的,所有的問題都解決了,就到達了里程碑。但社區并不完全遵從這個標準,因為其開發人員全部是志愿者,通常到了一定時間會發布一個版本。
技術論壇是一個技術討論的平臺,每個注冊用戶均可發帖參與討論。在開發過程中,每個新版本的說明通過該平臺發布。
社區的運轉是通過以上所述的六大基礎設施工具來實現的,我們通過這些工具可以理解到,開源軟件和社區的精髓在于其開放性,任何人員均可以通過網絡自由地獲取其信息并參與其中,這樣可以激勵每個人貢獻出自己的力量,開發人員同時也從社區獲得回報。開源社區的工具大多都是相同的,掌握這些工具可以幫助你深入了解開源社區和OpenWrt。
OpenWrt技術上成功的秘訣在于:統一編譯框架、統一配置接口(Unified Configuration Interface,UCI)、開放的軟件包管理系統及其讀寫分區系統、系統總線ubus和進程管理模塊procd。
所有的這些功能并不是一次性設計出來的,而是隨著時間的推進,根據用戶和開發進展逐步發展起來的,每一種技術都有其獨特的價值。
本文節選自《智能路由器開發指南 》
內容簡介
OpenWrt是在實現路由器功能方面最受歡迎的開源軟件之一。本書基于OpenWrt,詳細介紹了智能路由器的開發。本書共計15章,按照認識路由器的順序進行編寫,介紹了智能路由器、開發環境及編譯分析、OpenWrt包管理系統、OpenWrt配置、軟件開發、GDB調試、網絡基礎知識、路由器基礎軟件模塊、常用軟件模塊、IP路由、DNS與DHCP、iptables防火墻、UCI防火墻、UPnP、網絡測試及分析工具等。豐富的理論知識和代碼示例可以幫助讀者深入認識和理解OpenWrt技術,并能夠提升開發水平和開發效率。
本書適合軟件架構師、軟件開發工程師、軟件測試工程師以及計算機相關專業的學生閱讀。讀者通過閱讀本書,不僅可以掌握OpenWrt技術,還能進一步提升自己的軟件開發水平。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。