コンテンツにスキップ

アプリケーションデータ安全性@AWS

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. ネットワークレイヤー

OSI層とAWSリソースの対応関係

OSI 層と AWS リソースの対応関係を以下に示す。

AWS リソースごとにセキュリティを考慮する。

OSI層 OSI層の番号 対応するAWSリソース
アプリケーション層 L7 AWS ALB、Amazon EC2、Amazon RDS、Amazon Route 53、Amazon S3
プレゼンテーション層 L6 同上
セッション層 L5 同上
トランスポート層 L4 セキュリティグループ、AWS NLB
ネットワーク層 L3 AWS Internet Gateway、AWS NAT Gateway、AWS Transit Gateway
データリンク層 L2 Amazon VPC、サブネット
物理層 L1 仮想化のため、意識しなくてもよい。


02. L2 の防御

L2 の防御方法

L2 の攻撃を Amazon VPC やプライベートサブネットで防御する。

例えば、システムのコンポーネントごとに異なるプライベートサブネット (アプリ、DB、外部オンプレシステムへのプロキシ) を設ける。

これにより、いずれかのコンポーネントに侵入されても、他コンポーネントへの侵入を最小限に防げる。

なお、パブリックサブネットには Amazon EC2 は置かない。


推奨されるCIDRブロック

1 個の Amazon VPC 内には複数のサブネットが入る。

そのため、サブネットの CIDR ブロックは、サブネットの個数だけ含めなければならない。

また、Amazon VPC が持つ CIDR ブロックから、Amazon VPC 内の各 AWS リソースに IP アドレスを割り当てていかなければならず、Amazon VPC 内で IP アドレスが枯渇しないようにする。

RFC1918 では、以下の CIDR ブロックが推奨である。

RFC1918推奨のCIDRブロック IPアドレス 個数
10.0.0.0/8 10.0.0.010.255.255.255 16777216
172.16.0.0/12 172.16.0.0172.31.255.255 1048576
192.168.0.0/16 192.168.0.0192.168.255.255 65536


Amazon VPCによる防御

▼ Amazon VPC全体のCIDRブロック

あらかじめ、会社内のすべてのアプリケーションの CIDR ブロックをスプレッドシートなどで一括で管理しておく。

このとき、CIDR ブロックと、これの開始 IP アドレスと終了 IP アドレスをメモしておくとよい。

各アプリケーション間で Transit Gateway やピアリング接続を利用する可能性がある場合は、注意する。

拡張性を考慮して、アプリケーション間の CIDR ブロックは重ならないようにしておく必要がある。

例えば、以前に開発したアプリケーションが 10.200.47.0 までを使用していた場合、10.200.48.0 から使用を始める。

また、Amazon VPC で許可される IP アドレスの個数は最多 65536 個 (/16) で最少 16 個 (*.*.*.*/28) であり、実際は 512 個 (*.*.*.*/23) ほどあれば問題ないため、10.200.48.0/23 を設定する。


サブネットによる防御

▼ サブネット分割のメリット

サブネットを分割することにより、他のサブネットのネットワーク障害の影響を防いだり、サブネット間のアクセスを制限できる。

▼ 各サブネットのCIDRブロック

Amazon VPC の IP アドレスの最初から、パブリックサブネットとプライベートサブネットを割り当てる。

このとき、Amazon VPC 内の各 AWS リソースの特徴に合わせて、CIDR ブロックを割り当てる。

例えば、Amazon VPC の最初の IP アドレスを 10.0.0.0 とした場合は、1 つ目のパブリックサブネットのサブネットマスクは、10.0.0.0 から始める。

パブリックサブネットとプライベートサブネットを冗長化する場合は、Amazon VPC の IP アドレス数をサブネット数で割って各サブネットの IP アドレス数を算出し、CIDR ブロックを設定する。

例えば、Amazon VPC のサブネットマスクを /16 としている場合は、各サブネットのサブネットマスクは /24 とする。

一方で、Amazon VPC を /23 としている場合は、各サブネットは /27 とする。

