mirror of
https://github.com/ghndrx/prowler.git
synced 2026-02-10 14:55:00 +00:00
feat(ec2): Add ResourceArn (#1649)
Co-authored-by: sergargar <sergio@verica.io>
This commit is contained in:
@@ -9,7 +9,7 @@
|
|||||||
"SubServiceName": "ami",
|
"SubServiceName": "ami",
|
||||||
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
|
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
|
||||||
"Severity": "critical",
|
"Severity": "critical",
|
||||||
"ResourceType": "AwsEc2SecurityGroup",
|
"ResourceType": "Other",
|
||||||
"Description": "Ensure there are no EC2 AMIs set as Public.",
|
"Description": "Ensure there are no EC2 AMIs set as Public.",
|
||||||
"Risk": "A shared AMI is an AMI that a developer created and made available for other developers to use. If AMIs have embebed information about the environment could pose a security risk. You use a shared AMI at your own risk. Amazon can not vouch for the integrity or security of AMIs shared by Amazon EC2 users.",
|
"Risk": "A shared AMI is an AMI that a developer created and made available for other developers to use. If AMIs have embebed information about the environment could pose a security risk. You use a shared AMI at your own risk. Amazon can not vouch for the integrity or security of AMIs shared by Amazon EC2 users.",
|
||||||
"RelatedUrl": "",
|
"RelatedUrl": "",
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ class ec2_ami_public(Check):
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = image.region
|
report.region = image.region
|
||||||
report.resource_id = image.id
|
report.resource_id = image.id
|
||||||
|
report.resource_arn = image.arn
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"EC2 AMI {image.id} is not public."
|
report.status_extended = f"EC2 AMI {image.id} is not public."
|
||||||
if image.public:
|
if image.public:
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ class ec2_ebs_public_snapshot(Check):
|
|||||||
for snapshot in ec2_client.snapshots:
|
for snapshot in ec2_client.snapshots:
|
||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = snapshot.region
|
report.region = snapshot.region
|
||||||
|
report.resource_arn = snapshot.arn
|
||||||
if not snapshot.public:
|
if not snapshot.public:
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"EBS Snapshot {snapshot.id} is not Public."
|
report.status_extended = f"EBS Snapshot {snapshot.id} is not Public."
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ class ec2_ebs_snapshots_encrypted(Check):
|
|||||||
for snapshot in ec2_client.snapshots:
|
for snapshot in ec2_client.snapshots:
|
||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = snapshot.region
|
report.region = snapshot.region
|
||||||
|
report.resource_arn = snapshot.arn
|
||||||
if snapshot.encrypted:
|
if snapshot.encrypted:
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"EBS Snapshot {snapshot.id} is encrypted."
|
report.status_extended = f"EBS Snapshot {snapshot.id} is encrypted."
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ class ec2_ebs_volume_encryption(Check):
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = volume.region
|
report.region = volume.region
|
||||||
report.resource_id = volume.id
|
report.resource_id = volume.id
|
||||||
|
report.resource_arn = volume.arn
|
||||||
if volume.encrypted:
|
if volume.encrypted:
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"EBS Snapshot {volume.id} is encrypted."
|
report.status_extended = f"EBS Snapshot {volume.id} is encrypted."
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class ec2_elastic_ip_shodan(Check):
|
|||||||
for eip in ec2_client.elastic_ips:
|
for eip in ec2_client.elastic_ips:
|
||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = eip.region
|
report.region = eip.region
|
||||||
|
report.resource_arn = eip.arn
|
||||||
if eip.public_ip:
|
if eip.public_ip:
|
||||||
try:
|
try:
|
||||||
shodan_info = api.host(eip.public_ip)
|
shodan_info = api.host(eip.public_ip)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ class ec2_elastic_ip_unassgined(Check):
|
|||||||
report.region = eip.region
|
report.region = eip.region
|
||||||
if eip.public_ip:
|
if eip.public_ip:
|
||||||
report.resource_id = eip.public_ip
|
report.resource_id = eip.public_ip
|
||||||
|
report.resource_arn = eip.arn
|
||||||
report.status = "FAIL"
|
report.status = "FAIL"
|
||||||
report.status_extended = f"Elastic IP {eip.public_ip} is not associated with an instance or network interface."
|
report.status_extended = f"Elastic IP {eip.public_ip} is not associated with an instance or network interface."
|
||||||
if eip.association_id:
|
if eip.association_id:
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ class ec2_instance_imdsv2_enabled(Check):
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = instance.region
|
report.region = instance.region
|
||||||
report.resource_id = instance.id
|
report.resource_id = instance.id
|
||||||
|
report.resource_arn = instance.arn
|
||||||
report.status = "FAIL"
|
report.status = "FAIL"
|
||||||
report.status_extended = (
|
report.status_extended = (
|
||||||
f"EC2 Instance {instance.id} has IMDSv2 disabled or not required."
|
f"EC2 Instance {instance.id} has IMDSv2 disabled or not required."
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ class ec2_instance_internet_facing_with_instance_profile(Check):
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = instance.region
|
report.region = instance.region
|
||||||
report.resource_id = instance.id
|
report.resource_id = instance.id
|
||||||
|
report.resource_arn = instance.arn
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"EC2 Instance {instance.id} is not internet facing with an instance profile."
|
report.status_extended = f"EC2 Instance {instance.id} is not internet facing with an instance profile."
|
||||||
if instance.public_ip and instance.instance_profile:
|
if instance.public_ip and instance.instance_profile:
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ class ec2_instance_managed_by_ssm(Check):
|
|||||||
for instance in ec2_client.instances:
|
for instance in ec2_client.instances:
|
||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = instance.region
|
report.region = instance.region
|
||||||
|
report.resource_arn = instance.arn
|
||||||
if not ssm_client.managed_instances.get(instance.id):
|
if not ssm_client.managed_instances.get(instance.id):
|
||||||
report.status = "FAIL"
|
report.status = "FAIL"
|
||||||
report.status_extended = (
|
report.status_extended = (
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class ec2_instance_older_than_specific_days(Check):
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = instance.region
|
report.region = instance.region
|
||||||
report.resource_id = instance.id
|
report.resource_id = instance.id
|
||||||
|
report.resource_arn = instance.arn
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"EC2 Instance {instance.id} is not running."
|
report.status_extended = f"EC2 Instance {instance.id} is not running."
|
||||||
if instance.state == "running":
|
if instance.state == "running":
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ class ec2_instance_profile_attached(Check):
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = instance.region
|
report.region = instance.region
|
||||||
report.resource_id = instance.id
|
report.resource_id = instance.id
|
||||||
|
report.resource_arn = instance.arn
|
||||||
report.status = "FAIL"
|
report.status = "FAIL"
|
||||||
report.status_extended = f"EC2 Instance {instance.id} not associated with an Instance Profile Role."
|
report.status_extended = f"EC2 Instance {instance.id} not associated with an Instance Profile Role."
|
||||||
if instance.instance_profile:
|
if instance.instance_profile:
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ class ec2_instance_public_ip(Check):
|
|||||||
for instance in ec2_client.instances:
|
for instance in ec2_client.instances:
|
||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = instance.region
|
report.region = instance.region
|
||||||
|
report.resource_arn = instance.arn
|
||||||
if instance.public_ip:
|
if instance.public_ip:
|
||||||
report.status = "FAIL"
|
report.status = "FAIL"
|
||||||
report.status_extended = f"EC2 Instance {instance.id} has a Public IP: {instance.public_ip} ({instance.public_dns})."
|
report.status_extended = f"EC2 Instance {instance.id} has a Public IP: {instance.public_ip} ({instance.public_dns})."
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class ec2_instance_secrets_user_data(Check):
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = instance.region
|
report.region = instance.region
|
||||||
report.resource_id = instance.id
|
report.resource_id = instance.id
|
||||||
|
report.resource_arn = instance.arn
|
||||||
|
|
||||||
if instance.user_data:
|
if instance.user_data:
|
||||||
temp_user_data_file = tempfile.NamedTemporaryFile(delete=False)
|
temp_user_data_file = tempfile.NamedTemporaryFile(delete=False)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ class ec2_networkacl_allow_ingress_any_port(Check):
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = network_acl.region
|
report.region = network_acl.region
|
||||||
report.resource_id = network_acl.id
|
report.resource_id = network_acl.id
|
||||||
|
report.resource_arn = network_acl.arn
|
||||||
# If some entry allows it, that ACL is not securely configured
|
# If some entry allows it, that ACL is not securely configured
|
||||||
if not check_network_acl(network_acl.entries, tcp_protocol, check_port):
|
if not check_network_acl(network_acl.entries, tcp_protocol, check_port):
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class ec2_networkacl_allow_ingress_tcp_port_22(Check):
|
|||||||
for network_acl in ec2_client.network_acls:
|
for network_acl in ec2_client.network_acls:
|
||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = network_acl.region
|
report.region = network_acl.region
|
||||||
|
report.resource_arn = network_acl.arn
|
||||||
# If some entry allows it, that ACL is not securely configured
|
# If some entry allows it, that ACL is not securely configured
|
||||||
if not check_network_acl(network_acl.entries, tcp_protocol, check_port):
|
if not check_network_acl(network_acl.entries, tcp_protocol, check_port):
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class ec2_networkacl_allow_ingress_tcp_port_3389(Check):
|
|||||||
for network_acl in ec2_client.network_acls:
|
for network_acl in ec2_client.network_acls:
|
||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = network_acl.region
|
report.region = network_acl.region
|
||||||
|
report.resource_arn = network_acl.arn
|
||||||
# If some entry allows it, that ACL is not securely configured
|
# If some entry allows it, that ACL is not securely configured
|
||||||
if not check_network_acl(network_acl.entries, tcp_protocol, check_port):
|
if not check_network_acl(network_acl.entries, tcp_protocol, check_port):
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_any_port(Check):
|
|||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not all ports open to the Internet."
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not all ports open to the Internet."
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
# Loop through every security group's ingress rule and check it
|
# Loop through every security group's ingress rule and check it
|
||||||
for ingress_rule in security_group.ingress_rules:
|
for ingress_rule in security_group.ingress_rules:
|
||||||
if check_security_group(ingress_rule, "-1", any_address=True):
|
if check_security_group(ingress_rule, "-1", any_address=True):
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018(
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = security_group.region
|
report.region = security_group.region
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not MongoDB ports 27017 and 27018 open to the Internet."
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not MongoDB ports 27017 and 27018 open to the Internet."
|
||||||
# Loop through every security group's ingress rule and check it
|
# Loop through every security group's ingress rule and check it
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21(Check)
|
|||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not FTP ports 20 and 21 open to the Internet."
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not FTP ports 20 and 21 open to the Internet."
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
# Loop through every security group's ingress rule and check it
|
# Loop through every security group's ingress rule and check it
|
||||||
for ingress_rule in security_group.ingress_rules:
|
for ingress_rule in security_group.ingress_rules:
|
||||||
if check_security_group(
|
if check_security_group(
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22(Check):
|
|||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not SSH port 22 open to the Internet."
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not SSH port 22 open to the Internet."
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
# Loop through every security group's ingress rule and check it
|
# Loop through every security group's ingress rule and check it
|
||||||
for ingress_rule in security_group.ingress_rules:
|
for ingress_rule in security_group.ingress_rules:
|
||||||
if check_security_group(
|
if check_security_group(
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389(Check):
|
|||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Microsoft RDP port 3389 open to the Internet."
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Microsoft RDP port 3389 open to the Internet."
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
# Loop through every security group's ingress rule and check it
|
# Loop through every security group's ingress rule and check it
|
||||||
for ingress_rule in security_group.ingress_rules:
|
for ingress_rule in security_group.ingress_rules:
|
||||||
if check_security_group(
|
if check_security_group(
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = security_group.region
|
report.region = security_group.region
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Casandra ports 7199, 8888 and 9160 open to the Internet."
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Casandra ports 7199, 8888 and 9160 open to the Internet."
|
||||||
# Loop through every security group's ingress rule and check it
|
# Loop through every security group's ingress rule and check it
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_ki
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = security_group.region
|
report.region = security_group.region
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Elasticsearch/Kibana ports 9200, 9300 and 5601 open to the Internet."
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Elasticsearch/Kibana ports 9200, 9300 and 5601 open to the Internet."
|
||||||
# Loop through every security group's ingress rule and check it
|
# Loop through every security group's ingress rule and check it
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092(Check
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = security_group.region
|
report.region = security_group.region
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Kafka port 9092 open to the Internet."
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Kafka port 9092 open to the Internet."
|
||||||
# Loop through every security group's ingress rule and check it
|
# Loop through every security group's ingress rule and check it
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211(
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = security_group.region
|
report.region = security_group.region
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Memcached port 11211 open to the Internet."
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Memcached port 11211 open to the Internet."
|
||||||
# Loop through every security group's ingress rule and check it
|
# Loop through every security group's ingress rule and check it
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306(Check
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = security_group.region
|
report.region = security_group.region
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not MySQL port 3306 open to the Internet."
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not MySQL port 3306 open to the Internet."
|
||||||
# Loop through every security group's ingress rule and check it
|
# Loop through every security group's ingress rule and check it
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = security_group.region
|
report.region = security_group.region
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Oracle ports 1521 and 2483 open to the Internet."
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Oracle ports 1521 and 2483 open to the Internet."
|
||||||
# Loop through every security group's ingress rule and check it
|
# Loop through every security group's ingress rule and check it
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432(Ch
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = security_group.region
|
report.region = security_group.region
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Postgres port 5432 open to the Internet."
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Postgres port 5432 open to the Internet."
|
||||||
# Loop through every security group's ingress rule and check it
|
# Loop through every security group's ingress rule and check it
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379(Check
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = security_group.region
|
report.region = security_group.region
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Redis port 6379 open to the Internet."
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Redis port 6379 open to the Internet."
|
||||||
# Loop through every security group's ingress rule and check it
|
# Loop through every security group's ingress rule and check it
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = security_group.region
|
report.region = security_group.region
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Microsoft SQL Server ports 1433 and 1434 open to the Internet."
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Microsoft SQL Server ports 1433 and 1434 open to the Internet."
|
||||||
# Loop through every security group's ingress rule and check it
|
# Loop through every security group's ingress rule and check it
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23(Check)
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = security_group.region
|
report.region = security_group.region
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Telnet port 23 open to the Internet."
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has not Telnet port 23 open to the Internet."
|
||||||
# Loop through every security group's ingress rule and check it
|
# Loop through every security group's ingress rule and check it
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ class ec2_securitygroup_allow_wide_open_public_ipv4(Check):
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = security_group.region
|
report.region = security_group.region
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has no potential wide-open non-RFC1918 address."
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has no potential wide-open non-RFC1918 address."
|
||||||
# Loop through every security group's ingress rule and check it
|
# Loop through every security group's ingress rule and check it
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ class ec2_securitygroup_default_restrict_traffic(Check):
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = security_group.region
|
report.region = security_group.region
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
# Find default security group
|
# Find default security group
|
||||||
if security_group.name == "default":
|
if security_group.name == "default":
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ class ec2_securitygroup_from_launch_wizard(Check):
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = security_group.region
|
report.region = security_group.region
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) was not created using the EC2 Launch Wizard."
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) was not created using the EC2 Launch Wizard."
|
||||||
if "launch-wizard" in security_group.name:
|
if "launch-wizard" in security_group.name:
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ class ec2_securitygroup_in_use_without_ingress_filtering(Check):
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = security_group.region
|
report.region = security_group.region
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has ingress filtering."
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has ingress filtering."
|
||||||
for ingress_rule in security_group.ingress_rules:
|
for ingress_rule in security_group.ingress_rules:
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ class ec2_securitygroup_not_used(Check):
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = security_group.region
|
report.region = security_group.region
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) it is being used."
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) it is being used."
|
||||||
if len(security_group.network_interfaces) == 0:
|
if len(security_group.network_interfaces) == 0:
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class ec2_securitygroup_with_many_ingress_egress_rules(Check):
|
|||||||
report = Check_Report_AWS(self.metadata())
|
report = Check_Report_AWS(self.metadata())
|
||||||
report.region = security_group.region
|
report.region = security_group.region
|
||||||
report.resource_id = security_group.id
|
report.resource_id = security_group.id
|
||||||
|
report.resource_arn = security_group.arn
|
||||||
report.status = "PASS"
|
report.status = "PASS"
|
||||||
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has {len(security_group.ingress_rules)} inbound rules and {len(security_group.egress_rules)} outbound rules"
|
report.status_extended = f"Security group {security_group.name} ({security_group.id}) has {len(security_group.ingress_rules)} inbound rules and {len(security_group.egress_rules)} outbound rules"
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ class EC2:
|
|||||||
for page in describe_instances_paginator.paginate():
|
for page in describe_instances_paginator.paginate():
|
||||||
for reservation in page["Reservations"]:
|
for reservation in page["Reservations"]:
|
||||||
for instance in reservation["Instances"]:
|
for instance in reservation["Instances"]:
|
||||||
|
arn = f"arn:{self.audited_partition}:ec2:{regional_client.region}:{self.audited_account}:instance/{instance['InstanceId']}"
|
||||||
http_tokens = None
|
http_tokens = None
|
||||||
http_endpoint = None
|
http_endpoint = None
|
||||||
public_dns = None
|
public_dns = None
|
||||||
@@ -74,6 +75,7 @@ class EC2:
|
|||||||
self.instances.append(
|
self.instances.append(
|
||||||
Instance(
|
Instance(
|
||||||
instance["InstanceId"],
|
instance["InstanceId"],
|
||||||
|
arn,
|
||||||
instance["State"]["Name"],
|
instance["State"]["Name"],
|
||||||
regional_client.region,
|
regional_client.region,
|
||||||
instance["InstanceType"],
|
instance["InstanceType"],
|
||||||
@@ -101,9 +103,11 @@ class EC2:
|
|||||||
)
|
)
|
||||||
for page in describe_security_groups_paginator.paginate():
|
for page in describe_security_groups_paginator.paginate():
|
||||||
for sg in page["SecurityGroups"]:
|
for sg in page["SecurityGroups"]:
|
||||||
|
arn = f"arn:{self.audited_partition}:ec2:{regional_client.region}:{self.audited_account}:security-group/{sg['GroupId']}"
|
||||||
self.security_groups.append(
|
self.security_groups.append(
|
||||||
SecurityGroup(
|
SecurityGroup(
|
||||||
sg["GroupName"],
|
sg["GroupName"],
|
||||||
|
arn,
|
||||||
regional_client.region,
|
regional_client.region,
|
||||||
sg["GroupId"],
|
sg["GroupId"],
|
||||||
sg["IpPermissions"],
|
sg["IpPermissions"],
|
||||||
@@ -123,9 +127,11 @@ class EC2:
|
|||||||
)
|
)
|
||||||
for page in describe_network_acls_paginator.paginate():
|
for page in describe_network_acls_paginator.paginate():
|
||||||
for nacl in page["NetworkAcls"]:
|
for nacl in page["NetworkAcls"]:
|
||||||
|
arn = f"arn:{self.audited_partition}:ec2:{regional_client.region}:{self.audited_account}:network-acl/{nacl['NetworkAclId']}"
|
||||||
self.network_acls.append(
|
self.network_acls.append(
|
||||||
NetworkACL(
|
NetworkACL(
|
||||||
nacl["NetworkAclId"],
|
nacl["NetworkAclId"],
|
||||||
|
arn,
|
||||||
regional_client.region,
|
regional_client.region,
|
||||||
nacl["Entries"],
|
nacl["Entries"],
|
||||||
)
|
)
|
||||||
@@ -144,11 +150,15 @@ class EC2:
|
|||||||
encrypted = False
|
encrypted = False
|
||||||
for page in describe_snapshots_paginator.paginate(OwnerIds=["self"]):
|
for page in describe_snapshots_paginator.paginate(OwnerIds=["self"]):
|
||||||
for snapshot in page["Snapshots"]:
|
for snapshot in page["Snapshots"]:
|
||||||
|
arn = f"arn:{self.audited_partition}:ec2:{regional_client.region}:{self.audited_account}:snapshot/{snapshot['SnapshotId']}"
|
||||||
if snapshot["Encrypted"]:
|
if snapshot["Encrypted"]:
|
||||||
encrypted = True
|
encrypted = True
|
||||||
self.snapshots.append(
|
self.snapshots.append(
|
||||||
Snapshot(
|
Snapshot(
|
||||||
snapshot["SnapshotId"], regional_client.region, encrypted
|
snapshot["SnapshotId"],
|
||||||
|
arn,
|
||||||
|
regional_client.region,
|
||||||
|
encrypted,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
@@ -220,11 +230,16 @@ class EC2:
|
|||||||
try:
|
try:
|
||||||
public = False
|
public = False
|
||||||
for image in regional_client.describe_images(Owners=["self"])["Images"]:
|
for image in regional_client.describe_images(Owners=["self"])["Images"]:
|
||||||
|
arn = f"arn:{self.audited_partition}:ec2:{regional_client.region}:{self.audited_account}:image/{image['ImageId']}"
|
||||||
if image["Public"]:
|
if image["Public"]:
|
||||||
public = True
|
public = True
|
||||||
self.images.append(
|
self.images.append(
|
||||||
Image(
|
Image(
|
||||||
image["ImageId"], image["Name"], public, regional_client.region
|
image["ImageId"],
|
||||||
|
arn,
|
||||||
|
image["Name"],
|
||||||
|
public,
|
||||||
|
regional_client.region,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
@@ -240,9 +255,11 @@ class EC2:
|
|||||||
)
|
)
|
||||||
for page in describe_volumes_paginator.paginate():
|
for page in describe_volumes_paginator.paginate():
|
||||||
for volume in page["Volumes"]:
|
for volume in page["Volumes"]:
|
||||||
|
arn = f"arn:{self.audited_partition}:ec2:{regional_client.region}:{self.audited_account}:volume/{volume['VolumeId']}"
|
||||||
self.volumes.append(
|
self.volumes.append(
|
||||||
Volume(
|
Volume(
|
||||||
volume["VolumeId"],
|
volume["VolumeId"],
|
||||||
|
arn,
|
||||||
regional_client.region,
|
regional_client.region,
|
||||||
volume["Encrypted"],
|
volume["Encrypted"],
|
||||||
)
|
)
|
||||||
@@ -301,6 +318,7 @@ class EC2:
|
|||||||
@dataclass
|
@dataclass
|
||||||
class Instance:
|
class Instance:
|
||||||
id: str
|
id: str
|
||||||
|
arn: str
|
||||||
state: str
|
state: str
|
||||||
region: str
|
region: str
|
||||||
type: str
|
type: str
|
||||||
@@ -318,6 +336,7 @@ class Instance:
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
id,
|
id,
|
||||||
|
arn,
|
||||||
state,
|
state,
|
||||||
region,
|
region,
|
||||||
type,
|
type,
|
||||||
@@ -332,6 +351,7 @@ class Instance:
|
|||||||
instance_profile,
|
instance_profile,
|
||||||
):
|
):
|
||||||
self.id = id
|
self.id = id
|
||||||
|
self.arn = arn
|
||||||
self.state = state
|
self.state = state
|
||||||
self.region = region
|
self.region = region
|
||||||
self.type = type
|
self.type = type
|
||||||
@@ -350,12 +370,14 @@ class Instance:
|
|||||||
@dataclass
|
@dataclass
|
||||||
class Snapshot:
|
class Snapshot:
|
||||||
id: str
|
id: str
|
||||||
|
arn: str
|
||||||
region: str
|
region: str
|
||||||
encrypted: bool
|
encrypted: bool
|
||||||
public: bool
|
public: bool
|
||||||
|
|
||||||
def __init__(self, id, region, encrypted):
|
def __init__(self, id, arn, region, encrypted):
|
||||||
self.id = id
|
self.id = id
|
||||||
|
self.arn = arn
|
||||||
self.region = region
|
self.region = region
|
||||||
self.encrypted = encrypted
|
self.encrypted = encrypted
|
||||||
self.public = False
|
self.public = False
|
||||||
@@ -364,11 +386,13 @@ class Snapshot:
|
|||||||
@dataclass
|
@dataclass
|
||||||
class Volume:
|
class Volume:
|
||||||
id: str
|
id: str
|
||||||
|
arn: str
|
||||||
region: str
|
region: str
|
||||||
encrypted: bool
|
encrypted: bool
|
||||||
|
|
||||||
def __init__(self, id, region, encrypted):
|
def __init__(self, id, arn, region, encrypted):
|
||||||
self.id = id
|
self.id = id
|
||||||
|
self.arn = arn
|
||||||
self.region = region
|
self.region = region
|
||||||
self.encrypted = encrypted
|
self.encrypted = encrypted
|
||||||
|
|
||||||
@@ -376,14 +400,16 @@ class Volume:
|
|||||||
@dataclass
|
@dataclass
|
||||||
class SecurityGroup:
|
class SecurityGroup:
|
||||||
name: str
|
name: str
|
||||||
|
arn: str
|
||||||
region: str
|
region: str
|
||||||
id: str
|
id: str
|
||||||
network_interfaces: list[str]
|
network_interfaces: list[str]
|
||||||
ingress_rules: list[dict]
|
ingress_rules: list[dict]
|
||||||
egress_rules: list[dict]
|
egress_rules: list[dict]
|
||||||
|
|
||||||
def __init__(self, name, region, id, ingress_rules, egress_rules):
|
def __init__(self, name, arn, region, id, ingress_rules, egress_rules):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
self.arn = arn
|
||||||
self.region = region
|
self.region = region
|
||||||
self.id = id
|
self.id = id
|
||||||
self.ingress_rules = ingress_rules
|
self.ingress_rules = ingress_rules
|
||||||
@@ -394,11 +420,13 @@ class SecurityGroup:
|
|||||||
@dataclass
|
@dataclass
|
||||||
class NetworkACL:
|
class NetworkACL:
|
||||||
id: str
|
id: str
|
||||||
|
arn: str
|
||||||
region: str
|
region: str
|
||||||
entries: list[dict]
|
entries: list[dict]
|
||||||
|
|
||||||
def __init__(self, id, region, entries):
|
def __init__(self, id, arn, region, entries):
|
||||||
self.id = id
|
self.id = id
|
||||||
|
self.arn = arn
|
||||||
self.region = region
|
self.region = region
|
||||||
self.entries = entries
|
self.entries = entries
|
||||||
|
|
||||||
@@ -422,12 +450,14 @@ class ElasticIP:
|
|||||||
@dataclass
|
@dataclass
|
||||||
class Image:
|
class Image:
|
||||||
id: str
|
id: str
|
||||||
|
arn: str
|
||||||
name: str
|
name: str
|
||||||
public: bool
|
public: bool
|
||||||
region: str
|
region: str
|
||||||
|
|
||||||
def __init__(self, id, name, public, region):
|
def __init__(self, id, arn, name, public, region):
|
||||||
self.id = id
|
self.id = id
|
||||||
|
self.arn = arn
|
||||||
self.name = name
|
self.name = name
|
||||||
self.public = public
|
self.public = public
|
||||||
self.region = region
|
self.region = region
|
||||||
|
|||||||
@@ -65,6 +65,10 @@ class Test_ec2_ami_public:
|
|||||||
assert result[0].status == "PASS"
|
assert result[0].status == "PASS"
|
||||||
assert result[0].status_extended == f"EC2 AMI {image_id} is not public."
|
assert result[0].status_extended == f"EC2 AMI {image_id} is not public."
|
||||||
assert result[0].resource_id == image_id
|
assert result[0].resource_id == image_id
|
||||||
|
assert (
|
||||||
|
result[0].resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:image/{image_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_one_public_ami(self):
|
def test_one_public_ami(self):
|
||||||
@@ -111,3 +115,7 @@ class Test_ec2_ami_public:
|
|||||||
result[0].status_extended == f"EC2 AMI {image_id} is currently public."
|
result[0].status_extended == f"EC2 AMI {image_id} is currently public."
|
||||||
)
|
)
|
||||||
assert result[0].resource_id == image_id
|
assert result[0].resource_id == image_id
|
||||||
|
assert (
|
||||||
|
result[0].resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:image/{image_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -72,6 +72,10 @@ class Test_ec2_ebs_public_snapshot:
|
|||||||
snap.status_extended
|
snap.status_extended
|
||||||
== f"EBS Snapshot {snapshot.id} is currently Public."
|
== f"EBS Snapshot {snapshot.id} is currently Public."
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
snap.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:snapshot/{snapshot.id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_private_snapshot(self):
|
def test_ec2_private_snapshot(self):
|
||||||
@@ -109,3 +113,7 @@ class Test_ec2_ebs_public_snapshot:
|
|||||||
snap.status_extended
|
snap.status_extended
|
||||||
== f"EBS Snapshot {snapshot.id} is not Public."
|
== f"EBS Snapshot {snapshot.id} is not Public."
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
snap.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:snapshot/{snapshot.id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -66,6 +66,10 @@ class Test_ec2_ebs_snapshots_encrypted:
|
|||||||
snap.status_extended
|
snap.status_extended
|
||||||
== f"EBS Snapshot {snapshot.id} is unencrypted."
|
== f"EBS Snapshot {snapshot.id} is unencrypted."
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
snap.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:snapshot/{snapshot.id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_encrypted_snapshot(self):
|
def test_ec2_encrypted_snapshot(self):
|
||||||
@@ -103,3 +107,7 @@ class Test_ec2_ebs_snapshots_encrypted:
|
|||||||
snap.status_extended
|
snap.status_extended
|
||||||
== f"EBS Snapshot {snapshot.id} is encrypted."
|
== f"EBS Snapshot {snapshot.id} is encrypted."
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
snap.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:snapshot/{snapshot.id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -60,6 +60,10 @@ class Test_ec2_ebs_volume_encryption:
|
|||||||
assert (
|
assert (
|
||||||
result[0].status_extended == f"EBS Snapshot {volume.id} is unencrypted."
|
result[0].status_extended == f"EBS Snapshot {volume.id} is unencrypted."
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
result[0].resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:volume/{volume.id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_encrypted_volume(self):
|
def test_ec2_encrypted_volume(self):
|
||||||
@@ -93,3 +97,7 @@ class Test_ec2_ebs_volume_encryption:
|
|||||||
assert (
|
assert (
|
||||||
result[0].status_extended == f"EBS Snapshot {volume.id} is encrypted."
|
result[0].status_extended == f"EBS Snapshot {volume.id} is encrypted."
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
result[0].resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:volume/{volume.id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ class Test_ec2_elastic_ip_unassgined:
|
|||||||
def test_eip_unassociated(self):
|
def test_eip_unassociated(self):
|
||||||
# Create EC2 Mocked Resources
|
# Create EC2 Mocked Resources
|
||||||
ec2_client = client("ec2", region_name=AWS_REGION)
|
ec2_client = client("ec2", region_name=AWS_REGION)
|
||||||
ec2_client.allocate_address(Domain="vpc", Address="127.38.43.222")
|
allocation_id = ec2_client.allocate_address(
|
||||||
|
Domain="vpc", Address="127.38.43.222"
|
||||||
|
)["AllocationId"]
|
||||||
|
|
||||||
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
|
||||||
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
from prowler.providers.aws.services.ec2.ec2_service import EC2
|
||||||
@@ -62,6 +64,10 @@ class Test_ec2_elastic_ip_unassgined:
|
|||||||
"is not associated",
|
"is not associated",
|
||||||
results[0].status_extended,
|
results[0].status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
results[0].resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:eip-allocation/{allocation_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_eip_associated(self):
|
def test_eip_associated(self):
|
||||||
@@ -106,3 +112,7 @@ class Test_ec2_elastic_ip_unassgined:
|
|||||||
"is associated",
|
"is associated",
|
||||||
results[0].status_extended,
|
results[0].status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
results[0].resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:eip-allocation/{eip.allocation_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -73,6 +73,10 @@ class Test_ec2_instance_imdsv2_enabled:
|
|||||||
result[0].status_extended,
|
result[0].status_extended,
|
||||||
)
|
)
|
||||||
assert result[0].resource_id == instance.id
|
assert result[0].resource_id == instance.id
|
||||||
|
assert (
|
||||||
|
result[0].resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_one_uncompliant_ec2(self):
|
def test_one_uncompliant_ec2(self):
|
||||||
@@ -115,3 +119,7 @@ class Test_ec2_instance_imdsv2_enabled:
|
|||||||
result[0].status_extended,
|
result[0].status_extended,
|
||||||
)
|
)
|
||||||
assert result[0].resource_id == instance.id
|
assert result[0].resource_id == instance.id
|
||||||
|
assert (
|
||||||
|
result[0].resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -81,6 +81,10 @@ class Test_ec2_instance_internet_facing_with_instance_profile:
|
|||||||
result[0].status_extended,
|
result[0].status_extended,
|
||||||
)
|
)
|
||||||
assert result[0].resource_id == instance.id
|
assert result[0].resource_id == instance.id
|
||||||
|
assert (
|
||||||
|
result[0].resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_iam
|
@mock_iam
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
@@ -130,3 +134,7 @@ class Test_ec2_instance_internet_facing_with_instance_profile:
|
|||||||
"is internet-facing with Instance Profile", result[0].status_extended
|
"is internet-facing with Instance Profile", result[0].status_extended
|
||||||
)
|
)
|
||||||
assert result[0].resource_id == instance.id
|
assert result[0].resource_id == instance.id
|
||||||
|
assert (
|
||||||
|
result[0].resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -68,6 +68,10 @@ class Test_ec2_instance_older_than_specific_days:
|
|||||||
f"EC2 Instance {instance.id} is not older", result[0].status_extended
|
f"EC2 Instance {instance.id} is not older", result[0].status_extended
|
||||||
)
|
)
|
||||||
assert result[0].resource_id == instance.id
|
assert result[0].resource_id == instance.id
|
||||||
|
assert (
|
||||||
|
result[0].resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_one_old_ec2(self):
|
def test_one_old_ec2(self):
|
||||||
@@ -107,3 +111,7 @@ class Test_ec2_instance_older_than_specific_days:
|
|||||||
f"EC2 Instance {instance.id} is older", result[0].status_extended
|
f"EC2 Instance {instance.id} is older", result[0].status_extended
|
||||||
)
|
)
|
||||||
assert result[0].resource_id == instance.id
|
assert result[0].resource_id == instance.id
|
||||||
|
assert (
|
||||||
|
result[0].resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -81,6 +81,10 @@ class Test_ec2_instance_profile_attached:
|
|||||||
result[0].status_extended,
|
result[0].status_extended,
|
||||||
)
|
)
|
||||||
assert result[0].resource_id == instance.id
|
assert result[0].resource_id == instance.id
|
||||||
|
assert (
|
||||||
|
result[0].resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_one_non_compliant_ec2(self):
|
def test_one_non_compliant_ec2(self):
|
||||||
@@ -123,3 +127,7 @@ class Test_ec2_instance_profile_attached:
|
|||||||
"not associated with an Instance Profile", result[0].status_extended
|
"not associated with an Instance Profile", result[0].status_extended
|
||||||
)
|
)
|
||||||
assert result[0].resource_id == instance.id
|
assert result[0].resource_id == instance.id
|
||||||
|
assert (
|
||||||
|
result[0].resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -75,6 +75,10 @@ class Test_ec2_instance_public_ip:
|
|||||||
result[0].status_extended,
|
result[0].status_extended,
|
||||||
)
|
)
|
||||||
assert result[0].resource_id == instance.id
|
assert result[0].resource_id == instance.id
|
||||||
|
assert (
|
||||||
|
result[0].resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_one_ec2_with_public_ip(self):
|
def test_one_ec2_with_public_ip(self):
|
||||||
@@ -118,3 +122,7 @@ class Test_ec2_instance_public_ip:
|
|||||||
f"EC2 Instance {instance.id} has a Public IP", result[0].status_extended
|
f"EC2 Instance {instance.id} has a Public IP", result[0].status_extended
|
||||||
)
|
)
|
||||||
assert result[0].resource_id == instance.id
|
assert result[0].resource_id == instance.id
|
||||||
|
assert (
|
||||||
|
result[0].resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -102,6 +102,10 @@ class Test_ec2_instance_secrets_user_data:
|
|||||||
== f"Potential secret found in EC2 instance {instance.id} User Data."
|
== f"Potential secret found in EC2 instance {instance.id} User Data."
|
||||||
)
|
)
|
||||||
assert result[0].resource_id == instance.id
|
assert result[0].resource_id == instance.id
|
||||||
|
assert (
|
||||||
|
result[0].resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_one_ec2_file_with_secrets(self):
|
def test_one_ec2_file_with_secrets(self):
|
||||||
@@ -140,6 +144,10 @@ class Test_ec2_instance_secrets_user_data:
|
|||||||
== f"Potential secret found in EC2 instance {instance.id} User Data."
|
== f"Potential secret found in EC2 instance {instance.id} User Data."
|
||||||
)
|
)
|
||||||
assert result[0].resource_id == instance.id
|
assert result[0].resource_id == instance.id
|
||||||
|
assert (
|
||||||
|
result[0].resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_one_launch_configurations_without_user_data(self):
|
def test_one_launch_configurations_without_user_data(self):
|
||||||
@@ -173,3 +181,7 @@ class Test_ec2_instance_secrets_user_data:
|
|||||||
== f"No secrets found in EC2 instance {instance.id} since User Data is empty."
|
== f"No secrets found in EC2 instance {instance.id} since User Data is empty."
|
||||||
)
|
)
|
||||||
assert result[0].resource_id == instance.id
|
assert result[0].resource_id == instance.id
|
||||||
|
assert (
|
||||||
|
result[0].resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -107,6 +107,10 @@ class ec2_networkacl_allow_ingress_any_port:
|
|||||||
nacl.status_extended
|
nacl.status_extended
|
||||||
== f"Network ACL {nacl_id} has every port open to the Internet."
|
== f"Network ACL {nacl_id} has every port open to the Internet."
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
nacl.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:network-acl/{nacl_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_nacl(self):
|
def test_ec2_compliant_nacl(self):
|
||||||
@@ -153,3 +157,7 @@ class ec2_networkacl_allow_ingress_any_port:
|
|||||||
nacl.status_extended
|
nacl.status_extended
|
||||||
== f"Network ACL {nacl_id} has not every port open to the Internet."
|
== f"Network ACL {nacl_id} has not every port open to the Internet."
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
nacl.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:network-acl/{nacl_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -108,6 +108,10 @@ class Test_ec2_networkacl_allow_ingress_tcp_port_22:
|
|||||||
nacl.status_extended
|
nacl.status_extended
|
||||||
== f"Network ACL {nacl_id} has SSH port 22 open to the Internet."
|
== f"Network ACL {nacl_id} has SSH port 22 open to the Internet."
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
nacl.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:network-acl/{nacl_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_nacl(self):
|
def test_ec2_compliant_nacl(self):
|
||||||
@@ -155,3 +159,7 @@ class Test_ec2_networkacl_allow_ingress_tcp_port_22:
|
|||||||
nacl.status_extended
|
nacl.status_extended
|
||||||
== f"Network ACL {nacl_id} has not SSH port 22 open to the Internet."
|
== f"Network ACL {nacl_id} has not SSH port 22 open to the Internet."
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
nacl.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:network-acl/{nacl_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -108,6 +108,10 @@ class Test_ec2_networkacl_allow_ingress_tcp_port_3389:
|
|||||||
nacl.status_extended
|
nacl.status_extended
|
||||||
== f"Network ACL {nacl_id} has Microsoft RDP port 3389 open to the Internet."
|
== f"Network ACL {nacl_id} has Microsoft RDP port 3389 open to the Internet."
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
nacl.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:network-acl/{nacl_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_nacl(self):
|
def test_ec2_compliant_nacl(self):
|
||||||
@@ -155,3 +159,7 @@ class Test_ec2_networkacl_allow_ingress_tcp_port_3389:
|
|||||||
nacl.status_extended
|
nacl.status_extended
|
||||||
== f"Network ACL {nacl_id} has not Microsoft RDP port 3389 open to the Internet."
|
== f"Network ACL {nacl_id} has not Microsoft RDP port 3389 open to the Internet."
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
nacl.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:network-acl/{nacl_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -83,6 +83,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_any_port:
|
|||||||
"has all ports open to the Internet",
|
"has all ports open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_default_sg(self):
|
def test_ec2_compliant_default_sg(self):
|
||||||
@@ -130,3 +134,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_any_port:
|
|||||||
"has not all ports open to the Internet",
|
"has not all ports open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -89,6 +89,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_2
|
|||||||
"has MongoDB ports 27017 and 27018 open to the Internet",
|
"has MongoDB ports 27017 and 27018 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_default_sg(self):
|
def test_ec2_compliant_default_sg(self):
|
||||||
@@ -140,3 +144,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_2
|
|||||||
"has not MongoDB ports 27017 and 27018 open to the Internet",
|
"has not MongoDB ports 27017 and 27018 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -89,6 +89,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21:
|
|||||||
"has FTP ports 20 and 21 open to the Internet",
|
"has FTP ports 20 and 21 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_default_sg(self):
|
def test_ec2_compliant_default_sg(self):
|
||||||
@@ -140,3 +144,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21:
|
|||||||
"has not FTP ports 20 and 21 open to the Internet",
|
"has not FTP ports 20 and 21 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -85,6 +85,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22:
|
|||||||
"has SSH port 22 open to the Internet",
|
"has SSH port 22 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_default_sg(self):
|
def test_ec2_compliant_default_sg(self):
|
||||||
@@ -134,3 +138,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22:
|
|||||||
"has not SSH port 22 open to the Internet",
|
"has not SSH port 22 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -85,6 +85,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389:
|
|||||||
"has Microsoft RDP port 3389 open to the Internet",
|
"has Microsoft RDP port 3389 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_default_sg(self):
|
def test_ec2_compliant_default_sg(self):
|
||||||
@@ -134,3 +138,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389:
|
|||||||
"has not Microsoft RDP port 3389 open to the Internet",
|
"has not Microsoft RDP port 3389 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -89,6 +89,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7
|
|||||||
"has Casandra ports 7199, 8888 and 9160 open to the Internet",
|
"has Casandra ports 7199, 8888 and 9160 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_default_sg(self):
|
def test_ec2_compliant_default_sg(self):
|
||||||
@@ -140,3 +144,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7
|
|||||||
"has not Casandra ports 7199, 8888 and 9160 open to the Internet",
|
"has not Casandra ports 7199, 8888 and 9160 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -89,6 +89,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsear
|
|||||||
"has Elasticsearch/Kibana ports 9200, 9300 and 5601 open to the Internet",
|
"has Elasticsearch/Kibana ports 9200, 9300 and 5601 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_default_sg(self):
|
def test_ec2_compliant_default_sg(self):
|
||||||
@@ -140,3 +144,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsear
|
|||||||
"has not Elasticsearch/Kibana ports 9200, 9300 and 5601 open to the Internet",
|
"has not Elasticsearch/Kibana ports 9200, 9300 and 5601 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -88,6 +88,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092:
|
|||||||
assert search(
|
assert search(
|
||||||
"has Kafka port 9092 open to the Internet", sg.status_extended
|
"has Kafka port 9092 open to the Internet", sg.status_extended
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_default_sg(self):
|
def test_ec2_compliant_default_sg(self):
|
||||||
@@ -139,3 +143,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092:
|
|||||||
"has not Kafka port 9092 open to the Internet",
|
"has not Kafka port 9092 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -89,6 +89,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_1
|
|||||||
"has Memcached port 11211 open to the Internet",
|
"has Memcached port 11211 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_default_sg(self):
|
def test_ec2_compliant_default_sg(self):
|
||||||
@@ -140,3 +144,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_1
|
|||||||
"has not Memcached port 11211 open to the Internet",
|
"has not Memcached port 11211 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -89,6 +89,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306:
|
|||||||
"has MySQL port 3306 open to the Internet",
|
"has MySQL port 3306 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_default_sg(self):
|
def test_ec2_compliant_default_sg(self):
|
||||||
@@ -140,3 +144,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306:
|
|||||||
"has not MySQL port 3306 open to the Internet",
|
"has not MySQL port 3306 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -89,6 +89,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521
|
|||||||
"has Oracle ports 1521 and 2483 open to the Internet",
|
"has Oracle ports 1521 and 2483 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_default_sg(self):
|
def test_ec2_compliant_default_sg(self):
|
||||||
@@ -140,3 +144,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521
|
|||||||
"has not Oracle ports 1521 and 2483 open to the Internet",
|
"has not Oracle ports 1521 and 2483 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -89,6 +89,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_54
|
|||||||
"has Postgres port 5432 open to the Internet",
|
"has Postgres port 5432 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_default_sg(self):
|
def test_ec2_compliant_default_sg(self):
|
||||||
@@ -140,3 +144,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_54
|
|||||||
"has not Postgres port 5432 open to the Internet",
|
"has not Postgres port 5432 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -88,6 +88,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379:
|
|||||||
assert search(
|
assert search(
|
||||||
"has Redis port 6379 open to the Internet", sg.status_extended
|
"has Redis port 6379 open to the Internet", sg.status_extended
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_default_sg(self):
|
def test_ec2_compliant_default_sg(self):
|
||||||
@@ -139,3 +143,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379:
|
|||||||
"has not Redis port 6379 open to the Internet",
|
"has not Redis port 6379 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -89,6 +89,10 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_
|
|||||||
"has Microsoft SQL Server ports 1433 and 1434 open to the Internet",
|
"has Microsoft SQL Server ports 1433 and 1434 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_default_sg(self):
|
def test_ec2_compliant_default_sg(self):
|
||||||
@@ -140,3 +144,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_
|
|||||||
"has not Microsoft SQL Server ports 1433 and 1434 open to the Internet",
|
"has not Microsoft SQL Server ports 1433 and 1434 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -88,6 +88,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23:
|
|||||||
assert search(
|
assert search(
|
||||||
"has Telnet port 23 open to the Internet", sg.status_extended
|
"has Telnet port 23 open to the Internet", sg.status_extended
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_default_sg(self):
|
def test_ec2_compliant_default_sg(self):
|
||||||
@@ -139,3 +143,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23:
|
|||||||
"has not Telnet port 23 open to the Internet",
|
"has not Telnet port 23 open to the Internet",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -83,6 +83,10 @@ class Test_ec2_securitygroup_allow_wide_open_public_ipv4:
|
|||||||
"has no potential wide-open non-RFC1918 address",
|
"has no potential wide-open non-RFC1918 address",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_default_sg_with_non_RFC1918_address(self):
|
def test_ec2_default_sg_with_non_RFC1918_address(self):
|
||||||
@@ -130,3 +134,7 @@ class Test_ec2_securitygroup_allow_wide_open_public_ipv4:
|
|||||||
"has potential wide-open non-RFC1918 address",
|
"has potential wide-open non-RFC1918 address",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -77,6 +77,10 @@ class Test_ec2_securitygroup_default_restrict_traffic:
|
|||||||
sg.status_extended
|
sg.status_extended
|
||||||
== f"Default Security Group ({default_sg_id}) is open to the Internet."
|
== f"Default Security Group ({default_sg_id}) is open to the Internet."
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_default_sg(self):
|
def test_ec2_compliant_default_sg(self):
|
||||||
@@ -121,3 +125,7 @@ class Test_ec2_securitygroup_default_restrict_traffic:
|
|||||||
sg.status_extended
|
sg.status_extended
|
||||||
== f"Default Security Group ({default_sg_id}) is not open to the Internet."
|
== f"Default Security Group ({default_sg_id}) is not open to the Internet."
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -75,6 +75,10 @@ class Test_ec2_securitygroup_from_launch_wizard:
|
|||||||
"was created using the EC2 Launch Wizard",
|
"was created using the EC2 Launch Wizard",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_default_sg(self):
|
def test_ec2_compliant_default_sg(self):
|
||||||
@@ -122,3 +126,7 @@ class Test_ec2_securitygroup_from_launch_wizard:
|
|||||||
"was not created using the EC2 Launch Wizard",
|
"was not created using the EC2 Launch Wizard",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -84,6 +84,10 @@ class Test_ec2_securitygroup_in_use_without_ingress_filtering:
|
|||||||
"has no ingress filtering and it is not being used",
|
"has no ingress filtering and it is not being used",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_used_public_default_sg(self):
|
def test_ec2_used_public_default_sg(self):
|
||||||
@@ -139,6 +143,10 @@ class Test_ec2_securitygroup_in_use_without_ingress_filtering:
|
|||||||
"has no ingress filtering and it is being used",
|
"has no ingress filtering and it is being used",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_private_default_sg(self):
|
def test_ec2_private_default_sg(self):
|
||||||
@@ -177,3 +185,7 @@ class Test_ec2_securitygroup_in_use_without_ingress_filtering:
|
|||||||
"has ingress filtering",
|
"has ingress filtering",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -75,6 +75,10 @@ class Test_ec2_securitygroup_not_used:
|
|||||||
"it is not being used",
|
"it is not being used",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_used_default_sg(self):
|
def test_ec2_used_default_sg(self):
|
||||||
@@ -122,3 +126,7 @@ class Test_ec2_securitygroup_not_used:
|
|||||||
"it is being used",
|
"it is being used",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -85,6 +85,10 @@ class Test_ec2_securitygroup_with_many_ingress_egress_rules:
|
|||||||
assert search(
|
assert search(
|
||||||
"has 60 inbound rules and 1 outbound rules", sg.status_extended
|
"has 60 inbound rules and 1 outbound rules", sg.status_extended
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_ec2_compliant_default_sg(self):
|
def test_ec2_compliant_default_sg(self):
|
||||||
@@ -134,3 +138,7 @@ class Test_ec2_securitygroup_with_many_ingress_egress_rules:
|
|||||||
"has 1 inbound rules and 1 outbound rules",
|
"has 1 inbound rules and 1 outbound rules",
|
||||||
sg.status_extended,
|
sg.status_extended,
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
sg.resource_arn
|
||||||
|
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
|
import ipaddress
|
||||||
|
import re
|
||||||
from base64 import b64decode
|
from base64 import b64decode
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
from boto3 import client, resource, session
|
from boto3 import client, resource, session
|
||||||
|
from dateutil.tz import tzutc
|
||||||
|
from freezegun import freeze_time
|
||||||
from moto import mock_ec2
|
from moto import mock_ec2
|
||||||
|
|
||||||
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
|
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
|
||||||
@@ -9,6 +14,7 @@ from prowler.providers.aws.services.ec2.ec2_service import EC2
|
|||||||
AWS_ACCOUNT_NUMBER = 123456789012
|
AWS_ACCOUNT_NUMBER = 123456789012
|
||||||
AWS_REGION = "us-east-1"
|
AWS_REGION = "us-east-1"
|
||||||
EXAMPLE_AMI_ID = "ami-12c6146b"
|
EXAMPLE_AMI_ID = "ami-12c6146b"
|
||||||
|
MOCK_DATETIME = datetime(2023, 1, 4, 7, 27, 30, tzinfo=tzutc())
|
||||||
|
|
||||||
|
|
||||||
class Test_EC2_Service:
|
class Test_EC2_Service:
|
||||||
@@ -68,6 +74,7 @@ class Test_EC2_Service:
|
|||||||
|
|
||||||
# Test EC2 Describe Instances
|
# Test EC2 Describe Instances
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
|
@freeze_time(MOCK_DATETIME)
|
||||||
def test__describe_instances__(self):
|
def test__describe_instances__(self):
|
||||||
# Generate EC2 Client
|
# Generate EC2 Client
|
||||||
ec2_resource = resource("ec2", region_name=AWS_REGION)
|
ec2_resource = resource("ec2", region_name=AWS_REGION)
|
||||||
@@ -75,17 +82,38 @@ class Test_EC2_Service:
|
|||||||
# Get AMI image
|
# Get AMI image
|
||||||
image_response = ec2_client.describe_images()
|
image_response = ec2_client.describe_images()
|
||||||
image_id = image_response["Images"][0]["ImageId"]
|
image_id = image_response["Images"][0]["ImageId"]
|
||||||
# Create EC2 Instances
|
# Create EC2 Instances running
|
||||||
ec2_resource.create_instances(
|
ec2_resource.create_instances(
|
||||||
MinCount=2,
|
MinCount=1,
|
||||||
MaxCount=2,
|
MaxCount=1,
|
||||||
ImageId=image_id,
|
ImageId=image_id,
|
||||||
)
|
)
|
||||||
# EC2 client for this test class
|
# EC2 client for this test class
|
||||||
audit_info = self.set_mocked_audit_info()
|
audit_info = self.set_mocked_audit_info()
|
||||||
ec2 = EC2(audit_info)
|
ec2 = EC2(audit_info)
|
||||||
assert len(ec2.instances) == len(
|
assert len(ec2.instances) == 1
|
||||||
ec2_client.describe_instances()["Reservations"][0]["Instances"]
|
assert re.match(r"i-[0-9a-z]{17}", ec2.instances[0].id)
|
||||||
|
assert (
|
||||||
|
ec2.instances[0].arn
|
||||||
|
== f"arn:{audit_info.audited_partition}:ec2:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:instance/{ec2.instances[0].id}"
|
||||||
|
)
|
||||||
|
assert ec2.instances[0].type == "m1.small"
|
||||||
|
assert ec2.instances[0].state == "running"
|
||||||
|
assert re.match(r"ami-[0-9a-z]{8}", ec2.instances[0].image_id)
|
||||||
|
assert ec2.instances[0].launch_time == MOCK_DATETIME
|
||||||
|
assert not ec2.instances[0].user_data
|
||||||
|
assert not ec2.instances[0].http_tokens
|
||||||
|
assert not ec2.instances[0].http_endpoint
|
||||||
|
assert not ec2.instances[0].instance_profile
|
||||||
|
assert ipaddress.ip_address(ec2.instances[0].private_ip).is_private
|
||||||
|
assert (
|
||||||
|
ec2.instances[0].private_dns
|
||||||
|
== f"ip-{ec2.instances[0].private_ip.replace('.', '-')}.ec2.internal"
|
||||||
|
)
|
||||||
|
assert ipaddress.ip_address(ec2.instances[0].public_ip).is_global
|
||||||
|
assert (
|
||||||
|
ec2.instances[0].public_dns
|
||||||
|
== f"ec2-{ec2.instances[0].public_ip.replace('.', '-')}.compute-1.amazonaws.com"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test EC2 Describe Security Groups
|
# Test EC2 Describe Security Groups
|
||||||
@@ -101,7 +129,28 @@ class Test_EC2_Service:
|
|||||||
# EC2 client for this test class
|
# EC2 client for this test class
|
||||||
audit_info = self.set_mocked_audit_info()
|
audit_info = self.set_mocked_audit_info()
|
||||||
ec2 = EC2(audit_info)
|
ec2 = EC2(audit_info)
|
||||||
|
|
||||||
assert sg_id in str(ec2.security_groups)
|
assert sg_id in str(ec2.security_groups)
|
||||||
|
for security_group in ec2.security_groups:
|
||||||
|
if security_group.id == sg_id:
|
||||||
|
assert security_group.name == "test-security-group"
|
||||||
|
assert (
|
||||||
|
security_group.arn
|
||||||
|
== f"arn:{audit_info.audited_partition}:ec2:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:security-group/{security_group.id}"
|
||||||
|
)
|
||||||
|
assert re.match(r"sg-[0-9a-z]{17}", security_group.id)
|
||||||
|
assert security_group.region == AWS_REGION
|
||||||
|
assert security_group.network_interfaces == []
|
||||||
|
assert security_group.ingress_rules == []
|
||||||
|
assert security_group.egress_rules == [
|
||||||
|
{
|
||||||
|
"IpProtocol": "-1",
|
||||||
|
"IpRanges": [{"CidrIp": "0.0.0.0/0"}],
|
||||||
|
"Ipv6Ranges": [],
|
||||||
|
"PrefixListIds": [],
|
||||||
|
"UserIdGroupPairs": [],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
# Test EC2 Describe Nacls
|
# Test EC2 Describe Nacls
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
@@ -117,7 +166,16 @@ class Test_EC2_Service:
|
|||||||
# EC2 client for this test class
|
# EC2 client for this test class
|
||||||
audit_info = self.set_mocked_audit_info()
|
audit_info = self.set_mocked_audit_info()
|
||||||
ec2 = EC2(audit_info)
|
ec2 = EC2(audit_info)
|
||||||
|
|
||||||
assert nacl_id in str(ec2.network_acls)
|
assert nacl_id in str(ec2.network_acls)
|
||||||
|
for acl in ec2.network_acls:
|
||||||
|
if acl.id == nacl_id:
|
||||||
|
assert re.match(r"acl-[0-9a-z]{8}", acl.id)
|
||||||
|
assert (
|
||||||
|
acl.arn
|
||||||
|
== f"arn:{audit_info.audited_partition}:ec2:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:network-acl/{acl.id}"
|
||||||
|
)
|
||||||
|
assert acl.entries == []
|
||||||
|
|
||||||
# Test EC2 Describe Snapshots
|
# Test EC2 Describe Snapshots
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
@@ -137,7 +195,18 @@ class Test_EC2_Service:
|
|||||||
# EC2 client for this test class
|
# EC2 client for this test class
|
||||||
audit_info = self.set_mocked_audit_info()
|
audit_info = self.set_mocked_audit_info()
|
||||||
ec2 = EC2(audit_info)
|
ec2 = EC2(audit_info)
|
||||||
|
|
||||||
assert snapshot_id in str(ec2.snapshots)
|
assert snapshot_id in str(ec2.snapshots)
|
||||||
|
for snapshot in ec2.snapshots:
|
||||||
|
if snapshot.id == snapshot_id:
|
||||||
|
assert re.match(r"snap-[0-9a-z]{8}", snapshot.id)
|
||||||
|
assert (
|
||||||
|
snapshot.arn
|
||||||
|
== f"arn:{audit_info.audited_partition}:ec2:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:snapshot/{snapshot.id}"
|
||||||
|
)
|
||||||
|
assert snapshot.region == AWS_REGION
|
||||||
|
assert not snapshot.encrypted
|
||||||
|
assert not snapshot.public
|
||||||
|
|
||||||
# Test EC2 Get Snapshot Public
|
# Test EC2 Get Snapshot Public
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
@@ -165,8 +234,17 @@ class Test_EC2_Service:
|
|||||||
# EC2 client for this test class
|
# EC2 client for this test class
|
||||||
audit_info = self.set_mocked_audit_info()
|
audit_info = self.set_mocked_audit_info()
|
||||||
ec2 = EC2(audit_info)
|
ec2 = EC2(audit_info)
|
||||||
|
|
||||||
|
assert snapshot_id in str(ec2.snapshots)
|
||||||
for snapshot in ec2.snapshots:
|
for snapshot in ec2.snapshots:
|
||||||
if snapshot.id == snapshot_id:
|
if snapshot.id == snapshot_id:
|
||||||
|
assert re.match(r"snap-[0-9a-z]{8}", snapshot.id)
|
||||||
|
assert (
|
||||||
|
snapshot.arn
|
||||||
|
== f"arn:{audit_info.audited_partition}:ec2:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:snapshot/{snapshot.id}"
|
||||||
|
)
|
||||||
|
assert snapshot.region == AWS_REGION
|
||||||
|
assert not snapshot.encrypted
|
||||||
assert snapshot.public
|
assert snapshot.public
|
||||||
|
|
||||||
# Test EC2 Instance User Data
|
# Test EC2 Instance User Data
|
||||||
@@ -185,7 +263,7 @@ class Test_EC2_Service:
|
|||||||
ec2 = EC2(audit_info)
|
ec2 = EC2(audit_info)
|
||||||
assert user_data == b64decode(ec2.instances[0].user_data).decode("utf-8")
|
assert user_data == b64decode(ec2.instances[0].user_data).decode("utf-8")
|
||||||
|
|
||||||
# Test EC2 Instance User Data
|
# Test EC2 Get EBS Encryption by default
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test__get_ebs_encryption_by_default__(self):
|
def test__get_ebs_encryption_by_default__(self):
|
||||||
ec2_client = client("ec2", region_name=AWS_REGION)
|
ec2_client = client("ec2", region_name=AWS_REGION)
|
||||||
@@ -200,7 +278,7 @@ class Test_EC2_Service:
|
|||||||
if result.region == AWS_REGION:
|
if result.region == AWS_REGION:
|
||||||
assert result.status
|
assert result.status
|
||||||
|
|
||||||
# Test EC2 Describe Snapshots
|
# Test EC2 Describe Addresses
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test__describe_addresses__(self):
|
def test__describe_addresses__(self):
|
||||||
# Generate EC2 Client
|
# Generate EC2 Client
|
||||||
@@ -216,3 +294,117 @@ class Test_EC2_Service:
|
|||||||
ec2.elastic_ips[0].arn
|
ec2.elastic_ips[0].arn
|
||||||
== f"arn:aws:ec2:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:eip-allocation/{allocation_id}"
|
== f"arn:aws:ec2:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:eip-allocation/{allocation_id}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Test EC2 Describe Network Interfaces
|
||||||
|
@mock_ec2
|
||||||
|
def test__describe_network_interfaces__(self):
|
||||||
|
# Generate EC2 Client
|
||||||
|
ec2_client = client("ec2", region_name=AWS_REGION)
|
||||||
|
ec2_resource = resource("ec2", region_name=AWS_REGION)
|
||||||
|
# Create VPC, Subnet, SecurityGroup and Network Interface
|
||||||
|
vpc = ec2_resource.create_vpc(CidrBlock="10.0.0.0/16")
|
||||||
|
subnet = ec2_resource.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18")
|
||||||
|
sg = ec2_resource.create_security_group(
|
||||||
|
GroupName="test-securitygroup", Description="n/a"
|
||||||
|
)
|
||||||
|
eni_id = subnet.create_network_interface(Groups=[sg.id]).id
|
||||||
|
print(eni_id)
|
||||||
|
ec2_client.modify_network_interface_attribute(
|
||||||
|
NetworkInterfaceId=eni_id, Groups=[sg.id]
|
||||||
|
)
|
||||||
|
|
||||||
|
# EC2 client for this test class
|
||||||
|
audit_info = self.set_mocked_audit_info()
|
||||||
|
ec2 = EC2(audit_info)
|
||||||
|
|
||||||
|
assert sg.id in str(ec2.security_groups)
|
||||||
|
for security_group in ec2.security_groups:
|
||||||
|
if security_group.id == sg.id:
|
||||||
|
assert security_group.name == "test-securitygroup"
|
||||||
|
assert (
|
||||||
|
security_group.arn
|
||||||
|
== f"arn:{audit_info.audited_partition}:ec2:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:security-group/{security_group.id}"
|
||||||
|
)
|
||||||
|
assert re.match(r"sg-[0-9a-z]{17}", security_group.id)
|
||||||
|
assert security_group.region == AWS_REGION
|
||||||
|
assert eni_id in security_group.network_interfaces
|
||||||
|
assert security_group.ingress_rules == []
|
||||||
|
assert security_group.egress_rules == [
|
||||||
|
{
|
||||||
|
"IpProtocol": "-1",
|
||||||
|
"IpRanges": [{"CidrIp": "0.0.0.0/0"}],
|
||||||
|
"Ipv6Ranges": [],
|
||||||
|
"PrefixListIds": [],
|
||||||
|
"UserIdGroupPairs": [],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
# Test EC2 Describe Images
|
||||||
|
@mock_ec2
|
||||||
|
def test__describe_images__(self):
|
||||||
|
# Generate EC2 Client
|
||||||
|
ec2_client = client("ec2", region_name=AWS_REGION)
|
||||||
|
ec2_resource = resource("ec2", region_name=AWS_REGION)
|
||||||
|
# Create AMI
|
||||||
|
tag_specifications = [
|
||||||
|
{
|
||||||
|
"ResourceType": "image",
|
||||||
|
"Tags": [
|
||||||
|
{
|
||||||
|
"Key": "Base_AMI_Name",
|
||||||
|
"Value": "Deep Learning Base AMI (Amazon Linux 2) Version 31.0",
|
||||||
|
},
|
||||||
|
{"Key": "OS_Version", "Value": "AWS Linux 2"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
instance = ec2_resource.create_instances(
|
||||||
|
ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1
|
||||||
|
)[0]
|
||||||
|
image_id = ec2_client.create_image(
|
||||||
|
InstanceId=instance.instance_id,
|
||||||
|
Name="test-image",
|
||||||
|
Description="test ami",
|
||||||
|
TagSpecifications=tag_specifications,
|
||||||
|
)["ImageId"]
|
||||||
|
|
||||||
|
# EC2 client for this test class
|
||||||
|
audit_info = self.set_mocked_audit_info()
|
||||||
|
ec2 = EC2(audit_info)
|
||||||
|
|
||||||
|
assert len(ec2.images) == 1
|
||||||
|
assert ec2.images[0].id == image_id
|
||||||
|
assert re.match(r"ami-[0-9a-z]{8}", ec2.images[0].id)
|
||||||
|
assert (
|
||||||
|
ec2.images[0].arn
|
||||||
|
== f"arn:{audit_info.audited_partition}:ec2:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:image/{ec2.images[0].id}"
|
||||||
|
)
|
||||||
|
assert not ec2.images[0].public
|
||||||
|
assert ec2.images[0].region == AWS_REGION
|
||||||
|
|
||||||
|
# Test EC2 Describe Volumes
|
||||||
|
@mock_ec2
|
||||||
|
def test__describe_volumes__(self):
|
||||||
|
# Generate EC2 Client
|
||||||
|
ec2_client = client("ec2", region_name=AWS_REGION)
|
||||||
|
# Create Volume
|
||||||
|
volume_id = ec2_client.create_volume(
|
||||||
|
AvailabilityZone=AWS_REGION,
|
||||||
|
Encrypted=False,
|
||||||
|
Size=40,
|
||||||
|
TagSpecifications=[],
|
||||||
|
)["VolumeId"]
|
||||||
|
|
||||||
|
# EC2 client for this test class
|
||||||
|
audit_info = self.set_mocked_audit_info()
|
||||||
|
ec2 = EC2(audit_info)
|
||||||
|
|
||||||
|
assert len(ec2.volumes) == 1
|
||||||
|
assert ec2.volumes[0].id == volume_id
|
||||||
|
assert re.match(r"vol-[0-9a-z]{8}", ec2.volumes[0].id)
|
||||||
|
assert (
|
||||||
|
ec2.volumes[0].arn
|
||||||
|
== f"arn:{audit_info.audited_partition}:ec2:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:volume/{ec2.volumes[0].id}"
|
||||||
|
)
|
||||||
|
assert ec2.volumes[0].region == AWS_REGION
|
||||||
|
assert not ec2.volumes[0].encrypted
|
||||||
|
|||||||
Reference in New Issue
Block a user