透過安全殼層金鑰從版本存取 GitHub

本教學課程示範如何搭配使用 Secret Manager 和 Cloud Build,從建構作業存取私人的 GitHub 存放區。Secret Manager 是一項 Google Cloud 服務,可安全地儲存 API 金鑰、密碼和其他機密資料。

建立安全殼層金鑰

  1. 開啟終端機視窗。

  2. 建立名為 workingdir 的新目錄,然後前往該目錄:

    mkdir workingdir
    cd workingdir
    
  3. 建立新的 GitHub 安全殼層金鑰,其中 github-email 是您的 GitHub 電子郵件地址:

    ssh-keygen -t rsa -b 4096 -N '' -f id_github -C github-email
    

    這個指令會建立新的 SSH 金鑰 workingdir/id_github,但不會為 SSH 金鑰設定密碼片語。 如果安全殼層金鑰受密碼保護,Cloud Build 無法使用該金鑰。

將私人安全殼層金鑰儲存在 Secret Manager

建立安全殼層 (SSH) 金鑰組時,系統會在您的環境中建立一個 id_github 檔案。由於任何人都可以使用這個檔案對您的帳戶進行驗證,因此您必須先將該檔案儲存在 Secret Manager 中,再將其用於建構。

如要將 SSH 金鑰儲存在 Secret Manager,請按照下列步驟操作:

  1. 前往 Google Cloud 控制台的 Secret Manager 頁面:

    前往 Secret Manager 頁面

  2. 在「Secret Manager」(密鑰管理工具) 頁面中,按一下「Create Secret」(建立密鑰)

  3. 在「建立密鑰」頁面的「名稱」下方,輸入密鑰名稱。

  4. 在「Secret value」(密鑰值) 欄位中,按一下「Upload」(上傳),然後上傳 workingdir/id_github 檔案。

  5. 請勿變更「區域」部分。

  6. 按一下「建立密鑰」按鈕。

這會將 id_github 檔案上傳至 Secret Manager。

將公開安全殼層金鑰新增至私人存放區的部署金鑰

  1. 登入 GitHub

  2. 依序點選右上角的個人資料相片和「你的個人資料」

  3. 在個人資料頁面點選「Repositories」,然後點選存放區的名稱。

  4. 點選存放區的「Settings」

  5. 點選側欄的「Deploy Keys」,然後點選「Add deploy key」

  6. 提供標題,然後貼上 workingdir/id_github.pub 的公開安全殼層金鑰。

  7. 如要讓這個金鑰擁有存放區的寫入權限,請選取「Allow write access」。具備寫入權限的部署金鑰可讓部署作業推送至存放區。

  8. 按一下「Add key」

  9. 刪除磁碟中的安全殼層金鑰:

    rm id_github*
    

授予權限

您必須授予服務帳戶 Secret Manager 的存取權,才能用於建構作業。

  1. 在 Google Cloud 控制台中,前往「Cloud Build 權限」頁面:

    前往「Permissions」(權限)

  2. 從下拉式清單中,選取要變更角色的服務帳戶。

  3. Secret Manager Secret Accessor 角色的狀態設為「Enable」(啟用)

將公開安全殼層金鑰新增至已知主機

大多數電腦都含有名為 known_hosts 的檔案,其中包含遠端主機的已知金鑰。首次連線至遠端主機時,系統通常會從遠端主機收集金鑰,但您也可以手動新增金鑰。這個檔案中的金鑰用於驗證遠端主機的身分,並防範冒用身分的情況。

如要讓 Cloud Build 連線至 GitHub,必須將公開安全殼層金鑰新增至 Cloud Build 建構環境的 known_hosts 檔案。方法是將金鑰新增至暫時的 known_hosts.github 檔案,然後將 known_hosts.github 的內容複製到 Cloud Build 建構環境中的 known_hosts 檔案。

workingdir 目錄中,建立名為 known_hosts.github 的檔案,並將公開安全殼層金鑰加入這個檔案:

ssh-keyscan -t rsa github.com > known_hosts.github

在下一個設定建構的章節中,您會在 Cloud Build 設定檔中新增操作說明,將 known_hosts.github 的內容複製到 Cloud Build 建構環境中的 known_hosts 檔案。