また、各サブネットの CIDR ブロックを同じにする必要はない。例えば、アプリケーションが稼働するサブネットの IP アドレス数がやや多くなるようにし、代わりに、DB の稼働するサブネットの IP アドレス数を少なくする設計でもよい。

AWSリソース 最低限のIPアドレス数
AWS ALB AWS ALB当たり 8
AWS AutoScaling 自動水平スケーリング時のAmazon EC2最大数と同じ個数
Amazon VPCエンドポイント Amazon VPCエンドポイント当たり、IPアドレス 1
Amazon ECS、Amazon EKS Elastic Network Interface 数と同じ個数
AWS Lambda Elastic Network Interface 数と同じ個数

▼ アクセスタイプ別の命名

パブリックネットワークとの通信の遮断具合から名前をつける。

名前 種類 役割 配置例
publicサブネット パブリック 非武装地帯として動作する。Internet Gatewayを介して、パブリックネットワークからのリクエストを待ち受ける。 AWS ALB、AWS NAT Gateway
protectedサブネット プライベート 内部ネットワークとして動作する。パブリックネットワークからアクセスできず、同じAmazon VPC内からのリクエストのみを待ち受ける。また、publicサブネットのAWS NAT Gatewayを介してリクエストを送信する。 Amazon EC2、Fargate
privateサブネット プライベート 内部ネットワークとして動作する。パブリックネットワークからアクセスできず、前述のprotectedサブネット内からのリクエストのみを待ち受ける。また、リクエストを送信しない。 Amazon RDS、Redis

subnet_accsess-type

▼ コンポーネントタイプ別の命名

subnet_component-type

配置するコンポーネントの種類に関する名前をつける。

名前 種類 役割
frontendサブネット パブリック 非武装地帯として動作する。L7 ロードバランサー (AWS ALB) 、ルーター (AWS NAT Gateway) 、ssh コマンドで接続する踏み台サーバー (Amazon EC2) を配置する。
applicationサブネット プライベート 内部ネットワークとして動作する。Appサーバー (Amazon EC2、Amazon ECS、Amazon EKS) 、リバースプロキシサーバー (Amazon EC2、Amazon ECS、Amazon EKS) 、AWS SSM Session Managerで接続する踏み台サーバー (Amazon EC2) を配置する。
datastoreサブネット プライベート 内部ネットワークとして動作する。DBサーバー (Amazon Aurora、AWS Redis) を配置する。


ルートテーブルによる防御

route-table

▼ プライベートサブネットのリクエストをパブリックネットワークに公開する場合

上の図中で、サブネット 3 にはルートテーブル 2 が紐付けられている。

サブネット 3 内の宛先のプライベート IP アドレスが、10.0.0.0/16 の範囲内にあれば、リクエストと見なし、local (Amazon VPC 内の他サブネット) を宛先に選択する。

一方で、0.0.0.0/0 (local 以外の全 IP アドレス) の範囲内にあれば、リクエストと見なし、Internet Gateway を宛先に選択する。

Destination (プライベートCIDRブロック) Target
10.0.0.0/16 (Amazon VPCのCIDRブロック) local
0.0.0.0/0 Internet Gateway

▼ プライベートサブネットのリクエストをAmazon VPC内に閉じる場合

上の図中で、サブネット 2 にはルートテーブル 1 が紐付けられている。

サブネット 2 内の宛先のプライベート IP アドレスが、10.0.0.0/16 の範囲内にあれば、リクエストと見なし、local (Amazon VPC 内の他サブネット) を宛先に選択する。

一方で、範囲外にあれば通信を破棄する。

Destination (プライベートCIDRブロック) Target
10.0.0.0/16 (Amazon VPCのCIDRブロック) local

▼ プライベートサブネットのリクエストを同一サブネット内に閉じる場合

プライベートサブネットでネットワークを完全に閉じる場合、ルートテーブルにサブネットの CIDR ブロックを設定する。

Destination (プライベートCIDRブロック) Target
10.0.0.0/24 (サブネット 1 のCIDRブロック) local


03. L3 の防御

L3 の防御方法

