コンテンツにスキップ

アプリケーションデータ安全性@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公開鍵を管理する負荷や漏洩のリスクを低減する。