🔑

AWSを使うにあたりIAMのベストプラクティスをもう一度確認する

commits13 min read

この記事はAWS その2 Advent Calendar 2020の20日目です。

本当はre:Inventかその周辺で発表されたアップデートについて書こうかなと思ったんですが、自分自身の時間の都合と、例によって某ブログに大量に情報があるので今回は見送りましたw
zennに何か書こうと思って書くのも今回が初ですね。

さて、今回は個人的に以前から非常に気になってしまう使われ方が多いIAMの使い方について、あらためてネタにしようと思います。
どちらかというとAWSにそれほど詳しくない人向けのつもりです。
しれっと使ってますが、そもそもベストプラクティスって何? という方はとりあえずこちらを
ベストプラクティス (best practice)とは

あくまでもベストプラクティスなのでいきなり全部を満たすのは難しいかもしれませんが、こういうものがあるんだよ、というのを認知してもらえればと思います。

とりあえず真っ先に気を付けたほうがよいことや注意してほしいことは
よく見るまずい(と思う)使い方
真っ先にやるべきこと
に記載します。

IAMとは

公式ドキュメントをまずは貼っておきます。
IAMとは
AWS Identity and Access Managementが一応の略さない場合の正式ですがIAM(アイアム)と呼ばれることがほとんどです。

AWSのサービスに対するアクセスはAWS側のAPIに対するリクエストを送って行われますが、このIAMを使ってそれぞれのAPIについての権限をコントロールします。
AWSを使うにあたっては、まずマネジメントコンソールにアクセスするためのIAMユーザーを作成するのが最初です(後述しますが、ルートユーザーをそのまま使うのはやめましょう)。

あと、たまにIAMユーザーのことをアカウントと呼ぶ人がいますが、AWSにおいてはアカウントという言葉はユーザーを指す言葉ではないです。
この辺はサーバワークスさんのブログのこの記事がわかりやすいです。
アカウントに対してIAMユーザーを作成してコンソールにアクセスする、みたいなのをイメージしておけばとりあえずは問題ないです。
言葉の使い方を間違えるのは認識齟齬が発生する原因なのでこの辺はご注意を。

よく見るまずい(と思う)使い方

完全に主観ですが、本当は良くないのによくやっているところを見る気がする使い方。
より細かくはIAMベストプラクティスの説明の項に譲ります。

とりあえずIAMユーザーのアクセスキーを使わせる

これは本当にいろんなOSSのREADMEとかでもしれっとそうさせてますし、ググるとそういう情報ばっかり出てくるのですが、
IAMアクセスキーが必要なのは、AWSの外部からAWSアカウント内のサービスに対してアクセスを行う必要があるときのみです。
AWSの内部からAWSの各サービスを利用する場合は原則としてIAMロールを使用してください。
また、使う必要がないのにアクセスキーを発行することがないようにしましょう。

とりあえずAdministratorAccessを振る

本当に最初の少人数が触る状態とか、そもそも限られた人しか触らないみたいな状態ならいったんはよいかなと思いますが、AWSに触る人が増えてきたら適切に権限を設計する必要があります。

ここについては正直自分にも心当たりがありますね…

真っ先にやるべきこと

下記の記事がすばらしいまとめなのでぜひ参考にしてください。
AWSアカウントを作成したら最初にやるべきこと -セキュリティ編-

ここで言及するのはあくまでもIAM周りに限った話です。
真面目に業務で使うとかならCloudTrailやGuardDutyもぜひ使いましょう[1]

  • rootユーザーで初回ログイン時、以後使用するためのIAMユーザーを作成する
    • 基本的に必要がなければ以後rootユーザーは使わない。
    • rootユーザーにはMFAを設定しておくことを推奨
  • IAMユーザーの不要なアクセスキーを見直す
    • 棚卸して使っていなさそうなら無効化する
      • コンソールから最後に使用された日時を見ることが可能

以下ではAWS公式ドキュメントをなぞる形で説明を書いていきます。

IAMでのセキュリティベストプラクティス

タイトルは「IAMのベストプラクティス」と書きましたが、一応公式のドキュメント(2020/12/20現在)では下記です。
IAM でのセキュリティのベストプラクティス

これはそれぞれちょっと掘り下げてみます。
なるべく関連性が近いものを一緒に並べる感じにします。
※見出しの日本語が変ですが、あえて直さずにドキュメントの文言をそのまま引用しています。

基本編

