必見の記事

冴えないAWS環境の育てかた α

わしが育てた
2020.09.18

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

中山です

ソリューションアーキテクトとして、AWS環境の利活用をお手伝いするお仕事をしています。

まれによく見るAWS環境

とりあえずこれを見てほしい。

これが絶対にだめと言いたいわけではないです。 一時的な検証環境だったり、とにかくスピード重視でサービスをデリバリーさせる必要があったり、サービスの提供者側が何ら責任を負わない・障害時のビジネスインパクトが無い(そんな状況あるのか?)という前提があったり、状況次第ではこれで十分な時もあると思います。 しかし、一般的な業務システムやサービスの場合にはいろんな意味で不十分でしょう。

では、このような環境をどのように育てていくとよいでしょうか。 この記事では、そんな育てかたの一例を紹介していきたいと思います。

なお、本記事はくっそ長いです。

ちなみに、最終的にはこうなります。

文字が小さすぎて読めない! ちょっとそこのハ○キルーペ貸してくれーw

前提条件

最初に挙げた環境ですが、以下のような前提だとします。

  • サーバー上で動作しているものは一般的なWebアプリケーション
  • リレーショナルデータベースを利用している
  • 1つのEC2インスタンス上で全部構成されている

これ以降、どのような改善ができるかの述べていきますが、 アプリケーション自体の改善については基本的にスコープ外とします(サーバーレスやコンテナへの移行などは本記事では扱いません)。 ウェブサーバー・アプリケーションサーバーはスケールアウト可能であると仮定します。

また、AWSアカウントは1つだけ利用するような状況を想定しています(マルチアカウント管理はスコープ外)。

育て方のアプローチ

育てる要素はいろいろありますが、今回は以下の4つに分けて育ててみます。

  • AWSアカウントの育てかた
  • ネットワークの育てかた
  • サーバーの育てかた
  • データストアの育てかた

あと、長くなるので一つ一つの育成策に対する細かい解説はしません。 公式ドキュメントなどを参照しましょう。

評価基準

AWSにはWell Architected Frameworkというものがあります。

AWS Well-Architected Framework

以下の5つの柱に基づいて、設計や環境がベストプラクティスに基づいているかを確認することができます。

  • Operational Excellence
  • Security
  • Reliability
  • Performance Efficiency
  • Cost Optimization

厳密にこれに則っていくわけではありませんが、なんとなく意識しながらこの記事を書いていこうと思います。

AWSアカウントの育てかた

まずは、AWSアカウント自体を育てます。この部分はどんなアプリケーションを稼働させる場合であってもできること・やるべきことです。

利用するサービス

  • CloudTrail
  • IAM
  • Access Analyzer
  • Config
  • Budgets
  • GuardDuty
  • Detective
  • Security Hub
  • Trusted Advisor
  • Personal Health Dashboard
  • AWS Support

一部の作業項目では、AWS ChatbotおよびAmazon SNSを利用しています。

育てる

まず、何をやるか列挙します。

  • CloudTrail / 有効化(全リージョン)
  • CloudTrail / 改ざん検知
  • CloudTrail / CloudWatch Logsへの配信もしくはAthenaのテーブル定義
  • CloudTrail / CloudTrail Insightsの有効化
  • IAM / ルートアカウントのMFA有効化
  • IAM / パスワードポリシーの強化
  • IAM / IAM Userの作成
  • IAM / IAM UserにMFAを設定する
  • IAM / IAM Groupの作成および権限付与
  • IAM / IAM Userによる請求情報へのアクセス許可
  • Access Analyzer / 有効化
  • Access Analyzer / イベント通知
  • Config / 有効化
  • Config / すべてのリソースの記録を取得
  • Budgets / 予算を設定
  • Cost Explorer / 有効化
  • コスト配分タグの設定
  • GuardDuty / 全リージョンでの有効化
  • GuardDuty / イベント通知
  • Detective / 有効化
  • Security Hub / 有効化
  • Security Hub / Security Standardの有効化
  • Security Hub / イベントの通知
  • Trusted Advisor / イベントの通知
  • Personal Health Dashboard (AWS Health) / イベントの通知
  • AWS Support / プランの変更
  • Artifact / サービスアグリーメントの変更(準拠法、管轄裁判所)
  • 代替連絡先の設定
  • 支払通貨の変更

CloudTrail / 有効化(全リージョン)

CloudTrailを有効化しましょう。

Creating a Trail

これにより、AWSのAPIを「いつ」「だれが」「どのように」利用したのかを把握できるようになります。

この際、Multi region Trailが有効になっているか確認しましょう。 なお、現在はコンソールで設定する場合には必ず有効なるようです。

インシデントの調査に使用できますし、内部不正の抑止力にもなります。

CloudTrail / 改ざん検知

Trailを作成する際にファイルの整合性をチェックできるオプションを有効にしましょう。

Validating CloudTrail Log File Integrity

改ざんされる余地があると、正しく監査できない可能性がでてしまいます。

CloudTrail / CloudWatch Logsへの配信もしくはAthenaのテーブル定義

Trailを作成する際にCloudWatch Logsへのログの配信を設定しましょう。

Monitoring CloudTrail Log Files with Amazon CloudWatch Logs

CloudWatch Logsのコストが気になるときには、S3上のログをすぐに分析できるようにAthenaのテーブルを定義しておきましょう。

Querying AWS CloudTrail Logs

CloudTrailのログはコンソールでのフィルタリングも可能ですが、より高度な分析をしたい場合には事前にこれらの設定をしておくと良いでしょう。

CloudTrail / CloudTrail Insightsの有効化

Insights Eventsの取得を有効化しましょう。

Logging Insights Events for Trails

幅広いサービスの書き込み系イベントについて、通常とは異なる挙動を検知できます。 大事なアカウントで利用するとよいのではないでしょうか。

