アプリケーションデータ安全性@AWS¶
はじめに¶
本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。
01. ネットワークレイヤー¶
OSI層とAWSリソースの対応関係¶
OSI層とAWSリソースの対応関係を以下に示す。
AWSリソースごとにセキュリティを考慮する。
OSI層 | OSI層の番号 | 対応するAWSリソース |
---|---|---|
アプリケーション層 | L7 |
ALB、AWS EC2、AWS RDS、AWS Route53、S3 |
プレゼンテーション層 | L6 |
同上 |
セッション層 | L5 |
同上 |
トランスポート層 | L4 |
セキュリティグループ、NLB |
ネットワーク層 | L3 |
Internet Gateway、AWS NAT Gateway、Transit Gateway |
データリンク層 | L2 |
AWS VPC、サブネット |
物理層 | L1 |
仮想化のため、意識しなくても良い。 |
02. L2
の防御¶
L2
の防御方法¶
L2
の攻撃をAWS VPCやプライベートサブネットで防御する。
例えば、システムのコンポーネントごとに異なるプライベートサブネット (アプリ、DB、外部オンプレシステムへのプロキシ) を設ける。
これにより、いずれかのコンポーネントに侵入されても、他コンポーネントへの侵入を最小限に防げる。
なお、パブリックサブネットにはAWS EC2は置かない。
推奨されるCIDRブロック¶
1
個のAWS VPC内には複数のサブネットが入る。
そのため、サブネットのCIDRブロックは、サブネットの個数だけ含めなければならない。
また、AWS VPCが持つCIDRブロックから、AWS VPC内の各AWSリソースにIPアドレスを割り当てていかなければならず、AWS VPC内でIPアドレスが枯渇しないようにする。
RFC1918では、以下のCIDRブロックが推奨である。
RFC1918推奨のCIDRブロック | IPアドレス | 個数 |
---|---|---|
10.0.0.0/8 |
10.0.0.0 ~10.255.255.255 |
16777216 |
172.16.0.0/12 |
172.16.0.0 ~172.31.255.255 |
1048576 |
192.168.0.0/16 |
192.168.0.0 ~192.168.255.255 |
65536 |
AWS VPCによる防御¶
▼ AWS VPC全体のCIDRブロック¶
あらかじめ、会社内の全てのアプリケーションのCIDRブロックをスプレッドシートなどで一括で管理しておく。
この時、CIDRブロックと、これの開始IPアドレスと終了IPアドレスをメモしておくと良い。
各アプリケーション間でTransit Gatewayやピアリング接続を実行する可能性がある場合は。
拡張性を考慮して、アプリケーション間のCIDRブロックは重ならないようにしておく必要がある。
例えば、以前に開発したアプリケーションが10.200.47.0
までを使用していた場合、10.200.48.0
から使用を始める。
また、AWS VPCで許可されるIPアドレスの個数は最多65536
個 (/16
) で最少16個 (*.*.*.*/28
) であり、実際は512
個 (*.*.*.*/23
) ほどあれば問題ないため、10.200.48.0/23
を設定する。
サブネットによる防御¶
▼ サブネット分割のメリット¶
サブネットを分割することにより、他のサブネットのネットワーク障害の影響を防いだり、サブネット間のアクセスを制限できる。
▼ 各サブネットのCIDRブロック¶
AWS VPCのIPアドレスの最初から、パブリックサブネットとプライベートサブネットを割り当てる。
この時、AWS VPC内の各AWSリソースの特徴に合わせて、CIDRブロックを割り当てる。
例えば、AWS VPCの最初のIPアドレスを10.0.0.0
とした場合は、1つ目のパブリックサブネットのサブネットマスクは、10.0.0.0
から始める。
パブリックサブネットとプライベートサブネットを冗長化する場合は、AWS VPCのIPアドレス数をサブネット数で割って各サブネットのIPアドレス数を算出し、CIDRブロックを設定する。
例えば、AWS VPCのサブネットマスクを/16
としている場合は、各サブネットのサブネットマスクは/24
とする。
一方で、AWS VPCを/23
としている場合は、各サブネットは/27
とする。
また、各サブネットのCIDRブロックを同じにする必要はなく、アプリケーションが稼働するサブネットにIPアドレス数がやや多くなるようにし、代わりに、DBの稼働するサブネットのIPアドレスを少なくするような設計でも良い。
AWSリソース | 最低限のIPアドレス数 |
---|---|
ALB | ALB当たり8 個 |
AutoScaling | 自動水平スケーリング時のAWS EC2最大数と同じ個数 |
AWS VPCエンドポイント | AWS VPCエンドポイント当たり、IPアドレス1 個 |
AWS ECS、AWS EKS | Elastic Network Interface 数と同じ個数 |
Lambda | Elastic Network Interface 数と同じ個数 |
▼ アクセスタイプ別の命名¶
パブリックネットワークとの通信の遮断具合から名前をつける。
名前 | 種類 | 役割 | 配置例 |
---|---|---|---|
publicサブネット | パブリック | 非武装地帯として動作する。Internet Gatewayを介して、パブリックネットワークからのリクエストを待ち受ける。 | ALB、AWS NAT Gateway |
protectedサブネット | プライベート | 内部ネットワークとして動作する。パブリックネットワークからアクセスできず、同じAWS VPC内からのリクエストのみを待ち受ける。また、publicサブネットのAWS NAT Gatewayを介してリクエストを送信する。 | AWS EC2、Fargate |
privateサブネット | プライベート | 内部ネットワークとして動作する。パブリックネットワークからアクセスできず、前述のprotectedサブネット内からのリクエストのみを待ち受ける。また、リクエストを送信しない。 | AWS RDS、Redis |
▼ コンポーネントタイプ別の命名¶
配置するコンポーネントの種類に関する名前をつける。
名前 | 種類 | 役割 | 配置例 |
---|---|---|---|
frontendサブネット | パブリック | 非武装地帯として動作する。L7 ロードバランサー、ルーター、踏み台サーバー、を配置する。 |
ALB、AWS NAT Gateway |
applicationサブネット | プライベート | 内部ネットワークとして動作する。appサーバー、リバースプロキシサーバー、を配置する。 | AWS EC2、Fargate |
datastoreサブネット | プライベート | 内部ネットワークとして動作する。dbサーバーを配置する。 | AWS RDS、Redis |
ルートテーブルによる防御¶
▼ プライベートサブネットのリクエストをパブリックネットワークに公開する場合¶
上の図中で、サブネット3
にはルートテーブル2
が紐付けられている。
サブネット3内の宛先のプライベートIPアドレスが、10.0.0.0/16
の範囲内にあれば、リクエストと見なし、local (AWS VPC内の他サブネット) を宛先に選択する。
一方で、0.0.0.0/0
(local以外の全IPアドレス) の範囲内にあれば、リクエストと見なし、Internet Gatewayを宛先に選択する。
Destination (プライベートCIDRブロック) | Target |
---|---|
10.0.0.0/16 (AWS VPCのCIDRブロック) |
local |
0.0.0.0/0 |
Internet Gateway |
▼ プライベートサブネットのリクエストをAWS VPC内に閉じる場合¶
上の図中で、サブネット2
にはルートテーブル1が紐付けられている。
サブネット2
内の宛先のプライベートIPアドレスが、10.0.0.0/16
の範囲内にあれば、リクエストと見なし、local (AWS VPC内の他サブネット) を宛先に選択する。
一方で、範囲外にあれば通信を破棄する。
Destination (プライベートCIDRブロック) | Target |
---|---|
10.0.0.0/16 (AWS VPCのCIDRブロック) |
local |
▼ プライベートサブネットのリクエストを同一サブネット内に閉じる場合¶
プライベートサブネットでネットワークを完全に閉じる場合、ルートテーブルにサブネットのCIDRブロックを設定する。
Destination (プライベートCIDRブロック) | Target |
---|---|
10.0.0.0/24 (サブネット1 のCIDRブロック) |
local |
03. L3
の防御¶
L3
の防御方法¶
L3
の攻撃をセキュリティグループやTransit Gatewayで防御する。
03-02. セキュリティグループ¶
セキュリティグループによる防御¶
L3
の攻撃をセキュリティグループで防御する。
例えば、AWS EKSのNodeグループごとに異なるセキュリティグループを紐づけている。
ネットワークに公開するNodeグループのセキュリティグループでは、特定の送信元IPアドレスからのアクセスのみを許可する。
公開しないNodeグループでは、他のNodeグループのAWS EC2からのみアクセスを許可する。
これらにより、インターネットからは信頼できるクライアントからのアクセスのみを受信し、Nodeグループ間でも最小限のアクセスのみに制限できる
なお、ACLでもL3
を防御できるが、ネットワークが複雑になることを防ぐためにACLでは通信制限は採用しなくてもよい。
セキュリティグループ (インバウンド) による防御¶
▼ アプリケーションAWS EC2の場合¶
ALBに割り振られる可能性のあるIPアドレスを許可するために、ALBのセキュリティグループID、またはサブネットのCIDRブロックを設定する。
タイプ | プロトコル | ポート | ソース | 説明 |
---|---|---|---|---|
HTTP | TCP | 80 |
ALBのセキュリティグループID | HTTP access from ALB |
HTTPS | TCP | 443 |
踏み台AWS EC2のセキュリティグループID | SSH access from bastion AWS EC2 |
▼ 踏み台AWS EC2の場合¶
タイプ | プロトコル | ポート | ソース | 説明 |
---|---|---|---|---|
SSH | TCP | 22 |
社内のグローバルIPアドレス | SSH access from global ip address |
▼ EFSの場合¶
AWS EC2に割り振られる可能性のあるIPアドレスを許可するために、AWS EC2のセキュリティグループID、またはサブネットのCIDRブロックを設定する。
タイプ | プロトコル | ポート | ソース | 説明 |
---|---|---|---|---|
NFS | TCP | 2049 |
AWS EC2のセキュリティグループID | NFS access from app AWS EC2 |
▼ AWS RDSの場合¶
AWS EC2に割り振られる可能性のあるIPアドレスを許可するために、AWS EC2のセキュリティグループID、またはサブネットのCIDRブロックを設定する。
タイプ | プロトコル | ポート | ソース | 説明 |
---|---|---|---|---|
MYSQL/Aurora | TCP | 3306 |
AWS EC2のセキュリティグループID | MYSQL access from app AWS EC2 |
▼ Redisの場合¶
AWS EC2に割り振られる可能性のあるIPアドレスを許可するために、AWS EC2のセキュリティグループID、またはサブネットのCIDRブロックを設定する。
タイプ | プロトコル | ポート | ソース | 説明 |
---|---|---|---|---|
カスタムTCP | TCP | 6379 |
AWS EC2のセキュリティグループID | TCP access from app AWS EC2 |
▼ ALBの場合¶
AWS CloudFrontと連携する場合、AWS CloudFrontに割り振られる可能性のあるIPアドレスを許可するために、全てのIPアドレスを許可する。
代わりに、AWS CloudFrontにAWS WAFを紐付け、ALBの前でIPアドレスを制限する。
AWS CloudFrontとは連携しない場合、ALBのセキュリティグループでIPアドレスを制限する。
タイプ | プロトコル | ポート | ソース | 説明 | |
---|---|---|---|---|---|
HTTP | TCP | 80 |
0.0.0.0/0 |
HTTP access from AWS CloudFront | |
HTTPS | TCP | 443 |
0.0.0.0/0 |
HTTPS access from AWS CloudFront |
▼ NLBの場合¶
NLBはセキュリティグループをサポートしていない。
そのため、NLBのルーティング先 (AWS EC2など) でファイアーウォールを設定する必要がある。
▼ AWS VPCエンドポイント¶
AWS VPC内からAWS VPC外への通信は、AWS VPCエンドポイントで安全に通信する。
例えば、AWS EC2 NodeからAWS VPC外AWSリソースへの通信では、AWS VPCエンドポイントを使用する。
AWS VPCエンドポイントのセキュリティグループでは、AWS VPCのCIDRからのアウトバウンド通信のみを許可するとよい。
セキュリティグループ (アウトバウンド) による防御¶
▼ ALBの場合¶
ALBからAWS EC2にリクエストをルーティングする場合、特定のAWS EC2のみへのルーティングを許可するために、アウトバウンドのルールでAWS EC2のセキュリティグループIDを設定する。
タイプ | プロトコル | ポート | 宛先 | 説明 |
---|---|---|---|---|
HTTPS | TCP | 443 |
宛先のAWS 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アドレス以外の場合、全てのパスにリクエストを送信することを拒否する。 |
▼ ALBを直接的に指定することを防ぐ¶
*例*
AWS 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 ヘッダー以外に対するアクセスの場合、アクセスすることを許可する。 |
AWS WAFマネージドルールによる防御¶
▼ マネージドルールの動作確認の必要性¶
マネージドルールを導入する時は、事前にルールのカウントを使用することが推奨である。
カウントで検知されたリクエストのほとんどが悪意のないものであれば、設定したマネージドルールの使用をやめる必要がある。
▼ ブラウザを送信元とした場合¶
ブラウザを送信元とした場合、リクエストのヘッダーやボディはブラウザによって作成されるため、これに基づいた判断が必要である。
- ブラウザからのリクエスト自体が悪意判定されているか否か
- サイトのURLの記法によって、悪意判定されているか否か
- 送信元の国名が『日本』であるのにも関わらず、悪意判定されているか否か
- サイトに送信された全リクエストのうち、カウントで検知されたリクエスト数が多すぎないか否か
▼ 連携するアプリケーションを送信元とした場合¶
アプリケーションを送信元とした場合、リクエストのヘッダーやボディは連携するアプリケーションによって作成されるため、これに基づいた判断が必要である。
04-03. Certificate Manager¶
Certificate Managerによる防御¶
アプリケーションデータの暗号化のために、Certificate Manager (L7
) を使用する。
リクエストを受信するAWSリソース (例:ALB、Aurora AWS RDS、AWS CloudFront、AWS EC2/AWS ECS/AWS EKSなど) に紐づけられる。
安全性と利便性から、パブリックネットワークと信頼できるネットワーク (例:データセンター、プライベートネットワークなど) の境界をSSL/TLS終端とすることが多い。
04-04. AWS Systems Manager¶
AWS Systems Managerによる防御¶
開発者がAWS EC2へリモート接続する方法として、AWS Systems Managerのセッションマネージャーを採用する。
SSH公開鍵認証を採用しないことにより、SSH公開鍵を管理する負荷や漏洩のリスクを低減する。