基本≠簡単です。
IAMを使うにあたり真っ先に注意すべきことをここにまとめます。

AWS アカウントのルートユーザー アクセスキーをロックする

AWS アカウントのルートユーザー アクセスキーをロックする
AWSのアカウント作成時にはIAMユーザーではなくメールアドレスとパスワードでログインすることになりますが、ルートユーザーの使用は最小限にとどめましょう。
なぜなら、ルートユーザーは使うべきではない言葉なので修正してくださいの権限を保持しており何でも行えてしまうからです。
IAMユーザーでも強い権限を与えることは可能ですが、アカウントの設定メールアドレスやパスワード自体を変えてしまえたり、サポートプランのレベルを変更したりなど、ルートユーザーでしかできないことがあります。

この項目ではルートユーザーのアクセスキーのロックについて書かれています。
アクセスキーは万が一それが漏れてしまうとアクセスキーの権限を使ってコンソールログインなしにAWSアカウントに対して好きな操作を行えてしまいます。
よくあるのが高いEC2インスタンスを大量に立て仮想通貨をマイニングするのに使われるとかですね。
その気になればAWS上に構築したものをすべて壊すことももちろん可能ですし、悪意を持って行えば高いサービスを使いまくって利用者を破産に追い込むこともできるでしょう(万が一そんな事になってしまったら、まず急いでサポートに相談することをお勧めします。)。
これはアクセスキーに限らず、ルートユーザーのコンソールログイン用のパスワードが漏れても同じことです。
ルートユーザーのアクセスキーは原則必要ないのでもし作成していたら即刻削除しましょう。
ルートユーザーのパスワードは十分に複雑なものにし、できれば後述するMFAも有向にしましょう。

個々の IAM ユーザーを作成する

ユーザーのために強度の高いパスワードポリシーを設定する。

個々の IAM ユーザーを作成する
ユーザーのために強度の高いパスワードポリシーを設定する。

↑でルートユーザーを原則使わないと書きましたが、それに伴いAWSアカウントを作ったら真っ先にログイン用のIAMユーザーを作成してください。
自分が使うのであれば権限はいったんAdministrator Accessでとりあえずよいと思います。
本来は誰がどのような権限が必要かを見て適切に権限を設定する必要があります(後述)

当然のことながら、パスワードは十分に複雑なものにしましょう。
ほかのサービスでも同じことですが、簡単に予測できるパスワードや短すぎるパスワードを今でも平然と使っているケースはよく見ますし、使い回しもたくさん見ます。
aを@にするとかOを0にするとかはるか昔の対策で今ではほとんど無意味と考えてよいです。
それぞれや辞書攻撃総当たり攻撃パスワードリスト攻撃に対して脆弱です。
確率は低くても、1回でもパスワード認証を突破されたら情報は漏れるし好き放題されるしで非常にリスクが高いです。
AWSに限らず、パスワードの使い回しを避けて十分複雑なパスワードを使用しましょう。
パスワードと総当たり攻撃による解読時間についてはとりあえずWikipediaを貼っておきます。
パスワード長と解読時間の関係
なお、これは計算機の演算性能が飛躍的に上昇した場合時間がさらに短縮される可能性があります。

MFAの有効化

MFA の有効化

少しでも認証突破されてしまう確率を減らすためにMFAを使用することを推奨します。
AWS での多要素認証 (MFA) の使用
MFAに使えるものはいろいろありますが、個人的にはAuthyをお勧めします。[2]

IAM ユーザーへのアクセス許可を割り当てるためにグループを使います。

IAM ユーザーへのアクセス許可を割り当てるためにグループを使います。

これを守ると、同じAWSアカウントを使うのに複数のIAMユーザーを作ることが必要になりますが、それぞれに個別に権限を振るのではなく、IAMグループを使ってそのグループに所属させることによって権限を設定しましょう。
これは単純に考えても、たとえば10人ユーザーがいたとしてそれぞれ1人ずつ権限設定をしていくのは面倒です。
役割ごとにIAMグループを作ってそれぞれのグループに必要な権限設定をして、そのグループにユーザーを所属させて権限を設定したほうが管理上も楽です。
たとえば管理者のグループには強めの権限を振っておいて、開発者は権限を弱めにするなど。

ユーザーのために強度の高いパスワードポリシーを設定する。

ユーザーのために強度の高いパスワードポリシーを設定する。