L3 の攻撃をセキュリティグループや Transit Gateway で防御する。


03-02. セキュリティグループ

セキュリティグループによる防御

L3 の攻撃をセキュリティグループで防御する。

例えば、Amazon EKS の Node グループごとに異なるセキュリティグループを紐づけている。

ネットワークに公開する Node グループのセキュリティグループでは、特定の送信元 IP アドレスからのアクセスのみを許可する。

公開しない Node グループでは、他の Node グループの Amazon EC2 からのみアクセスを許可する。

これらにより、インターネットからは信頼できるクライアントからのアクセスのみを受信し、Node グループ間でも最小限のアクセスのみに制限できる

なお、ACL でも L3 を防御できるが、ネットワークが複雑になることを防ぐために ACL では通信制限は採用しなくてもよい。

セキュリティグループ (インバウンド) による防御

▼ アプリケーションサーバー (Amazon EC2) の場合

AWS ALB に割り振られる可能性のある IP アドレスを許可するために、AWS ALB のセキュリティグループ ID、またはサブネットの CIDR ブロックを設定する。

タイプ プロトコル ポート ソース 説明
HTTP TCP 80 AWS ALBのセキュリティグループID HTTP access from AWS ALB
HTTPS TCP 443 踏み台サーバー (Amazon EC2) のセキュリティグループID SSH access from bastion Amazon EC2

ssh コマンドで接続する踏み台サーバー (Amazon EC2) の場合

ssh コマンドで踏み台サーバー (Amazon EC2) に接続する場合、踏み台サーバー (Amazon EC2) をパブリックサブネットに配置する必要がある。

また、セキュリティグループのインバウンドルールで SSH プロトコルを許可する必要がある。

$ ssh -o serveraliveinterval=60 -f -N -L 3306:<Amazon Auroraのリーダーエンドポイント>:3306 -i "~/.ssh/foo.pem" <踏み台サーバーの実行ユーザー>@<踏み台サーバーのホスト> -p 22
タイプ プロトコル ポート ソース 説明
SSH TCP 22 社内のグローバルIPアドレス SSH access from global ip address

▼ AWS SSM Session Managerで接続する踏み台サーバー (Amazon EC2) の場合

aws ssm start-session コマンドで踏み台サーバー (Amazon EC2) に接続する場合、踏み台サーバー (Amazon EC2) をプライベートサブネットに配置できる。

また、セキュリティグループのインバウンドルールでは何も許可する必要がない。

$ aws ssm start-session --target <踏み台サーバー (Amazon EC2) インスタンスID> \
    --document-name AWS-StartPortForwardingSessionToRemoteHost \
    --parameters '{"host":["<Amazon Auroraのクラスターエンドポイント>"],"portNumber":["<踏み台サーバー (Amazon EC2) のポート番号>"], "localPortNumber":["<ローカルPCのポート番号>"]}'
タイプ プロトコル ポート ソース 説明
設定なし 設定なし 設定なし 設定なし 設定なし

▼ EFSの場合

Amazon EC2 に割り振られる可能性のある IP アドレスを許可するために、Amazon EC2 のセキュリティグループ ID、またはサブネットの CIDR ブロックを設定する。

タイプ プロトコル ポート ソース 説明
NFS TCP 2049 Amazon EC2のセキュリティグループID NFS access from app Amazon EC2

▼ Amazon RDSの場合

Amazon EC2 に割り振られる可能性のある IP アドレスを許可するために、Amazon EC2 のセキュリティグループ ID、またはサブネットの CIDR ブロックを設定する。

タイプ プロトコル ポート ソース 説明
MYSQL/Amazon Aurora TCP 3306 Amazon EC2のセキュリティグループID MYSQL access from app Amazon EC2

▼ Redisの場合

Amazon EC2 に割り振られる可能性のある IP アドレスを許可するために、Amazon EC2 のセキュリティグループ ID、またはサブネットの CIDR ブロックを設定する。

タイプ プロトコル ポート ソース 説明
カスタムTCP TCP 6379 Amazon EC2のセキュリティグループID TCP access from app Amazon EC2

