一、問題發生、排查以及解決
某天H博士在登入B伺服器時發現一個嚴重的問題,問題是H博士在執行指令碼出現一個異常,這個異常是過去我執行指令碼只需輸入一次密碼,現在要輸入五六次,只有輸入五六次後才能正確執行完指令碼。這個問題非常嚴重。我記得那天ZH向我請教了幾個關於Linux授權的問題。而後第二天H博士就開始反饋這個異常。於是ZH先處理,一直找不到問題在哪,於是便叫我來,一同排查是什麼原因。
H博士那邊給我們提供一個方案,他懷疑是SSH金鑰失效導致的,於是我們按照H博士提供的方案一一執行,發現還是不行。
而且在驗證H博士提供的方案之前,我參考我之前寫過的文章:Linux遠端傳輸檔案免密碼
試驗開發伺服器,按照我這邊試驗的,A伺服器上的使用者可以免密登入B伺服器,而B伺服器上的使用者可以免密登入A伺服器,前提是將彼此ssh-keygen -t rsa 生成金鑰放入.ssh/authorized_keys即可。
我按照我之前寫過試了試,完全沒有問題。
由此排除了是金鑰的問題。
接著懷疑是許可權的原因,最後我給H博士經常使用的使用者授予最大許可權chmod 777或chown -R 使用者 資料夾。但發現仍解決不了這個問題。
最後ZH和我一時想不到有效的辦法,ZH就準備重灌系統了,先從B伺服器開始入手。
而我最初想著重灌太費勁了,主要是備份很多東西和安裝很多奇葩環境,一直在想如何解決這個問題。
某天靈感突然一來,明確我們的問題(登入某個使用者執行該使用者所屬目錄的指令碼需要輸入多次密碼),我使用root使用者新建了一個使用者,按照H博士之前提供的方案,切換到新使用者,執行相關命令,然後驗證是否需要輸入密碼,最後發現完全不要。我此時還沒有意識到是使用者組許可權問題。
為了解決這個問題,歸納一下,我試瞭如下方法:
- 認為是許可權問題,授予該使用者最大許可權;
- 認為是金鑰問題,使用該使用者執行重新生成金鑰步驟;
- 兩臺伺服器存放金鑰驗證免密(最初定位錯了問題,認為是兩臺伺服器需要互動操作);
- 重新新建使用者驗證是否免密;
- 修改ssh配置檔案。
最後均不能解決這個問題,後來我只能表示黔驢技窮,ZH也想不到更好的辦法,基本上搜尋引擎我們能搜的,能嘗試的都嘗試了,都不能解決這樣的問題,ZH還親自讀指令碼和執行指令碼一步步用echo輸出除錯,還是不能定位問題根源在哪。最後我們採用最後的方案,重灌系統,迴歸原來的環境。
ZH當時重複說了多次,我就僅僅動了一下使用者許可權,其它什麼都沒有動(這是一條非常關鍵的資訊,當時我並未重視起來,僅僅是表面的以為沒有許可權,授個權就行了)。
自到ZH重灌以後,再次授權,復現了這個問題,然後我叫他別動,我在此新建一個使用者,發現執行免密登入所需步驟後,可以不用輸入密碼。最後他再次快速重灌,什麼都沒有動,然後我使用H博士常使用的使用者驗證是否輸入密碼(在此安裝免密步驟執行了),最後發現不要,問題就這麼解決了。
後來過了一段時間,ZH再次給我反饋有這麼一個問題,我問他做了什麼操作,他回答到H博士經常操作的是A使用者,但是我們部署微服務的是放在B使用者上,B使用者需要讀A使用者下的某個檔案,於是他給B使用者遞迴授權A使用者目錄,最後再次驗證A使用者是否需要輸入密碼,最後發現需要輸入了。最後我使用ll命令檢視了/home下的使用者許可權,發現有問題,譬如/home/A的使用者和使用者組應該是A A,而不是A B這樣的,此次我發現A B。最後我斷定一定是A使用者的許可權組不明確 生成的金鑰與許可權組有非常大的關聯,如果許可權組變了,金鑰是無法識別的,於是造成A使用者執行指令碼時需要輸入多次密碼。
經常多次試驗,果真是這個原因。
但因為B使用者上部署的微服務程式需要訪問A使用者下的目錄,這個問題不解決會有很大的影響,最後我們的方案是,/home下的A使用者和B使用者各自做各自的事情,不能交叉,例如A使用者除了執行指令碼外,還可以執行部署微服務,指令碼執行每天人為地固定執行,而程式是自動化的,B使用者僅僅是部署,完全沒有這個必要,於是A使用者只做兩件事情,一件事情是執行指令碼,另外一件事情是部署微服務,因為後續指令碼將會自動化,所以A使用者最終的職責就是部署微服務,由此我們推出了一個新的原則,叫做使用者專一原則(一個使用者只做一件事情或一類事情)。
二、總結
這個問題說大不大,說小也不小,足足磨了我們半個多月的時間,當然了,半個多月雖然還有其它的開發任務,但這個問題卡在這,讓人著實不爽。雖然最終解決了,但我仍不高興,因為明明我可以在幾個小時內或不用幾個小時就能快速解決這個問題,但最後卻足足耽擱了半個多月。
1.之後我在想為什麼這個問題這麼長才定位到原因?
我想關鍵在於問題復現步驟上,首先我沒有與ZH仔細溝通,詢問他做了什麼操作(沒有具體到原來是給B使用者授予A使用者的許可權),而僅僅是得到一個大致不精確的回答了授了一下許可權。如果試想當初我追根刨底,具體到執行了什麼命令,我想用不了這麼長時間就能快速解決,因為問題本身並不難。
由此推出,原因在於我沒有仔細詢問ZH在該伺服器上做了哪些操作,執行哪些具體命令,導致我錯誤的定位問題,如掃雷式排查,一個個試。
可見,遇到問題並不可怕,可怕的是沒有找問題發現者,仔細詢問是如何發現這個問題的,以及在發現這個問題時做了那些操作(因為這些操作可能是導致問題發生的引子)。
2.以後將如何避免這樣類似的問題?
我總結出如下兩個原則:
- (1)面對他人發現的問題,首先要仔細詢問他是如何發現的或在此做了些什麼(非常關鍵,需要重點留意),在與問題發現者的不斷溝通中,得到更多的資訊,這些資訊實際上有助於問題的正確定位(這一刻我明白了磨刀不誤砍柴工);
- (2)在(1)的基礎上,根據從(1)所知的資訊和結合以往的經驗,找到問題的可能原因,定位問題並解決,另外必要時可請教相關專業人士提供幫助,在請教前,記得將問題陳述清楚(如問題是如何發現的、問題發現前做了哪些事情、為了解決這個問題根據問題可能原因嘗試用哪些方法去解決等)。