これはアカウント自体の設定で、各IAMユーザーが設定できるパスワードについてルールを設けることができます。
IAM ユーザー用のアカウントパスワードポリシーの設定

最低限必要なのは、最小文字数を長めに設定することでしょう。
「パスワードは複雑さより長さが大切」 FBIが指南
アルファベット、数字、記号すべてを使うことを必須にすることもできますが、そこは必須化しなくてもよいかなと個人的には(必須化することによってそれぞれが一文字も含まれないパターンが候補から消えるため)

また、指定した期間が経過したらパスワードを変更させるルールを設けることも可能ですが、2020/12/20現在、パスワードの定期的な変更は非推奨です。
結局、パスワードの定期変更は不要なのか、必要なのか (1/2)
なぜかというと、パスワードを変更するのは多くは人間ですので、変更時に安易なパスワードを設定してしまう傾向が強く、結局人間がセキュリティを低下させてしまうからです。
本当はここももうちょっと書きたいのですが、長くなるので割愛します。
個人的にはパスワード認証のみではそもそもあまりセキュアではないので可能であればMFAと組み合わせるべきと考えています。
パスワード認証はなぜ危険なのか? 注意すべき攻撃手段とユーザーの行動

アクセスキーを共有しない

ここはそのまま引用します。
アクセスキーを共有しない

アクセスキーを使用すると、プログラムから AWS にアクセスできます。暗号化されていないコード内にアクセスキーを埋め込んだり、これらのセキュリティ認証情報を AWS アカウントのユーザー間で共有したりしないでください。AWS へのアクセスを必要とするアプリケーションの場合は、IAM ロールを使用して一時的セキュリティ認証情報を取得するようにプログラムを設定します。プログラムによるアクセスをユーザーに個別に許可するには、個人用のアクセスキーを持つ IAM ユーザーを作成します。

前述しましたがIAMアクセスキーが必要なのは、AWSの外部からAWSアカウント内のサービスに対してアクセスを行う必要があるときのみです。
AWSの内部からAWSの各サービスを利用する場合は原則としてIAMロールを使用してください。
ごく単純なところだと、たとえばEC2をALBを使ってスケーラブルな構成にする際にサーバ上に直接アクセスキーを配置しておくと、サーバの台数分アクセスキーが複製されることになります。
あとはルートユーザーのアクセスキーと同様、アクセスキーが漏れるとコンソールにログインしていなくてもそのアクセスキーのユーザーの権限できる任意の操作をされてしまいます。[3]
IAMロールを設定しておけば、cliや各種SDKはクレデンシャル情報を何も設定していない場合は基本的に設定したロールから権限情報を取得してそれを使用するような挙動になっています。

ローカルから動作確認をするなどのときにはアクセスキーがどうしても必要になりますが、キーそのものに過剰に権限を持たせずにAssumeRoleを使用することを推奨します。
これによりユーザー自体に権限を持たせずに、権限が欲しいときだけに一時クレデンシャルを発行してそれを設定することによりAWSの操作を行うことができます。
cliだと~/.aws/configに書いておくだけで簡単に使えます。
AWS CLIで簡単にAssumeRole(スイッチロール)

おそらくですが、AWSの各サービスに割り当てられたIAMロールは各サービスからAssumeRoleを使って権限を呼び出されて使われています。

ロールを使用してアクセス許可を委任する

ロールを使用してアクセス許可を委任する

↑ではAWS上で各リソースにアクセスするときはキーではなくIAMロールを使用しましょうという話でしたが、
ここで言っているのはAWSの別アカウントからのアクセスを許可させる場合にはアクセスキーを渡すのではなくIAMロールの使用を許可することで権限を渡しましょう、という話です。
(前述のAssumeRoleをほかのアカウントから利用できるように設定する)

WebサービスとかでもAWSのリソースアクセスを要求する際にAWSのアクセスキーを要求するものとIAMロールを要求するものがありますが、できれば全部ロールを要求するようにしてほしいですね…。
たとえばDataDogなんかはIAMロールで権限を渡せます。
Terraform Cloudは2020/12/20現在ロールで権限を渡すことはできないはずです(見た限り。違ったら修正します)。

不要な認証情報の削除

不要な認証情報の削除

書いてあるとおりです。

IAM ユーザーの不要な認証情報 (つまり、パスワードとアクセスキー) は削除します。たとえば、コンソールを使用しないアプリケーションで IAM ユーザーを作成した場合、IAM ユーザーにパスワードは必要ありません。同様に、ユーザーのみコンソールを使用する場合、他のユーザーのアクセスキーは削除します。最近使用されていないパスワードやアクセスキーは削除の対象となります

