基于μClinux操作系統下Boa的CGI技術(shù)實(shí)現
引 言
隨著(zhù)企業(yè)安全意識的增強以及現代化管理水平的提高,對設備的遠程監控在工業(yè)控制系統中得到了越來(lái)越廣泛的應用。近年來(lái),Web技術(shù)廣泛普及,把Web技術(shù)應用在這種監控系統中,可以讓操作者通過(guò)瀏覽器維護和管理監測點(diǎn),查看監測數據。同時(shí),監測中心的服務(wù)程序也可以很方便地通過(guò)Web把監測數據取回來(lái),進(jìn)行進(jìn)一步的處理,十分方便。
μClinux是應用于微控制領(lǐng)域的一種嵌入式Linux操作系統,它源碼開(kāi)放,移植性好,支持多種硬件平臺和幾乎所有常見(jiàn)網(wǎng)絡(luò )通信協(xié)議,支持文件系統豐富,是一個(gè)功能完整的嵌入式操作系統。并且有大量?jì)?yōu)秀的開(kāi)放源代碼的應用軟件和開(kāi)發(fā)工具可用,因此,采用μClinux作為操作平臺,使用Web技術(shù)進(jìn)行遠程在線(xiàn)監測系統的開(kāi)發(fā)。
為了能夠通過(guò)Web來(lái)維護和管理遠程在線(xiàn)監控系統,必須選擇一個(gè)恰當的Web服務(wù)器,不但要求所選擇的Web服務(wù)器支持動(dòng)態(tài)Web技術(shù),也要求它能夠在嵌入式系統中穩定地工作。
1.1 Web服務(wù)器原理和功能
嵌入式Web服務(wù)器以TCP/IP協(xié)議棧為基礎構建,需要實(shí)現HTTP,TCP和UDP等協(xié)議。任何一個(gè)客戶(hù)機,都可以通過(guò)HTTP協(xié)議與嵌入式Web Server建立連接。嵌入式Web服務(wù)器在Web瀏覽器和設備之間提供了統一的GUI接口,使得客戶(hù)端可以像在本地一樣透明地監控管理設備狀況。
嵌入式Web服務(wù)器的主要功能有:響應多個(gè)客戶(hù)的實(shí)時(shí)HTTP請求,并為每個(gè)客戶(hù)建立連接,這是嵌入式Web服務(wù)器的首要功能;對設備的實(shí)時(shí)監控管理,參數的在線(xiàn)查看與配置等;對設備訪(fǎng)問(wèn)的安全控制機制,包括SSL、用戶(hù)口令等;實(shí)現設備的故障智能報警。
1.2 Boa的特點(diǎn)
在μClinux中常用的Web服務(wù)器有:Boa,thttpd,httpd,其中httpd只支持靜態(tài)頁(yè)面,顯然不適合高級應用,thttpd和Boa所提供的功能基本一樣,但是thttpd在運行過(guò)程中所需要的資源要遠大于Boa,因此使用Boa作為該嵌入式系統的Web服務(wù)器。系統的軟件開(kāi)發(fā)模型選用B/S模型。
Boa是一個(gè)高性能的單任務(wù)型Web服務(wù)器,可以運行在幾乎所有的類(lèi)Unix的平臺上,Boa支持認證,支持CGI,功能比較全,占用資源也少,非常適合于用在資源有限的嵌入式系統中,目前Boa已經(jīng)以源碼的形式包含在μClinux的發(fā)行包中。
2 Boa源碼分析
在此通過(guò)以下對Boa的源代碼進(jìn)行簡(jiǎn)單的分析,來(lái)提出解決避免惡意攻擊的安全解決方案。
2.1 Boa工作流程
圖1是Boa工作流程圖。Boa從新到達的套接字獲得HTTP請求(由一個(gè)request結構來(lái)存儲),并將其保存在隊列當中。首先,get_request()將從套接字獲得的數據全部保存在request→header_line中,然后調用process_request()來(lái)處理在隊列中的每一個(gè)請求。根據request結構中status所表示的不同狀態(tài),將進(jìn)行不同的處理。如果這個(gè)請求符合HTTP協(xié)議,則會(huì )調用process_option_Iine()將一些頭部信息填寫(xiě)到request結構中完成這些環(huán)境變量的設置,隨后process_header_end()會(huì )對用戶(hù)進(jìn)行驗證。如果驗證通過(guò)則判斷request結構中的is_cgi,非0則是CGI程序,調用init_cgi()函數進(jìn)行處理,為0則是靜態(tài)頁(yè)面,調用init_get()函數進(jìn)行處理。
2.2 init_get函數工作流程
圖2為處理靜態(tài)頁(yè)面請求的init_get()函數的基本工作流程。圖2中process_get()函數完成的功能為將request結構中的data_men字符串返回套接字并在用戶(hù)瀏覽器上顯示相應的內容。
2.3 init_cgi函數工作流程
對CGI程序的處理函數init_cgi()首先調用一系列函數完成對CGI環(huán)境變量的設置,create_common_env(),complete_env()完成了大多數CGI環(huán)境變量的注冊工作。采用PIPE(管道)方式,就是將CGI程序的輸出重定向到管道,然后Boa從管道讀取并轉發(fā)給客戶(hù)端瀏覽器。整個(gè)流程結束后,返回到主函數的無(wú)限循環(huán)中等待處理下一個(gè)套接字連接的到達。init_cgi()具體工作流程如圖3所示。
管道讀取函數read_from_pipe()完成的主要功能是從套接字req→data_fd讀取數據到req→header_end中,并進(jìn)行處理;然后修改req→status=PIPE_WRITE來(lái)調用write_from_pipe()將req→header_line的內容返回套接字fd,并在用戶(hù)瀏覽器上顯示相應的內容。
3 Boa源碼改進(jìn)
經(jīng)過(guò)上述對Boa源碼的分析可以看出,Boa服務(wù)器將根據瀏覽器地址欄中輸入的文件路徑調用相應的CGI程序或靜態(tài)頁(yè)面顯示在瀏覽器中。這種方式使入侵者很容易找到源文件,隱蔽性和安全性極差。這里在對Boa源碼進(jìn)行修改后,在瀏覽器中輸入對該系統指定的靜態(tài)網(wǎng)頁(yè)類(lèi)型的請求后,Boa服務(wù)器會(huì )自動(dòng)進(jìn)行文件路徑重定向,調用相應的CGI程序進(jìn)行處理,而用戶(hù)不會(huì )察覺(jué)到這一變化。從而使用戶(hù)無(wú)法得知源文件的路徑,增加了程序的隱蔽性和安全性。
在源代碼判斷是否CGI程序之前添加判斷:如果文件路徑(req→pathname)的后綴代表本系統指定的靜態(tài)頁(yè)面,則將其修改為實(shí)際CGI程序所在路徑,并更改is_cgi變量為“CGI”。經(jīng)過(guò)這樣修改后,程序會(huì )調用CGI程序的處理函數init_cgi(),使原本的靜態(tài)請求變成動(dòng)態(tài)的CGI請求。修改后的Boa流程如圖4所示(虛線(xiàn)為添加部分)。
4 CGI程序設計技術(shù)
4.1 CGI簡(jiǎn)介
到目前為止,實(shí)現動(dòng)態(tài)Web頁(yè)面有4種技術(shù)可供選擇:CGI,ASP,PHP和JSP。因為目前μClinux還不支持ASP,PHP等動(dòng)態(tài)Web頁(yè)面技術(shù),因此在該實(shí)現中選擇了CGI。
CGI規定Web服務(wù)器調用其他可執行程序的接口協(xié)議標準,提供Web服務(wù)器一個(gè)執行外部程序的通道。這種服務(wù)端技術(shù)使得瀏覽器和服務(wù)器之間具有交互性。CGI程序屬于一個(gè)外部程序,需要編譯成可執行文件,以便在服務(wù)端運行。Web服務(wù)器通過(guò)調用CGI程序實(shí)現與Web瀏覽器的交互,也就是CGI程序接收Web瀏覽器發(fā)送給Web服務(wù)器的信息,進(jìn)行處理,將響應結果再回送給Web服務(wù)器及Web瀏覽器。
4.2 CGI程序工作原理
CGI工作原理如下:客戶(hù)端的用戶(hù)通過(guò)瀏覽器完成一定輸入工作后,向服務(wù)器發(fā)出。HTTP請求(稱(chēng)為CGI請求),服務(wù)器守護進(jìn)程,接收到該請求后,就創(chuàng )建一個(gè)子進(jìn)程(稱(chēng)為CGI進(jìn)程)。該CGI子進(jìn)程將CGI請求的有關(guān)數據設置成環(huán)境變量,在CGI程序與服務(wù)器間建立兩臺數據通道,然后啟動(dòng)URL指定的CGI程序。子進(jìn)程通過(guò)標準輸出流將處理結果傳遞給服務(wù)器守護進(jìn)程,守護進(jìn)程再將處理結果作為應答消息回送到客戶(hù)端。一個(gè)CGI程序的任務(wù)分為輸入任務(wù)和輸出任務(wù)。輸入任務(wù)根據請求方法的不同,從環(huán)境變量QUE-RY_STRING或標準輸入中讀取用戶(hù)輸入數據。輸出任務(wù)生成HTTP響應頭標內容,如消息正文的數據類(lèi)型和數據長(cháng)度等;生成HTTP響應消息正文內容,如動(dòng)態(tài)生成的HTML文件內容。
4.3 CGI程序改進(jìn)方法
傳統的CGI程序編寫(xiě)方法簡(jiǎn)單地用printf()函數來(lái)產(chǎn)生HTML源代碼。在輸出的字符串中如果有雙引號,在其前面必須有一個(gè)后斜字符,這是因為整個(gè)HTML代碼串已經(jīng)在雙引號內,所以HTML代碼串中的雙引號符必須用一個(gè)后斜字符來(lái)轉義。這樣的CGI程序代碼冗長(cháng),不利于閱讀,且容易出錯。這里所采用的方法是預先將需要顯示的網(wǎng)頁(yè)保存成文件,采用仿“ASP”的技術(shù),將需要動(dòng)態(tài)顯示的內容寫(xiě)入符號“|%”與“|”之間。并設計配置文件,指定替換內容。CGI程序逐行讀取源文件,將符號“|%”與“|”之間的內容替換成配置文件指定的內容。
HTML源文件的格式設計如下:
單選按鈕:
CGI程序找出“|%”與“|”之間的關(guān)鍵字key,如果key中不包含“@”則直接替換與之對應的值;如果包含“@”,將關(guān)鍵字分為三部分:replacestr=checked,key=system_mode,keyvalue=route。尋找數據結構中與key相等的name[i],將對應的value[i]與keyval-ue比較,如果相等則替換為type的值。具體流程如圖5所示。
當在任意用戶(hù)端瀏覽器中輸入目標板的IP地址及對應的文件名后,就會(huì )顯示如圖6所示界面。其中在地址欄中輸入的路徑已經(jīng)按照本文之前的方法被Boa服務(wù)器修改,實(shí)際路徑為:http://192.168.0.1/cgi-bin/qs2.cgi。因此用戶(hù)無(wú)法找到源文件,減小了被惡意用戶(hù)攻擊的可能性。圖5中選中單選框和添加文本框內容這些操作都是經(jīng)過(guò)CGI程序替換顯示的配置文件中的內容。修改這些內容后點(diǎn)擊下一步程序會(huì )自動(dòng)保存到配置文件中,下一次再進(jìn)入頁(yè)面后就會(huì )顯示上一次保存的結果。
5 結 語(yǔ)
這里通過(guò)對Boa源代碼的分析,提供了較為完善的文件隱藏機制,該研究為Web服務(wù)器在嵌入式設備遠程監控應用中提出了一個(gè)更為安全的解決方案。此外,通過(guò)對傳統的CGI程序設計方法進(jìn)行改進(jìn),可顯著(zhù)減少CGI程序代碼量,使其便于修改升級。這種方法完全可以應用在其他嵌入式系統中,因此具有廣泛的應用意義。系統也有一些尚需改進(jìn)的地方,如:文件路徑隱藏方式有些簡(jiǎn)單;CGI程序配置文件沒(méi)有進(jìn)行加密;這些都有待今后進(jìn)一步研究。
評論