forked from xueshanf/aws-cloudtrail-with-splunk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cloudtrail-admin.sh
executable file
·255 lines (229 loc) · 6.52 KB
/
cloudtrail-admin.sh
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#!/bin/bash
set -e
shopt -s extglob # enables pattern lists like +(...|...)
# Default variables
init() {
# Supported regions
regions="us-east-1 us-west-1 us-west-2 eu-west-1 sa-east-1 ap-northeast-1 ap-southeast-1 ap-southeast-2"
regionRegexp='+(us-east-1|us-west-1|us-west-2|eu-west-1|sa-east-1|ap-northeast-1|ap-southeast-1|ap-southeast-2)'
# Script actions
actionsRegexp='+(create|delete|show)'
# Dryrun flag
dryrun=0
# Interactive flag
interactive=1
}
# Create trails for all supported regions and create SNS topics
create_trails(){
# Setup the first trail to receive global events
region=$defaultRegion
thisTrail=${trailname}-$region
trail=$(aws --profile $profile cloudtrail describe-trails --region $region --trail-name-list $thisTrail | jq --raw-output '.trailList[].Name')
if [ "$trail" = "$thisTrail" ]; then
echo "$accountId already has CloudTrail setup: $trail."
else
includeGlobal="true"
if ! aws --profile $profile s3 ls s3://$trailbucket > /dev/null 2>&1; then
bucketOpt="--s3-new-bucket"
fi
thisTrail=${trailname}-$region
setup_trail
fi
bucketOpt="--s3-use-bucket"
includeGlobal="false"
# Setup the rest of the trails
for region in $regions
do
thisTrail=${trailname}-$region
trail=$(aws --profile $profile cloudtrail describe-trails --region $region --trail-name-list $thisTrail | jq --raw-output '.trailList[].Name')
if [ "$trail" = "$thisTrail" ]; then
echo "$accountId already has CloudTrail setup: $thisTrail."
else
setup_trail
fi
done
}
setup_trail(){
snstopic=$thisTrail
cmd="aws --profile $profile cloudtrail create-subscription --region $region \
--name $thisTrail \
$bucketOpt $trailbucket --sns-new-topic $snstopic \
--include-global-service-events $includeGlobal"
echo "Creating $thisTrail"
[ $dryrun -eq 0 ] && $cmd
}
create_sqs(){
# This is optional. Some third party AWS log service, e.g. SplunkAppForAWS, may need a SQS.
# Cloudtrail SQS and Trail name
queuename=${accountId}-cloudtrail
if [ $interactive -eq 1 ]; then
answer='N'
echo -n "Do you want to create SQS $queuename? [Y/N]"
read answer
echo ""
if [ "X$answer" != "XY" ]; then
echo "No queue is created."
exit 0
fi
fi
echo "Creating SQS service."
cmd="aws --profile $profile sqs create-queue --queue-name $queuename --region $defaultRegion"
[ $dryrun -eq 0 ] && $cmd
}
show(){
echo "Trails"
for i in $regions
do
aws --profile $profile cloudtrail describe-trails --region $i | jq --raw-output '.trailList[].Name'
done
echo "SNS"
for i in $regions
do
aws --profile $profile sns list-topics --region $i | jq --raw-output '.Topics[].TopicArn' | grep "$profile-cloudtrail"
done
echo "SQS"
if [ ! -z "$accountId" ]; then
aws --profile $profile sqs list-queues --queue-name-prefix $accountId | jq --raw-output '.QueueUrls[]'
else
aws --profile $profile sqs list-queues | jq --raw-output '.QueueUrls[]'
fi
}
# Delete SNS topics
delete_sns(){
# Delete SNS topics
for i in $regions
do
snstopic=${trailname}-$i
topicarn=$(aws --profile $profile sns list-topics --region $i |grep $snstopic | awk '{print $2}' | sed 's/\"//g')
if [ $topicarn ]; then
cmd="aws --profile $profile sns delete-topic --topic-arn $topicarn --region $i"
echo "Deleting $topicarn."
[ $dryrun -eq 0 ] && $cmd
fi
done
}
# Delete Cloudtrails
delete_trails() {
for i in $regions
do
thisTrail=$trailname-$i
trail=$(aws --profile $profile cloudtrail describe-trails --region $i --trail-name-list $thisTrail | jq --raw-output '.trailList[].Name')
if [ -z "$trail" ];
then
echo "$thisTrail doesn't exist."
continue
fi
cmd="aws --profile $profile cloudtrail delete-trail --region $i --name $thisTrail"
echo "Deleting $thisTrail."
[ $dryrun -eq 0 ] && $cmd
done
}
# Delete sqs
delete_sqs() {
queuename=${accountId}-cloudtrail
queueurl=$(aws --profile $profile sqs get-queue-url --queue-name $queuename --query QueueUrl | sed 's/\"//g')
if [ -z $queueurl ]; then
echo "No SQS to delete."
else
cmd="aws --profile $profile sqs delete-queue --queue-url $queueurl"
echo "Deleting $queueurl."
[ $dryrun -eq 0 ] && $cmd
fi
}
help(){
echo "create-cloudtrail -a <action> -p <profile> [-b <bucket>] -r region [-n] [-y]"
echo ""
echo " -a <create|show|delete>: action. create, show or delete cloudtrails setup by this tool."
echo " -p <aws profile>: authenticate as this profile."
echo " -b <bucket>: optional. bucket name to get all trail reports."
echo " -r <region>: region to get AWS global events, e.g. IAM"
echo " -y : non-interative mode. Answer to yes to all default values."
echo " -n : dryrun. print out the commands"
echo " -h : Help"
}
# Main
# Set default values
init
while getopts "a:p:b:r:hny" OPTION
do
case $OPTION in
a)
action=$OPTARG
case $action in
$actionsRegexp)
;;
*)
echo "Unsupported action $action."
exit 1
esac
;;
p)
profile=$OPTARG
;;
b)
bucket=$OPTARG
;;
r)
defaultRegion=$OPTARG
case $defaultRegion in
$regionRegexp)
;;
*)
echo "Unsuported region $region."
exit 1
esac
;;
n)
dryrun=1
;;
y)
interactive=0
;;
[h?])
help
exit
;;
esac
done
if [[ -z $action || -z $profile || -z $defaultRegion && $action != 'show' ]]; then
help
exit 1
fi
echo "Getting AWS account number ..."
accountId=$(aws --profile $profile iam get-user | jq '.User.Arn' | grep -Eo '[[:digit:]]{12}')
if [ -z "$accountId" ]; then
echo "Cannot find AWS account number."
exit 1
else
if [[ ! -z "bucket" && $interactive -ne 0 && $action != "show" ]]; then
answer='N'
echo -n "Do you accept the $accountId SNA and cloudtrail bucket prefix? [Y/N]"
read answer
echo ""
[ "X$answer" != "XY" ] && echo "Do nothing. Quit."&& exit 0
fi
fi
# Don't exist on non-zero code because the following aws commmands exit code
# is '1' on sucess.
set +e
# Cloudtrail name, one name per account.
trailname=${profile}-cloudtrail
# S3 bucket to receive logs
trailbucket=${bucket:-${accountId}-cloudtrail}
# Call functions based on action
case $action in
'create')
create_trails
create_sqs
;;
'delete')
delete_trails
delete_sns
delete_sqs
;;
'show')
show
;;
esac
[ $dryrun -eq 1 ] && echo "Dryrun mode. Nothing is changed."
exit 0