[レポート] AWS Fargateにおけるセキュリティベストプラクティス #CON414 #reinvent
CON414 Security best practices for AWS Fargate
はじめに
この記事はre:invent 2019 CON414 Security best practices for AWS Fargate のセッションレポートです。 セッションで使用されたコードはこちらで公開されています。
このセッションではシンプルなWebアプリを題材にFargateのセキュリティベストプラクティスについてデモを交えて解説が行われました。 記事と合わせてコードを参照して内容を確認するのをお勧めします。
セッション概要
In this session, we highlight several of the recommendations for container security on AWS Fargate. You learn about using a private registry and securing the cluster and your services. We also discuss network security basics and security monitoring using AWS solutions. Please bring your laptop.
スピーカー
- Len Henry - Senior Solutions Architect, Amazon Web Services
アプリのアーキテクチャ
- Basic認証を設定したnginxとSSHサーバを起動するコンテナをFargateタスクとして実行します
- コンテナイメージはECRに登録されています
- タスクはVPC内で起動します
インフラのセットアップとタスクの起動
デモの最初のステップではインフラのセットアップと最初のタスクの起動を行います。
この状態でもFargateではデフォルトで以下のセキュリティ対策が行われています。
- タスクの分離: コンピューティング、ストレージ、ネットワークはタスクごとに分離されている
- 不変な環境: タスクは一度実行される変更できない
- コンテナイメージはセキュアな方法でアクセスされる
- アプリケーションのログはセキュアな方法でアクセスされる
このステップでは起動したタスクにインターネットから以下のサービスが公開されています。 (実環境でSSHとWebを同じコンテナで動かすことはないと思いますが・・・)
- Web(port 80)
- SSH(port 23)
セキュリティグループ設定の変更
初期状態ではタスクに設定されるセキュリティグループは下記のように、インターネットからのアクセスがフルオープンになっているので、必要なポートだけに絞りこみます。これによりweb以外のポートのアクセスが制限されました。
変更前 00-cluster-fargate-vpc.yml
ContainerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Access to the Fargate containers VpcId: !Ref 'VPC' SecurityGroupIngress: # Allow access to task from anywhere on the internet - CidrIp: 0.0.0.0/0 IpProtocol: -1
変更後 01-cluster-fargate-vpc-asm.yml
ContainerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Access to the Fargate containers VpcId: !Ref 'VPC' SecurityGroupIngress: # Allow access to task from anywhere on the internet, but only on port 80 - CidrIp: 0.0.0.0/0 FromPort: 80 ToPort: 80 IpProtocol: tcp
コンテナイメージ内の機密情報の保護
最初のバージョンのDockerfileではBasic認証用のhtpasswdファイルをCOPYコマンドでコピーしていました。 そのためコンテナイメージにパスワードが含まれています。これをAWS Secret Managerを使ってパスワードを取得するように変更します。 Secret Managerに保存したあんなことやこんなことはごっつ簡単にコンテナ内から環境変数として参照できます。
次の変更を行います。
- 以下のようにCloudFormationスタックを変更する
- Secret Managerにhtpasswdの内容を保存する 01-cluster-fargate-vpc-asm.yml
- タスク実行ロールにSecret Managerへのアクセスポリシーを追加する 01-cluster-fargate-vpc-asm.yml
- Dockerfileを変更してコンテナ実行時にhtpasswdファイルの中身を環境変数から取得するようにする 01-Dockerfile
- タスク定義にSecret Managerへの参照を追加する 01-taskdefinition.json
追加のエクササイズ
セッションでも以下の追加エクササイズも出題されました。
- ECSリソースに対するCloudtrailログを監視するCloudWatch Alarmsを設定する
- VPC Flow logを監視する
- KMSを使ってSecret Managerの内容を暗号化する
- コンテナをELBでロードバランシングする
まとめ
Fargate上でのタスクのアクセス制限とSecret Managerを使った機密情報の扱いについてデモを交えて学びました。 これまであまり考えていなかったのですが、改めてFargateであってもEC2で構成された環境と同じようにネットワーク設計をした機密情報の保護を行えばいいことのだなと気づきました。 re:Inventの前後でFargateに興味が湧いてきたのですが、実際のワークロードをコンテナ化するときにはこの辺りがEC2の時の知識が使いまわせると設計が捗る・・・気がします。