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