-
Notifications
You must be signed in to change notification settings - Fork 30
/
amzcwevents_lambda_security_group.py
105 lines (88 loc) · 3.76 KB
/
amzcwevents_lambda_security_group.py
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
# Copyright [2016]-[2016] Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License.
# A copy of the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file.
# This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the License for the specific language governing permissions
# and limitations under the License.
#
# Description: Checks that all security groups block access to the specified ports.
#
# awscwevents_lambda_security_group.py
#
# Author: jeffscottlevine
# Date: 2016-09-05
#
# This file contains an AWS Lambda handler which responds to AWS API calls that modify the ingress
# permissions of security groups to see if the permissions now differ from the required permissions
# as specificed in the REQUIRED_PERMISSIONS variable below.
#
# Note: The permissions are not remediated within this function because doing so could possibly
# trigger a recursion issue with this Lambda function triggering itself.
#
# 2017-01-13 - Added "Ipv6Ranges" to REQUIRED_PERMISSIONS to accommodate IPv6 within Amazon VPC.
import boto3
import botocore
import json
APPLICABLE_APIS = ["AuthorizeSecurityGroupIngress", "RevokeSecurityGroupIngress"]
# Specify the required ingress permissions using the same key layout as that provided in the
# describe_security_group API response and authorize_security_group_ingress/egress API calls.
REQUIRED_PERMISSIONS = [
{
"IpProtocol" : "tcp",
"FromPort" : 80,
"ToPort" : 80,
"UserIdGroupPairs" : [],
"IpRanges" : [{"CidrIp" : "0.0.0.0/0", "Description": ""}],
"PrefixListIds" : [],
"Ipv6Ranges": []
},
{
"IpProtocol" : "tcp",
"FromPort" : 443,
"ToPort" : 443,
"UserIdGroupPairs" : [],
"IpRanges" : [{"CidrIp" : "0.0.0.0/0", "Description": ""}],
"PrefixListIds" : [],
"Ipv6Ranges": []
}]
# evaluate_compliance
#
# This is the main compliance evaluation function.
def evaluate_compliance(event):
event_name = event["detail"]["eventName"]
if event_name not in APPLICABLE_APIS:
print("This rule does not apply for the event ", event_name, ".")
return
group_id = event["detail"]["requestParameters"]["groupId"]
print("group id: ", group_id)
client = boto3.client("ec2");
try:
response = client.describe_security_groups(GroupIds=[group_id])
except botocore.exceptions.ClientError as e:
print("describe_security_groups failure on group ", group_id, " .")
return
print("security group definition: ", json.dumps(response, indent=2))
ip_permissions = response["SecurityGroups"][0]["IpPermissions"]
authorize_permissions = [perm for perm in REQUIRED_PERMISSIONS if perm not in ip_permissions]
revoke_permissions = [perm for perm in ip_permissions if perm not in REQUIRED_PERMISSIONS]
if authorize_permissions or revoke_permissions:
if authorize_permissions:
for perm in authorize_permissions:
print("This permission must be authorized: ", json.dumps(perm, separators=(',',':')))
if revoke_permissions:
for perm in revoke_permissions:
print("This permission must be revoked: ", json.dumps(perm, separators=(',',':')))
else:
print("All permissions are correct.")
# lambda_handler
#
# This is the main handle for the Lambda function. AWS Lambda passes the function an event and a context.
def lambda_handler(event, context):
print("event: ", json.dumps(event))
evaluation = evaluate_compliance(event)