AWS

AWSアクセスキーを自動的に無効化する方法

sho

はじめに

西藤です。

みなさんはAWSの各種サービスを使った開発を行う際、AWSの各種操作の権限を取得するための「アクセスキー」の取り扱いはどのようにしていますか?

アクセスキー(とシークレットキー)は漏洩した場合、不正にAWSリソースを作成・利用されてしまう恐れなどがあります。

そのため、不正利用を防ぐために

  • アクセスキーを用いず、「ロール」ベースでの権限付与
  • アクセスキー自体に付与する権限を必要最低限のものにする

などの対策が考えられます。

しかし、「個人的に何かAWSを使って検証したい」というようなときには「権限を最小限に絞って….」などの調整は後回しにしてしまいがちです。
「AWSを使った検証」が目的なのですから、「権限の調整」に時間を取られたくはありませんよね。
とはいえ、不正利用されないためのなんらかの措置は講じておきたいもの….

今回はそんな開発者の方に使っていただきたい自動化設定の実装例を紹介いたします。

実装想定

今回は次のような場面を想定しています。

  • IAMユーザーを発行しており、それに紐づくアクセスキーを使用している

仮にこのIAMユーザー名を access-key-userとしましょう。
AWSマネジメントコンソールの画面で言うとこんな感じでしょうか

IAMユーザーの例

そして、今回は

  • 日本時刻0:00になったら access-key-userのアクセスキーを無効化する。

という仕組みを実装します。
(”Serverless Framework”を使用しますが、デプロイ自体の解説は割愛いたします。)

実装用のコード内容

Lambda関数

Lambda関数はPythonで実装して、コードは次の通りです。

handler.py

import json
import os
import boto3

def deactivate_access_key(access_key):
    responce = access_key.deactivate()
    print(responce)
    HTTPStatusCode = responce['ResponseMetadata']['HTTPStatusCode']
    print("HTTPStatusCode:")
    print(HTTPStatusCode)
    accessKeyId = access_key.access_key_id
    print(accessKeyId + " is deactivated.")
    return

def main(event, context):
    # 環境変数から取得
    targetAccessKeyUserName = os.environ['TARGET_ACCESS_KEY_USER_NAME']
    targetAccessKeyId = os.environ['TARGET_ACCESS_KEY_ID']
    # IAMのリソース作成
    iamResource = boto3.resource('iam')
    access_key = iamResource.AccessKey(targetAccessKeyUserName, targetAccessKeyId)
    # アクセスキーの無効化
    deactivate_access_key(access_key)
    return

コード内には環境変数が2つありますが、それぞれ
TARGET_ACCESS_KEY_USER_NAMEは無効化を行いたいアクセスキーが紐づくIAMユーザー名(今回の例では access-key-user
TARGET_ACCESS_KEY_IDは無効化を行いたいアクセスキー(AKIAIOSFODNN7EXAMPLEのような英数字で表される)
を適用します。
※もし、Serverless Frameworkを使わない場合はLambdaの環境変数設定にて記載してください。

そして、このLambda関数が実行されるとターゲットとなるアクセスキーが無効化されます。

Serverless Frameworkの実装準備

次に、上記のLambda関数を毎日0:00に自動実行する設定を行なっていきます。
Serverless Frameworkでの実装で使う.envファイルとserverless.ymlファイルは次のようになります。

.env

AWS_ACCESS_KEY_ID=<Serverless Frameworkでデプロイを行う用のアクセスキー>
AWS_SECRET_ACCESS_KEY=<Serverless Frameworkでデプロイを行う用のシークレットキー>
TARGET_ACCESS_KEY_USER_NAME=access-key-user
TARGET_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE

serverless.yml

service: deactivate-access-key

plugins:
  - serverless-dotenv-plugin
  - serverless-prune-plugin

custom:
  dotenv:
    include:
      - TARGET_ACCESS_KEY_USER_NAME
      - TARGET_ACCESS_KEY_ID
  prune:
    automatic: true
    number: 1

package:
  exclude:
    - ./**
  include:
    - ./handler.py

provider:
  name: aws
  runtime: python3.8
  region: ap-northeast-1
  stage: dev
  memorySize: 128
  iamRoleStatements:
    - Effect: Allow
      Action:
        - "iam:UpdateAccessKey"
      Resource:
        - "*"

functions:
  deactivate-access-key:
    description: アクセスキーの無効化
    name: deactivate-access-key
    handler: handler.main
    events:
      - schedule:
          name: deactivate-access-key
          description: JST 0:00にアクセスキーを無効化する
          rate: cron(00 15 * * ? *)

注目していただきたいのは、最後、数行分の部分です。
cronでの指定がありますがこれにより上記のLambda関数が毎日JST 0:00に実行されるようにCloudWatch Eventsルールの設定が付きますので、
「夜になったらAWSアクセスキーを自動的に無効化」が実現します。

あと、Dockerベースでデプロイできるようにしましょう。
Dockerfiledocker-compose.ymlは次の通りです。

Dockerfile

FROM node:15.3.0-alpine

RUN npm update -g

# install serverless framework
RUN npm install -g serverless
# install serverless plugins
RUN npm i -D serverless-dotenv-plugin
RUN npm install --save-dev serverless-prune-plugin

# change work directory
WORKDIR /app

COPY . /app/

docker-compose.yml

version: "3.8"
services:
  serverless:
    build:
      context: .
    volumes:
      - .:/app
    env_file:
      - .env

実装結果

以上を踏まえて、デプロイすると次のようになります。

Lambda関数
Lambda関数

CloudWatch Eventsルール
CloudWatch Eventsルール

JST 0:00になるとアクセスキーを無効化するLambda関数が実行される。と言う形です。

そして、この設定を終えて、Lambda実行ログを見ますと

Lambdaの実行ログ

と言うようにアクセスキーの無効化が実行された旨表示されており、アクセスキーのあるIAMユーザーの情報を見にいくと

無効化されたアクセスキー

ちゃんと、アクセスキーが無効になっています。

まとめ

以上でAWSアクセスキーを自動的に無効化する実装の完了です。

このようにしておけば、仮にAWSアクセスキーに強力な権限を付与したまま残してしまっていても、少なくとも毎日0:00になったらアクセスキー自体が無効化されるので、「強い権限付与した状態を忘れたまま放置してしまっていた」と言うような場面は回避できます。

本来は最小権限の原則に則って必要な権限を必要なだけ付与する、アクセスキーの漏洩に注意しキー自体も定期的なローテーションを行うなど、IAMのベストプラクティスに沿った運用を行うことが大原則ではありますが、安全にアクセスキーを使うための1つのアイディアとして参考になれば幸いです。

AUTHOR
sho
sho
記事URLをコピーしました