CloudShellを最小権限で起動してみた

CloudShellを最小権限で起動してみて、できたこと、できなかったことをまとめてみました。
2021.12.21

こんにちは、東京オフィスのあしさんです。

CloudShellってとても便利ですよね、AWS CLIの実行環境として一番お手軽なサービスなのに無料で使えることが素晴らしく、私も毎日のようにお世話になっています。

同僚ののんピカジと何気ない会話をしていたところ、「CloudShellの権限周りの設定ってどうなってるんだっけ?」という話題になり、「ログインしているユーザやロールの権限を使ってる」のようなざっくりとした知識はありましたが、そこまで詳しく理解できてないな、と思ったことが今回のブログのきっかけです。

権限周りの設定について調べる、といっても範囲が広すぎるので、何かないかなと公式ドキュメントを読んでいたところ、Managing AWS CloudShell access and usage with IAM policiesにて以下の記載を見つけました。

To launch AWS CloudShell from the AWS Management Console, an IAM user needs permissions for the following actions:

  • CreateEnvironment
  • CreateSession
  • GetEnvironmentStatus
  • StartEnvironment

If any of these actions aren't explicitly allowed by an attached policy, an IAM permissions error is returned when you try to launch CloudShell.

要するに、マネジメントコンソールからCloudShellを起動したい場合は最低限上記の4アクションの許可が必要だ、ということが書いてあります。

CloudShellを使うときはとりあえずAWS管理ポリシーのCloudShellFullAccessだ!って思ってしまっていた節があった私です。

なんとなく最低限の権限で起動したらおもしろそうだなとひらめいたので、試しにCloudShellを最小権限で起動してみることにしました。

いきなりまとめ

CloudShellを起動に必要な最小権限(4アクション)で起動すると、以下のようなことがわかった。

  • できたこと
    • CloudShellの起動
    • ClousShellセッションの開始
    • 使用シェルの選択
    • ファイル、ストレージ機能(ファイル削除含む)
    • CloudShell画面のカスタマイズ
  • できなかったこと
    • CloudShellからのファイルダウンロード、アップロード
    • ClousShellセッションの終了
    • 動作リージョンの選択
    • AWS CLIの実行
  • 総括
    • CloudShellを最小権限で起動すると、ログイン中のAWSクレデンシャル情報を保持しないCLI実行環境が使用できる
      • AWSクレデンシャル情報をデフォルトで持っていないため、AWS CLI等のコマンドは使えない
      • サポートしているシェル(bash,zsh,powershell)はすべて利用可能
    • Actionsタブの機能がTabs Layout以外すべて使えなくなる。
      • できないこと:ファイルアップロード、ダウンロード、CloudShell再起動、ホームディレクトリリセット

実際にやってみた

CloudShell起動に必要な4アクションのみを有効化したIAMロールを準備、そのロールをAssumeRoleした状態でCloudShellを起動し、できること/できないことを確認してみました。

できたこと

CloudShellの起動

これができないと以降の検証ひとつもできないですからね、、、

使用シェルの選択

サポートしている3種類(bash,zsh,powershell)はどれも選択して使用できます。

[cloudshell-user@ip-10-0-126-170 ~]$ 
[cloudshell-user@ip-10-0-126-170 ~]$ bash
[cloudshell-user@ip-10-0-126-170 ~]$ 
[cloudshell-user@ip-10-0-126-170 ~]$ zsh
[cloudshell-user@ip-10-0-126-170]~% 
[cloudshell-user@ip-10-0-126-170]~% pwsh
PowerShell 7.1.4
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type 'help' to get help.

   A new PowerShell stable release is available: v7.2.1 
   Upgrade now, or check out the release page at:       
     https://aka.ms/PowerShell-Release?tag=v7.2.1       

PS /home/cloudshell-user>

ファイル、ストレージ機能(ファイル削除含む)

ファイル・ディレクトリの作成や削除など、通常のCLI実行環境と同じように利用可能です。

[cloudshell-user@ip-10-0-126-170]~% mkdir test-dir
[cloudshell-user@ip-10-0-126-170]~% cd test-dir 
[cloudshell-user@ip-10-0-126-170]~/test-dir% 
[cloudshell-user@ip-10-0-126-170]~/test-dir% pwd
/home/cloudshell-user/test-dir
[cloudshell-user@ip-10-0-126-170]~/test-dir% 
[cloudshell-user@ip-10-0-126-170]~/test-dir% touch test.file
[cloudshell-user@ip-10-0-126-170]~/test-dir% ls -l
total 0
-rw-rw-r-- 1 cloudshell-user cloudshell-user 0 Dec 17 17:01 test.file
[cloudshell-user@ip-10-0-126-170]~/test-dir% rm test.file 
[cloudshell-user@ip-10-0-126-170]~/test-dir% 
[cloudshell-user@ip-10-0-126-170]~/test-dir% ls -l
total 0
[cloudshell-user@ip-10-0-126-170]~/test-dir%