AdministratorAccessを持っているユーザーのアクセスキーをバンバン発行しているのを見たりしますけど、危ないのでなるべく避けましょう。
また、キーだけ必要なユーザーの場合にはそもそもパスワードを設定する必要がありません。パスワードはコンソールにログインするために必要なものだからですね。

貼ったドキュメントにもありますが、下記あたりを参考に対処するとよいでしょう。
使用していない認証情報の検索
IAM ユーザーのパスワードの管理
IAM ユーザーのアクセスキーの管理
AWS アカウントの認証情報レポートの取得

認証情報を定期的にローテーションする。

認証情報を定期的にローテーションする。

アクセスキーは必要がなければ使わないと書きましたが、もし使う場合は定期的にローテーションすることを推奨されています。
また、ドキュメントではパスワードもローテーションを推奨されていますが、パスワードの定期変更は前述の通り現在は非推奨となっているのでご注意を。

応用編

応用と呼んでよいのかわかりませんが…。
AWSの利用に慣れてきたら考えるべきところだと思っていることをこちらに。
実質上、主に権限周りをどうするかのことです。

このあたりはIAMユーザー、グループ、ロール、ポリシーのそれぞれの関係性を理解してないとイメージしづらいかもしれないので、
わかりやすいこちらの記事をぜひ御覧ください。
AWS初心者にIAM Policy/User/Roleについてざっくり説明する

以前はポリシージェネレータを使ってjsonを組み立てるみたいなことをやってましたが、今はビジュアルエディタがあるので比較的IAMポリシーは作りやすくなったと思います。
AWS Policy Generator
[新機能]IAMのVisual Editorを使って見た[便利!]

最小限の特権を認める。

どういうことかというと、過剰に権限を与えずに必要な権限だけ与えましょう、ということです。
IAMユーザーとかには何も考えずにAdministratorAccessを設定しがちですが、本来は役割ごとに権限を分けるべきです。
また、IAMロールについては実際の利用時には必要最小限の権限だけ振るようにするのがベストです。
たとえばS3にアクセスするにしても、S3FullAccessをとりあえず渡すのをやめて、特定バケットの特定のディレクトリのみに絞るなど。
ただ、真面目に権限設計しようと思うとそれなりにたいへんです。
個人的にはまずは強めの権限を与えて開発して、後から必要な権限のみに絞るみたいなやり方になることが多いようには感じます。

AWS 管理ポリシーを使用したアクセス許可の使用開始

アクセスレベルを使用して、IAM アクセス許可を確認する

AWS 管理ポリシーを使用したアクセス許可の使用開始
アクセスレベルを使用して、IAM アクセス許可を確認する

このあたりはドキュメントやIAMのコンソールを見たほうが早いですが、
自分で権限設定を細かく設定するのももちろんよいのですが、AWSのマネージドポリシーがあります。
前述のS3FullAccessなんかもそうですね。
サービスごとにFullAccessとかReadOnlyAccessとかあったりしますが、職務機能に合わせたポリシーもあります。
こちらもしれっと書いていたAdministratorAccessとかが該当します。
職務機能の AWS 管理ポリシー

インラインポリシーではなくカスタマー管理ポリシーを使用する

インラインポリシーではなくカスタマー管理ポリシーを使用する

インラインポリシーとは、ざっくり言うとIAMユーザー・IAMロールに個別に設定するポリシーのことで、ほかのユーザーやロールに使い回すことができません。
基本的にはインラインポリシーは使わず、マネージドポリシーを作成してそれを割り当てることをお勧めします。

参考
[AWS]管理ポリシーとインラインポリシーの違いが分からなかったので改めてIAMポリシーのお勉強をする
管理ポリシーとインラインポリシー

脚注
  1. ただし、課金が発生するのでいくらかかるかについては見積もっておくこと ↩︎

  2. ちなみに、多要素認証と二段階認証は紛らわしいですが別の概念です。
    「二要素認証」と「二段階認証」の違い ↩︎

  3. アクセスキーをアプリケーションにハードコードしてコミットしてGitHubに上げてしまい不正利用された、みたいな話は調べると結構出てきます。
    GitHub に AWS キーペアを上げると抜かれるってほんと???試してみよー!
    ↩︎

GitHubで編集を提案

Discussion

ログインするとコメントできます