接続元 IP アドレスに基づいて IAM 権限を変更をしたい

188件のシェア(すこし話題の記事)

今日はユーザが意識することなく、接続元 IP アドレスによって IAM 権限を「管理者権限」「参照権限」に切り替える方法を紹介したいと思います。やりたいことを絵にすると、以下のとおりです。

例えば、オフィスやセキュリティエリア内など特定の IP アドレスからアクセスしている場合は、「管理者権限」として利用でき、自宅などパブリックアクセスの場合には「参照権限」のみに権限が変わる想定です。

今回は IAM 管理アカウントでのみ IAM ユーザを発行し、AWS リソースのあるアカウントにはスイッチロールでログインする想定で検証していますが、スイッチロールしない環境でも同じことは出来るかと思います。

IAM ユーザー準備(スイッチ元 AWS アカウント側)

IAM 管理アカウントに IAM ユーザを作成します。AWS コンソールにはこのアカウントの IAM ユーザでログインし、各環境にスイッチロールして利用します。ユーザにはスイッチロール権限をもたせるので、インラインポリシーなどで以下のように記述します。

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "sts:AssumeRole",
    "Resource": [
        "arn:aws:iam::xxxxxxxxxxxx:role/cmi-test.admin" #スイッチ先アカウントの IAM ロール ARN を記載
    ]
  }
}

IAM ポリシー作成(スイッチ先 AWS アカウント側)

今回は接続元に基づき、以下のような権限にします。

接続元 権限
特定 IP アドレス AdministratorAccess
それ以外 ViewOnlyAccess

「ViewOnlyAccess」についてはそのまま利用するので良いのですが、「AdministratorAccess」には接続元を限定する条件が必要です。が、「AdministratorAccess」は AWS 管理ポリシーのため編集できません。

なので、「AdministratorAccess」のポリシーをそのままコピーし、ユーザー管理ポリシーとして作成します。(今回は IPrestriction-admin というポリシー名にしました)

Condition として IpAddress aws:SourceIP を指定していますので、このポリシーは 59.xx.xx.xx/32 からの接続時のみ有効であることになります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        "59.xx.xx.xx/32"
                    ]
                }
            }
        }
    ]
}

IAM ロール作成(スイッチ先 AWS アカウント側)

スイッチロール用の IAM ロールを作成します。(今回は cm-test.admin というロール名にしました)ロールの「信頼関係」にスイッチ元の IAM ユーザを指定します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::xxxxxxxxxxxx:user/marumo1981" #スイッチ元アカウントの IAM ユーザー ARN を記載
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

IAM ポリシーのアタッチ

先ほど作成した IPrestriction-admin をアタッチします。加えて AWS 管理ポリシーの ViewOnlyAccess もアタッチします。

IP アドレス制限のある管理権限ポリシーと、制限のない参照権限ポリシーの両方をアタッチするのがポイントです。これにより、特定 IP アドレスで接続している場合は管理権限が利用でき、それ以外の場合でも参照権限だけは利用できるようにしています。

では、実際の動作を試してみましょう。

動作確認

不特定な IP アドレスから接続

https://checkip.amazonaws.com/ にアクセスし、接続元 IP を確認します。特定 IP アドレスは 59.xx.xx.xx なので、管理者権限は利用できない IP アドレスであることが確認できました。

この状態でスイッチロールし、EC2 ダッシュボードを開いてみました。矢印部分を確認すると cm-test.admin となっていますので、スイッチロールできていることが判ります。また、EC2 のリソース一覧が表示されているので、少なくとも参照権限が利用できていることも判ります。

ここから1つの EC2 インスタンスを起動させてみます。

起動できないことから、管理者権限がないことが確認できましたね。

特定 IP アドレスから接続

次に、特定 IP アドレスからアクセスしてみます。同様に https://checkip.amazonaws.com/ で確認すると、59.xx.xx.xx となっており、意図した特定 IP アドレスで接続できていることが確認できました。

アクティブなロールは矢印部分のとおり、先ほどと同じ cm-test.admin であることが確認できました。

ここから1つの EC2 インスタンスを起動させてみます。

先ほどは起動権限がなくエラーになりましたが、今回は起動処理を実行することができました!権限の異なる IAM ロールへスイッチするのではなく、同じ IAM ロールを使って、接続元 IP アドレスに基づいて権限が変わっていることが確認できましたね!

さいごに

「接続元 IP アドレスで AWS コンソールを制限したい」というニーズは一定数存在するんだろうなと思いますが、何を目的とした制限であるか不明確なケースは少なくないかと思います。いわゆる、とりあえず制限しとくというやつですね。本当に制限したいものだけを接続元 IP で制限して、それ以外は使えるようにしておくと、業務効率があがるケースもあるんじゃないかと思い、ご紹介させていただきました!

誰かのお役にたてば幸いです。

以上!大阪オフィスの丸毛(@marumo1981)でした!