GitLab CIでAWS Systems Managerを使用したEC2インスタンスへのセキュアなSSH,SCP


はじめに

AWS Systems Managerを使用する経緯
GitLab.com が提供する GitLab Runner はIPアドレスが固定されていない為、GitLab CIからEC2インスタンスにアクセスする際はSSHのインバウンドポートをフルオープンで運用していました。

IP range
For outgoing connections from CI/CD runners, we are not providing static IP addresses. All GitLab.com shared runners are deployed into Google Cloud Platform (GCP). Any IP-based firewall can be configured by looking up all IP address ranges or CIDR blocks for GCP.
https://docs.gitlab.com/ee/user/gitlab_com/#ip-range

ただし、セキュリティ上どこからでもログイン出来てしまう状況は良く無いです。

そこで、AWS Systems Manager(SSM)のセッションマネージャを利用してセキュアにログインするフローを導入したので、その設定方法をご紹介します。

従来ログインとSSM経由ログインの比較

  • SSHキーが不要
  • セキュリティグループでSSHポートの開放が不要
  • プライベートサブネットでも踏み台なしでアクセス可能
  • IAMによるアクセス制御が可能
  • ログインログ、イベントログが取得可能(S3、Cloud Watch 等との連携)

1. EC2インスタンスのセットアップ

IAMロールの設定

セッションマネージャから接続を許可するIAMロールをEC2インスタンスに設定します。

「AmazonSSMManagedInstanceCore」の許可ポリシーでIAMロールを作成します。

Systems Manager > フリートマネージャーのノードIDに対象EC2インスタンスが表示されていればOK。

SSM Agentのインストール

SSM Agentは、以下の Amazon Machine Images (AMIs) にデフォルトでプリインストールされています。

  • Amazon Linux
  • Amazon Linux 2
  • Amazon Linux 2 ECS に最適化されたベース AMIs
  • SUSE Linux Enterprise Server(SLES) 12 と 15
  • Ubuntu Server 16.04、18.04 および 20.04

その他の Linux SSM Agent で作成された EC2 インスタンスには、AMIsを手動でインストールする必要があります。

2. IAMユーザーのセットアップ

IAMコンソール https://console.aws.amazon.com/iam/ を開き、以下2つのポリシーを作成しIAMユーザーに付与します。

ポリシー1: セッションマネージャ経由でのSSH接続を許可

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ssm:StartSession",
            "Resource": [
                "arn:aws:ec2:region:account-id:instance/instance-id",
                "arn:aws:ssm:*:*:document/AWS-StartSSHSession"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "ssm:TerminateSession",
                "ssm:ResumeSession"
            ],
            "Resource": [
                "arn:aws:ssm:*:*:session/${aws:username}-*"
            ]
        }
    ]
}

region, account-id, instance-id は環境に応じて書き換える必要があります。

ポリシー2: Run Commandの実行許可

{
   "Version":"2012-10-17",
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "ssm:SendCommand"
         ],
         "Resource":[
            "arn:aws:ssm:*:*:document/*"
         ]
      },
      {
         "Effect":"Allow",
         "Action":[
            "ssm:SendCommand"
         ],
         "Resource":[
            "arn:aws:ec2:region:account-id:instance/instance-id"
         ]
      }
   ]
}

region, account-id, instance-id は環境に応じて書き換える必要があります。

IAMユーザーの作成

上記2つのポリシーを付与したユーザーを「認証情報タイプ: アクセスキー - プログラムによるアクセス」で作成しアクセスキーID, シークレットアクセスキーを手元に控えます。(GitLab CIの設定で使用)

3. GitLab CIの設定

Variablesの登録

GitLabプロジェクト管理画面のSettings > CI/CD > Variablesに以下の環境変数を設定します。

Type Key Value Masked
Variable AWS_ACCESS_KEY_ID 上記で取得したアクセスキーID true
Variable AWS_SECRET_ACCESS_KEY 上記で取得したシークレットアクセスキー true
File EC2_SERVER_PEM EC2インスタンスのpemファイル

.gitlab-ci.ymlの作成

.gitlab-ci.yml
ssm_test:
  stage: build
  image: python:3.9-slim
  before_script:
    - apt update && apt install -y --no-install-recommends curl ssh openssh-client openssh-server
    - pip install awscli
    - curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/ubuntu_64bit/session-manager-plugin.deb" -o "session-manager-plugin.deb"
    - dpkg -i session-manager-plugin.deb
    - chmod 400 $EC2_SERVER_PEM
    - mkdir -p ~/.ssh/ && echo -e "Host *\n\tStrictHostKeyChecking no\nhost i-* mi-*\n\tProxyCommand sh -c \"aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'\"\n\n" >> ~/.ssh/config
    - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
    - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
    - aws configure set region region
  script:
    - ssh -i $EC2_SERVER_PEM ec2-user@instance-id "実行コマンド"
    - scp -i $EC2_SERVER_PEM コピー元パス ec2-user@instance-id:保存先パス

region, instance-id は環境に応じて書き換える必要があります。


以上で全ての設定が完了です
AWS Systems Manager セッションマネージャ を利用して、セキュアにログインを行いましょう!