コンテンツにスキップ

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

はじめに

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


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

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

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

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

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


02. L2の防御

L2の防御方法

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

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

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

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


推奨されるCIDRブロック

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

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

また、VPCが持つCIDRブロックから、VPC内の各AWSリソースにIPアドレスを割り当てていかなければならず、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


VPCによる防御

▼ VPC全体のCIDRブロック

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

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

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

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

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

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


サブネットによる防御

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

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

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

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

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

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

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

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

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

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

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

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

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

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

subnet_accsess-type

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

subnet_component-type

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

名前 種類 役割 配置例
frontendサブネット パブリック 非武装地帯として動作する。L7ロードバランサー、ルーター、踏み台サーバー、を配置する。 ALB、NAT Gateway
applicationサブネット プライベート 内部ネットワークとして動作する。appサーバー、リバースプロキシサーバー、を配置する。 EC2、Fargate
datastoreサブネット プライベート 内部ネットワークとして動作する。dbサーバーを配置する。 RDS、Redis


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

route-table

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

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

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

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

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

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

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

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

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

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

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

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

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


03. L3の防御

L3の防御方法

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


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

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

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

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

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

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

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

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

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

▼ アプリケーションEC2の場合

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

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

▼ 踏み台EC2の場合

タイプ プロトコル ポート ソース 説明
SSH TCP 22 社内のグローバルIPアドレス SSH access from global ip address

▼ EFSの場合

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

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

▼ RDSの場合

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

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

▼ Redisの場合

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

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

▼ ALBの場合

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

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

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

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

▼ NLBの場合

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

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

▼ VPCエンドポイント

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

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

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


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

▼ ALBの場合

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

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


03-03. Transit Gateway

Transit Gatewayによる防御

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


04. L7の防御

L7の防御方法

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

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


04-02. WAF

WAFによる防御

L7の攻撃を防御する。


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アドレス以外の場合、全てのパスにリクエストを送信することを拒否する。

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

*例*

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

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ヘッダー以外に対するアクセスの場合、アクセスすることを許可する。


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

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

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

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

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

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

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

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

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


04-03. Certificate Manager

Certificate Managerによる防御

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

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

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


04-04. Systems Manager

Systems Managerによる防御

開発者がEC2へリモート接続する方法として、Systems Managerのセッションマネージャーを採用する。

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