GitLab CI/CDでSSHキーを使う
GitLabには現在、ビルド環境(GitLab Runnerが動作する環境)でSSHキーを管理するためのビルトインサポートがありません。
SSHキーを使いたいときに使ってください:
- 内部サブモジュールのチェックアウト。
- パッケージマネージャを使って非公開パッケージをダウンロードします。例えば、Bundler。
- アプリケーションを自分のサーバーやHerokuなどにデプロイします。
- ビルド環境からリモートサーバーにSSHコマンドを実行します。
- ビルド環境からリモートサーバーへのファイルのRsync。
上記に心当たりがある場合は、SSHキーが必要な可能性が高いです。
最も広くサポートされている方法は、.gitlab-ci.yml
を拡張することで、ビルド環境にSSHキーを注入することです。これはどんなタイプのExecutor(例えばDockerやShellなど)でも動作するソリューションです。
どのように動作するか
- で新しいSSHキー・ペアをローカルに作成します。
ssh-keygen
- 秘密鍵をファイルタイプのCI/CD変数としてプロジェクトに追加します。
-
ssh-agent
during jobを実行して秘密鍵をロードします。 - 公開鍵をアクセスしたいサーバーにコピーするか(通常は
~/.ssh/authorized_keys
)、非公開の GitLab リポジトリにアクセスする場合はデプロイ鍵として追加します。
以下の例では、ssh-add -
コマンドは$SSH_PRIVATE_KEY
の値をジョブログに表示しませんが、デバッグログを有効にすれば表示される可能性があります。パイプラインの可視性も確認しておきましょう。
Dockerエクゼキュータ使用時のSSHキー
CI/CDジョブがDockerコンテナ内で実行され(環境が封じ込められていることを意味します)、コードを非公開サーバにデプロイしたい場合、それにアクセスする方法が必要です。この場合、SSHキーペアを使うことができます。
-
まずSSHキーペアを作成する必要があります。詳しくは、SSHキーを生成する手順を参照してください。SSH キーにパスフレーズを追加しないでください。
before_script
がパスフレーズを要求します。 -
新しいファイルタイプのCI/CD変数を作成します。Keyとして
SSH_PRIVATE_KEY
という名前を入力し、Valueフィールドに先ほど作成した_秘密_鍵の内容を貼り付けます。 -
before_script
アクションで.gitlab-ci.yml
を変更します。以下の例では Debian ベースのイメージを想定しています。必要に応じて編集してください:before_script: ## ## Install ssh-agent if not already installed, it is required by Docker. ## (change apt-get to yum if you use an RPM-based image) ## - 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )' ## ## Run ssh-agent (inside the build environment) ## - eval $(ssh-agent -s) ## ## Give the right permissions, otherwise ssh-add will refuse to add files ## Add the SSH key stored in SSH_PRIVATE_KEY file type CI/CD variable to the agent store ## - chmod 400 "$SSH_PRIVATE_KEY" - ssh-add "$SSH_PRIVATE_KEY" ## ## Create the SSH directory and give it the right permissions ## - mkdir -p ~/.ssh - chmod 700 ~/.ssh ## ## Optionally, if you will be using any Git commands, set the user name and ## and email. ## # - git config --global user.email "user@example.com" # - git config --global user.name "User name"
before_script
はデフォルトまたはジョブごとに設定できます。 -
非公開サーバーのSSHホスト鍵が検証されていることを確認してください。
-
最後のステップとして、最初のステップで作成した_公開_鍵をビルド環境内からアクセスしたいサービスに追加します。GitLab の非公開リポジトリにアクセスする場合は、それをデプロイ鍵として追加する必要があります。
これで完了です!これで、ビルド環境で非公開サーバーやリポジトリにアクセスできるようになりました。
Shellエクゼキュータ使用時のSSHキー
DockerではなくShell Executorを使う場合は、SSHキーを設定する方が簡単です。
GitLab RunnerがインストールされているマシンからSSHキーを生成し、このマシンで実行されるすべてのプロジェクトにそのキーを使うことができます。
-
まず、ジョブを実行するサーバーにサインインします。
-
次に、ターミナルから
gitlab-runner
ユーザーとしてサインインします:sudo su - gitlab-runner
-
SSHキーを生成する手順に従って、SSHキーペアを生成します。SSH キーにパスフレーズを追加しないでください。
before_script
がパスフレーズを要求します。 -
最後のステップとして、先ほど作成した_公開_鍵をビルド環境からアクセスしたいサービスに追加します。GitLab の非公開リポジトリにアクセスする場合は、デプロイ鍵として追加する必要があります。
鍵を生成したら、リモートサーバーにサインインしてフィンガープリントを受け取ります:
ssh example.com
GitLab.com のリポジトリにアクセスするには、git@gitlab.com
を使います。
SSH ホストキーの検証
中間者攻撃(man-in-the-middle attack)に狙われていないことを確認するために、非公開サーバ自身の秘密鍵を確認するのは良い習慣です。もし何か不審なことが起きたら、ジョブが失敗するのでそれに気づくでしょう(公開キーが一致しないとSSH接続は失敗します)。
サーバーのホスト鍵を調べるには、信頼できるネットワークから(理想的には非公開サーバー自身から)ssh-keyscan
コマンドを実行します:
## Use the domain name
ssh-keyscan example.com
## Or use an IP
ssh-keyscan 10.0.2.2
新しいファイルタイプのCI/CD変数を作成し、SSH_KNOWN_HOSTS
を “Key “とし、ssh-keyscan
の出力を “Value “として追加します。
複数のサーバーに接続する必要がある場合は、すべてのサーバーのホスト・キーを1行に1つずつ、変数のValueに集めなければなりません。
ssh-keyscan
ssh-keyscan
、 ssh-keyscan
代わりにファイル型のCI/CD変数を使用することで、何らかの理由でホストドメイン名が変更されてもssh-keyscan
変更する必要がないという利点が ssh-keyscan
あります。また、値はあらかじめ定義されているので、ホストキーが突然変わってもCI/CDジョブが失敗することはありません。SSH_KNOWN_HOSTS
変数が作成されたので、上記の.gitlab-ci.yml
](#ssh-keys-when-using-the-docker-executor) の[の内容に加えて、 を追加してください:
before_script:
##
## Assuming you created the SSH_KNOWN_HOSTS file type CI/CD variable, uncomment the
## following two lines.
##
- cp "$SSH_KNOWN_HOSTS" ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
##
## Alternatively, use ssh-keyscan to scan the keys of your private server.
## Replace example.com with your private server's domain name. Repeat that
## command if you have more than one server to connect to.
##
# - ssh-keyscan example.com >> ~/.ssh/known_hosts
# - chmod 644 ~/.ssh/known_hosts
##
## You can optionally disable host key checking. Be aware that by adding that
## you are susceptible to man-in-the-middle attacks.
## WARNING: Use this only with the Docker executor, if you use it with shell
## you will overwrite your user's SSH config.
##
# - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" >> ~/.ssh/config'
プロジェクトの例
GitLab.comで公開されている共有Runnerを使ったSSHプロジェクトの例を用意しました。
ハックしたいですか?フォークしてコミットし、変更をプッシュしてください。数瞬で公開 Runner によって変更が選択され、ジョブが開始されます。