1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
import os
import boto3
from datetime import date
# Email stuff
SOURCE_ADDRESS = os.environ.get('SOURCE_ADDRESS')
CC_EMAIL_ADDRESS = os.environ.get('CC_EMAIL_ADDRESS')
USER_GROUP_TARGET = os.environ.get('USER_GROUP_TARGET')
# Day settings
WARN_DAYS = int(os.environ.get('WARN_DAYS'))
DISABLE_DAY = int(os.environ.get('DISABLE_DAY'))
DELETE_DAY = int(os.environ.get('DELETE_DAY'))
def findOldAccessKeys():
iam = boto3.client('iam')
currentdate = date.today()
# List all users
for user in iam.list_users()['Users']:
emailBool = False
userGroups = iam.list_groups_for_user(UserName=user['UserName'])
# For each group
for groupName in userGroups['Groups']:
# For users in the group 'GroupName'
if USER_GROUP_TARGET in groupName['GroupName']:
res = iam.list_access_keys(UserName=user['UserName'])
# For each access key they have
for AccessKeys in res['AccessKeyMetadata']:
active_days = currentdate - AccessKeys['CreateDate'].date()
# If the key is active
if (AccessKeys['Status'] == 'Active'):
# If it is past its due date
response = iam.list_user_tags(
UserName = user['UserName'],
MaxItems = 123
)
for tag in response['Tags']:
if (tag['Key'] == 'email'):
emailBool = True
email = tag['Value']
# Delete key if range
if (active_days.days >= DELETE_DAY):
print(f"Username: {user['UserName']} ({active_days.days}) is over {DELETE_DAY} days, deleting the access key.")
delete_access_key(iam, AccessKeys['AccessKeyId'], user['UserName'])
# Disable key
elif (active_days.days >= DISABLE_DAY):
print(f"Username: {user['UserName']} ({active_days.days}) is over {DISABLE_DAY} days, disabling access key & sending email.")
disable_access_key(iam, AccessKeys['AccessKeyId'], user['UserName'])
if (emailBool == True):
send_disable_email(user['UserName'], email)
else:
print(f"[!] Email tag does not exist for: {user['UserName']}")
send_email_dne(user['UserName'])
# In the warning range
elif (active_days.days >= WARN_DAYS):
print(f"Username: {user['UserName']} ({active_days.days}) is over {WARN_DAYS} days, sending reminder email.")
if (emailBool == True):
sendWarningEmail(user['UserName'], email, active_days.days)
else:
print(f"[!] Email tag does not exist for: {user['UserName']}")
send_email_dne(user['UserName'])
def delete_access_key(iam, keyID, username):
iam.delete_access_key(
AccessKeyId = keyID,
UserName = username
)
def disable_access_key(iam, keyID, username):
iam.update_access_key(
AccessKeyId = keyID,
Status = 'Inactive',
UserName = username
)
def send_email_dne(username):
ses = boto3.client('ses')
bodyEmail = f"Could not find a email for the AWS user {username}"
ses.send_email(
Source = SOURCE_ADDRESS,
Destination = {
'ToAddresses': [
SOURCE_ADDRESS,
]
},
Message = {
'Subject': {
'Data': 'Email Does Not Exist | AWS Access Key'
},
'Body': {
'Html': {
'Data': bodyEmail
}
}
}
)
def send_disable_email(username, email):
ses = boto3.client('ses')
bodyEmail = f"""Hello {username},<br><br>
Your aws cli access key is outdated, and has been disabled.<br>
Please login to aws and create a new access key.<br><br>
Guide to update your access key<br>
https://aws.amazon.com/blogs/security/how-to-find-update-access-keys-password-mfa-aws-management-console/<br>
Linux / OSX cli tool<br>
https://github.com/stefansundin/aws-rotate-key<br>
"""
ses.send_email(
Source = SOURCE_ADDRESS,
Destination = {
'ToAddresses': [
email,
],
'CcAddresses': [
CC_EMAIL_ADDRESS,
]
},
Message = {
'Subject': {
'Data': 'Outdated AWS Access Key'
},
'Body': {
'Html': {
'Data': bodyEmail
}
}
}
)
def sendWarningEmail(username, email, days):
ses = boto3.client('ses')
bodyEmail = f"""Hello {username},<br><br>
Your aws cli access key is reaching its expiration date.<br>
Please replace your access key, it will be disabled in {DISABLE_DAY - days} days.<br><br>
Guide to update your access key<br>
https://aws.amazon.com/blogs/security/how-to-find-update-access-keys-password-mfa-aws-management-console/<br>
Linux / OSX cli tool<br>
https://github.com/stefansundin/aws-rotate-key<br>
"""
ses.send_email(
Source = SOURCE_ADDRESS,
Destination = {
'ToAddresses': [
email,
]
},
Message = {
'Subject': {
'Data': 'Outdated AWS Access Key Warning'
},
'Body': {
'Html': {
'Data': bodyEmail
}
}
}
)
def lambda_handler(event, context):
findOldAccessKeys()
|