NRIネットコム Blog

NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

踏み台にはECSコンテナを。~ログイン有無を検知して自動停止させる~

こんにちは、後藤です。今回はAWS構成における踏み台についての記事です。

データベースなどのインターネットに繋げたくないリソースに踏み台リソース経由でアクセスさせることは、セキュリティ設計としてよくある構成だと思います。 今回はその踏み台リソースに「ユーザーログイン有無を検知して自動停止する」ロジックを組み込んだ方法を共有します。

また、一般的によく用いられるのはEC2だと思いますが、今回はECS on Fargate(以降はFargateと略)を使います。しかも自動停止ロジックにLambdaを使いません!!コンテナの中で完結させます。



踏み台を設計する時に気になること

そもそも踏み台について設計する際に何が気になるのでしょうか。それはOS管理負担と自動停止です。
踏み台にEC2を用いるとOSパッチ適用などの運用コストが発生します。業務系サーバでないのに心労が重なるのはなるべく避けたいところです。
また、踏み台は常時使うものではないので起動させておくとその分無駄な課金が発生します。停止忘れのためにLambda定期実行などの考慮が必要になってきます。

そこでFargateを採用し、当記事のロジックをコンテナ内に組み込むことで、OS管理負担と停止忘れ設計から解放することができます。

自動停止ロジック概要

踏み台コンテナはECSタスク定義からタスク実行によって起動します。起動中はスクリプトを実行し、スクリプトが終了した時点でコンテナが停止します。
ここでのポイントはタスク実行によって起動するということです。一般的な構成はECSサービスを用いることでスケーリングなどの制御を行うと思います。 しかし今回はECSサービスを使わないことで、コンテナ停止時にも自動で起動しないようにします。

以降は踏み台コンテナの中身についてです。

フォルダ構成

.
├─check_login.sh
└─Dockerfile

最小限のフォルダ構成にしています。

Dockerfile

FROM public.ecr.aws/amazonlinux/amazonlinux:2023
COPY ./check_login.sh .
RUN chmod 700 check_login.sh

RUN yum update -y && \
    yum install -y procps && \
    dnf -y localinstall  https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm && \
    dnf -y install mysql mysql-community-client

ENTRYPOINT ["./check_login.sh"]

・(1行目)SSMエージェントがデフォルトで入っているという理由からベースイメージにamazonlinux2023を指定します。
・(6~8行目)psコマンドとmysqlクライアントをインストールしています。今回はRDSへの接続のためにmysqlクライアントにしていますが、ElastiCache for redisに接続するためにredisクライアントツールを入れるなど、適宜インストール内容は変えてください。SSMエージェントをコマンドでインストールする場合はベースイメージはamazonlinux2023である必要はありません。
・(10行目)コンテナ起動中はシェルスクリプト実行コマンドを実行します。

なおSSMエージェントを入れている理由は、FargateにログインするにはSSMエージェントを介してログインする必要があるためです。
またFargateのバージョンが1.4(2023年9月時点の最新版)であるという条件もあります。aws.amazon.com

check_login.shスクリプト

#!/bin/bash
LOGIN_USER="exist"

while :
do
    sleep 900
    LOGIN_USER_NUMBER=`ps -ef | grep ssm-session-worker | grep -v grep | wc -l`
    
    if [ $LOGIN_USER_NUMBER != 0 ]; then
        LOGIN_USER="exist"
    else
        if [ $LOGIN_USER = "no exist" ];then
            exit 0
        else
            LOGIN_USER="no exist"
        fi
    fi
done

ロジックの肝となる部分です。
15分ごとにコンテナ内のSSMエージェントのプロセスを確認します。SSMエージェントのプロセス数、つまりSSMユーザーのログイン数によってLOGIN_USERフラグを切り替える処理内容になっています。LOGIN_USERフラグが"no exist"になってから15分後にログイン数が0であればスクリプトを終了し、コンテナが停止します。

シェルスクリプトの内容を処理フロー図に起こすと以下になります。

まとめ

以下を満たすことで、OS管理負担と停止忘れ設計から解放される踏み台リソースが実現できます。
・踏み台にはECS on Fargateを採用すること
・タスク実行によってコンテナを起動すること
・Dockerfile内のENTRYPOINTにてシェルスクリプト実行コマンドを指定すること
・シェルスクリプト内ではユーザーログイン数によってスクリプトを終了する分岐処理を記述すること

ぜひDockerfileのインストール内容、スクリプト内容をカスタマイズしてみてください。

付録

・踏み台コンテナをタスク実行によって起動するAWS CLIコマンド

CLUSTER_NAME=<クラスター名を入力>
TASK_DEFINITION=<タスク定義名を入力>
SECURITYGROUP_ID=<コンテナにアタッチするセキュリティグループIDを入力>
SUBNET_ID=<コンテナをデプロイするサブネットIDを入力>

aws ecs run-task \
--cluster $CLUSTER_NAME \
--task-definition $TASK_DEFINITION \
--network-configuration awsvpcConfiguration=“{subnets=['$SUBNET_ID'],securityGroups=['$SECURITYGROUP_ID'],assignPublicIp=DISABLED}” \
--enable-execute-command \
--launch-type FARGATE \
--platform-version ‘1.4.0’

・踏み台コンテナにログインするAWS CLIコマンド

TASK_ID = <タスクIDを入力>
RUNTIME_ID = <作成したコンテナのランタイムIDを入力>

aws ssm start-session --region ap-northeast-1 --target ecs:${CLUSTER_NAME}_${TASK_ID}_${RUNTIME_ID}

執筆者: 後藤 涼太
AWSをメインとするクラウドエンジニア
AWS認定資格 全取得済み
執筆記事:https://tech.nri-net.com/archive/author/r-goto