On Blahfe

踏み台をSSM Session ManagerとAWS SSOで実現する

blog/backendsession-manageraws-sso

踏み台のユーザーが増えてきたため公開鍵管理や監視と運用負荷が上がってきました。オペミスが発生しやすい上 監査的な意味で無視できない状況になってきたので重い腰を上げることにしました。

thumbnail

PROBLEM

  • EC2インスタンスの踏み台運用がつらい
    • 公開鍵管理がつらい
      • 提出・設定・確認ともに運用コストがかかる
      • AWSアカウント数 x ユーザー数で指数関数的に運用コストが増していくことが想定される
      • インフラ管理が分散していると、提出側・設定側ともに重複コストが発生する
    • 監視運用がつらい
      • 定期的に踏み台がブルートフォース攻撃を受けており、脅威が低いとは言えストレスがかかる
      • 踏み台アクセスへの監査ログが不十分

SOLUTION

というわけで、Session ManagerとSSOでアクセス管理の効率化を狙います。

踏み台サーバーの設定

まず、データフローとしては下記の図の通りで、今回はプライベートサブネット上にEC2を置いて素のSession ManagerでDBへの接続することにします。当該インスタンスは AmazonSSMManagedInstanceCore ポリシー1を含んだロールを適用。なお、ECS ExecではSession Managerでポートフォワーディングを実現でき無かったことに加え、既存の踏み台資産を流用するため今回の実装対象から外しました。

UML

SSOの設定

踏み台サーバーの設定が終わったら、次に当該インスタンスへ接続するためにSSOで渡すロールをアクセス権限セットに設定します。下記カスタムポリシーはEC2インスタンスにアクセスするための必要最低限のものになります。

カスタムポリシー
json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cloudwatch:PutMetricData",
                "ds:CreateComputer",
                "ds:DescribeDirectories",
                "ec2:DescribeInstanceStatus",
                "logs:*",
                "ssm:*",
                "ec2messages:*"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ssm:StartSession"
            ],
            "Resource": [
                "arn:aws:ssm:*:*:session/<EC2インスタンスID>",
                "arn:aws:ec2:*:*:instance/<EC2インスタンスID>"
            ]
        },
        {
            "Effect": "Deny",
            "Action": [
                "ssm:Describe*",
                "ssm:Get*",
                "ssm:List*",
                "logs:Describe*",
                "logs:Get*",
                "logs:List*"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "iam:CreateServiceLinkedRole",
            "Resource": "arn:aws:iam::*:role/aws-service-role/ssm.amazonaws.com/AWSServiceRoleForAmazonSSM*",
            "Condition": {
                "StringLike": {
                    "iam:AWSServiceName": "ssm.amazonaws.com"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": "iam:CreateServiceLinkedRole",
            "Resource": "arn:aws:iam::*:role/aws-service-role/ssm.amazonaws.com/AWSServiceRoleForAmazonSSM*",
            "Condition": {
                "StringLike": {
                    "iam:AWSServiceName": "ssm.amazonaws.com"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:DeleteServiceLinkedRole",
                "iam:GetServiceLinkedRoleDeletionStatus"
            ],
            "Resource": "arn:aws:iam::*:role/aws-service-role/ssm.amazonaws.com/AWSServiceRoleForAmazonSSM*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ssmmessages:CreateControlChannel",
                "ssmmessages:CreateDataChannel",
                "ssmmessages:OpenControlChannel",
                "ssmmessages:OpenDataChannel"
            ],
            "Resource": "*"
        }
    ]
}

セッションを張るための事前準備

セッションを張るためには下記3つの手順が必要になります。SSO経由のセッション設定が2通りありますが、クレデンシャル方式はセッションが切れる毎に変更する手間があるため、CLI方式をお薦めします。

  1. AWS CLI v2をインストール
  2. 下記いずれかの方式でSSO経由のセッション設定を行う
  3. Session Manager プラグインをインストール

DBクライアントの設定

最後に、DBクライアントについて3つの手順を踏んで接続を試みます2。なお、ローカル環境でポートフォワーディングを都度行うのを省略したい方は、DataGripを利用すると良いでしょう。

  1. ローカル環境にて ~/.ssh/config ファイルを編集
    • Session Managerにproxyと対象RDSのエンドポイントを記載
      config
      Host <任意のhost名>
          HostName <※ 指定しなければlocalhostになる>
          User ec2-user
          ProxyCommand sh -c "aws ssm start-session --target <接続する踏み台のインスタンスID> --document-name AWS-StartSSHSession --parameters 'portNumber=%p' --region ap-northeast-1 --profile <プロフィール>"
          LocalForward <任意のポート> <RDSエンドポイント>:<RDSポート>
          IdentityFile ~/.ssh/<EC2に接続する秘密鍵>
      
    • 設定したhost名でセッションマネージャー越しにssh接続できるかを確認
      sh
      $ ssh <設定したhost名>
      
  2. 手順1で設定したsshで接続することでポートフォワーディング
  3. DBクライアントで下記のように接続情報を設定し接続する
    • Host: <手順1のconfigファイルにて任意指定したホスト名>
    • Port: <手順4のconfigファイルにて任意指定したポート>
    • 他項目: DB接続情報

WRAPUP

パブリックサブネット上の踏み台に慣れている方は馴染みのない方法に戸惑うかも知れませんが、踏み台資産を流用できるという意味で導入のコストもそれほどかかりませんし、ユーザーとしても利用の敷居は高くありませんでした。後々の管理コストを心配している方は一度検討してみてはいかがでしょうか。

  1. AmazonEC2RoleforSSM は非推奨のため適用しないように注意します。

  2. 今回はメンテナンスコストを避けるためSSH over SSMの関連ツール ssh-ssm.sh ssm-tool は使わない方針でいます。

nabinno
Emacsianでアート好き、ランニング好きな@nabinnoが書いています
GitHub / X / LinkedIn / ネクイノ
blog/market

今後の成長分野:新たなテクノロジーの展望

テクノロジーの進化は、絶え間ない変化の中で私たちの日常を塗り替えてきました。時には経済的な危機が、新たな可能性を切り拓く契機となることもあります。そこで、過去のリセッション期に生まれたテクノロジーの足

market-trendrecession
blog/organization

ATKerneyの課題解決パターンの魅力的な探求

ATKerneyの課題解決パターン は、課題の本質を見極め、効果的な戦略的構造化を通じて解決策を導き出す手法にフォーカスしています。この冒険の旅は、解決者と協力者たちが心を一つにし、課題に立ち向かう様

problem-solvingatkerney
blog/market

就職氷河期とは何だったのか

私はいわゆる就職氷河期世代です。周囲から時折漏れ聞こえる不平のような言葉がありますが、それを単なる不平として片付けるのはもったいない気がします。できれば、その中に新しい視点を見つけ、次のチャンスへ繋げ

labor-economicsrecessionemployment-ice-age