GitHub 작업에서 비밀을 복구하는 방법

이 블로그 게시물에서는 GitHub Actions와 같은 CI/CD 서비스에서 암호를 복구하는 방법을 공유합니다.

여기 계시다면 비밀이 *** 로 CI/CD 로그에서 숨겨져 있다는 것을 이미 알고 계실 것입니다. 예를 들면 다음과 같습니다.

jobs:
  openssl:
    name: Recover With OpenSSL
    runs-on: ubuntu-20.04
    steps:
      - env:
          MY_CLIENT_SECRET: ${{ secrets.MY_CLIENT_SECRET }}
        run: |
          echo "MY_CLIENT_SECRET (***)     = ${MY_CLIENT_SECRET}"



# Output
MY_CLIENT_SECRET (***)     = ***


위의 내용은 현재 귀하가 처한 상황이기 때문에 그다지 도움이 되지 않습니다.

빠르고 더티(위험)



개인 리포지토리의 경우 base64을 사용하여 비밀을 CI/CD 서비스 로그에 인쇄하기 전에 인코딩할 수 있습니다. 이렇게 하면 GitHub Actions가 *** 로 비밀을 숨기지 않습니다. 그런 다음 인코딩된 값을 복사하고 로컬에서 디코딩합니다.

name: Recovering secrets

# Assumption:
# You've created the following GitHub secrets in your repository:
# MY_CLIENT_ID - encode/decode with base64 - useful for private repositories

on:
  push:
  workflow_dispatch:

jobs:
  base64:
    name: Recover With Base64
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/checkout@v3
      - env:
          MY_CLIENT_ID: ${{ secrets.MY_CLIENT_ID }}
        run: |
          echo "MY_CLIENT_ID (***)    = ${MY_CLIENT_ID}"
          echo "MY_CLIENT_ID (base64) = $(echo ${MY_CLIENT_ID} | base64)"
          echo "Copy the above value, and then execute locally:"
          echo "echo PASTE_HERE | base64 -D"




위의 방법은 누구나 비밀을 해독할 수 있으므로 위험하므로 공개 저장소의 경우에는 사용하지 않습니다. 그리고 인쇄된 인코딩 값이 c29tZS1jbGllbnQtaWQtdmFsdWUK라고 가정할 때 매우 위험한 이유에 대한 증거가 있습니다.

echo c29tZS1jbGllbnQtaWQtdmFsdWUK | base64 -D
# some-client-id-value


방금 전 세계에 MY_CLIENT_ID를 노출했습니다 ... 무서워요.

CICD 서비스에서 비밀을 복구하는 방법



외부 세계에 노출하지 않고 CICD 시스템에서 비밀을 복구하는 가장 좋은 방법은 비밀을 CI/CD 로그에 인쇄하기 전에 암호화하는 것입니다.

name: Recovering secrets

# Assumption:
# You've created the following GitHub secrets in your repository:
# MY_CLIENT_SECRET - encrypt/decrypt with openssl - useful for public and private repositories
# MY_OPENSSL_PASSWORD - used to protect secrets
# MY_OPENSSL_ITER - Use a number of iterations on the password to derive the encryption key.
#                   High values increase the time required to brute-force the resulting file.
#                   This option enables the use of PBKDF2 algorithm to derive the key.

on:
  push:
  workflow_dispatch:

jobs:
  openssl:
    name: Recover With OpenSSL
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/checkout@v3
      - env:
          MY_CLIENT_SECRET: ${{ secrets.MY_CLIENT_SECRET }}
          MY_OPENSSL_PASSWORD: ${{ secrets.MY_OPENSSL_PASSWORD }}
          MY_OPENSSL_ITER: ${{ secrets.MY_OPENSSL_ITER }}
        run: |
          echo "MY_CLIENT_SECRET (***)     = ${MY_CLIENT_SECRET}"
          echo "MY_CLIENT_SECRET (openssl) = $(echo "${MY_CLIENT_SECRET}" | openssl enc -e -aes-256-cbc -a -pbkdf2 -iter ${MY_OPENSSL_ITER} -k "${MY_OPENSSL_PASSWORD}")"
          echo "Copy the above value, and then execute locally:"
          echo "echo PASTE_HERE | openssl base64 -d | openssl enc -d -pbkdf2 -iter \$MY_OPENSSL_ITER -aes-256-cbc -k \$MY_OPENSSL_PASSWORD"




위의 문자열U2FsdGVkX1+6/+7bvNG/Ga7siAI994FkMUn5Njzn4zyNwvf8qM3MY0MMmd9sCFvz을 해독하는 유일한 방법은 iterpassword 의 올바른 수를 사용하는 것입니다. 그렇지 않으면 brute-force attack 을 사용해야 합니다. 행운을 빕니다 :)

내 로컬 컴퓨터에서 위의 값을 해독한 방법은 다음과 같습니다.

echo U2FsdGVkX1+CeN0/ScQLZGU8f0ix86fh1oLJg/1M+o2lbCM+pBA8BIUCbkHMCjRZ \
| openssl base64 -d \
| openssl enc -d -pbkdf2 -iter $MY_OPENSSL_ITER -aes-256-cbc -k $MY_OPENSSL_PASSWORD


마지막 말


.github/workflows/recover-github-secrets.yml 와 같이 CI/CD(GitHub) 비밀을 복구하기 위한 별도의 워크플로를 만든 다음 워크플로를 실행한 다음 비밀 복구를 완료하면 해당 로그를 삭제하는 것이 좋습니다.



참조


  • An example of how the above YAML files are executed in GitHub Actions
  • GitHub Actions full YAML example of using base64 and openssl for recovering GitHub secrets
  • 좋은 웹페이지 즐겨찾기