網(wǎng)絡(luò)技術(shù)是從1990年代中期發(fā)展起來(lái)的新技術(shù),它把互聯(lián)網(wǎng)上分散的資源融為有機(jī)整體,實(shí)現(xiàn)資源的全面共享和有機(jī)協(xié)作,使人們能夠透明地使用資源的整體能力并按需獲取信息。資源包括高性能計(jì)算機(jī)、存儲(chǔ)資源、數(shù)據(jù)資源、信息資源、知識(shí)資源、專家資源、大型數(shù)據(jù)庫(kù)、網(wǎng)絡(luò)、傳感器等。 當(dāng)前的互聯(lián)網(wǎng)只限于信息共享,網(wǎng)絡(luò)則被認(rèn)為是互聯(lián)網(wǎng)發(fā)展的第三階段。 鎖文件 通常,類(lèi) Unix 系統(tǒng)是通過(guò)創(chuàng)建表示一個(gè)鎖的文件來(lái)實(shí)現(xiàn)不同進(jìn)程間共享的鎖。使用單獨(dú)的文件來(lái)表示鎖,是“勸告式(advisory)”鎖而不是“強(qiáng)制(mandatory)”鎖的一個(gè)例子。換句話說(shuō),操作系統(tǒng)不會(huì)強(qiáng)制您通過(guò)鎖來(lái)共享資源,所以,所有需要該資源的進(jìn)程都必須協(xié)同使用該鎖。這看起來(lái)好像很簡(jiǎn)單,但并不是所有簡(jiǎn)單的主意都不是好主意;創(chuàng)建單獨(dú)的文件,就可以方便地獲得系統(tǒng)的狀態(tài),其中包括哪些資源被加鎖了。如果您使用這種方法,有一些標(biāo)準(zhǔn)的技巧可以簡(jiǎn)化這些鎖的清除,具體地說(shuō),是刪除那些掛起的鎖。例如,一個(gè)父進(jìn)程可以設(shè)置一個(gè)鎖,然后調(diào)用一個(gè)子進(jìn)程來(lái)執(zhí)行工作(確保父進(jìn)程可以有效地調(diào)用子進(jìn)程),當(dāng)子進(jìn)程返回時(shí),父進(jìn)程釋放該鎖。或者,可以使用 cron 作業(yè)來(lái)查看那些鎖(其中包括進(jìn)程的 id);如果進(jìn)程沒(méi)有處于活動(dòng)狀態(tài),那么該作業(yè)就會(huì)清除那些鎖,并重新啟動(dòng)相應(yīng)的進(jìn)程。最后,鎖文件的清除可以作為系統(tǒng)啟動(dòng)的一部分(從而使您的鎖在系統(tǒng)突然崩潰之后不再處于掛起狀態(tài))。 如果您正在創(chuàng)建單獨(dú)的文件來(lái)表示鎖,那么要注意一個(gè)常見(jiàn)的錯(cuò)誤:對(duì) creat() 或者與之相當(dāng)?shù)?open() 的調(diào)用(模式為 O_WRONLY | O_CREAT | O_TRUNC)。問(wèn)題是,root 總是 可以這樣創(chuàng)建文件,即便鎖文件已經(jīng)存在,這意味著該鎖不能為 root 正常工作。簡(jiǎn)單的解決方案是在使用 open() 時(shí)指定標(biāo)記 O_WRONLY | O_CREAT | O_EXCL(將權(quán)限設(shè)置為 0,使同一用戶的其他進(jìn)程無(wú)法獲得該鎖)。注意 O_EXCL 的使用,這是創(chuàng)建“專用”文件的正式途徑;甚至在本地文件系統(tǒng)上,root 也可以這樣做。這個(gè)簡(jiǎn)單的方法對(duì) NFS 版本 1 或者版本 2 不適用;如果必須在使用這些老的 NFS 版本連接的遠(yuǎn)程系統(tǒng)上使用鎖文件,那么可以使用 Linux 文檔中給出的方案:“在相同的文件系統(tǒng)上創(chuàng)建一個(gè)惟一的文件(例如,結(jié)合主機(jī)名和 pid),使用 link(2) 來(lái)創(chuàng)建一個(gè)指向鎖文件的鏈接,使用 stat(2) 來(lái)檢查該惟一文件的鏈接計(jì)數(shù)器是否增加到了 2。不要使用 link(2) 調(diào)用的返回值。” 如果您使用文件來(lái)表示鎖,那么要確保這些鎖文件放置在攻擊者無(wú)法利用(例如,不能刪除它們或者添加干擾它們的文件)的位置。典型的解決方案是使用一個(gè)目錄,使該目錄的權(quán)限根本不允許未經(jīng)授權(quán)的程序添加或者刪除文件。確保只有您可以信任的程序才能添加或者刪除鎖文件! 文件系統(tǒng)層次結(jié)構(gòu)標(biāo)準(zhǔn)(Filesystem Hierarchy Standard,F(xiàn)HS)得到了 Linux 系統(tǒng)的廣泛使用,同時(shí)還引入了這類(lèi)鎖文件的標(biāo)準(zhǔn)約定。如果您只是希望確保您的服務(wù)器在一臺(tái)給定的機(jī)器上運(yùn)行不超過(guò)一次,那么您通常應(yīng)該創(chuàng)建一個(gè)名為 /var/run/NAME.pid 的進(jìn)程標(biāo)識(shí)符,以進(jìn)程 id 作為文件內(nèi)容。根據(jù)同樣的思路,您應(yīng)該將設(shè)備鎖文件之類(lèi)的鎖文件放置在 /var/lock 中。 鎖文件的代替者 使用單獨(dú)的文件來(lái)表示鎖是一個(gè)非常古老的方法。另一個(gè)方法是使用 POSIX 記錄鎖(record locks),它通過(guò) fcntl(2) 實(shí)現(xiàn)為一個(gè)任意的鎖。采用 POSIX 記錄鎖的理由有很多:POSIX 記錄鎖在幾乎所有的類(lèi) Unix 平臺(tái)上都獲得了支持(它得到了 POSIX.1 的授權(quán)),它可以鎖定文件的一部分(而不是只會(huì)鎖定整個(gè)文件),而且它可以區(qū)別處理讀鎖和寫(xiě)鎖的不同之處。此外,如果一個(gè)進(jìn)程死掉,那么它的 POSIX 記錄鎖就會(huì)自動(dòng)被刪除。 只有所有程序都共同合作的時(shí)候,使用單獨(dú)的文件或者 fcntl(2) 任意鎖才能生效。如果您不喜歡該思想,那么可以轉(zhuǎn)而使用 System V 風(fēng)格的強(qiáng)制鎖。強(qiáng)制鎖允許您鎖定一個(gè)文件(或者它的一部分),使每一次 read(2) 和 write(2) 都檢查鎖,任何沒(méi)有持有該鎖的操作都將被掛起,直到該鎖被釋放為止。這樣做可能稍微方便一些,但也有其缺點(diǎn);擁有 root 特權(quán)的進(jìn)程也可能被強(qiáng)制鎖掛起,這樣通常容易造成拒絕服務(wù)(denial-of-service)攻擊。實(shí)際上,拒絕服務(wù)問(wèn)題是非常嚴(yán)重的,因此通常要避免使用強(qiáng)制鎖。強(qiáng)制鎖是可用范圍很廣,但它不是通用的;Linux 和基于 System V 的系統(tǒng)支持這種鎖,但其他的類(lèi) Unix 系統(tǒng)不支持它。在 Linux 上,為了啟用強(qiáng)制文件鎖,必須用特定的方式裝配文件系統(tǒng),因此很多配置在默認(rèn)情況下不支持強(qiáng)制文件鎖。 在一個(gè)進(jìn)程內(nèi)部,線程可能也同樣需要鎖;有很多書(shū)都非常詳細(xì)地討論了這些問(wèn)題。在這里,我們要討論的主要問(wèn)題是確保您小心地涵蓋了所有情況;很容易忘記某個(gè)特定情形,或者沒(méi)有正確處理。事實(shí)上,正確使用鎖是很難的,攻擊者可能利用這些鎖處理中的錯(cuò)誤。如果您需要在一個(gè)進(jìn)程內(nèi)部對(duì)線程使用很多鎖,那么可以考慮使用自動(dòng)完成鎖的維護(hù)的語(yǔ)言或者語(yǔ)言結(jié)構(gòu)。有很多語(yǔ)言,比如 Java 和 Ada95,都有內(nèi)置的可以自動(dòng)處理鎖維護(hù)(并使結(jié)果有可能更正確)的語(yǔ)言結(jié)構(gòu)。 只要有可能,在開(kāi)發(fā)程序時(shí)最好根本不使用鎖。一個(gè)單獨(dú)的服務(wù)器進(jìn)程每次只接受一個(gè)客戶機(jī)請(qǐng)求,然后處理該請(qǐng)求,直到完成該請(qǐng)求為止,而后再獲得下一個(gè)請(qǐng)求,從某種意義上講,進(jìn)程內(nèi)部的所有對(duì)象是被自動(dòng)鎖定的;這種簡(jiǎn)單的設(shè)計(jì)可以避免很多危險(xiǎn)的加鎖問(wèn)題。如果您需要一個(gè)鎖,那么保持其簡(jiǎn)單性(比如為幾乎所有內(nèi)容都使用惟一的鎖)是有好處的。這并不總是實(shí)用的,因?yàn)檫@樣設(shè)計(jì)有時(shí)會(huì)損害性能。具體地說(shuō),單服務(wù)器系統(tǒng)需要確保無(wú)論哪個(gè)操作都無(wú)法占用過(guò)長(zhǎng)的時(shí)間。但是這個(gè)建議是值得考慮的;使用很多鎖的系統(tǒng)會(huì)更可能有缺陷,而且維護(hù)這些鎖也會(huì)影響性能。 處理文件系統(tǒng) 安全程序的編寫(xiě)必須確保攻擊者無(wú)法以導(dǎo)致問(wèn)題的方式利用共享的資源,有時(shí)這并不像看起來(lái)那樣容易辦到。文件系統(tǒng)是最常見(jiàn)的共享資源之一。所有的程序都可以共享文件系統(tǒng),所以,有時(shí)需要額外的努力,以確保攻擊者不能以引發(fā)問(wèn)題的方式利用文件系統(tǒng)。 有很多確定為安全的程序都存在稱為“time of check - time of use”(TOCTOU)的競(jìng)爭(zhēng)條件缺陷。這只說(shuō)明了程序檢查某種情形是否可行,然后稍后使用那一信息,但是攻擊者可能會(huì)在這兩個(gè)步驟之間改變?cè)撉樾巍?duì)文件系統(tǒng)來(lái)說(shuō),以下問(wèn)題尤為突出;在這兩個(gè)步驟之間,攻擊者通常可以創(chuàng)建一個(gè)普通的文件或者一個(gè)符號(hào)鏈接。例如,如果某個(gè)已授予特權(quán)的程序檢查是否不存在給定名稱的文件,然后打開(kāi)該文件寫(xiě)入信息,那么在那兩個(gè)步驟之間,攻擊者可以創(chuàng)建一個(gè)使用該名稱的符號(hào)鏈接文件... 比如 /etc/passwd 或者其他一些敏感文件。 網(wǎng)絡(luò)的神奇作用吸引著越來(lái)越多的用戶加入其中,正因如此,網(wǎng)絡(luò)的承受能力也面臨著越來(lái)越嚴(yán)峻的考驗(yàn)―從硬件上、軟件上、所用標(biāo)準(zhǔn)上......,各項(xiàng)技術(shù)都需要適時(shí)應(yīng)勢(shì),對(duì)應(yīng)發(fā)展,這正是網(wǎng)絡(luò)迅速走向進(jìn)步的催化劑。 |
溫馨提示:喜歡本站的話,請(qǐng)收藏一下本站!