daiphone’s blog

AWS / JavaScript / Docker / PHP / Python を中心とした技術ネタと、趣味少々

AWSでMFA設定が有効なIAMユーザーを使って、CLI経由でリソースにアクセスする方法

はじめに

AWSを本格的に使い始めてもうすぐ1年が経とうとしています。

気づけば、資格を取り、気づけば社内の担当プロジェクトの環境構築をやり、気づけばインフラ全体の整備を任されるところまできました。

最近転職した会社でも、その部分の知見を買われて入社したため、

より知識を深めていかなければと日々奮闘してます。

背景

新たな会社での最初の使命は、インフラ環境の整備でした。

私の会社はインフラ整備が行き届いていなかったため、多くの課題がありました。

課題

  • AWSのベストプラクティスに則っていない
  • 開発者が研究開発用で使うアカウントが存在しない
  • 管理者権限を持つIAMユーザーを共用している
  • IAMユーザーが個々に割り振られていない
  • アプリケーション開発におけるテンプレート構成が存在しない
  • etc...

これらを解決することが私の一つの使命でした。

そのような現状を調べるために、aws cliでアクセスしようとしたところ、

$ aws2 ec2 describe-vpcs
An error occurred (UnauthorizedOperation) when calling the DescribeVpcs operation: You are not authorized to perform this operation.

???????????

アクセスができない!

実は、自身のIAMユーザー作成の際に、MFA認証がされていないセッションからのアクセスは禁止するポリシーを付与していたんです。

面倒だけど、セキュリティを担保する上では必要なので、IAMユーザー側の設定を変更せずに、またCLI用のIAMユーザーを別で作成せずに、解決できる方法を探してました。

先に答え知りたい人向けtips

aws2 sts get-session-token \
    --serial-number arn:aws:iam::{AccountID}:mfa/{LoginUserId} \
    --token-code {TokenCode}

"{}"内をよしなに変更すると、認証可能なアクセスキー等が出力されますので

それを環境変数にセットして通常通りコマンド叩けば完了です。

そもそもMFA設定とは?

多段階認証(Multi-Factor Authnetication)のことです。

詳細はこちら→ wiki

MFA設定しているとCLIが使えない?

MFAを設定していると、各セッションごとに認証が必要になってくるので、

CLIを認証せずにそのまま叩こうとするとエラーになります。

$ aws2 ec2 describe-vpcs
An error occurred (UnauthorizedOperation) when calling the DescribeVpcs operation: You are not authorized to perform this operation.

通常ブラウザでAWSマネジメントコンソールにアクセスして、プライベートウィンドウを開いて再度アクセスした際に、

ログインが必要になるのと同じ原理ですね。

セッションが違うので。

ならばどうする

CLIからTokenCodeを送って、一時的な認証キーを取得します。

認証キー取得

$ aws2 sts get-session-token \
    --serial-number arn:aws:iam::123456789012:mfa/hogehogeuser \
    --token-code 999999
{
    "Credentials": {
        "AccessKeyId": "FTGYHUIJRFTGYHU",
        "SecretAccessKey": "seyufuaiefjadufhufeufaef67",
        "SessionToken": "feyufasjiHFUiFJIFjoejfesjfhfdfhuseufsfybfujsfa//////////fweufuah4wkfhu4efeuafhk4ggalifja;f'ag9ejgautfybunckmscaffds",
        "Expiration": "2020-01-18T18:27:03+00:00"
    }
}

取得した認証キーを環境変数にセットする

bashの場合

#!/bin/bash

export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
export AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN

fishの場合

#!/usr/local/bin/fish
set -x AWS_ACCESS_KEY_ID $AWS_ACCESS_KEY_ID
set -x AWS_SECRET_ACCESS_KEY $AWS_SECRET_ACCESS_KEY
set -x AWS_SESSION_TOKEN $AWS_SESSION_TOKEN

動作確認

VPCを取得するコマンドを叩いてみます。

$ aws2 ec2 describe-vpcs
{
    "Vpcs": [
        {
            "CidrBlock": "xxx.xx.x.x/16",
            "DhcpOptionsId": "dopt-xxxxxxx",
            "State": "available",
            "VpcId": "vpc-xxxxxxx",
            "OwnerId": "123456789012",
            "InstanceTenancy": "default",
            "CidrBlockAssociationSet": [
                {
                    "AssociationId": "vpc-cidr-assoc-xxxxxxxx",
                    "CidrBlock": "xxx.xx.x.x/16",
                    "CidrBlockState": {
                        "State": "associated"
                    }
                }
            ],
            "IsDefault": true
        }
    ]
}

無事取得できてますね。

補足

今回のユーザーは「MFAの認証が通っていないとリソースへのアクセスができませんよ」という

ポリシーを独自に付与していたため、このような状況になりました。

通常のポリシーではこのようなことは発生しないと思いますので、必要に応じて利用する形でいいでしょう。

AWSコマンドって便利

AWSを利用していると、CLIを利用してリソースに対して変更を行ったりする機会が増えていきます。

やっぱりこちらのほうがシンプルで簡単なんですよね。

あと、手順をCode化できるし。

GUIでやると、細かい部分の手順が抜けてしまい、再現性が低くなってします。

もちろん最初からCLIでやろうとしても、このコマンドの意味は?とか、

オプションの必要性の有無等、考慮する点が多いので、少しハードルは高いかもしれません。

あと、権限によっては、一瞬で全インスタンス削除とかできちゃいますしね笑

GUIでリソースの基本的な利用方法に慣れる
↓
何度もマネジメントコンソールにアクセスするの面倒だと感じる
↓
やりたい処理をCLIで書き起こす
↓
応用

こんな感じでやっていくと、効率よく学習できると思います。