AWS の学習をしたい場合、Web で調べたり、書籍を見たり、ドキュメントを見たりと様々な方法があります。ただ、AWS の情報は巷に溢れているため、座学の学習のみでは情報がまとまっていなかったり、分かりづらい表現だったりしてなかなか腹落ちしないことも多く、理解に時間がかかったり、理解したつもりでも実際は異なっていたなどのことも多くあるかと思います。
そこでご提案したい学習方法は、座学で学んだことを実際にAWS を触って試してみることです。AWS のようなクラウドサービスは、高額な初期投資をせずにアカウントを作成すればすぐに実際に触りながら学習をすすめることができます。特にAWS アカウントを作成してから1年間は無料利用枠が利用でき学習目的程度の利用量であれば、ほぼ無料で利用可能です。
https://aws.amazon.com/jp/free/
ただ、クラウドに無料利用枠があると言っても、そもそもクラウドの料金の基本は、従量課金制であるため、知らない間に無料利用枠を超えて使いすぎてしまっていたり、不正にアカウントにアクセスされて大量のリソースが使われてしまい、高額な利用料金が発生してしまうなどのリスクも考えられます。このような意図せずに利用しすぎてしまった場合や不正にアクセスされてしまった場合などでも、基本的には責任共有モデルの考えにより、利用者側の責任となり料金の支払い義務が発生します。
このような高額な利用料金が発生してしまうのではないかという不安から、学習のためだけにAWS アカウントを作成するということに躊躇されている方も多いと思います。
そこで、この記事では、主に不正アクセスされないようにAWS アカウントを多要素認証(Multi-Factor Authentication: MFA) で保護する方法を記載します。(自分自身の利用範囲が無料利用枠を超えないように対策する方法は別の記事に書きたいと思います。)
以下にAWS アカウントをMFA で保護するためのステップを記載します。
- AWS アカウントのルートユーザとIAM ユーザの違いを知る
- 認証情報には、人が使うものとプログラムが使うもの(アクセスキー) の2種類があることを知る
- 認証と認可の違いを理解する
- MFA によるAWS アカウントの保護方法を知る(Part 2 にて説明します)
この記事では、まずPart 1として、上記の1 ~ 3 までを説明します。
AWS アカウントのルートユーザとIAM ユーザの違いを知る
AWS の利用を開始するためには、まずAWS アカウントを作成する必要があります。アカウントを作成するときに、メールアドレスやパスワード、連絡先、支払い方法などの設定を行います。
アカウントを作成した直後は、メールアドレスとパスワードがアカウントにアクセスする際に利用できる唯一の認証情報となります。このメールアドレスとパスワードを利用してアカウントにアクセスしたユーザのことをルートユーザと呼びます。このルートユーザはアカウント内のあらゆる操作が可能なスーパーユーザであり、その権限をコントロールすることができません。
そのため、セキュリティの推奨事項としては、普段のアカウント操作にはルートユーザでは権限が強すぎるため、代わりに細かい権限を指定できるIAM ユーザを作成して利用します。
このようにルートユーザ、IAM ユーザの2種類の認証方法があり、それぞれにMFA の設定を行うことができます。
認証情報には、人が使うものとプログラムが使うもの(アクセスキー) の2種類があることを知る
次に理解していただきたいのは、認証情報の種類です。AWS には認証情報として、人がマネジメントコンソールというWeb UI にログインするときに利用する認証情報(Email/パスワードやIAM ユーザ名/パスワード) の他に、プログラムからAWS アカウントにアクセスする際に利用する認証情報(アクセスキー) が存在しています。
これを理解するために、まずAWS の基本を抑えましょう。AWS アカウント内の各種リソース(EC2 インスタンスやS3 バケットなど) を操作する場合は、インターネットに公開されているAWS API をコールする必要があります。
API というのは、Application Programming Interface の略であり、プログラムからアクセスすることを前提にしたインタフェースです。AWS API はHTTP プロトコル上に実装されています。
このAPI は、人が手動で各種リソースの操作をしたい場合には不向きです。そこで人が操作するためのマネジメントコンソール(Web UI) が用意されています。人が手動でマネジメントコンソールを操作すると、裏ではAPI コールに変換されて実行されています。また、AWS CLI や各種プログラム言語向けSDK を利用することで、AWS API をプログラムから直接呼び出すことができます。
このように2種類のアクセス方法が存在しているわけですが、何の権限もない人が勝手にAWS API を利用して皆さんのアカウント内のリソースを操作できてしまってはいけません。そのためにAWS API の呼び出しには認証・認可の仕組みが用意されています。
まず、人がマネジメントコンソールにアクセスする際には、マネジメントコンソールにサインインする必要があります。この際に利用される認証情報は、前のセクションで説明した、ルートユーザのEmail/パスワード もしくは、IAM ユーザのユーザ名/パスワードになります。この認証情報は人が利用する前提のものとなりユーザ名/パスワードは自分で自由に設定可能です。
もう一つの認証情報はプログラムから直接AWS API を呼び出す際に指定するアクセスキーという認証情報となります。イメージ的には以下の図のようになります。
人が使うユーザ名/パスワードも、プログラムが利用するアクセスキーも同じ認証情報であり両方とも秘匿にしておかなければならない情報になります。
AWS でよくある不正アクセスの原因として、アクセスキーが流出してしまったということがあげられます。
なぜアクセスキーが流出しやすいのかというと、アクセスキーの以下のような特徴によると考えられます。
- アクセスキーはAWS が自動で生成して払い出される英数字の文字列である。そのため認証情報であるという認識が薄くなりがちである(もしくは無い)
- プログラムから利用するという性質上、何らかのファイルに書き込んで利用することが多い(プログラムコード内やプログラムで利用する設定ファイルなど)
アクセスキーは、アクセスキーIDとシークレットアクセスキーで成り立ち、AWS により自動生成されて払い出されます。例えば、以下のような英数字の文字列として払い出されます。(当然このアクセスキーは無効なものを掲載しています。アクセスキーを人目につく場所に記載することは絶対にやめましょう!!!)
このため、この情報が認証情報であるという認識が薄れてしまい、例えば開発チームで利用しているSlack のようなチャットアプリでアクセスキーを共有するという行為を簡単にしてしまったりします。そうすると本来秘匿にしておかなければならないアクセスキーが、複数の開発者が知っている共有情報になってしまいます。その結果、誰かから外部にそのアクセスキーが漏れるリスクが増えてます。アクセスキーが漏れてしまうと、そのアクセスキーを利用して不正にアカウントにアクセスされてしまうということになります。
また、アクセスキーはプログラムから利用されるという前提になりますので、プログラムから読み込めるどこかに保存しておく必要があります。例えば、プログラムのソースコード内であったり、アプリケーションの設定ファイルや環境変数などです。一般的にソースコードや設定ファイルなどは、コードリポジトリなどに保存され複数の開発者から共有されることになり、もしその中にアクセスキーが記述されていれば、開発者間で認証情報であるアクセスキーが共有されてしまっているという状態になります。
更によくある事故が、アクセスキーの記載されたソースコードをそのまま世界中に公開されたリポジトリ(Github など)にアップロードしてしまうというパターンです。この場合、世界中の誰でも認証情報であるアクセスキーを入手でき、誰でもアカウントにアクセスできてしまうという事態が発生します。
上記のような事態にならないように、アクセスキーは認証情報であり秘匿にしておかなければならない情報であるという認識をきちんと持ち適切に管理することと、リポジトリに保存するコードや設定ファイルなどにアクセスキーを絶対に記載しないという心がけが重要となります。
とはいえ、意図せずにGit リポジトリなどにアクセスキーの含まれたコードをアップロードしてしまう可能性は拭えません。それを防ぐためにAWS からgit-secrets というツールが公開されています。このツールを活用することで、うっかりアクセスキーがリポジトリに保存されてしまうという事故を防ぐことができますので、ぜひご活用ください。
https://github.com/awslabs/git-secrets
認証と認可の違いを理解する
認証の理解を深めた次は、認可に関する理解が必要となります。
AWS API を呼び出すためには、認証処理を通る必要がありますが、認証というのはAPI をコールしたのは誰なのかを特定する処理です。そのために、その人しか知り得ない認証情報を受け取って判断するわけです。ただ、認証が通ったからと言って、実際に呼び出されたAPI を実行しても良いとは限りません。API を呼び出した人に対してAPI を呼び出す適切な権限があるかをチェックした上で、権限があればAPI が実行されますし、権限がなければAPI の実行は拒否されます。このような、権限によりAPI の実行可否を判断する処理を一般的に認可と呼びます。ちなみに、英語では、認証はAuthentication で、認可はAuthorization です。この2つは一緒くたに語られることもありますが、違いがあるということを理解しておきましょう。
なお、AWS API に対する認証と認可を担うAWS サービスが、AWS Identity and Access Management (IAM) です。
認証情報は、人が使うものとプログラムが利用するアクセスキーの2種類が存在していました。IAM ではIAM ユーザに紐付いてこの2種類の認証情報が管理されます。
API の呼び出し可否をコントロールするのがIAM ポリシーというものです。IAM ポリシー内に呼び出しても良いAPI や呼び出しては行けないAPIをJSON 形式で記述し、IAM ユーザに紐付けます。そうすると認証処理を通過したIAM ユーザのリクエストは、そのIAM ユーザに紐づくIAM ポリシーの記述内容によって、API 呼び出しの可否が判断されます。
なお、ルートユーザには、何でもできるスーパーユーザであるため、IAM ポリシーにより権限をコントロールすることはできません。
以下の図はIAM によるAWS API に対する認証・認可のイメージです。
なお、IAM ポリシーは以下のようにJSON 形式で記述します。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Stmt1453690971587", "Effect": "Allow", "Action": [ "ec2:Describe*", "ec2:StartInstances", "ec2:StopInstances” ], "Resource": "*", "Condition": { "IpAddress": { "aws:SourceIp": "192.168.11.11/32” } } } ] }
MFA によるAWS アカウントの保護方法を知る
ここまでの内容を踏まえた上で、実際にMFA によるAWS アカウントの保護方法をPart 2 にて説明します。
お読みいただきましてありがとうございました!