▼ AWS ALBの場合

Amazon CloudFront と連携する場合、Amazon CloudFront に割り振られる可能性のある IP アドレスを許可するために、すべての IP アドレスを許可する。

代わりに、Amazon CloudFront に AWS WAF を紐付け、AWS ALB の前で IP アドレスを制限する。

Amazon CloudFront とは連携しない場合、AWS ALB のセキュリティグループで IP アドレスを制限する。

タイプ プロトコル ポート ソース 説明
HTTP TCP 80 0.0.0.0/0 HTTP access from Amazon CloudFront
HTTPS TCP 443 0.0.0.0/0 HTTPS access from Amazon CloudFront

▼ NLBの場合

NLB はセキュリティグループをサポートしていない。

そのため、NLB のルーティング先 (Amazon EC2 など) でファイアーウォールを設定する必要がある。

▼ Amazon VPCエンドポイント

Amazon VPC 内から Amazon VPC 外への通信は、Amazon VPC エンドポイントで安全に通信する。

例えば、Amazon EC2 Node から Amazon VPC 外 AWS リソースへの通信では、Amazon VPC エンドポイントを使用する。

Amazon VPC エンドポイントのセキュリティグループでは、Amazon VPC の CIDR からのアウトバウンド通信のみを許可するとよい。


セキュリティグループ (アウトバウンド) による防御

▼ AWS ALBの場合

AWS ALB から Amazon EC2 にリクエストをルーティングする場合、特定の Amazon EC2 のみへのルーティングを許可するために、アウトバウンド通信のルールで Amazon EC2 のセキュリティグループ ID を設定する。

タイプ プロトコル ポート 宛先 説明
HTTPS TCP 443 宛先のAmazon EC2のセキュリティグループID Full access


03-03. Transit Gateway

Transit Gatewayによる防御

AWS データセンター間の通信で使用する Transit Gateway であれば、パケットの物理レイヤーを暗号化できる。


04. L7 の防御

L7 の防御方法

L7 の攻撃を AWS WAF や Certificate Manager で防御する。

代わりに、アプリケーションの実装で防御してもよい。


04-02. AWS WAF

AWS WAFによる防御

L7 の攻撃を防御する。


AWS WAFルールによる防御

▼ ユーザーエージェント拒否

*例*

悪意のあるユーザーエージェントを拒否する。

ルール:block-user-agents

Statementの順番 If a request Inspect Match type Regex pattern set Then 挙動
0 matches URI path Matches pattern from regex pattern set 文字列セット Block 指定した文字列を含むユーザーエージェントの場合、アクセスすることを拒否する。
Default Action 説明
Allow 指定したユーザーエージェントでない場合、すべてのパスにリクエストを送信することを許可する。

▼ CIツールのアクセスを許可

*例*

社内の送信元 IP アドレスのみ許可した状態で、CI ツール (例:GitHub Actions、CircleCI、GitLab CI、Argo Workflows、Tekton など) が社内サービスにリクエストを送信できるようにする。

ルール:allow-request-including-access-token

Statementの順番 If a request Inspect Header field name Match type String to match Then 挙動
0 matches Header Authorization Exactly matched string Bearer <アクセストークン文字列>』で文字列を設定する Allow Authorization ヘッダーに指定した文字列を含むリクエストの場合、アクセスすることを拒否する。
Default Action 説明
Block 正しいトークンを持たないアクセスの場合、すべてのパスにリクエストを送信することを拒否する。

▼ 特定のパスを社内アクセスに限定

*例*

アプリケーションでは、特定の URL パスにリクエストを送信できる送信元 IP アドレスを社内だけに制限する。

2 個のルールを作成する必要がある。

ルール:allow-access--to-url-path

Statementの順番 If a request Inspect IP set Match type Regex pattern set Then 挙動
0 matches (AND) Originates from an IP address in 社内IPセット - - - 社内の送信元IPアドレスの場合、指定したパスにリクエストを送信することを許可する。
1 matches URI path - Matches pattern from regex pattern set 文字列セット Allow 0番目かつ、指定した文字列を含むURLパスアクセスの場合、アクセスすることを許可する。