設定建構

如要設定版本:

  1. 建立名為 cloudbuild.yaml 的建構設定檔,其中包含兩個步驟:第一個 gcloud 步驟會存取 Secret Manager 中的 SSH 金鑰,並將其儲存為名為 ssh 的磁碟區中的 id_rsa,以及 known_hosts.github 的副本。磁碟區用於在建構步驟之間保存檔案。第二個 git 步驟會使用 id_rsa 中的金鑰,連線至 git@github.com:git-username/git-repository 的存放區。

    # Access the id_github file from Secret Manager, and setup SSH
    steps:
    - name: 'gcr.io/cloud-builders/git'
      secretEnv: ['SSH_KEY']
      entrypoint: 'bash'
      args:
      - -c
      - |
        echo "$$SSH_KEY" >> /root/.ssh/id_rsa
        chmod 400 /root/.ssh/id_rsa
        cp known_hosts.github /root/.ssh/known_hosts
      volumes:
      - name: 'ssh'
        path: /root/.ssh
    
    # Clone the repository
    - name: 'gcr.io/cloud-builders/git'
      args:
      - clone
      - --recurse-submodules
      - git@github.com:GIT_USERNAME/GIT_REPOSITORY
      volumes:
      - name: 'ssh'
        path: /root/.ssh
    
    availableSecrets:
      secretManager:
      - versionName: projects/PROJECT_ID/secrets/SECRET_NAME/versions/latest
        env: 'SSH_KEY'
    

將上述指令中的預留位置值替換為下列值:

  • GIT_USERNAME:存放區擁有者的 GitHub 使用者名稱。
  • GIT_REPOSITORY:要存取的 GitHub 存放區名稱。
  • PROJECT_ID:您儲存密鑰的 Google Cloud 專案 ID。
  • SECRET_NAME:您在 Secret Manager 中建立的密鑰名稱。

如要瞭解上述程式碼片段中使用的 YAML 多行字串,請參閱 YAML 多行

提交建構

如要提交建構作業,請執行下列指令:

gcloud builds submit --config=cloudbuild.yaml .

輸出結果會與下列內容相似:

Creating temporary tarball archive of 3 file(s) totalling 4.1 KiB before compression.
Uploading tarball of [.] to [gs://[PROJECT-ID]_cloudbuild/source/1504288639.02---.tgz]
Created [https://cloudbuild.googleapis.com/v1/projects/[PROJECT-ID]/builds/871b68bc---].
Logs are available at [https://console.cloud.google.com/cloud-build/builds/871b68bc---?project=[PROJECT-ID]].
----------------------------- REMOTE BUILD OUTPUT ------------------------------
starting build "871b68bc-cefc-4411-856c-2a2b7c7d2487"

FETCHSOURCE
Fetching storage object: gs://[PROJECT-ID]_cloudbuild/source/1504288639.02---.tgz#1504288640827178
Copying gs://[PROJECT-ID]_cloudbuild/source/1504288639.02---.tgz#1504288640827178...
/ [1 files][  3.9 KiB/  3.9 KiB]
Operation completed over 1 objects/3.9 KiB.
BUILD
Step #0: Already have image (with digest): gcr.io/cloud-builders/gcloud
Starting Step #0
Finished Step #0
Step #1: Already have image (with digest): gcr.io/cloud-builders/git
Starting Step #1
Step #1: # github.com SSH-2.0-libssh_0.7.0
Finished Step #1
Step #2: Already have image (with digest): gcr.io/cloud-builders/git
Starting Step #2
Step #2: Cloning into '[REPOSITORY-NAME]'...
Step #2: Warning: Permanently added the RSA host key for IP address 'XXX.XXX.XXX.XXX' to the list of known hosts.
Finished Step #2
PUSH
DONE
-----------------------------------------------------------------------------------------------------------------

ID                                    CREATE_TIME                DURATION  SOURCE                                                                              IMAGES  STATUS
871b68bc-cefc-4411-856c-2a2b7c7d2487  XXXX-XX-XXT17:57:21+00:00  13S       gs://[PROJECT-ID]_cloudbuild/source/1504288639.02---.tgz  -                                 SUCCESS