ただし、ホームディレクトリ配下以外は永続ストレージではなく、かつ永続ストレージであるホームディレクトリ配下も1GBまでの容量制限があり、120日アクセスされていないと自動で削除される設定になっているので注意が必要です。

ClousShellセッションの開始

セッションの開始はCloudShellが起動できた時点でできるということになるので、とくに言及するところはないです。

CloudShell画面のカスタマイズ

以下のような画面レイアウト等のカスタマイズはできました。

  • タブのレイアウト
  • フォントサイズ
  • テーマ
  • 安全なペースト

タブのレイアウトの変更はActionsのTabs layoutから行うことができます。

切り替えられるタブ増やしたり、縦に表示するタブを増やしたり、横に表示するタブを増やすことができます。

他についてはPreferenceから変更可能です。

フォントサイズはSmallest〜Largestまで変更ができます。(画像はLarge)

テーマはライト or ダークが選択可能です。

安全なペーストはオンにすると、複数行の文字列のペースト時に確認ウインドウが表示されます。

このようにフロント側で何かする、に対しては最小権限でも制約がないようですね。

以上が、最小権限でできたこと、でした。


できなかったこと

CloudShellからのファイルダウンロード、アップロード

ファイルのアップロードやダウンロードはCloudShell画面のActionsタブから選択可能です。

ダウンロードは、ダウンロード実行時に実行が拒否される警告が表示され

アップロードは、一旦実行はできますが、「File upload failed(アップロードに失敗した)」という警告が表示されました。

CloudShellセッションの終了

セッションの終了もCloudShell画面のActionsタブから選択可能です。

しかし、最小権限だとRestartを選択しても何も起きません。

後でCloudTrailを確認したところ、APIアクション「StopEnvironment」は実行できていてAccess Deniedとなっていました。

CloudShellホームディレクトリの削除

セッションの終了と同様にCloudShell画面のActionsタブから選択可能です。

こちらもDeleteを選択しても何も起きず。

CloudTrailからAPIアクション「DeleteEnvironment」は実行できているが、Access Deniedとなっていることが確認できます。

動作リージョンの選択

「500 - Internal Server Error」となりました。

エラー出力をみるとコンテナロールからクレデンシャル情報が取得できていないように見えます。

Error when retrieving credentials from container-role: Error retrieving metadata: Received non 200 response (500) from ECS metadata

[cloudshell-user@ip-10-0-126-170]~% aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None

Error when retrieving credentials from container-role: Error retrieving metadata: Received non 200 response (500) from ECS metadata: <?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>500 - Internal Server Error</title>
 </head>
 <body>
  <h1>500 - Internal Server Error</h1>
 </body>
</html>
[cloudshell-user@ip-10-0-126-170]~%

参考までに、CloudShellFullAccessが付与されたロールで起動したCloudShellから同じコマンドを実行すると、以下のように出力されます。

[cloudshell-user@ip-10-0-189-190 ~]$ aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ********************   container-role    
secret_key     ********************   container-role    
    region           ap-northeast-1              env    ['AWS_REGION', 'AWS_DEFAULT_REGION']

access_key、secret_keyの欄にType:container-roleとあってよくわからなかったので調べてみたところ、以下公式ドキュメントの抜粋ですがcredential_sourceという項目でEcsContainerのパラメータを選択可能であることがわかりました。

Amazon EC2 インスタンスまたは EC2 コンテナ内で使用され、role_arn パラメータで指定したロールを引き受けるために使用する認証情報を AWS CLI が検索できる場所を指定します。source_profile と credential_source の両方を同じプロファイルで指定することはできません。 EcsContainer – AWS CLI が ECS コンテナにアタッチされた IAM ロールをソースの認証情報として使用することを指定します。

この情報から、CloudShellが設定なしでAWS CLIコマンドを実行できるのは、内部的かつ自動的にCloudShellの実態であるECSコンテナに付与されたIAMロール経由でクレデンシャル情報が渡されているからである、と理解できました。

