《避免讓持續(xù)集成服務(wù)器成為一個(gè)安全隱患!》要點(diǎn):
本文介紹了避免讓持續(xù)集成服務(wù)器成為一個(gè)安全隱患!,希望對(duì)您有用。如果有疑問(wèn),可以聯(lián)系我們。
作者:顧宇 thoughtworks高級(jí)咨詢(xún)師
最近臨時(shí)接手了一個(gè)客戶(hù)測(cè)試環(huán)境和產(chǎn)品環(huán)境的維護(hù)工作.接手的客戶(hù)資產(chǎn)里包含:代碼庫(kù),生產(chǎn)環(huán)境主機(jī),測(cè)試環(huán)境主機(jī)以及搭建在測(cè)試環(huán)境主機(jī)上的CI(基于Jenkins).這個(gè)CI可以用來(lái)部署測(cè)試環(huán)境和生產(chǎn)環(huán)境的應(yīng)用.
不久,接到了客戶(hù)的一個(gè)維護(hù)請(qǐng)求:把最新的生產(chǎn)環(huán)境數(shù)據(jù)同步到測(cè)試環(huán)境里.
這個(gè)維護(hù)工作需要通過(guò)SSH登錄到測(cè)試環(huán)境主機(jī)上進(jìn)行操作.測(cè)試主機(jī)是通過(guò)authorized_keys進(jìn)行 SSH 認(rèn)證的,因此沒(méi)有用戶(hù)名和密碼.這樣有兩個(gè)好處:一方面無(wú)需生產(chǎn)環(huán)境用戶(hù)名密碼.一方面可以按需吊銷(xiāo)不再用的客戶(hù)端.這樣可以避免密碼泄露.所以我需要把自己的ssh public key交給管理員,讓他把我的 key 加到可訪問(wèn)列表里.
悲劇的是,管理員告訴我他的 key 因?yàn)楦鼡Q電腦的關(guān)系沒(méi)有及時(shí)更新.所以,他也登錄不上去了.而且之前所有的管理員的 key 都失效了.我手上只有CI的管理員的用戶(hù)名和密碼,于是一個(gè)邪惡的想法就誕生了:
既然 CI 可以執(zhí)行腳本,那么我是否可以通過(guò)CI把我的key注入進(jìn)去?
于是我用Execute Shell的Job變成了我的命令行,通過(guò)CI運(yùn)行日志得知了宿主用戶(hù)的文件目錄信息.然后把自己的ssh public key加到了登錄列表里(此處省略敏感信息):
sudo sh -c “cp ~/.ssh/authorized_keys ~/.ssh/authorized_keys.bak”
sudo sh -c “echo ‘{你的ssh public key}’ >> ~/.ssh/authorized_keys”
It works !
我成功的登錄了機(jī)器,但這卻暴露了一個(gè)問(wèn)題:CI 有可能會(huì)成為一個(gè)安全隱患.
首先,CI 可以執(zhí)行代碼.這就意味著它有可能執(zhí)行有害代碼.
其次,CI 缺乏足夠的用戶(hù)鑒權(quán),這很有可能導(dǎo)致未授權(quán)用戶(hù)訪問(wèn).
那么,如何構(gòu)建一個(gè)更安全的CI服務(wù)器?
“神操縱著萬(wàn)物,你感覺(jué)得到他,但永遠(yuǎn)看不見(jiàn)他.” ——《圣經(jīng)·希伯來(lái)書(shū)11:27》
在服務(wù)器的世界里,root用戶(hù)就是神,具有至高的權(quán)力和力量.如果有人獲得了”神力“,后果可能不堪設(shè)想.
無(wú)論是Web服務(wù)器,還是CI服務(wù)器.都是這個(gè)世界里的二等公民,權(quán)限和力量都應(yīng)該受到約束.執(zhí)行的時(shí)候應(yīng)該“
此外,應(yīng)該極力避免sudo的濫用,尤其是對(duì)那些從外部訪問(wèn)的用戶(hù).很多情況下,為了操作方便,很多用戶(hù)都有sudo的權(quán)限.但這恰恰造成了低權(quán)限用戶(hù)提升自己的訪問(wèn)權(quán)限進(jìn)行有害操作.
在上述的故事里,因?yàn)闆](méi)有對(duì)Jenkins的主機(jī)用戶(hù)做有效的隔離,導(dǎo)致了我可以用sudo注入自己的key獲得機(jī)器的訪問(wèn)權(quán)限.
因?yàn)镃I會(huì)執(zhí)行腳本或運(yùn)行程序,而這些程序和腳本極有可能是不安全的.所以,CI任務(wù)應(yīng)該在隔離的安全沙盒中執(zhí)行,例如:受限的用戶(hù),受限的權(quán)限,受限的空間.
在上述的故事里,我就通過(guò)CI執(zhí)行了一段不安全的腳本成功獲得了登錄主機(jī)的權(quán)限.
如果這些任務(wù)執(zhí)行在隔離并受控的Docker容器里,那么會(huì)安全得多.
也可以考慮采用TravisCI這樣的第三方CI服務(wù)來(lái)保證安全性.
在上述的故事里,因?yàn)槿狈τ行У膫浞輽C(jī)制,導(dǎo)致了所有人都失去了對(duì)主機(jī)的訪問(wèn).此外,我在修改authorized_keys的時(shí)候先進(jìn)行了備份.這樣,如果我注入失敗,還可以還原.
這里的備份,不光是對(duì)配置,數(shù)據(jù)的備份,還有崗位的備份.
如果有備份的管理員,完全不會(huì)出現(xiàn)這種事情.
如果有備份QA服務(wù)器,完全可以不需要當(dāng)前的QA服務(wù)器.
在做任何變更前,都應(yīng)該做好備份以及還原的準(zhǔn)備.因?yàn)槿魏巫兏紩?huì)帶來(lái)“蝴蝶效應(yīng)”.
但是,光備份是不夠的.如果備份不能有效還原,那和沒(méi)有備份沒(méi)有什么區(qū)別.所以,要定時(shí)的進(jìn)行備份恢復(fù)測(cè)試.確保備份在各種情況下可用.
上述的CI是暴露在互聯(lián)網(wǎng)中的,任何一個(gè)人訪問(wèn)到這個(gè)站點(diǎn),通過(guò)一定程度的密碼破解,就可以獲得這個(gè)CI的訪問(wèn)控制權(quán)限.從而可以做出上述的操作.
所以,有了用戶(hù)名和密碼,并不一定是可信用戶(hù).所以需要通過(guò)更多的手段,諸如手機(jī)短信驗(yàn)證碼或者第三方認(rèn)證集成來(lái)驗(yàn)證用戶(hù)的身份.
試想一下,如果上述的例子我并沒(méi)有服務(wù)器的訪問(wèn)權(quán)限.而是通過(guò)提交未經(jīng)審查的代碼自動(dòng)運(yùn)行測(cè)試腳本.實(shí)際上也會(huì)造成同樣的效果.
有時(shí)候我們會(huì)為了方便,讓CI自動(dòng)觸發(fā)測(cè)試.但是,恰恰是這種“方便”,卻帶來(lái)了額外的安全隱患.而這樣的方便,不光方便了自己,也方便了惡意入侵者.
所以,不能為了方便而留下安全隱患.在關(guān)鍵操作上設(shè)置為手動(dòng)操作,并通過(guò)一定的機(jī)制保證關(guān)鍵操作的可靠性才是最佳實(shí)踐.
采用Sibling的方式在Docker里運(yùn)行CI任務(wù).
賬戶(hù)密碼管理統(tǒng)一采用LDAP認(rèn)證,如果過(guò)期則從外部修改.
CI的登錄權(quán)限和其它的認(rèn)證方式(比如GItHub,Okta等)集成起來(lái).并用組限制登錄.
對(duì)于生產(chǎn)環(huán)境的CI,通過(guò)更加細(xì)粒度的權(quán)限限制來(lái)隔離一些危險(xiǎn)操作.
不少CI軟件的官方都提供了最佳實(shí)踐以及安全指南幫助我們更好的構(gòu)建CI服務(wù)器.請(qǐng)務(wù)必在構(gòu)建CI前閱讀并理解這些安全實(shí)踐和措施,并遵照安全最佳實(shí)踐構(gòu)建CI服務(wù)器:
Jenkins最佳實(shí)踐:https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Best+Practices
Jenkins官方安全指南:https://wiki.jenkins-ci.org/display/JENKINS/Securing+Jenkins
上面提到了太多的如果.如果這些“如果”能發(fā)生在事前,這些問(wèn)題就不會(huì)產(chǎn)生.CI本身是開(kāi)發(fā)的最佳實(shí)踐,但如果缺乏安全的意識(shí),一味的追求方便和高效,則會(huì)帶來(lái)很大的安全隱患.技通過(guò)一些簡(jiǎn)單而基礎(chǔ)的措施和手段,我們就能大大的減少安全隱患.
轉(zhuǎn)載請(qǐng)注明本頁(yè)網(wǎng)址:
http://www.fzlkiss.com/jiaocheng/2374.html