ろーてくxyz blog

ローテクを駆使してIT関係でサヴァイヴしようとする人による備忘録

一定期間AWS MFAを設定しないユーザログインをスクリプトで無効にさせる

もうPowerDNSの記事は忘れ去れてしまってる感じですが、定期的にAWSのユーザ監査をするようなスクリプトを動かしてみました。

こんな感じでコンソールログイン有効かつMFA未設定を条件で抽出して、アカウント作成から7日以上経っていいる ユーザを対象にAWSのコンソールログイン + Access Keyを作ってる場合はそれを無効化するものを作成してみました。

until_daysにて何日以上の条件の日数を指定すれば該当させる条件を変更できます。

boto3とUTCJSTに変換でpytzを使ってるので、この2つのモジュールが必要です。

#!/usr/bin/env python3

import sys
import boto3
from boto3.session import Session
import datetime
from pytz import timezone


if(len(sys.argv) != 2):
  print(sys.argv[0] + ' [aws cli profile name]')
  sys.exit()


try:
  session = Session(profile_name=sys.argv[1])
except Exception as e:
  print('\n' + 'Profile Errors: ' + str(e) + '\n')
  sys.exit()


iam = session.client('iam')


def get_users():
  user_lists = []
  res = iam.list_users()
  for lists in res['Users']:
    userlist = lists['UserName']
    user_lists.append(userlist)
  return user_lists


def check_create_date(username):
  res = iam.get_user(UserName=username)
  create_date = res['User']['CreateDate']
  create_date = create_date.astimezone(timezone('Asia/Tokyo'))
  return create_date


def get_mfa_stats(username):
  res = iam.list_mfa_devices(UserName=username)
  if not res['MFADevices']:
    mfa_stats = 'MFA_False'
  else:
    mfa_stats = 'MFA_True'
  return mfa_stats


def check_console_login(username):
  try :
    iam.get_login_profile(UserName=username)
    check_result = 'Login_Yes'
  except Exception :
    check_result = 'Login_No'
  return check_result


def suspend_user(username):
  update_res = []
  delete_res = iam.delete_login_profile(UserName=username)
  update_res.append(delete_res)
  check_access_keys = iam.list_access_keys(UserName=username)
  for key_lists in check_access_keys['AccessKeyMetadata']:
    res = iam.update_access_key(UserName=username, AccessKeyId=key_lists['AccessKeyId'], Status='Inactive')
    update_res.append(res)
  return update_res


def main():
  print('### check start.')
  for user_list in get_users():
    mfa_stats = get_mfa_stats(user_list)
    console_login_stats = check_console_login(user_list)
    if 'MFA_False' in mfa_stats and 'Login_Yes' in console_login_stats:
      create_date = check_create_date(user_list)
      create_date = create_date.date()
      now_date = datetime.date.today()
      res_date = (now_date-create_date).days
      until_days = 7
      if until_days <= res_date:
        print(user_list + ' is Console Login YES. but have not set MFA for more than ' +
              str(res_date)  + 'days')
        suspend_result = suspend_user(user_list)
        print(suspend_result)
    else:
      True
  print('### Finish')


if __name__ == '__main__':
  main()

実行前:
Console PasswordがEnableになっています。この段階ではWebからAWSログインできます。

❯ ./script.py [aws credential profile name]
### check start.
test.user is Console Login YES. but have not set MFA for more than 10days
[{'ResponseMetadata':  無効化した時のHTTP応答コードが返ってきます ]
### Finish

実行後:
該当のユーザが存在した場合は、
Console Passwordの設定をDisableに変更。この状態でWebからログインはできません。
合わせて、Access Keyの生成をしてる場合は、Inactiveのステータスにします。

セキュリティ関連のSaaSでも同様に出来るのでは?と思いますので、本当はそちらを使うのが良いのでしょうが、AWS CLIからも行ける感じですね。
これを利用して、長期ログインしていないユーザの精査なども出来ると思います。
わざわざこんな事しなくても良い方法があるような気もしますが。

AWS側での仕様変更などもあると思いますし、本スクリプト使用により生じたいかなる事象・事故について一切の責任を負いかねます。*