GitLab CI/CDでSSHキーを使用する
- プラン: Free、Premium、Ultimate
- 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated
GitLabには、(GitLab Runnerが実行される)ビルド環境でSSHキーを管理するためのサポートが組み込まれていません。
SSHキーは、次の操作を行う場合に使用します。
- 内部サブモジュールをチェックアウトする。
- パッケージマネージャーを使用して、プライベートパッケージをダウンロードする(Bundlerなど)。
- 独自のサーバーやHerokuなどにアプリケーションをデプロイする。
- ビルド環境からリモートサーバーにSSHコマンドを実行する。
- ビルド環境からリモートサーバーにRsyncでファイルを転送する。
最も広くサポートされている方法は、.gitlab-ci.ymlを拡張してSSHキーをビルド環境に挿入することです。これは、あらゆるタイプのexecutor(DockerやShellなど)と連携するソリューションです。
SSHキーを作成して使用する
GitLab CI/CDでSSHキーを作成して使用するには、次のようにします。
ssh-keygenを使用して、ローカルに新しいSSHキーペアを作成します。- 秘密キーをファイルタイプのCI/CD変数としてプロジェクトに追加します。変数の値は、改行コード(
LF文字)で終わる必要があります。改行コードを追加するには、CI/CD設定に保存する前に、SSHキーの最終行の末尾でEnterキーまたはReturnキーを押します。 - ジョブで
ssh-agentを実行し、秘密キーを読み込みます。 - アクセスするサーバーに公開キーをコピーします(通常は
~/.ssh/authorized_keys)。プライベートGitLabリポジトリにアクセスする場合は、公開キーをデプロイキーとして追加する必要もあります。
次の例では、ssh-add -コマンドでジョブログに$SSH_PRIVATE_KEYの値は表示されませんが、デバッグログの生成を有効にすると表示される可能性があります。パイプラインの表示レベルを確認する必要が生じる可能性もあります。
Docker executor使用時のSSHキー
CI/CDジョブがDockerコンテナ内で実行され(つまり、環境がコンテナ内に隔離されていて)、プライベートサーバーにコードをデプロイする場合は、アクセスする方法が必要です。この場合、SSHキーペアを使用できます。
まず、SSHキーペアを作成する必要があります。詳細については、SSHキーを生成するの手順に従ってください。SSHキーにパスフレーズを追加しないでください。追加すると、
before_scriptで入力を求められます。新しいファイルタイプのCI/CD変数を作成します。
- キーフィールドに、
SSH_PRIVATE_KEYと入力します。 - 値フィールドに、先ほど作成したキーペアの秘密キーの内容を貼り付けます。ファイルが改行コードで終わっていることを確認してください。改行コードを追加するには、変更を保存する前に、SSHキーの最終行の末尾でEnterキーまたはReturnキーを押します。
- キーフィールドに、
.gitlab-ci.ymlにbefore_scriptアクションを追加します。次の例では、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 executor使用時のSSHキー
DockerではなくShell executorを使用している場合は、SSHキーの設定がさらに簡単になります。
GitLab RunnerがインストールされているマシンからSSHキーを生成し、このマシンで実行されるすべてのプロジェクトにそのキーを使用できます。
まず、ジョブを実行するサーバーにサインインします。
次に、ターミナルから、
gitlab-runnerユーザーとしてサインインします。sudo su - gitlab-runnerSSHキーを生成する手順に従って、SSHキーペアを生成します。SSHキーにパスフレーズを追加しないでください。追加すると、
before_scriptで入力を求められます。最後のステップとして、先ほど作成した公開キーを、ビルド環境からアクセスする必要があるサービスに追加します。プライベートGitLabリポジトリにアクセスする場合は、その公開キーをデプロイキーとして追加する必要があります。
キーを生成したら、リモートサーバーにサインインして、フィンガープリントを受け入れます。
ssh example.comGitLab.com上のリポジトリにアクセスするには、git@gitlab.comを使用します。
SSHホストキーを検証する
中間者攻撃の標的になっていないことを確認するために、プライベートサーバー自体の公開キーを確認することをおすすめします。何か疑わしいことが起きると、ジョブが失敗する(公開キーが一致しない場合は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を設定し、「値」にssh-keyscanの出力を追加します。ファイルが改行コードで終わっていることを確認してください。改行コードを追加するには、変更を保存する前に、SSHキーの最終行の末尾でEnterキーまたはReturnキーを押します。
複数のサーバーに接続する必要がある場合は、すべてのサーバーのホストキーを1行に1つずつ記載し、変数の値に収集する必要があります。
.gitlab-ci.yml内でssh-keyscanを直接使用する代わりに、ファイルタイプのCI/CD変数を使用すると、何らかの理由でホストのドメイン名が変更されても.gitlab-ci.ymlを変更する必要がないという利点があります。また、値はユーザーによって事前定義されているため、ホストキーが突然変更されてもCI/CDジョブは失敗しません。そのため、サーバーまたはネットワークに問題があると判断できます。
SSH_KNOWN_HOSTS変数を作成したら、上記の.gitlab-ci.ymlの内容に加えて、以下を追加する必要があります。
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. Include the -t
## flag to specify the key type.
##
# - ssh-keyscan -t rsa,ed25519 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'ファイルタイプのCI/CD変数を使用せずにSSHキーを使用する
ファイルタイプのCI/CD変数を使用したくない場合は、SSHプロジェクトの例に別の方法が示されています。この方法では、前述の推奨されているファイルタイプ変数ではなく、標準のCI/CD変数を使用します。
トラブルシューティング
Error loading key "/builds/path/SSH_PRIVATE_KEY": error in libcrypto(キー「/builds/path/SSH_PRIVATE_KEY」の読み込みエラー: libcrypto内のエラー)メッセージ
このメッセージは、SSHキーに形式エラーがある場合に返される可能性があります。
SSHキーをファイルタイプのCI/CD変数として保存する場合、値は改行コード(LF文字)で終わる必要があります。改行コードを追加するには、変数を保存する前に、SSHキーの-----END OPENSSH PRIVATE KEY-----行の末尾で、EnterキーまたはReturnキーを押します。