AWS 権限管理のベストプラクティスについて考えてみた
Posted on
- #aws
AWS は Management Console や API ですべて操作できます(Direct Connect など一部例外もあります)。データセンターの物理的なセキュリティなどは AWS が責任を負うところで、ユーザーはまったく意識する必要はありません。
その代わり、OS やミドルウェアの管理、アプリケーションの設計や実装、適切な権限管理などはユーザーが責任を負うところです。
今回はあまり取り上げられないけど、すごく大事な権限管理についてまとめてみました。自分が仕事で関わっているプロダクトで権限管理を見直すときに調べたことをベースにしていますが、もっと良いプラクティスがあればぜひ教えてください。
AWS アカウントは使わない
普段の運用で AWS アカウントは使いません。 AWS アカウントとは、最初にサインアップするときに作られるアカウントです。
このアカウントは Linux で言うところの root ユーザーであり、すべての操作が行える権限を持っています。権限が強すぎるので、普段の運用では次に紹介する IAM ユーザーを使います。 AWS アカウントを使うのは、アカウント情報(クレジットカード情報や住所など)を変更するときくらいです。
また、このアカウントにはアクセスキーを発行すべきではありません。このアクセスキーが漏洩すると API や AWS CLI で何でもできてしまいます。すでに発行している場合は、用途を確認した上で無効にしましょう。
無効にするには IAM のダッシュボードに移動し、Security Status の "Delete your root access keys" を選択します。
開発者それぞれに IAM ユーザーを作る
開発者が普段の運用で使うのが IAM ユーザーです。 AWS アカウントが Linux の root ユーザーなら、IAM ユーザーは一般ユーザーに当たります。
開発者それぞれに 1 つの IAM ユーザーを割り当てます(組織の場合、メールアドレスのローカルパートを使うといいと思います)。開発者それぞれに割り当てることで、後述する CloudTrail でユーザーの操作が追跡できます。
AWS アカウントはすべての権限が与えられていますが、IAM ユーザーはポリシーで細かい権限管理が可能です。たとえば、プログラマー A さんには EC2 と S3 だけ、DB エンジニア B さんには RDS だけといったことができますし、派遣社員には本番環境のリソースを触らせないといったこともできます。
誰にどんな権限を与えるかは運用の仕方によって違ってきますが、最低でも IAM の権限は剥奪しておきましょう。そうしないと、自分で自分のポリシーを変更できてしまいます。 NotAction
を使うと指定されたものを反転して許可します。次のポリシーだと IAM 以外となります。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"NotAction": "iam:*",
"Resource": "*"
}
]
}
開発者の端末から AWS CLI で操作するときも、その IAM ユーザーに発行されたアクセスキーを使います。
異動や退職で開発者が入れ替わった場合は、IAM ユーザーを削除するだけで済みます。もし共通の IAM ユーザーを使い回してるとパスワードを変更したり、アクセスキーをローテーションする必要が出てきます(面倒な上に、忘れると事故につながる)。
本番環境と開発環境で AWS アカウントを分ける
VPC を分けたり、タグを工夫することで、1 つのアカウント内で本番環境と開発環境を分けることは可能です。ただ実際にやってみると、適切な権限を設定するために IAM ポリシーを細かく指定したり、タグを忘れずに付けたりと結構面倒です。
「開発環境だと思って Terminate したら、実は本番環境だった」みたいな人的なオペレーションミスも容易に想像できるので、AWS アカウントは本番環境と開発環境で分けたほうが良いと思います。
AWS には Consolidated Billing というオプションがあり、複数アカウントの料金を一括で支払うことができます。請求をまとめておけばボリュームディスカウントの対象にもなります。
Cross-Account Access を活用する
Cross-Account Access は今年の 1 月に発表された機能です。
通常アカウントを切り替えるときはログインしなおす必要がありますが、Cross-Account Access を設定しておけばログアウトせずに一時的に別のアカウントにスイッチできます(Cross-Account となっていますが、同じアカウントの別のロールにスイッチすることも可能)。
Google アカウントのマルチログインによく似ていますが、Cross-Account Access はあらかじめ許可された権限が移譲されるイメージです。具体的には、スイッチ先のアカウントで IAM ロールと許可する権限を設定しておき、スイッチしたときにスイッチ元の権限とスイッチ先の権限を入れ替えています。
この機能をうまく使えば、本番環境と開発環境で AWS アカウントが分かれていても、それほど手間にはなりません。
2 段階認証を有効にする
パスワードが漏洩したときの対策として 2 段階認証を有効にしましょう。以前「2 段階認証は本当に安全なのか調べてみた」というエントリーを書きましたが、2 段階認証を破るのは技術的に困難なので万が一の保険になります。
2 段階認証は AWS アカウントと IAM ユーザーの両方に設定しましょう。 MFA デバイス(6 桁のワンタイムパスワードを表示する端末)には、仮想と物理の 2 種類があります。
物理 MFA デバイスは導入コストもかかるので、IAM ユーザーにはスマートフォンにインストールした仮想 MFA デバイス(Google Authenticator や Authy など)を使えばいいでしょう。スマートフォンを紛失してログインできなくなっても、AWS アカウントから強制的に解除することができます。
AWS アカウントには物理 MFA デバイスを使って、使わないときは金庫にでもしまっておきましょう。「AWS のアカウント管理の話」にも書かれていますが、AWS Management Console は接続元の IP アドレス制限ができません。物理 MFA デバイスの保管場所を固定することで接続元を限定します。
適切なパスワードポリシーを設定する
IAM ユーザーにはパスワードポリシーを設定できます。具体的には、パスワードの長さ、大文字・小文字・数字・記号など使用を強制する文字、パスワードの有効期限など。
おそらく会社でパスワードポリシーが決まっていると思うので、それに合わせるのが良いでしょう。または PCI DSS などの要求基準を参考にするのもいいかもしれません。
IAM ロールを活用して、コードからクレデンシャル情報を排除する
EC2 上のアプリケーションから API や AWS CLI を使う際、設定ファイルやコードにクレデンシャル情報(アクセスキーやシークレットキーのこと)をハードコーディングしてはいけません。
以下のような懸念が出てくるためです。
- 権限管理が破綻する(ソースコードを見れる人なら誰でも入手できる)
- Git などのバージョン管理システムにクレデンシャル情報が残ってしまう
- キーをローテーションするためにリリースが必要になる
このような問題を解決するために EC2 には IAM ロールという仕組みがあります。 IAM ロールを使えば EC2 インスタンスに対して権限を付与することができます(インスタンスメタデータから一時キーを取得できるようになる、というのが正確な説明です)。
具体的なコードで見てみましょう。 AWS SDK for Ruby のドキュメントには、こんなサンプルコードが載っています。
s3 = AWS::S3.new(
:access_key_id => 'YOUR_ACCESS_KEY_ID',
:secret_access_key => 'YOUR_SECRET_ACCESS_KEY')
IAM ロールを使えば、もっとシンプル、かつクレデンシャル情報を排除できます。
s3 = AWS::S3.new
IAM ロールの仕組みは「IAM ロール徹底理解 〜 AssumeRole の正体」に詳しく書かれています。
全リージョンで CloudTrail を有効にする
権限管理ではありませんが、AWS を安全に利用するには CloudTrail も重要なポイントです。
CloudTrail は API 呼び出しのすべてを記録して、そのログを S3 に保存してくれるサービスです。 CloudTrail のログには誰が、いつ、どこから、何をしたかが詳細に記録されているので、セキュリティ監査の証跡ログとして利用できます。
開発者それぞれに IAM ユーザーを作っておけば、何かインシデントが起きたときもログから追跡が可能になります。
また CloudWatch Logs の機能を使えば、あらかじめ定義したルールに従って SNS で通知することもできます。
CloudTrail は無料で使えるので、アカウントを作ったら真っ先に全リージョンで有効にしましょう。
まとめ
AWS と言えば各サービスに目が行きがちですが、権限管理をおろそかにするとあとで苦労します。
本番運用が始まってしまうと変更するのはなかなか大変なので、最初からうまく設計しておくとスムーズに運用できます。 AWS エンジニアには、このあたりのスキルも必要かもしれません。