こんにちは、臼田です。
みなさん、アクセス制御してますか?(挨拶
今回はAWSに対するめちゃくちゃ厳しいアクセス制限が必要なユースケースの実装方法についての話です。前提の話からつらつら書いていきます。
実現したいことと課題
「AWSアカウントレベルでアクセス制御したい」
これは普通の課題です。AWSアカウントは大きなテナントの区切りであり、アクセス制御その他の分界点です。一般にはAWSに対するコントロールはIAMで行われ、これを管理・制御することでアクセス制御できます。
「社員のPCから許可したAWSアカウントへのアクセスのみ許可したい」
これは結構難しいです。端末側の管理の課題もありますし、AWSではアカウント単位のアクセスをドメインやパラメータなどで制御することが難しいです。ブラウザからのアクセスは全て同じ console.aws.amazon.com
ドメインですのでドメインレベルのフィルターなどでは制御できません。
そこで登場するのがNetskopeです。Netskopeではクラウドサービスのテナントを識別する機能があり、AWSで言えばアカウントIDレベルでのアクセス制御が可能です。
以下のようにSkope ITにてログからAWSアプリケーションを確認するとInstance IDとしてAWSアカウントIDが表示され、これにInstance Nameとして名前をつけることが可能です。これをApp Instanceと言います。
このInstance Nameを利用してReal-time Protection機能を利用すると、このApp Instanceに対するログインを許可したり、止めることが可能です。許可するInstanceだけ許可して、その下のポリシーで全てのAWSアカウントを拒否するといいでしょう。
さて、ここまではブラウザでの話です。それではCLI / SDK / CDKなどはどうでしょうか?つまりこういう課題です。
「開発者がアクセスしていいAWSアカウントのみ許可したい。ブラウザもCLI等も。おまけに開発者端末に外部のIAMクレデンシャルが持ち込まれても止めたい。」
制約がてんこ盛りになりました。まず上記NetskopeのApp Instanceはブラウザアクセスのみ有効です。そのためCLIなどのブラウザ外のアクセスを制御する仕組みが必要です。さらにクレデンシャルの持ち込みも対策する必要があります。これはつまり、開発者の端末には重要な機密情報があり、これの意図的な漏洩(あるいは外部からの高度な攻撃の末の漏洩)を防ぐ目的です。代表的なところでは管理外のS3バケットへのアップロードなどです。もちろんAWS以外へのDLPも対策している前提ですね。
これをいかに実現するか頭を捻って考えました。
極限まで制御するアーキテクチャ
出来上がったのが以下です。どん!
構成要素が多いのであとで順に説明していきます。
重要な要素はVPC Endpointです。この機能はエンドポイントポリシーにより、通過するAWSへのAPI通信を細かく制御することが可能です。AWSアカウントレベルはもちろん、リソースレベルで細かく制御が可能です。特定のユーザーから特定のリソースへの特定の操作だけ許可する、といった粒度です。
具体例をあげると、AWSアカウント 111111111111
のIAM User test-user
がAWSアカウント111111111111
のS3バケットtest-bucket
にオブジェクトをアップロードするs3:PutObject
だけ許可する、といった感じです。このVPC Endpointを通る限りは他のユーザーでも、他のアカウントのS3バケットでも、同じアカウントの他のS3バケットでも、ダウンロードでも全部止めます。送信元IPアドレスの制限などもConditionとして付け加えられます。
このようなVPC Endpointを利用した、クレデンシャル持ち込みまでフォーカスに入れた制御は以下のSecurity-JAWS第23回で「閉域要件におけるS3周辺ポリシーの組み合わせ方」というタイトルでみずほリサーチ&テクノロジーズ株式会社 の方が解説されています。
動画の1:50:14付近が参考になります。
この機能を最大限活用しよう、というのが今回のコンセプトです。
上記動画の事例は、アクセス元の端末が固定の閉域網端末でした。しかし今回の要件は社外でも利用する開発者端末です。これにVPC Endpoint経由の通信を強制するため、Netskope Private App(NPA)を利用します。
NPAは端末にNetskope Clientを導入することにより、指定したドメインへの通信をNetskope Publisher経由で通信させることができる機能です。PublisherをAWSのVPC内に立てることで、社外からVPC内部のシステムへのアクセスを安全に行うことができます。
AWSをブラウザで操作する場合は console.aws.amazon.com
でアクセスするのでこの通信は(NPAでは扱わず)そのままとし、AWS CLIやSDKやCDKによる*.amazonaws.com:443
の通信だけNPA経由とします。これにより開発者端末からのAWS CLI等アクセスは全てNPAからAWSのVPC内に通せます。
VPC Endpointを通らない通信が発生すると困るので、それらは全てAWS Network Firewallによって止めます。
VPC Endpointはサービス単位での作成となります。また、対応していないAWSサービスもあります。そのため、対応していないサービスの通信について検討する必要があります。今回は対応していないものは全て止める方針で考えました。理由としては、特に開発者が利用したいと想定されるAWS CDKについては、S3やCloudFormationが利用できればよく、CDK経由で様々なリソースがデプロイできるため、あまり全てのAWSサービスについて許可を検討していく必要がないことがあります。部分的にVPC Endpointによる制約を外しつつ許可したいのであれば、Network Firewallのルールを細かくして許可していくことも可能でしょう。ただ一部VPC Endpointはポリシーに対応していないのでVPC Endpointがあればすべてを制御できるわけではないので注意する必要があります。
実装してみた
VPCの準備
まずはVPCの準備から。以下の構成で作っていきます。
ポイントは真ん中のNetwork Firewall用のサブネットと、これに対するルーティングです。
Publisherを設置する一番下のサブネットからの0.0.0.0/0
とNatGatewayのサブネットからPublisherのサブネットへははNetworkFirewallのインターフェイスに向けます。このあたりの構成のやり方はAWSのユーザーガイドではNatGatewayの上にNetwork Firewallを設置していたりするので、好きなようにやってください。今回はPublisherのところにのみ適用したかったのでこうなっています。IGWのルートに手を入れなくて済むところも地味ポイント。
順番としてはVPCとサブネットを適当に作ったらNetwork Firewallを作成して、最後にルーティングを整えます。
VPCやサブネットはよくあるものなので作成の説明を割愛します。VPCの画面からFiewall Managerを開いて作成していきます。
名前・VPC・サブネットを選択します。今回は1つのサブネットだけですが、Publisher含めここを冗長化するのであれば増やしておきます。
ファイアウォールを作成するときにポリシーも必要なのでとりあえず空のポリシーを作成します。
作成できたらルールを作ります。ルールはステートレスとステートフルがあるので、ステートフルの方を作成します。
今回は特定のドメインを止めるだけなので、キャパシティーは適当に10とし、Domain listを選択します。
ドメインソースに対象のamazonaws.com
を入れます。アクションを拒否で作成します。
これでNetwork Firewallの作成は完了です。続いてこれを通すようにルーティングを設定します。Publisherを設置するPrivateサブネットのルートテーブルで0.0.0.0/0
のターゲットをゲートウェイロードバランサーのエンドポイントを選び、Network Firewallのエンドポイントを選択します。
同様にパブリックサブネット側のルートでPublisherのサブネットへのルートを追加します。
あとは利用するサービスのVPC Endpointを作成します。以下のようなポリシーを使うと、利用するクレデンシャルのアカウントを制限できます。必要に応じて対象を絞ったり好きなようにアレンジしてください。なお、前述の通り一部サービスのVPC Endpointはポリシーを設定できないので注意してください。今回対象としているCloudFormationも絞れないサービスの1つです。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowRestrictedAccounts",
"Action": "*",
"Effect": "Allow",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:PrincipalAccount": [
"111111111111",
"999999999999"
]
}
},
"Principal": "*"
}
]
}
これで一通りVPC周りの整備が完了です。
Netskopeの設定
続いてNetskope側を設定して完成形にしていきます。以下の構成です。
前提として、Netskopeの整備や対象のクライアントへのNetskopeクライアントの展開は済んでいる前提です。
まずPublisherの設置です。ヘルプドキュメントを参考に設置してください。前述の手順でSSM周りのVPC Endpointを作成しておくと、以下手順でセッションマネージャーを使ってアクセスできる様になるので活用してください。
Publisherを作成したらPrivate Appを作成します。App DefinitionからHOST*.amazonaws.com
のポートはTCP443
でPublisherを関連付け、Use Publisher DNSはオフにします。
Private Appを作成したらReal-time Protectionでポリシーを作成して配布します。Private Appのポリシー作成から該当ポリシーを選択して作成、適用します。しばらくして端末側が更新されるか、すぐに更新したけば端末を再起動して反映させましょう。
これで完了です。
動作確認
端末側からnslookupで確認すると、191.x.x.xのNPAのIPアドレスが返ってきて、NPA経由になっていることが確認できます。今回は2つのアカウントのプロファイルを用意しました。デフォルトのものは正常にEC2にクエリできていて、--profile prod
は権限がなく止まることが確認できました。これはVPC Endpointにて止まっています。
% nslookup ec2.ap-northeast-1.amazonaws.com
Server: 192.168.3.1
Address: 192.168.3.1#53
Name: ec2.ap-northeast-1.amazonaws.com
Address: 191.1.1.9
% aws ec2 describe-regions --query "Regions[0]"
{
"Endpoint": "ec2.eu-north-1.amazonaws.com",
"RegionName": "eu-north-1",
"OptInStatus": "opt-in-not-required"
}
% aws ec2 describe-regions --query "Regions[0]" --profile prod
An error occurred (UnauthorizedOperation) when calling the DescribeRegions operation: You are not authorized to perform this operation.
S3とCloudFormationのVPC Endpointを追加するとCDKもデプロイできました。
% cdk deploy
This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening).
Please confirm you intend to make the following modifications:
IAM Statement Changes
┌───┬─────────────────────────────┬────────┬─────────────────┬─────────────────────────────┬──────────────────────────────┐
│ │ Resource │ Effect │ Action │ Principal │ Condition │
├───┼─────────────────────────────┼────────┼─────────────────┼─────────────────────────────┼──────────────────────────────┤
│ + │ ${HelloCdkQueue.Arn} │ Allow │ sqs:SendMessage │ Service:sns.amazonaws.com │ "ArnEquals": { │
│ │ │ │ │ │ "aws:SourceArn": "${HelloC │
│ │ │ │ │ │ dkTopic}" │
│ │ │ │ │ │ } │
└───┴─────────────────────────────┴────────┴─────────────────┴─────────────────────────────┴──────────────────────────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)
Do you wish to deploy these changes (y/n)? y
HelloCdkStack: deploying...
[0%] start: Publishing xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:current_account-current_region
[100%] success: Published xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:current_account-current_region
HelloCdkStack: creating CloudFormation changeset...
✅ HelloCdkStack
Stack ARN:
arn:aws:cloudformation:ap-northeast-1:111111111111:stack/HelloCdkStack/xxxxxxxxxx-xxxx-xxxxx-xxxxxxxxxxxx
まとめ
Netskope Private AppとVPC EndpointとAWS Network Firewallの組み合わせでAWS CLIやSDKやCDKの利用がAWSアカウントレベルで制御する方法についてまとめました。
VPC Endpointさまさまですね。とはいえVPC Endpointに対応していないサービスがあったり、ポリシーに対応していないサービスがあったりするので、目的とどこまで実現するかは要相談です。データ系のサービスに関する通信はかなり制御できますので、試してみてください。