運維別走,留下你的root權限
作為互聯網公司的后臺程序員,我們知道,線上服務器要給用戶提供穩定、可靠、快速的Web服務,所以公司一般都會把線上服務器隔離,設置防火墻,限制內網及辦公網絡對這些服務器的訪問。

公司對線上服務器做限制之后,內外網都只能訪問這些服務器的對外服務端口,例如http服務的80端口或REST服務的8080端口,而其他所有端口一律都會被防火墻攔截(ping端口除外)。我們無法ssh登錄到這些線上服務器從而修改配置、排查問題等。
幸運的是,雖然辦公網絡不能直接連接到線上服務器,但是公司還是提供了跳板機(jumper)來供我們使用。畢竟線上服務是可能出問題的,如果出問題,必然需要連接到服務器排查。這個跳板機相當于辦公網絡與線上服務器之間的一座橋梁。辦公電腦先連接到跳板機,然后再讓跳板機連接線上服務器,你在跳板機上執行的操作都會被記錄,公司要求這樣間接連到服務器,從而監控你在服務器上的操作。

我們用辦公電腦連接到跳板機,然后再連接服務器,這樣問題貌似都解決了、可以去診斷問題了。且慢!我們還發現自己的賬號只是普通用戶,沒有root權限,很多事情依然做不了。例如,需要使用root權限才能修改catalina.sh中的某些JVM選項。所以需申請root權限。
關于root權限,每家公司都有自己的規定。不知道其他公司是怎么規定的,我所在的公司為了不讓root密碼泄露出去,只提供sudo權限的申請渠道,絕不直接提供root密碼給程序員。因為有sudo權限之后,我們可以不用知道root密碼就切換到root身份(通過執行"sudo su")。在我所在的公司,后臺程序員如果需要sudo權限,那么需要提申請給運維,運維負責審批。而且,申請到的sudo權限有時間限制,等結束時間一到,運維就會立即收回sudo權限,非常的摳門。
但是我的這個運維好像極不愿意把sudo權限給后臺,完全不愿讓你多用兩天,即使你申請的是那種沒有接入線上流量、專用于調試的機器的sudo權限。只要你申請的使用時間稍微長一點,他就不批準,如圖所示。

為了工作,申請sudo/root權限還被拒了?郁悶。就是因為sudo/root權限的使用時間申請得長了一點,運維就不分配權限,有點過分。于是我只好縮短sudo權限的申請時間,改為只申請3天,這次他直接就批了。這個運維,這又是何必呢!
這次sudo權限算是申請下來了,但是等這次的sudo權限的結束時間到了以后,要用root 還要再去找運維申請,我覺得這很麻煩。雖然從管理的角度看,這是很正確的事,但是我知道自己不會干壞事啊。為了不想下次再去找運維申請權限,我就在想了,可不可以把臨時分配給我用3天的root權限緩存下來,不設置時間限制,讓我慢慢用?這個需求可以實現嗎?
稍微一想,顯然可以啊。既然都把sudo 權限給我了,那我不就是root了嗎,還有啥干不了的事情。而且方法有很多呢。本文根據Linux的基礎知識,一下子就整理出3種方法,把root權限緩存下來慢慢用,方便自己開發,再也不用看運維臉色啦(當然,不能告訴運維)。同時,這些方法也讓我深刻明白一個道理,root千萬不能給不受信任的人,一秒鐘都不行(我又能理解運維了)。
那么,看我是怎么緩存root權限的吧。首先,直接把root密碼改掉這種事情太絕了,而且容易暴露,不是本文要介紹的方法,不能這么干。我們要的是不修改root密碼并且等sudo權限過期之后,還可以切換到root的方法。
方法一:創建一個新用戶,把UID設為0
這是最簡單、最快的方法。Linux系統不是根據用戶名來判斷root用戶,而是根據用戶的UID是不是等于0來判斷root用戶的。既然我們不知道root密碼,那我們就再建立一個用戶,把UID設為0,這樣系統里面就多出來一個我們知道密碼的root用戶啦。只不過這個用戶的用戶名不是root。登錄服務器shell,輸入命令如下:

