mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-24 13:01:56 +00:00
feat(elbv2): add elbv2_nlb_tls_termination_enabled check (#5550)
Co-authored-by: Sergio <sergio@prowler.com>
This commit is contained in:
+34
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"Provider": "aws",
|
||||
"CheckID": "elbv2_nlb_tls_termination_enabled",
|
||||
"CheckTitle": "Check if Network Load Balancers (NLB) has TLS termination enabled.",
|
||||
"CheckType": [
|
||||
"Data Protection"
|
||||
],
|
||||
"ServiceName": "elbv2",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "AwsElbv2LoadBalancer",
|
||||
"Description": "Check if Network Load Balancers (NLB) has TLS listeners.",
|
||||
"Risk": "Ensure that your Amazon Network Load Balancers (NLBs) are configured to terminate TLS connections in order to optimize the performance of the backend servers while encrypting the communication between the load balancer and the associated targets (i.e. server instances).",
|
||||
"RelatedUrl": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/ELBv2/network-load-balancer-listener-security.html#",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "aws elbv2 create-listener --load-balancer-arn <nlb_arn> --protocol TLS --port 443 --ssl-policy ELBSecurityPolicy-TLS13-1-2-2021-06 --certificates CertificateArn=<certificate_arn> --default-actions Type=forward,TargetGroupArn=<target_group_arn>",
|
||||
"NativeIaC": "",
|
||||
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/ELBv2/network-load-balancer-listener-security.html#",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "When Transport Layer Security (TLS) termination is enabled, you can offload the encryption and decryption of the TLS traffic from your backend application servers to your Amazon Network Load Balancer, enhancing the performance of your backend servers while keeping the workload secure. ",
|
||||
"Url": "https://docs.aws.amazon.com/elasticloadbalancing/latest/network/listener-update-rules.html"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
"encryption"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
from prowler.lib.check.models import Check, Check_Report_AWS
|
||||
from prowler.providers.aws.services.elbv2.elbv2_client import elbv2_client
|
||||
|
||||
|
||||
class elbv2_nlb_tls_termination_enabled(Check):
|
||||
def execute(self):
|
||||
findings = []
|
||||
for lb_arn, lb in elbv2_client.loadbalancersv2.items():
|
||||
if lb.type == "network":
|
||||
report = Check_Report_AWS(self.metadata())
|
||||
report.region = lb.region
|
||||
report.resource_id = lb.name
|
||||
report.resource_arn = lb_arn
|
||||
report.resource_tags = lb.tags
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"ELBv2 NLB {lb.name} is not configured to terminate TLS connections."
|
||||
for listener in lb.listeners.values():
|
||||
if listener.protocol == "TLS":
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"ELBv2 NLB {lb.name} is configured to terminate TLS connections."
|
||||
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client, resource
|
||||
from moto import mock_aws
|
||||
|
||||
from tests.providers.aws.utils import (
|
||||
AWS_REGION_EU_WEST_1,
|
||||
AWS_REGION_EU_WEST_1_AZA,
|
||||
AWS_REGION_EU_WEST_1_AZB,
|
||||
AWS_REGION_US_EAST_1,
|
||||
set_mocked_aws_provider,
|
||||
)
|
||||
|
||||
|
||||
class Test_elbv2_nlb_listener_security:
|
||||
@mock_aws
|
||||
def test_elb_no_balancers(self):
|
||||
from prowler.providers.aws.services.elbv2.elbv2_service import ELBv2
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_aws_provider(
|
||||
[AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1]
|
||||
),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.elbv2.elbv2_nlb_tls_termination_enabled.elbv2_nlb_tls_termination_enabled.elbv2_client",
|
||||
new=ELBv2(
|
||||
set_mocked_aws_provider([AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1])
|
||||
),
|
||||
):
|
||||
# Test Check
|
||||
from prowler.providers.aws.services.elbv2.elbv2_nlb_tls_termination_enabled.elbv2_nlb_tls_termination_enabled import (
|
||||
elbv2_nlb_tls_termination_enabled,
|
||||
)
|
||||
|
||||
check = elbv2_nlb_tls_termination_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_aws
|
||||
def test_elbv2_without_tls_listener(self):
|
||||
conn = client("elbv2", region_name=AWS_REGION_EU_WEST_1)
|
||||
ec2 = resource("ec2", region_name=AWS_REGION_EU_WEST_1)
|
||||
|
||||
security_group = ec2.create_security_group(
|
||||
GroupName="a-security-group", Description="First One"
|
||||
)
|
||||
vpc = ec2.create_vpc(CidrBlock="172.28.7.0/24", InstanceTenancy="default")
|
||||
subnet1 = ec2.create_subnet(
|
||||
VpcId=vpc.id,
|
||||
CidrBlock="172.28.7.192/26",
|
||||
AvailabilityZone=AWS_REGION_EU_WEST_1_AZA,
|
||||
)
|
||||
subnet2 = ec2.create_subnet(
|
||||
VpcId=vpc.id,
|
||||
CidrBlock="172.28.7.0/26",
|
||||
AvailabilityZone=AWS_REGION_EU_WEST_1_AZB,
|
||||
)
|
||||
|
||||
lb = conn.create_load_balancer(
|
||||
Name="my-lb",
|
||||
Subnets=[subnet1.id, subnet2.id],
|
||||
SecurityGroups=[security_group.id],
|
||||
Scheme="internal",
|
||||
Type="network",
|
||||
)["LoadBalancers"][0]
|
||||
|
||||
response = conn.create_target_group(
|
||||
Name="a-target",
|
||||
Protocol="HTTP",
|
||||
Port=8080,
|
||||
VpcId=vpc.id,
|
||||
HealthCheckProtocol="HTTP",
|
||||
HealthCheckPort="8080",
|
||||
HealthCheckPath="/",
|
||||
HealthCheckIntervalSeconds=5,
|
||||
HealthCheckTimeoutSeconds=3,
|
||||
HealthyThresholdCount=5,
|
||||
UnhealthyThresholdCount=2,
|
||||
Matcher={"HttpCode": "200"},
|
||||
)
|
||||
target_group = response.get("TargetGroups")[0]
|
||||
target_group_arn = target_group["TargetGroupArn"]
|
||||
response = conn.create_listener(
|
||||
LoadBalancerArn=lb["LoadBalancerArn"],
|
||||
Protocol="TCP",
|
||||
Port=443,
|
||||
DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.services.elbv2.elbv2_service import ELBv2
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_aws_provider(
|
||||
[AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1]
|
||||
),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.elbv2.elbv2_nlb_tls_termination_enabled.elbv2_nlb_tls_termination_enabled.elbv2_client",
|
||||
new=ELBv2(
|
||||
set_mocked_aws_provider([AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1])
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.elbv2.elbv2_nlb_tls_termination_enabled.elbv2_nlb_tls_termination_enabled import (
|
||||
elbv2_nlb_tls_termination_enabled,
|
||||
)
|
||||
|
||||
check = elbv2_nlb_tls_termination_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "ELBv2 NLB my-lb is not configured to terminate TLS connections."
|
||||
)
|
||||
assert result[0].resource_id == "my-lb"
|
||||
assert result[0].resource_arn == lb["LoadBalancerArn"]
|
||||
|
||||
@mock_aws
|
||||
def test_elbv2_with_tls_listener(self):
|
||||
conn = client("elbv2", region_name=AWS_REGION_EU_WEST_1)
|
||||
ec2 = resource("ec2", region_name=AWS_REGION_EU_WEST_1)
|
||||
|
||||
security_group = ec2.create_security_group(
|
||||
GroupName="a-security-group", Description="First One"
|
||||
)
|
||||
vpc = ec2.create_vpc(CidrBlock="172.28.7.0/24", InstanceTenancy="default")
|
||||
subnet1 = ec2.create_subnet(
|
||||
VpcId=vpc.id,
|
||||
CidrBlock="172.28.7.192/26",
|
||||
AvailabilityZone=AWS_REGION_EU_WEST_1_AZA,
|
||||
)
|
||||
subnet2 = ec2.create_subnet(
|
||||
VpcId=vpc.id,
|
||||
CidrBlock="172.28.7.0/26",
|
||||
AvailabilityZone=AWS_REGION_EU_WEST_1_AZB,
|
||||
)
|
||||
|
||||
lb = conn.create_load_balancer(
|
||||
Name="my-lb",
|
||||
Subnets=[subnet1.id, subnet2.id],
|
||||
SecurityGroups=[security_group.id],
|
||||
Scheme="internal",
|
||||
Type="network",
|
||||
)["LoadBalancers"][0]
|
||||
|
||||
response = conn.create_target_group(
|
||||
Name="a-target",
|
||||
Protocol="HTTP",
|
||||
Port=8080,
|
||||
VpcId=vpc.id,
|
||||
HealthCheckProtocol="HTTP",
|
||||
HealthCheckPort="8080",
|
||||
HealthCheckPath="/",
|
||||
HealthCheckIntervalSeconds=5,
|
||||
HealthCheckTimeoutSeconds=3,
|
||||
HealthyThresholdCount=5,
|
||||
UnhealthyThresholdCount=2,
|
||||
Matcher={"HttpCode": "200"},
|
||||
)
|
||||
target_group = response.get("TargetGroups")[0]
|
||||
target_group_arn = target_group["TargetGroupArn"]
|
||||
response = conn.create_listener(
|
||||
LoadBalancerArn=lb["LoadBalancerArn"],
|
||||
Protocol="TLS",
|
||||
Port=443,
|
||||
DefaultActions=[{"Type": "forward", "TargetGroupArn": target_group_arn}],
|
||||
)
|
||||
|
||||
from prowler.providers.aws.services.elbv2.elbv2_service import ELBv2
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_aws_provider(
|
||||
[AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1]
|
||||
),
|
||||
), mock.patch(
|
||||
"prowler.providers.aws.services.elbv2.elbv2_nlb_tls_termination_enabled.elbv2_nlb_tls_termination_enabled.elbv2_client",
|
||||
new=ELBv2(
|
||||
set_mocked_aws_provider([AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1])
|
||||
),
|
||||
):
|
||||
from prowler.providers.aws.services.elbv2.elbv2_nlb_tls_termination_enabled.elbv2_nlb_tls_termination_enabled import (
|
||||
elbv2_nlb_tls_termination_enabled,
|
||||
)
|
||||
|
||||
check = elbv2_nlb_tls_termination_enabled()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "ELBv2 NLB my-lb is configured to terminate TLS connections."
|
||||
)
|
||||
assert result[0].resource_id == "my-lb"
|
||||
assert result[0].resource_arn == lb["LoadBalancerArn"]
|
||||
Reference in New Issue
Block a user