Jenkins的憑證管理
什么是憑證?
憑證(cridential)是Jenkins進行受限操作時的憑據。比如使用SSH登錄遠程機器時,用戶名和密碼或SSH key就是憑證。而這些憑證不可能以明文寫在Jenkinsfile中。Jenkins憑證管理指的就是對這些憑證進行管理。
為了最大限度地提高安全性,在Jenkins master節點上對憑證進行加密存儲(通過Jenkins實例ID加密),只有通過它們的憑證ID才能在pipeline中使用,並且限制了將證書從一個Jenkins實例復制到另一個Jenkins實例的能力。
也因為所有的憑證都被存儲在Jenkins master上,所以在Jenkins master上最好不要執行任務,以免被pipeline非法讀取出來。那么在哪里執行pipeline呢?應該分配到Jenkins agent上執行。
創建憑證
首先確保當前用戶有添加憑證的權限。我們使用超級管理員的身份登錄。單擊Jenkins首頁左側的Credentials→System
然后單擊“Global credentials (unrestricted)”鏈接,再單擊“Add Credentials”
憑證的類型
Jenkins默認支持以下憑證類型:Secret text、Username with password、Secret file、SSHUsername with private key、Certificate:PKCS#12、Docker Host CertificateAuthentication credentials。
Secret text是一串需要保密的文本,比如GitLab的API token。
Username with password指用戶和密碼憑證。
Secret file指需要保密的文本文件。使用Secret file時,Jenkins會將文件復制到一個臨時目錄中,再將文件路徑設置到一個變量中。構建結束后,所復制的Secret file會被刪除。
SSH Username with private key指一對SSH用戶名和密鑰。
添加憑證后,安裝Credentials Binding Plugin插件,通過其提供的withCredentials步驟就可以在pipeline中使用憑證了。
Secret text
Username with password
Secret file
SSH Username with private key
sshUserPrivateKey函數還支持以下參數。
• usernameVariable:SSH用戶名的變量名。
• passphraseVariable:SSH key密碼的變量名。
credentials helper方法使用憑證
Secret text:
AWS-SECRET-KEY-ID和AWS-SECRET-ACCESS-KEY是我們預先定義的憑證ID。creden-tials方法將憑證的值賦給變量后,我們就可以像使用普通環境變量一樣使用它們了,如:echo"${AWS ACCESS KEY ID}"。
Username with password:
與 Secret text 不同的是,我們需要通過 BITBUCKET CREDS USR 拿到用戶名的值,通過BITBUCKET CREDS PSW拿到密碼的值。而變量BITBUCKET CREDS的值則是一個字符串,格式為:<用戶名>:<密碼>。
Secret file:
credentials helper方法只支持Secret text、Username with password、Secretfile三種憑證。
使用HashiCorp Vault
(1)安裝HashiCorp Vault插件
(2)添加Vault Token憑證
(3)配置Vault插件
(4) 在pipeline中讀取
我們可以在environment和steps中使用vault步驟。推薦在environment中使用。
vault步驟的參數如下:
• path,存儲鍵值對的路徑。
• key,存儲內容的鍵。
• vaultUrl(可選),vault服務地址。
• credentialsId(可選),vault服務認證的憑證。
如果不填vaultUrl與credentialsId參數,則使用系統級別的配置。
在Jenkins日志中隱藏敏感信息
如果使用的是credentials helper方法或者withCredentials步驟為變量賦值的,那么這個變量的值是不會被明文打印到Jenkins日志中的。除非使用以下方法:
在沒有使用credential的場景下,我們又該如何在日志中隱藏變量呢?可以使用Masked Pass-word插件。通過該插件提供的包裝器,可以隱藏我們指定的敏感信息。
初次使用 Masked Password 插件很容易以為是使用 s1 和 s2 作為變量的,如 echo"被隱藏的密文:${s1} 和 ${s2}"。實際上,var參數只是用於方便在自由風格的Jenkins項目中區分不同的需要隱藏的密文。在pipeline中使用,它就沒有存在的意義了。但是即使這樣也不能省略它,必須傳一個值。password參數傳的是真正要隱藏的密文。
那么,為什么echo "secret1"這條語句中並沒有使用預定義的變量,secret1也會被隱藏呢?這是由Masked Password插件的實現方式決定的。
Jenkins 提供了 ConsoleLogFilter 接口,可以在日志打印階段實現我們自己的業務邏輯。Masked Password 插件實現了 ConsoleLogFilter 接口,然后利用正則表達式將匹配到的文本replaceAll成********。
MaskPasswordsBuildWrapper包裝器除了支持varPasswordPairs參數,還支持varMaskRegexes參數,使用自定義的正則表達式匹配需要隱藏的文本。寫法如下:
通過Masked Password插件還可以設置全局級別的密文隱藏,在Manage Jenkins→ConfigureSystem頁中可以找到,具體配置如圖