詭異案例:系統(tǒng)服務(wù)無法啟動怎么辦?
上周二,我(@佘華煜)接到了一個很詭異的案例,表現(xiàn)為任務(wù)欄右下角網(wǎng)絡(luò)連接圖標(biāo)始終為一個紅叉,已排除網(wǎng)卡硬件、鏈路和網(wǎng)卡驅(qū)動的問題。主板都新?lián)Q了一塊,可是問題依舊,這無疑將問題的根源指向了操作系統(tǒng)。本想通過網(wǎng)絡(luò)疑難解答包先自動排錯,可是發(fā)現(xiàn)該疑難解答提示服務(wù)未能啟動因此不能進(jìn)行自動排錯,經(jīng)查證,Diagnostic Policy Service 服務(wù)處于起不來的狀態(tài),報錯"錯誤5:拒絕訪問"。
經(jīng)過我的排查,我發(fā)現(xiàn)系統(tǒng)的很多服務(wù)都未能啟動,尤其是網(wǎng)絡(luò)相關(guān)的很多服務(wù),例如DHCP,防火墻,ICS,IPSec Policy Agent 等等。當(dāng)我手動嘗試啟動這些服務(wù)時,除了有些報相關(guān)服務(wù)尚未啟動之外,無一例外地,都報了一個錯誤——錯誤5:拒絕訪問。(需要先啟動的相關(guān)服務(wù)都是該錯誤)
查看系統(tǒng)日志,將里面的更詳細(xì)的錯誤代碼拿去微軟搜索,發(fā)現(xiàn)沒有什么收獲。在一些社區(qū)解決方案中,也沒能找到行之有效的解決辦法,甚至微軟官方論壇有一個同樣的案例,一個錯誤的/不太相關(guān)的解答被標(biāo)記為正解……
這顯然不是正解,我得找到一個解決該問題的辦法。于是經(jīng)過各種嘗試,我最后通過 Process Monitor 的幫助,找到了服務(wù)無法啟動的直接原因和解決辦法。由于當(dāng)時沒有截圖,所以今天我還原了一個當(dāng)時的情景,以 Base Filtering Engine 服務(wù)的無法啟動為例,闡述當(dāng)時我的解決思路。Base Filtering Engine 服務(wù)簡稱 BFE,相關(guān)的網(wǎng)絡(luò)安全服務(wù)(如 Windows 防火墻和 IPSec)依賴于它。
在打開 Process Monitor 的記錄以后,我立即點擊啟動服務(wù),來嘗試啟動 BFE。它立即報錯"拒絕訪問",我同時也嘗試啟動了那些不能啟動的服務(wù),都成功地重現(xiàn)了問題。停止 ProcMon 的記錄后,在已記錄下的log中,我可以看見當(dāng)該問題重現(xiàn)時系統(tǒng)各進(jìn)程所做的一些操作。通過粗略的快速瀏覽翻查和關(guān)鍵字"denied"搜索,引起我注意的是,很多注冊表的訪問遇到了 access denied 的錯誤。而在文件訪問中,尚未發(fā)現(xiàn)該錯誤。為了精細(xì)地驗證,我對當(dāng)前記錄下的log進(jìn)行了篩選器的應(yīng)用。
應(yīng)用篩選后,我們可以看見所有相關(guān)的 Access Denied 的條目。當(dāng)時真實環(huán)境里的可以看見很多這樣的條目,因為很多服務(wù)都出現(xiàn)了無法啟動的故障,而撰寫本文時的實驗環(huán)境里,我只制造了 BFE 這一種服務(wù)的該問題。通過 Path 列,我們可以看見其具體的路徑為 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BFE\Parameters\Policy\Persistent . 右擊該條目,選擇 Jump To… ,注冊表編輯器便會被調(diào)用打開打開,并且自動定位到該鍵。我查看其權(quán)限設(shè)置,發(fā)現(xiàn)所有條目繼承于 Policy 鍵。
那我們就來看看該處的 Policy 鍵上的權(quán)限設(shè)置,與正常的計算機(jī)的同一位置的權(quán)限設(shè)置有何不同。
不難發(fā)現(xiàn),服務(wù)不能啟動(尤其是提示拒絕訪問)的直接原因是因為,該服務(wù)無權(quán)訪問注冊表的這個鍵。(通過 Process Monitor 可以看出,它實際上要訪問的是 Policy 的子鍵"Persistent"卻遭到拒絕)
要嘗試恢復(fù),那我們要做的就是至少在 Persistent 鍵及其子鍵/鍵值上授予 BFE 合適的訪問權(quán)限。為了一步到位,我做的是參照正常的系統(tǒng),將正常的 ACE 項在權(quán)限傳播的起始處——Policy 鍵上設(shè)置,并往下傳播。設(shè)置時,除了還原應(yīng)有的 BFE 的權(quán)限,還完全一致地將其他缺失權(quán)限補(bǔ)齊,將多余權(quán)限刪除,這樣可以避免一些額外的潛在問題。(例如權(quán)限仍過小或者過大)
值得注意的是,BFE 這個服務(wù)賬號不同于一般用戶賬號和組,所以直接鍵入 BFE 時間查不到名稱的。正確的做法是鍵入"NT Service\BFE"檢查名稱。
而默認(rèn)地,BFE 在 BFE 服務(wù)的注冊表項上的訪問權(quán)限是特殊的。雖然我們可以直接授予完全控制權(quán)限來解決該問題,但是我們最好還是參照 LUA 原則,跟系統(tǒng)默認(rèn)的一樣,將其設(shè)為特殊權(quán)限。特殊權(quán)限的具體項目如下圖所示:
好了,設(shè)置好并且應(yīng)用權(quán)限之后,再次點擊啟動服務(wù)按鈕,就可以看到該服務(wù)正常啟動了。
最后,對于該詭異案例,有幾個說明:
1. 究竟是什么操作導(dǎo)致了系統(tǒng)出現(xiàn)這樣的問題,讓諸多系統(tǒng)服務(wù)注冊表鍵權(quán)限變成非默認(rèn)值,至今尚不明確。據(jù)用戶稱,他就是出了個差,回來后就這樣了,其間沒有裝過什么軟件或者手動做過這種設(shè)置注冊表權(quán)限的危險操作。搜索互聯(lián)網(wǎng),很多人都有遇到此問題的經(jīng)歷,但是沒有哪個帖子能夠明確指出是什么操作引起了這個問題。如果您恰好有過此方面的研究,歡迎告訴我。
2. 事實上,該用戶最后重裝系統(tǒng)了,這也是我建議他做的。因為,該問題的發(fā)生,可能還伴有其他的一些未知的系統(tǒng)嚴(yán)重性更改,修復(fù)了注冊表權(quán)限,并且讓服務(wù)啟動后,不能確保他在該系統(tǒng)上,今后不會遇到其他的怪異問題。
3. 就像我遇到的這個真實案例一樣,該錯誤一旦發(fā)生,往往會伴有很多系統(tǒng)服務(wù)遇到此拒絕訪問的啟動問題。如果要應(yīng)用此方法全面修復(fù),那是非常耗費時間和精力的。這里給出一個能盡量加速解決此問題的思路:
話說當(dāng)年 NT 5.0 時代,可以通過系統(tǒng)自帶的 secedit 命令重置所有安全設(shè)置和權(quán)限,但是現(xiàn)在已然不行了。鑒于目前尚未發(fā)現(xiàn)任何 fix 程序能夠自動重置系統(tǒng)服務(wù)的默認(rèn)注冊表權(quán)限的,只能用以上4步進(jìn)行修復(fù)。如果您所遇到的情形中只有一兩項服務(wù)有此問題,那么完全可以不采用腳本的方式,而是采用 GUI 的工具去看服務(wù)以及手動修復(fù)權(quán)限設(shè)置。等我今后有空的話,會寫一個重置系統(tǒng)自帶服務(wù)對應(yīng)的注冊表權(quán)限的腳本。(貌似意義不太大)若您有高見,請不吝賜教。