以上命令首先新建了一個普通用戶joker,然后我們編輯/etc/passwd這個文件,把我們新創建的joker用戶的UID和GID都改為0即可。

以上設置完成之后,我們以后就用su joker命令直接切換到root用戶啦。總結起來就一句話,用臨時sudo權限在系統里面安插一個不知名的root間諜。這種方法的隱蔽性其實不高。運維只要多看passwd文件,發現這個奇怪的joker用戶,把它刪掉,我們緩存下的root就沒有啦。不過,對于不勤奮工作的運維來說,即使是這么簡單的方法,都已經足夠了。我創建完這個用戶以后,根本沒人去看/etc/passwd,我的這個root用戶一直長期駐留。
另外,現在很多公司的服務器基本都是容器或虛擬機。如果這臺服務器實例被刪除的話,那我們手動創建的用戶自然也就沒有咯。不過,發布war包之類的上線操作一般不會導致刪除容器,所以發布完代碼之后,我們的joker(root)用戶還在。
方法二:在/etc/sudoers中給自己配一個權限
既然運維就是通過 sudo來管理root權限的,那我們也對sudo下手,給自己開一個永久免費的sudo權限不就好了嗎。不過要注意,我們配的sudo配置文件不要被運維的sudo配置文件覆蓋掉。另外,還要記得做得隱蔽點。
在Linux系統上,sudo的配置文件有/etc/sudoers這個文件,還有/etc/sudoers.d/目錄下的所有文件,兩個地方的文件格式相似。如果你是普通用戶且是第一次執行sudo,會遇到以下提示。

我遇到這個提示的時候,還以為這是運維設置的,嚇一跳。后來才知道,每個Linux系統都有上面的提示信息。執行sudo后,如果沒有權限,提示是下面這樣的:

所以,我們在/etc/sudoers.d/目錄下新建一個空白文件,例如joker,按照以下格式編輯,給自己用戶開一個sudo權限。

第一個字段是自己的用戶名;第二個字段標識允許遠程登錄的機器名,寫ALL就好了;第三個字段是允許切換到的用戶名,寫ALL就是允許切換到所有用戶;第四個字段是允許執行的命令,寫ALL允許執行所有命令。這個文件寫好保存以后,權限自動開通。如果覺得輸入密碼也麻煩,可以這樣寫:

方法三:修改su的配置
在Linux系統上,要想切換到root,最先想到的是su命令。Linux默認允許任何用戶執行su,但是需要知道目標用戶的密碼。有沒有不輸入密碼,允許普通用戶切換到root的方法呢?
分析su的man手冊之后,我發現su是通過調用PAM模塊來取得用戶身份的,并且su調用PAM的時候使用了一個策略配置文件,即/etc/pam.d/su。如果不修改這個配置文件(運維也沒有動過的話),根據默認配置,如果我們的用戶屬于admin用戶組或者wheel用戶組,那么就可以不輸入密碼就可以切換到root的權限。因此,解決方案來了,即把我們的用戶加入admin或wheel用戶組。
先打開/etc/group,看一下用戶組是admin還是wheel。

在我的系統上,用戶組是wheel,于是運行

加入了wheel用戶組之后,我這個用戶不用輸入密碼也能su切換到root啦。前面說過,默認情況下,PAM允許admin/wheel用戶組的用戶取得root用戶身份。這是建立在 /etc/pam.d/su 這個文件沒有被運維修改的前提之上的。假如是個狡猾的運維,把這里改掉了,那么加入admin/wheel的方法就行不通了。

上圖就是一個"狡猾"運維,把那兩行注釋掉了。不過,既然沒有刪掉,臨時拿到root權限的我們直接還原就好了。

從此以后,我不找運維也有root權限了,會不會被人發現?
結束語:假如你們公司的運維也不肯給root權限,而且還時不時拒絕sudo申請,又或者是只允許你使用sudo很短的一段時間,那么可以嘗試本文介紹的這3個方法。這些方法實現了只要運維給你用一次sudo,即使只允許執行一次,那也就是給你永久root。非常不錯。