IAM / ルートアカウントのMFA有効化

ルートアカウントにMFAを設定しましょう。

Using Multi-Factor Authentication (MFA) in AWS

説明は不要ですよね(にっこり

IAM / パスワードポリシーの強化

パスワードポリシーを強化しましょう。

Setting an Account Password Policy for IAM Users

組織のポリシーがあればそれに準じましょう。

最近はパスワードの定期変更を求めないガイドも増えてきました。

安全なパスワード管理

IAM / IAM Userの作成

一人一人にIAM Userを発行しましょう。

Creating an IAM User in Your AWS Account

ユーザーを共有してしまうと、CloudTrailでログを取得する意味もなくなります。 各操作を誰が行ったのか、識別できるように正しいユーザーの運用を行いましょう。

IAM / IAM UserにMFAを設定する

IAM UserにMFAを設定しましょう。

Using Multi-Factor Authentication (MFA) in AWS

最近のセキュリティインシデントを鑑みると、パスワード (What you know) だけで良いはずがありません。

デバイスは好きなものを選べばいいと思いますが、設定をデバイス間で同期できるものは適切に運用しましょう。

Multi-factor Authentication

なお、MFAの設定はセルフサービスで展開すると管理者の負担は小さくなると思います。 デバイスが壊れたりしたときはさすがに管理者の出番ですが。

IAM: Allows IAM Users to Self-Manage an MFA Device

MFAを設定しない横着なやつに備えて以下のようなポリシーを設定して差し上げましょう。

Amazon EC2: Requires MFA (GetSessionToken) for Specific EC2 Operations

IAM / IAM Groupの作成および権限付与

同じ役割のユーザーはIAM Groupでまとめたうえで権限を付与しましょう。

IAM Groups

Attaching a Policy to an IAM Group

ユーザー毎に権限付与すると管理が煩雑になります。 そのため、Groupに対して権限を付与しましょう。 Groupのメンバーには自動的に権限が付与されます。

なお、AWSが定義済みのポリシーを利用すると設計の負担を軽減できます。

AWS Managed Policies

この際、IAMの管理権限を安易に付与するのは控えましょう。 どうしてもIAMの権限を渡したいなら、Permissions boundaryを利用して意図しない特権昇格を予防しましょう。

Permissions Boundaries for IAM Entities

IAM / IAM Userによる請求情報へのアクセス許可

IAM Userに対して請求情報へのアクセスを許可しましょう。

Overview of managing access permissions

デフォルトだとrootアカウントしか請求情報へのアクセス権を持っていません。 しかし、rootアカウントを日常的に利用するのは望ましくありません。 IAM Userが参照できるようにしておきましょう。

Access Analyzer / 有効化

Access Analyzerを有効化して意図しないアクセス許可を管理しましょう。

Enabling Access Analyzer

S3などのリソースにアクセスポリシーを設定できますが、安易に設定して機密情報が世界中にフルオープンになることがあります。 有効化して、ポリシーを適切に管理しましょう。

Access Analyzer / イベント通知

Access Analyzerのイベントを通知しましょう。

Monitoring AWS IAM Access Analyzer with Amazon EventBridge

検知されたイベントを確認し、必要なアクセス許可はアーカイブしましょう。 意図しないイベントの場合には適切な状態へ是正しましょう。

Archiving Findings

Config / 有効化

Configを有効化しましょう。

Setting Up AWS Config with the Console

リソース変更の過程が分かるので、トラブルシュートなどでも役に立ちます。

Config / すべてのリソースの記録を取得

Configを有効化する際、IAMを含むサポート対象のすべてのリソースで構成情報を取得しましょう。

Supported Resource Types

Budgets / 予算を設定

料金が予算を超えないようにBudgetsを設定しましょう。

Creating a budget

実際に使った金額が閾値に達したら通知することもできますし、予算に達しそうになったら通知することもできます。 なお、ChatbotでSlackなどに通知することもできます。

Using AWS Chatbot with other AWS services

Cost Explorer / 有効化

Cost Explorerを有効化しましょう。

Enabling Cost Explorer

「何でコストが発生しているのか」を分析できないと「コストを削減したい・・・」と思ったときに困ります。

コスト配分タグの設定

コスト配分タブを設定しましょう。

Using Cost Allocation Tags

独自の観点で分析したいときにお好みでどうぞ。 一つのアカウントを多目的に利用している、かつ経費の配布部門が分かれているケースなどで必要になるでしょう。 ただし、ネットワーク転送量など厳密に分離できない課金要素もあるので、厳密な分離が必要な場合はAWSアカウントを分けましょう。

GuardDuty / 全リージョンでの有効化

GuardDutyを全リージョンで有効化しましょう。

Setting up GuardDuty

CloudTrail / VPC FlowLogs / DNSなどのログに基づいてセキュリティリスクのあるイベントを検知してくれます。 あくまでも検知です。

いくらログを取得していても、「どのアクティビティがヤバいか」を判断するのは難しいので、非常に助かります。

GuardDuty / イベント通知

GuardDutyのイベントを通知しましょう。

Creating custom responses to GuardDuty findings with Amazon CloudWatch Events

問題に気がつけなければ意味ないので、必ず通知しましょう。 Slackに通知したいときはChatbotでどうぞ。

Using AWS Chatbot with other AWS services

Detective / 有効化

Detectiveを有効化しましょう。

Enabling Amazon Detective

いざという時にセキュリティログ・イベントを調査できるように有効化しましょう。

Security Hub / 有効化

Security Hubを有効化しましょう。

Setting up AWS Security Hub

セキュリティイベントの集約も良い機能ですが、個人的には次のSecurity Standardを使いたいので有効化しておいていただきたいです。

Security Hub / Security Standardの有効化

Security Standardを利用しましょう。

Disabling or enabling a security standard

Security Standardを利用することで、AWSリソースの設定にセキュリティリスクがないか評価してくれます。 設定は非常に簡単で、裏ではConfig Rulesが利用されています。

ルールセットは3種類あります。 内容を確認し、要件にマッチしたものを選ぶと良いでしょう。 一旦は全部有効化して、その結果を踏まえて判断するのでも良いと思います。

CIS AWS Foundations Benchmark standard

Payment Card Industry Data Security Standard (PCI DSS)

AWS Foundational Security Best Practices standard

Security Hub / イベントの通知

Security Standardで検知した違反を通知しましょう。

Configuring a CloudWatch Events rule for automatically sent findings

他のサービス同様、問題の発生に気づけないと意味がないので、適切に通知設定を実施しましょう。

ただし、GuardDutyやAccess AnalyzerなどのいくつかのサービスはデフォルトでSecurity Hubと連携しているので、何も考えずに設定だけすると連携するサービスに関連する通知が重複します。 Security Hubと各サービスとの連携を無効化することも可能なので、必要に応じて調整してください。

Disabling and enabling the flow of findings from an integration (console)

あと、Chatbotとの連携もできます。

Using AWS Chatbot with other AWS services

Trusted Advisor / イベントの通知

Trusted Advisorで検知した問題を通知しましょう。

Monitoring Trusted Advisor check results with Amazon CloudWatch Events

Trusted Advisorでは、セキュリティ以外の観点で環境を評価してくれるのでこちらも確認することをお勧めします。

Personal Health Dashboard (AWS Health) / イベントの通知

Healthイベントを通知しましょう。

Monitor for AWS Health events with Amazon CloudWatch Events

メンテナンス通知を見逃してインスタンス再起動したら、きっと後悔しますよ。

これもChatbotいけます。

Using AWS Chatbot with other AWS services

AWS Support / プランの変更

適切なサポートプランを設定しましょう。

Changing your AWS support plan

各プランのサービスレベルに応じて適切なものを選択してください。

AWS サポートのプラン比較

Artifact / サービスアグリーメントの変更(準拠法、管轄裁判所)

(必要なら)サービスアグリーメントを変更しましょう。

Managing an Agreement for a Single Account

「日本の法律を準拠法として採用し、本契約に関するあらゆる紛争に関する第一審裁判所を東京地方裁判所とする」ことができます。 そもそも、AWSと事を構える可能性がどれだけあるのか分かりませんが。

代替連絡先の設定

代替連絡先を設定しましょう。

Adding, changing, or removing alternate contacts

お金やセキュリティ的な通知をちゃんと認識できるようにしましょう。 当然、受け取った通知はちゃんと確認しましょう。

支払通貨の変更

支払い通貨を日本円に変更しましょう。

Changing which currency you use to pay your bill

デフォルトだと海外利用扱いなので、カードの海外利用の手数料分お安くなります。

小まとめ

ということで、AWSアカウント自体はこんな感じで育ちました。

ここまでは、AWSを何のために使う場合でもやるべき内容ですね。THE 基礎。

ネットワークの育てかた

次に、ネットワークを育てていきます。

利用するサービス

材料は以下の通りです。

  • Route53
  • CloudFront
  • ACM
  • WAF
  • Subnet(VPC)
  • Route Table(VPC)
  • ELB
  • VPC FlowLogs(VPC)
  • Security Group(VPC)

育てる

やることは以下の通り。

  • Route53 / ドメインを登録(もしくは移管)
  • Route53 / ヘルスチェックの有効化
  • CloudFront / ディストリビューションの作成
  • CloudFront / 追加のメトリックを有効化
  • CloudFront / アクセスログの取得
  • CloudFront / 特定地域からのアクセスをブロック
  • CloudFront / カスタムエラーレスポンスとしてSorry Pageを構成
  • CloudFront / 監視
  • ACM / サーバー証明書の作成
  • ACM / CloudFrontへの関連付けと適切なセキュリティポリシーの選択
  • AWS WAF / WebACLの作成
  • AWS WAF / ログの収集
  • VPC / 複数のAvailability ZoneにSubnetを作成
  • VPC / 通信の範囲に応じてSubnetを作成
  • VPC / NAT Gatewayの作成
  • VPC / Subnetの種類別にRoute Tableを定義
  • ELB / Application Load Balancer (ALB) の作成
  • ELB + CloudFront / CloudFrontからのアクセスのみを許可
  • ELB / HTTP Desync緩和モードの設定
  • ELB / 監視
  • VPC / VPC FlowLogの作成

Route53 / ドメインを登録(もしくは移管)

Route53でドメインをホストしましょう。

Creating a public hosted zone

Route53でドメインを新たに登録することもできますし、ドメインを移管することもできます。

Registering domain names using Amazon Route 53

Transferring domains

既存のレジストラーを継続して利用するのもいいですが、管理コンソールにログインする際にMFAが利用できなかったり監査ログが取得できないといった場合には移管を検討するとよいのではないでしょうか。

あと、SLAも100%ですし。

Amazon Route 53 サービスレベルアグリーメント

Route53 / ヘルスチェックの有効化

ヘルスチェックを利用してみましょう。

Creating, updating, and deleting health checks

サービスの利用者視点で正常性やパフォーマンスを見ることも大事です。 実際はRoute53 Health Checkerから監視されます。

もちろん、通知もご一緒に。

Monitoring health check status and getting notifications

より高度な監視は、Syntheticsで。

Using Synthetic Monitoring

CloudFront / ディストリビューションの作成

CloudFrontを利用しましょう。

Values That You Specify When You Create or Update a Distribution

パフォーマンスの向上だけでなく、DDoS攻撃への耐性を向上させることができます。

とりあえず、静的コンテンツのキャッシュからはじめるとよいのではないでしょうか。 動的なコンテンツでも利用できます。

ちなみに、最近キャッシュキーやオリジンリクエストに関するポリシーを独立したリソースとして扱えるようになりました。

Working with policies

CloudFront / 追加のメトリックを有効化

追加のメトリクスを有効化しよう。

Viewing additional CloudFront distribution metrics

ほしいメトリクスがある場合には有効化を検討しましょう。

CloudFront / アクセスログの取得

アクセスログを取得しましょう。

Configuring and Using Standard Logs (Access Logs)

事故調査など、様々な機会でログを利用することがあると思います。 取得しておきましょう。

ちなみに、最近リアルタイムでログを取得できるようになりました。 こっちはお好みで。

Real-time logs

CloudFront / 特定地域からのアクセスをブロック

(必要なら)特定地域からのアクセスをブロックしましょう。

Restricting the Geographic Distribution of Your Content

精度はそこそこですし、状況に応じて検討したらよいと思います。

CloudFront / カスタムエラーレスポンスとしてSorry Pageを構成

Sorry Pageを用意しましょう。

Generating Custom Error Responses

オリジンで障害が発生したときに生のエラーが出てしまうとあまりイメージがよろしくないので、状況を制御できてる感を出していきましょう。

CloudFront / 監視

CloudFrontを監視しましょう。

Viewing CloudFront and Lambda@Edge metrics

エラーレートやレイテンシなどを監視しておくとよいのではないでしょうか。

CloudWatch Alarmを利用する場合の通知にはChatbotを利用できます。

Amazon CloudWatch Alarms

ACM / サーバー証明書の作成

ACMでサーバー証明書を発行しましょう。

Requesting a Public Certificate

ドメイン認証ですが、無料です。

EV証明書を利用したい場合にはインポートもできるけど、EV証明書じゃないと絶対ダメなケースってどれくらいあるんですかね?

Importing Certificates into AWS Certificate Manager

ACM / CloudFrontへの関連付けと適切なセキュリティポリシーの選択

証明書を発行したらCloudFrontと紐付けましょう。

SSL Certificate

その際、適切なセキュリティポリシーを指定しましょう。 よほど古いクライアントをサポートする必要が無い限り、TLS1.2以降のみをサポートするようにしましょう。 なお、最近TLS1.3もサポートされました。 やったね!

Supported protocols and ciphers between viewers and CloudFront

AWS WAF / WebACLの作成

AWS WAFでWebアプリケーションを保護しましょう。

Getting started with AWS WAF

あくまでも、緩和策として利用しましょう。

なお、ルールはアプリケーションの種類にマッチしたマネージドルールを利用するのがお手軽でおすすめです。

Managed rule groups

運用開始時はカウントから(いきなりブロックしない)始めるといいんじゃないでしょうか。

AWS WAF / ログの収集

AWS WAFでもログを収集しましょう。

Logging Web ACL traffic information

Firehose経由で収集できます。

VPC / 複数のAvailability ZoneにSubnetを作成

複数のAvailability ZoneにまたがってSubnetを作成しましょう。

Working with VPCs and subnets

Availability Zoneについてはこちらをご確認ください。

Availability Zones

サーバーをAZに跨がって展開できればAZがぶっ壊れても、ある程度は大丈夫です。

ここから、1つのインスタンスを以下のように分割することを前提に話を進めます。

  • リレーショナルデータベースを別のインスタンスで稼働させる
  • Web・アプリケーションサーバーを冗長化する

VPC / 通信の範囲に応じてSubnetを作成

サーバーの通信範囲に応じたSubnetを作成しましょう。

インターネットから直接アクセスされるリソースもあれば、インターネット「へ」のアクセスだけできればよいリソースあります。 ものによっては、VPC内で通信できればよいものもあります。

どこに通信できるかはRoute Tableで制御できますが、 前の手順でAZに跨がって作成したSubnetをさらにルーティングの要件毎に作成します。 Route Tableの設定は後述します。

今回は、以下の3種類のSubnetを作成することとします。

  • Public
    • インターネットからのリクエストを受け付けるリソースを配置する
  • Private
    • インターネットからのリクエストは受け付けないが、インターネットへアクセスする必要があるリソースを配置する
  • Data
    • インターネットと通信する必要がないリソースを配置する(後述するAWS Managedなリソースを配置する予定)

具体的な構成はこの辺が参考になるのでどうぞ。

Modular and Scalable VPC Architecture

VPC / NAT Gatewayの作成

NAT Gatewayを利用しましょう。

NAT gateways

プライベートなサブネットからインターネットへアクセスするときに必要となる要素です。

EC2インスタンスでもNATできますが、管理がめんどくさいのでマネージドなこちらを利用しましょう。 コストを限界まで抑えたい場合はNATインスタンスをどうぞ。

NAT instances

VPC / Subnetの種類別にRoute Tableを定義

Subnetの種類毎にルートテーブルを定義しましょう。

設定イメージは以下の通りです。

  • Public
    • Internet Gatewayをデフォルトルートに設定
  • Private
    • NAT Gatewayをデフォルトルートに設定
    • NAT GatewayはAZに依存するのでRoute TableをAZ毎に定義
  • Data
    • デフォルトのルート(VPC内でのルーティング)のみ

ELB / Application Load Balancer (ALB) の作成

ELBを利用してウェブサーバー・アプリケーションサーバーをリクエストの振り分けを行いましょう。 一般的なWebサービスならALBをどうぞ。

Getting started with Application Load Balancers

EC2インスタンスはホストの障害などで止まることがあります。 止まらないことを祈る、というのはエンジニアのすることではありません。 Design for Failureでお願いします。

本当はAutoScalingまで言及してもよいのですが、アプリケーションが対応できるかはケースバイケース(いにしえのアプリケーションでは何かしら問題があることが多い)なので、本記事では言及しません。 そういったアプリケーションは12-Factor App原則に反していることが多い印象です。

The Twelve-Factor App (日本語訳)

データベースについては後ほど言及します。

ELB + CloudFront / CloudFrontからのアクセスのみを許可

CloudFrontからオリジンへのリクエストを転送する際、カスタムヘッダーをつけることでELBへのアクセスをCloudFrontに限定できます。

Adding Custom Headers to Origin Requests

20190730 AWS Black Belt Online Seminar Amazon CloudFrontの概要

ALBでは、リクエストヘッダーの内容に応じて応答を変えることができます。

Rule condition types

指定したターゲットに転送するほかに、リダイレクトや固定レスポンスをALBから返すことも可能です。

Rule action types

IPアドレスでも実現可能ですが、運用がめんどくさいので個人的にはあまり推してません。 どうしてもネットワークレベルで止めたい場合、こちらでCloudFrontのIPを確認できます。 動的に追加されたりしますので、正直めんどい。

AWS IP address ranges

Managed Prefix listでCloudFrontに対応してくれたらいいんですが、今はまだないです。。。(2020年9月17日時点)

Prefix lists

ELB / HTTP Desync緩和モードの設定

HTTP Desync緩和モードで攻撃のリスクを緩和しましょう。

Desync mitigation mode

とりあえず、Defensiveくらいから始めるといいんじゃないでしょうか。 というか、機能がリリースされた段階でいずれかのモードになっているはずので、確認の上で適切なモードを選択してください。

ELB / 監視

ELBの健全性を監視しましょう。

CloudWatch metrics for your Application Load Balancer

異常なインスタンス数やエラー数などを監視しておくとよいのではないでしょうか。

通知にはChatbotを利用できます。

Amazon CloudWatch Alarms

VPC / VPC FlowLogの作成

VPC Flow Logを有効化しましょう。

VPC Flow Logs

VPC内のフロー情報を保存し、インシデントの時の調査に役立てることができます。 なお、FlowLogを保存していなくてもGuardDutyやDetectiveを利用することは可能。

保存はS3とCloudWatch Logsをサポートしています。 コストを抑えたいならS3でどうぞ。

VPC / Security Groupで必要最小限のアクセスのみを許可

Security Groupで必要最小限度のアクセスだけを許可しましょう。

Security groups for your VPC

プロトコル、アクセス元のIPアドレス、アクセス元のAWSリソースに割り当てられているSecurity Groupに基づいてアクセス制御できます。 境界型の防御の有効性は「相対的に」下がっていますが、不要なわけではありません。 ちゃんとやりましょう。

小まとめ

ここまでの図をまとめるとこんな感じ。

文字が小さすぎて(以下略

サーバーの育てかた

次はサーバーです。

利用するサービス

  • EC2
  • EBS
  • Inspector
  • Systems Manager (Patch Manager)
  • Systems Manager (Inventory)
  • Systems Manager (Session Manager)
  • Systems Manager (Parameter Store)
  • CloudWatch
  • CloudWatch Logs
  • AWS Backup

育てる

やることは以下の通り。

  • EC2 / Nitro Systemで動作するインスタンスタイプを利用
  • EC2 / Key Pairの公開鍵をインポート
  • EC2 / IAM Roleの割り当て
  • EC2 / IMDSv2の有効化(を検討)
  • EC2 / OSの設計を堅牢化(要件に応じたAMIの選択)
  • EC2 / Time Sync Serviceで時刻同期
  • EC2 + CloudWatch / AutoRecoveryの有効化
  • EC2 / OS内のコンポーネントを最新化
  • EBS + KMS / ボリュームの暗号化
  • Inspector / 脆弱性を評価
  • Systems Manager / SSM Agentのインストール
  • Systems Manager (Patch Manager/RunCommand) / パッチスキャンおよびパッチ適用
  • Systems Manager (Inventory) / インベントリの収集
  • Systems Manager (Session Manager) / インスタンスの管理操作
  • Systems Manager (Session Manager) / OSユーザーの指定
  • Systems Manager (Session Manager) / ログの収集
  • Systems Manager (Parameter Store) / データベースへの接続情報を保存
  • CloudWatch / CloudWatch Agentで追加のメトリクスを収集
  • CloudWatch / EC2インスタンスの監視
  • CloudWatch Logs / ログの収集
  • CloudWatch Logs / メトリクスフィルタによるログの監視
  • CloudWatch Logs Insights / ログの分析
  • AWS Backup / EC2インスタンスのバックアップ
  • AWS Backup / イベントの通知

EC2 / Nitro Systemで動作するインスタンスタイプを利用

Nitro Systemに対応したインスタンスタイプを使いましょう。

Instances built on the Nitro System

セキュリティやパフォーマンスの面で従来のものより優れているので、是非利用しましょう。

ただし、古いインスタンスタイプからの移行の場合には少し注意が必要な場合もあります。

Migrating to latest generation instance types

EC2 / Key Pairの公開鍵をインポート

ローカルでキーペアを生成して公開鍵をインポートしましょう。

Option 2: Import your own public key to Amazon EC2

既存のEC2インスタンスのKeyを入れ替えることはできないので、新しく作るときはこうしましょうって話です。

秘密鍵含めてAWS側で生成することもできますが、ネットワーク上を通したくないとか、なんとなく気になる方はインポートする方法もあるので、お好みでどうぞ。

Amazon EC2のキーペア生成について、本来あるべき形

EC2 / IAM Roleの割り当て

AWSの認証情報をIAM Roleから取得できるようにしましょう。

IAM roles for Amazon EC2

AWSのAPIをCallする時にアクセスキーを利用することも可能ですが、半永久的に利用できる認証情報なので漏洩すると危険が危ないです。 なので、IAM Roleを割り当ててインスタンスメタデータから一時的なクレデンシャルを取得して利用するのがよいでしょう。

アプリケーションで利用していなくても、後述する様々な管理サービス(Systems Managerなど)で利用するので、必ず理解しておきましょう。

EC2 / IMDSv2の有効化(を検討)

SSRF対策としてIMDSv2を利用することを検討しましょう。

Configuring the instance metadata service

ただし、アプリケーションが対応しているか事前に確認していただく必要があります。

なお、AWSの認証情報を全く利用しないのであればメタデータへのアクセスを無効化するというのもありです。

EC2 / OSの設計を堅牢化(要件に応じたAMIの選択)

セキュリティ要件に応じて、セキュアなAMIを利用しましょう。

WindowsならSTIGに対応したAMIが無償で利用できます。

Amazon EC2 Windows Server AMIs for STIG compliance

マーケットプレイスでCIS Benchmarkに準拠したAMIを購入することもできる。

Center for Internet Security

構築手順がちゃんと残っていて新規構築が可能なケースであれば、既存環境の改善で利用できる余地があるでしょう。 とは言っても、ここまでガチガチにする必要があるケースはそんなに多くないと思います。

EC2 / Time Sync Serviceで時刻同期

Time Sync Serviceで時刻同期をしましょう。

Setting the time for your Linux instance

Setting the time for a Windows instance

ログの時刻が間違ってたら、もうそれはログじゃないですね。

なお、インスタンス作成時に利用するAMIの提供時期やLinuxのディストリビューションによっては最初から設定済みの場合もあります。 よく確認しましょう。

EC2 + CloudWatch / AutoRecoveryの有効化

AutoRecoveryを利用してホストの障害に備えましょう。

Recover your instance

AutoScalingを利用する際には利用することはないですが、長期間同じインスタンスを運用する環境であれば利用を検討するとよいのではないでしょうか。

この機能が動作する条件はやや限定的なので、仕様は正しく利用しよう。

EC2 / OS内のコンポーネントを最新化

OS内のコンポーネントを最新化しましょう。

Configuring your Windows instance

Windowsの場合、以下のようなコンポーネントを利用しています。

このほか、後述するSSM AgentやCloudWatch Agentが構成されていたらそれらも最新の状態に維持するべきです。

破壊的な変更がないかぎり、環境は最新化しましょう。 後述するSystems Managerを利用すれば、更新作業も簡単に実行できます。

EBS + KMS / ボリュームの暗号化

EBSボリュームを暗号化しましょう。

Amazon EBS encryption

これは組織のセキュリティポリシー次第ですが、必要なら暗号化しておきましょう。

Inspector / 脆弱性を評価

EC2インスタンスの脆弱性を評価しましょう。

Getting started with Amazon Inspector

Inspector Agentをインストールすることで、EC2インスタンス内の脆弱性を検出できるようになります。

脆弱性が見つかった場合、リスクの内容に応じて対処するかどうか判断しましょう。 考え方自体はこちらが参考になります。 FutureVulsはいいぞ。

対応方針の検討

パッケージの脆弱性だけでなく、OSの構成やネットワークに関する脆弱な設定を検出することもできます。

Rules packages in Amazon Inspector

Systems Manager / SSM Agentのインストール

Systems Managerを利用するためにAgentをインストールしましょう。 なお、前述の通りAMIによってはインストール済みです。

Installing and configuring SSM Agent on EC2 instances for Linux

Installing and configuring SSM Agent on EC2 instances for Windows Server

後述する様々な機能を利用できます。 利用するにあたっては、IAM Role (Instance Profile)を通して必要な権限を付与しよう。

Step 4: Create an IAM instance profile for Systems Manager

Systems Manager (Patch Manager/RunCommand) / パッチスキャンおよびパッチ適用

適用するべきパッチの有無をスキャンし、必要に応じてパッチの適用を実行しましょう。

AWS Systems Manager Patch Manager

情報は、一番守りの薄いところから漏れます。 「桶の理論 セキュリティ」で検索してみてください。

最近はKernelのパッチ適用をオンラインでできるようにもなっている。

Use Kernel Live Patching on Amazon Linux 2 instances

パッチを個別にインストールしたい場合にはRunCommandが使いやすいかもしれません。 いろいろ試してみましょう。

Systems Manager (Inventory) / インベントリの収集

インベントリを収集しましょう。

AWS Systems Manager Inventory

どんなソフトウェアを利用しているかわからないと、意図せず所有している以上のライセンスを利用している状態になっているかもしれません。 まずは、現状把握から始めましょう。

ライセンスルールの強制までやりたい場合は、License Managerでどうぞ。

What is AWS License Manager?

Systems Manager (Session Manager) / インスタンスの管理操作

EC2での管理操作はSession Managerを利用しましょう。

AWS Systems Manager Session Manager

従来はSecurity GroupでSSHやRDPのアクセスを許可する必要がありますが、 Session Managerを利用すればSecurity Groupでの許可は不要になります(Systems ManagerのAPIに対するアウトバウンドのみでOK)。

Systems Manager (Session Manager) / OSユーザーの指定

Session Managerで利用するOSユーザーを限定しましょう。

Enable run as support for Linux instances

IAMのエンティティに付与するタグやSession Managerの設定により、どのOSユーザーでセッションを開始するか指定できます。 セキュリティ要件に合わせて対応しましょう。

Systems Manager (Session Manager) / ログの収集

Session Managerによる接続および操作ログを取得しましょう。

Auditing and logging session activity

なお、接続の履歴はCloudTrailで取得できます。

接続後の操作はS3もしくはCloudWatch Logsにログを収集できるが、port forwarding および SSHでの接続ではサポートされていないので注意。

監視まではする必要ないと思いますが、抑止力として有効ではないでしょうか。

Systems Manager (Parameter Store) / データベースへの接続情報を保存

DBへの接続情報や設定などにParameter Storeを活用しましょう。

AWS Systems Manager Parameter Store

いろいろ修正が必要にはなるでしょうが、設定ファイルにハードコードするのはさすがにね。。。

CloudWatch / CloudWatch Agentで追加のメトリクスを収集

EC2インスタンスにCloudWatch Agentを利用して、標準のメトリクスには無い情報を取得しましょう。

Collecting Metrics and Logs from Amazon EC2 Instances and On-Premises Servers with the CloudWatch Agent

CPUの利用率やネットワーク転送量などのメトリクスはデフォルトで取得できますが、メモリの利用率やディスクの利用率などのメトリクスはデフォルトでは取得できません。 必要に応じて取得しましょう。

IAM Roleに必要な権限を付与するのもお忘れなく。

Create IAM Roles and Users for Use with the CloudWatch Agent

ウィザードも便利です。

CloudWatch Agent Predefined Metric Sets

CloudWatch / EC2インスタンスの監視

EC2インスタンスの正常性を監視しましょう。

List the available CloudWatch metrics for your instances

CPU / Memoryの利用率の監視(通知)は必須じゃないと思っていて、もしリソースが逼迫していればCloudFrontやELBでレイテンシやステータスコードで異常を検知できるはずで、どちらかというとそちらを監視した方がいいのではないでしょうか。 やるなら、Anomaly Detectionで普段と異なる傾向を監視するくらいでしょうか。

Using CloudWatch Anomaly Detection

ディスクの空き容量は逼迫したタイミングでいきなり問題が顕在化するので、監視していた方がよいと思います。 それ以外にも、EC2インスタンスのステータスも監視しておくといいでしょう(必要に応じて、前述のAutoRecoveryを添えて)。

この辺は絶対的な答えはないと思いますが、絶対ダメなのはオオカミ少年化して通知を誰も見なくなるって状況を作ってしまうことだと思います。 通知を意味のあるものにしましょう。 最初から完璧なものはできないので継続的な改善が大事です。

CloudWatch Logs / ログの収集

必要なログを収集しましょう。

CloudWatch Agent Configuration File: Logs Section

トラブルシューティングなどの際に利用するようなログを保存しておきましょう。

機能が正常に動作しているか、等を確認することが主目的になるかと思います。 もちろん、ログによっては処理に要した時間などを出力させることもあるでしょう。 ここではログ自体の設計については述べませんが、システム運用に必要となる各種ログを整理して必要なものは収集して、保存・分析していきましょう。

CloudWatch Logs / メトリクスフィルタによるログの監視

ログの監視をしましょう。

Creating Metrics From Log Events Using Filters

例えば、アクセスログを監視して特定のステータスコードの数を監視する、といったことが考えられます。

Example: Count HTTP 404 Codes

ログからシステム管理者が何らかのアクションを必要とする状況を検知しなければならないのであれば、利用してみてください。

CloudWatch Logs Insights / ログの分析

ログの分析にCloudWatch Logs Insightsを利用しましょう。

Analyzing Log Data with CloudWatch Logs Insights

それなりに高度な絞り込みができて非常に便利です。

目grepできる人間はどこにでもいるわけじゃないんですよ。

AWS Backup / EC2インスタンスのバックアップ

EC2インスタンスをバックアップしましょう。

Working with Amazon EC2

EC2インスタンス内にデータを保持していて、万が一EC2インスタンスが消滅したときにできるだけ直近の状態を復元する必要がある場合にはバックアップを取得しておきましょう。

データや設定情報を別のデータベースやParameter Storeなどのバックエンドサービスで管理し、EC2インスタンスはGolden AMIやAnsibleなどで復元できるようにしておくのが理想ではあります(バックアップ不要な状況にする)。

AWS Backup / イベントの通知

AWS Backupに関するイベントを通知しましょう。

Using Amazon SNS to Track AWS Backup Events

バックアップできてませんでしたー(てへぺろ)なんて状況が許されるはずがありません。

小まとめ

ここまでの内容をまとめるとこんな感じでしょうか。

データストアの育てかた

さて、最後のレイヤーです。

利用するサービス

  • RDS

・・・今回の想定シーンだと、これだけですね。 RDS、めっちゃ多機能なんですよね。

育てる

やることは以下の通り。

  • RDS / RDSインスタンスにデータベースを移行
  • RDS / Multi-AZを有効化
  • RDS / ボリュームを自動拡張
  • RDS + KMS / ボリュームを暗号化
  • RDS / 通信を暗号化
  • RDS / バックアップを自動化
  • RDS / Performance Insightsを有効化
  • RDS / 拡張モニタリングを有効化
  • RDS / ログを外部に出力
  • RDS / マイナーバージョンアップグレードを管理
  • RDS / 削除保護を有効化
  • RDS / 重要なイベントを通知

RDS / RDSインスタンスにデータベースを移行

RDSを利用してデータベースを移行しましょう。 マネージドはいいぞ。

What Is Amazon Relational Database Service (Amazon RDS)?

現状のままではデータベースサーバーが単一障害点になりますし、データ保護やパフォーマンス管理も面倒です。 RDSに移行しましょう。 どのように便利なのかは、後述します。

なお、RDSの利用を検討する場合、制約に抵触しないかよく確認しましょう。 Oracle DatabaseやSQL Serverの場合は以下のページなどにRDSではサポートされていない機能が明記されています。 これ以外もちゃんと読みつつ、実際に検証して確認しましょう。

Oracle Database Feature Support

Features Not Supported and Features with Limited Support

データベースの移行にはいろんな方法を利用することができますので、状況に応じた方法を選択しましょう。

AWS Database Migration On-Demand Webinar

RDS / Multi-AZを有効化

Multi-AZを有効化しましょう。

High Availability (Multi-AZ) for Amazon RDS

マスターとなるインスタンスで障害が発生しても、すぐにフェールオーバーしてサービスを再開できます。

RDS / ボリュームを自動拡張

ボリュームが逼迫したら自動で拡張するように構成しましょう。

Managing Capacity Automatically with Amazon RDS Storage Autoscaling

データの急増が発生しても、サービス停止という事態を回避するのに役に立つでしょう。 もちろん、こういった状況が発生したということは認識するべきなので、後述するイベント監視は重要です。

RDS + KMS / ボリュームを暗号化

ボリュームを暗号化しましょう。

Encrypting Amazon RDS Resources

これも要件に応じて選択しましょう。

RDS / 通信を暗号化

必要に応じてデータベースクライアントとの通信を暗号化しましょう。

Using SSL/TLS to Encrypt a Connection to a DB Instance

これは、要件やセキュリティポリシーなどでエンドツーエンドの暗号化が要求される時などに利用するといいでしょう。 一般的にはVPC内の通信を暗号化する必要なケースは少ないはずです。

RDS / バックアップを自動化

RDSのバックアップを自動化しましょう。

Backing Up and Restoring an Amazon RDS DB Instance

バックアップウウィンドウや世代数を指定できます。 自動的に取得したスナップショットはインスタンスの削除と共に消える運命にあるので、そこだけ注意しましょう。 あとでデータが必要になる場合には事前に手動でスナップショットを作成しておきましょう。

RDS / Performance Insightsを有効化

Performance Insightsを有効化して遅い原因を分析しましょう。

Overview of Performance Insights

遅いクエリやその原因の特定を支援してくれます。

RDS / 拡張モニタリングを有効化

必要に応じて拡張モニタリングでOSレベルのメトリックを取得しましょう。

Enhanced Monitoring

RDS / ログを外部に出力

各種ログをCloudWatch Logsに保存しましょう。

Publishing Database Logs to Amazon CloudWatch Logs

監査ログの取得できますが、すごい量(コスト)になるので必要な場合にだけ出力するようにしましょう。

RDS / マイナーバージョンアップグレードを管理

自動マイナーバージョンアップの有効化を検討しましょう。

Automatically Upgrading the Minor Engine Version

バージョンアップに伴うダウンタイムのタイミングを制御したい場合には無効にしておきましょう。 ただし、AWS Health APIから発行されるイベントを監視して、マイナーバージョンアップが必要な状況が発生していないか監視しておきましょう。

RDS / 削除保護を有効化

削除保護を有効化しましょう。

Deletion Protection

データが死ぬとサービスが死ぬと思うので、保険として有効化しておくとよいのではないでしょうか。

RDS / 重要なイベントを通知

重要なイベントを通知しましょう。

Using Amazon RDS Event Notification

フェールオーバーの発生など、サービスの可用性・パフォーマンスなどに重大な影響が発生していると思われるイベントの発生を監視しましょう。

小まとめ

ということで、完成したものがこちら。

でかい(小並感)

考察

いかがでしたでしょうか。

いやー、この記事書くのにめっちゃ時間かかりましたw

AWSのサービスは「部品」

こういった改善はちょっとずつ積み重ることができるし、AWSの各種サービスはそういうふうにできている。

この記事を書いていて改めて感じました。

多くの課題を抱えているとどこから手をつけていいか分からなくなりがちですが、冷静に今の環境とその課題を整理し、順番に片付けていきましょう。 今回は「AWSアカウント」「ネットワーク」「サーバー」「データストア」に分類してできることを整理しました。 あとは「アプリケーション」のレイヤーについても検討できればよいでしょう。

全部やる必要があるのか

ないです。

適切な設計をしなかったことによって起こりうる問題の影響度や発生する可能性などを鑑み、 優先度をつけながら投資できる範囲でやっていくしかありません。

何をやって、何をやらないか、考えていきましょ!

理想を思い描いていくことからはじめる

この記事で紹介した内容はあくまでも手段です。 手段を実行する場合、目的があるはずです。

・・・ありますよね?

例えば、様々なセキュリティ対策は第三者による攻撃や内部不正に対して「予防」「検知」「防御」「対応」「復旧」などを実現するために実施されます。 この分類は、NISTのサーバーセキュリティフレームワークで定義されています。 他にもいろんなフレームワークがあるので参考にするとよいでしょう。

【解説】NIST サイバーセキュリティフレームワークの実践的な使い方

監視は正常にサービスをデリバリーできていることを確認し、問題があれば復旧にすぐ着手できるようにするために行われます。 また、迅速にサービスを復旧させるためには監視をしているだけではダメで、問題を特定できるようにするためのログやメトリクスを予め取得しておく必要がありますし、容易に分析するための手段を用意しておくことも重要です。 それ以前に、一部のコンポーネントが壊れてもサービス提供を継続できるようにしておくことが何よりも重要です。 いずれにしても、突き詰めれば「適切な価値提供を継続したい」ってところに行き着くと思います。

求めるものが異なれば、今日紹介したこと意外にもやるべきことは多々あるでしょう。 まずは、理想を確認するところからはじめてはどうでしょうか。

まとめ

ということで、冴えないAWS環境を一通り改善までの流れを書いてみました。 やったこととしては、「新しい要素を追加」「サーバー内の機能を分離してマネージドサービスで実現」の繰り返しかなーという感じでしたね。

状況によっては他にもやるべきことがあると思います。 ぜひご意見をいただければと思います。

現場からは以上です。