AWS CLIの実行

今回は例としてEC2のインスタンス一覧を取得するAWS CLIコマンドでやってみました。

1つ前の動作リージョンの選択の項目でAWSクレデンシャル情報が取得できていないことによるエラーが出ていたので予測はできましたが、同様にクレデンシャルのエラーで実行できませんでした。

[cloudshell-user@ip-10-0-76-64 ~]$ aws ec2 describe-instances

Error when retrieving credentials from container-role: Error retrieving metadata: Received non 200 response (500) from ECS metadata: <?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>500 - Internal Server Error</title>
 </head>
 <body>
  <h1>500 - Internal Server Error</h1>
 </body>
</html>
[cloudshell-user@ip-10-0-76-64 ~]$

以上が、最小権限でできなかったこと、でした。


まとめ(再掲)

  • できたこと
    • CloudShellの起動
    • ClousShellセッションの開始
    • 使用シェルの選択
    • ファイル、ストレージ機能(ファイル削除含む)
    • CloudShell画面のカスタマイズ
  • できなかったこと
    • CloudShellからのファイルダウンロード、アップロード
    • ClousShellセッションの終了
    • 動作リージョンの選択
    • AWS CLIの実行
  • 総括
    • CloudShellを最小権限で起動すると、ログイン中のAWSクレデンシャル情報を保持しないCLI実行環境が使用できる
      • AWSクレデンシャル情報をデフォルトで持っていないため、AWS CLI等のコマンドは使えない
      • サポートしているシェル(bash,zsh,powershell)はすべて利用可能
    • Actionsタブの機能がTabs Layout以外すべて使えなくなる。
      • できないこと:ファイルアップロード、ダウンロード、CloudShell再起動、ホームディレクトリリセット

結局、最小権限のCloud Shell環境って使えるの?

今回AWS Credentialが利用できずAWS CLIコマンドが実行できなかったのは、起動に必要な最小権限のアクションしか権限付与していなかったことで、PutCredentialsアクションが有効化されていないことが原因です。 CloudTrailからCloudShell起動時のAPIログを確認してみると、PutCredentialsアクションが拒否されていることから、予測できました(CLI実行時ではありません)。

このことから、PutCredentialsアクションを拒否してしまえば、AWSクレデンシャル情報を持っていないただのCLI環境を提供できる、ということがわかります。

用件によっては、お手軽なCLI実行環境の使用は許可したいけど、AWSクレデンシャル情報は渡したくない、というユースケースがありうるかもしれません。

そんなケースをAWS側も想定していて、CloudShell環境へのアクセスは許可するがPutCredentialsを禁止にしてAWSクレデンシャルを使用できないようにしたポリシーの例が、公式ドキュメント(Managing AWS CloudShell access and usage with IAM policies)に参考として記載されています。

{
    "Version": "2012-10-17",
    "Statement": [{
        "Sid": "CloudShellUser",
        "Effect": "Allow",
        "Action": [
            "cloudshell:*"
        ],
        "Resource": "*"
    }, {
        "Sid": "DenyCredentialForwarding",
        "Effect": "Deny",
        "Action": [
            "cloudshell:PutCredentials"
        ],
        "Resource": "*"
    }]
}

このようなポリシーを付与すれば、他の細かい設定なしで、最小権限のCloudShellを使うことを強制できます。

最大1GBの容量制限のある半永続ストレージ(120日アクセスで削除)しか使えないという制限事項はありますが、利用料金は無料という破格での提供のため、Cloud9など他との比較次第では出番はあるはずです。

公式ドキュメントでは上記のケースのほかに、CloudShellへアクセスできないようにするCloudShell環境は普通に使えるけどファイルアップロード・ダウンロードのみ禁止にする、の2パターンのポリシー設定の例が挙げられていました。

こちらも用件次第で役に立ちそうです。

感想

今回CloudShellを題材にAWSサービスを最小権限で動かしてみましたが、限定された権限でどこまで動くのかを考えながらサービスに触れていると、AWSってAPIアクションのひとつひとつによって動いているんだな再認識できます。(注釈:当たり前な話なのですが)

マネジメントコンソールだけに触れているとAWSがどのように動いているのか理解しづらいので、今回のように権限を限定してAPI単位で意識するところまではいかなくとも、CLIからAWSサービスに触れることでコンソールからやると省略されてしまう細かい設定項目について理解できたりといいことがたくさんあるかもしれません。

以上、東京オフィスのあしさんでした!