ルール:block-access-to-url-path

Statementの順番 If a request Inspect Match type Regex pattern set Then 挙動
0 matches URI path Matches pattern from regex pattern set 文字列セット Block 指定した文字列を含むURLパスアクセスの場合、アクセスすることを拒否する。
Default Action 説明
Allow 指定したURLパス以外のアクセスの場合、そのパスにリクエストを送信することを許可する。

▼ 社内アクセスに限定

*例*

アプリケーション全体にリクエストを送信できる送信元 IP アドレスを、特定の IP アドレスだけに制限する。

ルール:allow-global-ip-addresses

Statementの順番 If a request Inspect IP set Originating address Then 挙動
0 matches (OR) Originates from an IP address in 社内IPセット Source IP address - 社内の送信元IPアドレスの場合、すべてのパスにリクエストを送信することを許可する。
1 matches Originates from an IP address in 協力会社IPセット Source IP address Allow 0番目あるいは、協力会社の送信元IPアドレスの場合、すべてのパスにリクエストを送信することを許可する。
Default Action 説明
Block 指定した送信元IPアドレス以外の場合、すべてのパスにリクエストを送信することを拒否する。

▼ AWS ALBを直接的に指定することを防ぐ

*例*

Amazon Route 53 のドメイン経由ではなく、AWS ALB の直接的に指定して、リクエストとを送信することを防ぐ。

AWS ALB の IP アドレスは定期的に変化するため、任意の IP アドレスを指定できる正規表現を定義する必要がある。

^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$

ルール:block-direct-access-to-lb

Statementの順番 If a request Inspect Match type Regex pattern set Then 挙動
0 matches Header Matches pattern from regex pattern set 文字列セット Block 指定した Host ヘッダーに対するアクセスの場合、アクセスすることを拒否する。
Default Action 説明
Allow 指定した Host ヘッダー以外に対するアクセスの場合、アクセスすることを許可する。


AWS WAFマネージドルールによる防御

▼ AWS WAFマネージドルールとは

AWS が事前に用意している防御ルールで、よくある L7 に対するサイバー攻撃(例:SQL インジェクション、XSS、OS コマンドインジェクション)を防御できる。

▼ マネージドルールの動作確認の必要性

マネージドルールを導入するときは、事前にルールのカウントを使用することが推奨である。

カウントで検知されたリクエストのほとんどが悪意のないものであれば、設定したマネージドルールの使用をやめる必要がある。

▼ ブラウザを送信元とした場合

ブラウザを送信元とした場合、リクエストのヘッダーやボディはブラウザによって作成されるため、これに基づいた判断が必要である。

  • ブラウザからのリクエスト自体が悪意判定されているか
  • サイトの URL の記法が原因で悪意判定されているか
  • 送信元の国名が『日本』であっても悪意判定されているか
  • サイトに送信された全リクエストのうち、カウントで検知されたリクエスト数が多すぎないか

▼ 連携するアプリケーションを送信元とした場合

アプリケーションを送信元とした場合、リクエストのヘッダーやボディは連携するアプリケーションによって作成されるため、これに基づいた判断が必要である。


04-03. Certificate Manager

Certificate Managerによる防御

アプリケーションデータの暗号化のために、Certificate Manager (L7) を使用する。

リクエストを受信する AWS リソース (例:AWS ALB、Amazon Aurora Amazon RDS、Amazon CloudFront、Amazon EC2/Amazon ECS/Amazon EKS など) に紐づけられる。

安全性と利便性から、パブリックネットワークと信頼できるネットワーク (例:データセンター、プライベートネットワークなど) の境界を SSL/TLS 終端とすることが多い。


04-04. AWS Systems Manager

AWS Systems Managerによる防御

開発者が Amazon EC2 へリモート接続する方法として、AWS SSM Session Manager を採用する。

SSH 公開鍵認証を採用しないことにより、SSH 公開鍵を管理する負荷や漏洩のリスクを低減する。