単一のAWSアカウントに潜む重大な危険

Amazon Webサービス(AWS)のアカウントは、AWSでビジネスを展開している人にとって非常に大事なものです。ですが、AWSアカウントをたった一つしかもっていない場合、重大なセキュリティの危険に直面することになるでしょう。何が問題なのか、そしてどうすれば解決できるのかを、この記事でご紹介したいと思います。

危険性をはらむデフォルト設定:単一のAWSアカウント

単一のAWSアカウントには、EC2仮想サーバ、S3バケット、RDSデータベースなどビジネスに必要な様々なリソースとともに、IAMユーザが含まれています。アカウントへのログイン方法は基本的に2通りあります。ユーザ名とパスワードを入力するAWS Management Console、またはCLIやSDKで用いられるAWSアクセス認証情報を使うのです。以下の図は、その仕組みを示したものです。

Single AWS account
訳注
account「このアカウントにはIAMユーザと、仮想サーバ、ストレージ、データベースなどのリソースが含まれています」
IAM user「私は管理者権限があります」
terminal「あなたはAWSアクセス認証情報によってIAMユーザにアクセスできます」

例えば、端末で次のように入力します。

$ aws ec2 describe-instances

すると、AWSアクセス認証情報(通常は~/.aws/に格納)がリクエストの認証に使われます。IAMユーザとしての認証です。このIAMユーザは多くの場合AdministratorAccessをもっていて、何でもできます。なぜでしょう? それは、すべてのサービスを管理できるようにするためです。しかし、AWSアクセス認証情報が漏れてしまった場合は大変なことになります。

この状況を改善するには、2つの対策があります。

第1の対策:AdministratorAccessをもつユーザを使わない

最小権限の原則に従えば、AdministratorAccessはほとんどの場合必要ありません。IAMサービスを使えないPowerUserAccessの方が適切でしょう。もっと望ましいのは、ReadOnlyAccessに設定しておき、必要なときにだけ書き込み権限をもたせる方法です。ただし、IAMユーザを使って実装するのは大変です。各”最小権限”についてユーザを作成し、各ユーザについてアクセス認証情報を作成する必要があるからです。AWSアカウント内に自分以外のユーザが存在する場合は、たちまち管理不能になってしまいます。これはセキュリティの負債とでも呼ぶべきものでしょう。

第2の対策:多要素認証を使う

AWSは多要素認証(MFA)のサポートが優れており、ハードウェアデバイスまたはソフトウェアデバイスを使ってトークンを生成できます。パスワードまたはアクセス認証情報にこのMFAトークンを組み合わせて認証するようにすれば、あなたのアカウントへのアクセスはずっと難しくなります。

では、これらの対策を実装する方法について説明しましょう。

要塞アカウントによる関心の分離

単一のAWSアカウントをもつのではなく、もう一つ別のアカウントを作成します。これを要塞アカウント(bastion account)と呼ぶことにしましょう。要塞アカウントはIAMユーザだけをもつようにします。以下はその概念図です。

Bastion AWS account
訳注
bastion account「このアカウントにはIAMユーザだけが含まれています。他には何もありません!」
IAM user「私にできるのは、一時的な認証情報を得てロールを引き受けることだけです」account「このアカウントには仮想サーバ、ストレージ、データベースなどのリソースが含まれています」
IAM role「私は管理者権限があります」

要塞アカウント内のIAMユーザは強い制限をうけます。彼らは一時的な認証情報を得てロールを引き受けるだけです。これを実装するには、次のように、要塞アカウント内にインラインポリシー付きのグループを作ります。

{
"Version": "2012-10-17",
"Statement": [
    {
        "Sid": "1",
        "Effect": "Allow",
        "Action": [
            "sts:AssumeRole"
        ],
        "Resource": "*",
        "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
    },
    {
        "Sid": "2",
        "Effect": "Allow",
        "Action": [
            "sts:GetSessionToken"
        ],
        "Resource": "*"
    }
]
}

このグループを要塞アカウント内のすべてのIAMユーザに割り当てます。彼らに他のポリシーが一切適用されないように注意してください!

最初のStatementは、ユーザにロールを引き受けさせます(ただし、MFAを使用してリクエストが認証された場合のみ)。2番目のStatementは、MFAトークンを提供することによってユーザに一時セッションを取得させます。これがどのように働くか見てみましょう。

安全な解決策:ロール委任付きのMFA

そろそろ解決策をまとめましょう。その働きは? 次の図は、MFA認証とロール委任の流れです。

MFA with role delegation
1.あなたは自分のマシン上(通常、~/.aws/内または環境変数内)に、要塞アカウント内のIAMユーザのためのAWSアクセス認証情報をもっています。あなたはAWS APIを呼び出し、MFAトークンを提供することによって一時的な認証情報を取得します。そのMFAトークンが有効な場合は、要塞アカウント内のIAMユーザのために一時的なセッションを作成したことになります。

2.あなたは一時的な認証情報を受信し、IMAユーザとして認証されます。

3.一時的な認証情報を使って、あなたは別のアカウントのロールを引き受けることができます(以前はこれができませんでした。なぜなら、このユーザがMFA認証されている場合にだけロールを引き受けることが許可されるからです)。別のアカウントのロールを引き受けるには、そのロールはあなたのアカウントで使用されることが明示的に許可されている必要があります! ロールがもつべき最大の権限は、PowerUserAccessです。そのロールにIAMとのやりとりを許可してはなりません。

4.あなたは一時的な認証情報を受信して、自分のAWSアカウントで作業を始めることができます。

実装

この処理を自動化するには、私たちのmfacliスクリプトを使用できます。

Amazon Webサービスの詳細

Amazon Web Services in Action
Amazon Webサービスの詳細に興味がありますか? Andreasと私が書いているAmazon Web Services in Actionという本がManningから出版されます。この本は、従来デプロイされていた分散アプリケーションをAWSプラットフォームに移行している開発者とDevOps(デブオプス)技術者を対象としています。AWSの経験は必要ありません。