-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(mq): add new check
mq_broker_cluster_deployment_mode
(#5481)
Co-authored-by: Sergio <[email protected]>
- Loading branch information
1 parent
6a09171
commit df37327
Showing
6 changed files
with
285 additions
and
12 deletions.
There are no files selected for viewing
Empty file.
32 changes: 32 additions & 0 deletions
32
...ices/mq/mq_broker_cluster_deployment_mode/mq_broker_cluster_deployment_mode.metadata.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"Provider": "aws", | ||
"CheckID": "mq_broker_cluster_deployment_mode", | ||
"CheckTitle": "MQ RabbitMQ Brokers should use cluster deployment mode.", | ||
"CheckType": [ | ||
"Software and Configuration Checks/Industry and Regulatory Standards/NIST 800-53 Controls" | ||
], | ||
"ServiceName": "mq", | ||
"SubServiceName": "", | ||
"ResourceIdTemplate": "arn:aws:mq:region:account-id:broker:broker-id", | ||
"Severity": "low", | ||
"ResourceType": "AwsAmazonMQBroker", | ||
"Description": "Ensure that RabbitMQ Brokers use cluster deployment mode.", | ||
"Risk": "Using a single-instance RabbitMQ broker limits fault tolerance and high availability. Without cluster deployment, broker failures could lead to significant downtime and potential data loss.", | ||
"RelatedUrl": "https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/rabbitmq-basic-elements.html", | ||
"Remediation": { | ||
"Code": { | ||
"CLI": "aws mq create-broker --broker-name <your-broker-name> --engine-type RabbitMQ --deployment-mode CLUSTER_MULTI_AZ", | ||
"NativeIaC": "", | ||
"Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/mq-controls.html#mq-6", | ||
"Terraform": "" | ||
}, | ||
"Recommendation": { | ||
"Text": "Ensure RabbitMQ brokers are deployed in cluster mode to enhance resilience and prevent data loss during failures.", | ||
"Url": "https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/rabbitmq-broker-architecture.html#rabbitmq-broker-architecture-cluster" | ||
} | ||
}, | ||
"Categories": [], | ||
"DependsOn": [], | ||
"RelatedTo": [], | ||
"Notes": "" | ||
} |
36 changes: 36 additions & 0 deletions
36
...rs/aws/services/mq/mq_broker_cluster_deployment_mode/mq_broker_cluster_deployment_mode.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
from typing import List | ||
|
||
from prowler.lib.check.models import Check, Check_Report_AWS | ||
from prowler.providers.aws.services.mq.mq_client import mq_client | ||
from prowler.providers.aws.services.mq.mq_service import DeploymentMode, EngineType | ||
|
||
|
||
class mq_broker_cluster_deployment_mode(Check): | ||
"""Ensure MQ RabbitMQ Broker has cluster deployment mode. | ||
This check will fail if the RabbitMQ Broker does not have cluster deployment mode. | ||
""" | ||
|
||
def execute(self) -> List[Check_Report_AWS]: | ||
"""Execute the check. | ||
Returns: | ||
List[Check_Report_AWS]: A list of reports for each RabbitMQ Broker that does not have cluster deployment mode. | ||
""" | ||
findings = [] | ||
for broker in mq_client.brokers.values(): | ||
if broker.engine_type == EngineType.RABBITMQ: | ||
report = Check_Report_AWS(self.metadata()) | ||
report.region = broker.region | ||
report.resource_id = broker.id | ||
report.resource_arn = broker.arn | ||
report.resource_tags = broker.tags | ||
report.status = "FAIL" | ||
report.status_extended = f"MQ RabbitMQ Broker {broker.name} does not have a cluster deployment mode." | ||
if broker.deployment_mode == DeploymentMode.CLUSTER_MULTI_AZ: | ||
report.status = "PASS" | ||
report.status_extended = f"MQ RabbitMQ Broker {broker.name} does have a cluster deployment mode." | ||
|
||
findings.append(report) | ||
|
||
return findings |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
183 changes: 183 additions & 0 deletions
183
...s/services/mq/mq_broker_cluster_deployment_mode/mq_broker_cluster_deployment_mode_test.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
from unittest import mock | ||
|
||
from boto3 import client | ||
from moto import mock_aws | ||
|
||
from tests.providers.aws.utils import ( | ||
AWS_ACCOUNT_NUMBER, | ||
AWS_REGION_US_EAST_1, | ||
set_mocked_aws_provider, | ||
) | ||
|
||
|
||
class Test_mq_rabbitmq_broker_cluster_mode: | ||
@mock_aws | ||
def test_no_brokers(self): | ||
from prowler.providers.aws.services.mq.mq_service import MQ | ||
|
||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) | ||
|
||
with mock.patch( | ||
"prowler.providers.common.provider.Provider.get_global_provider", | ||
return_value=aws_provider, | ||
): | ||
with mock.patch( | ||
"prowler.providers.aws.services.mq.mq_broker_cluster_deployment_mode.mq_broker_cluster_deployment_mode.mq_client", | ||
new=MQ(aws_provider), | ||
): | ||
# Test Check | ||
from prowler.providers.aws.services.mq.mq_broker_cluster_deployment_mode.mq_broker_cluster_deployment_mode import ( | ||
mq_broker_cluster_deployment_mode, | ||
) | ||
|
||
check = mq_broker_cluster_deployment_mode() | ||
result = check.execute() | ||
|
||
assert len(result) == 0 | ||
|
||
@mock_aws | ||
def test_no_rabbitmq_brokers(self): | ||
from prowler.providers.aws.services.mq.mq_service import MQ | ||
|
||
mq_client = client("mq", region_name=AWS_REGION_US_EAST_1) | ||
mq_client.create_broker( | ||
BrokerName="test-broker", | ||
EngineType="ACTIVEMQ", | ||
EngineVersion="5.15.0", | ||
HostInstanceType="mq.t2.micro", | ||
Users=[ | ||
{ | ||
"Username": "admin", | ||
"Password": "admin", | ||
}, | ||
], | ||
DeploymentMode="ACTIVE_STANDBY_MULTI_AZ", | ||
PubliclyAccessible=False, | ||
AutoMinorVersionUpgrade=True, | ||
)["BrokerId"] | ||
|
||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) | ||
|
||
with mock.patch( | ||
"prowler.providers.common.provider.Provider.get_global_provider", | ||
return_value=aws_provider, | ||
): | ||
with mock.patch( | ||
"prowler.providers.aws.services.mq.mq_broker_cluster_deployment_mode.mq_broker_cluster_deployment_mode.mq_client", | ||
new=MQ(aws_provider), | ||
): | ||
# Test Check | ||
from prowler.providers.aws.services.mq.mq_broker_cluster_deployment_mode.mq_broker_cluster_deployment_mode import ( | ||
mq_broker_cluster_deployment_mode, | ||
) | ||
|
||
check = mq_broker_cluster_deployment_mode() | ||
result = check.execute() | ||
|
||
assert len(result) == 0 | ||
|
||
@mock_aws | ||
def test_rabbitmq_broker_cluster_mode_enabled(self): | ||
mq_client = client("mq", region_name=AWS_REGION_US_EAST_1) | ||
broker_name = "test-broker" | ||
broker_id = mq_client.create_broker( | ||
BrokerName="test-broker", | ||
EngineType="RABBITMQ", | ||
EngineVersion="5.15.0", | ||
HostInstanceType="mq.t2.micro", | ||
Users=[ | ||
{ | ||
"Username": "admin", | ||
"Password": "admin", | ||
}, | ||
], | ||
DeploymentMode="CLUSTER_MULTI_AZ", | ||
PubliclyAccessible=False, | ||
AutoMinorVersionUpgrade=True, | ||
)["BrokerId"] | ||
|
||
from prowler.providers.aws.services.mq.mq_service import MQ | ||
|
||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) | ||
|
||
with mock.patch( | ||
"prowler.providers.common.provider.Provider.get_global_provider", | ||
return_value=aws_provider, | ||
): | ||
with mock.patch( | ||
"prowler.providers.aws.services.mq.mq_broker_cluster_deployment_mode.mq_broker_cluster_deployment_mode.mq_client", | ||
new=MQ(aws_provider), | ||
): | ||
# Test Check | ||
from prowler.providers.aws.services.mq.mq_broker_cluster_deployment_mode.mq_broker_cluster_deployment_mode import ( | ||
mq_broker_cluster_deployment_mode, | ||
) | ||
|
||
check = mq_broker_cluster_deployment_mode() | ||
result = check.execute() | ||
|
||
assert len(result) == 1 | ||
assert result[0].status == "PASS" | ||
assert ( | ||
result[0].status_extended | ||
== f"MQ RabbitMQ Broker {broker_name} does have a cluster deployment mode." | ||
) | ||
assert result[0].resource_id == broker_id | ||
assert ( | ||
result[0].resource_arn | ||
== f"arn:{aws_provider.identity.partition}:mq:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:broker:{broker_id}" | ||
) | ||
assert result[0].region == AWS_REGION_US_EAST_1 | ||
|
||
@mock_aws | ||
def test_rabbitmq_broker_active_standby_mode_disabled(self): | ||
mq_client = client("mq", region_name=AWS_REGION_US_EAST_1) | ||
broker_name = "test-broker" | ||
broker_id = mq_client.create_broker( | ||
BrokerName=broker_name, | ||
EngineType="RABBITMQ", | ||
EngineVersion="5.15.0", | ||
HostInstanceType="mq.t2.micro", | ||
Users=[ | ||
{ | ||
"Username": "admin", | ||
"Password": "admin", | ||
}, | ||
], | ||
DeploymentMode="SINGLE_INSTANCE", | ||
PubliclyAccessible=False, | ||
AutoMinorVersionUpgrade=False, | ||
)["BrokerId"] | ||
|
||
from prowler.providers.aws.services.mq.mq_service import MQ | ||
|
||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) | ||
|
||
with mock.patch( | ||
"prowler.providers.common.provider.Provider.get_global_provider", | ||
return_value=aws_provider, | ||
): | ||
with mock.patch( | ||
"prowler.providers.aws.services.mq.mq_broker_cluster_deployment_mode.mq_broker_cluster_deployment_mode.mq_client", | ||
new=MQ(aws_provider), | ||
): | ||
# Test Check | ||
from prowler.providers.aws.services.mq.mq_broker_cluster_deployment_mode.mq_broker_cluster_deployment_mode import ( | ||
mq_broker_cluster_deployment_mode, | ||
) | ||
|
||
check = mq_broker_cluster_deployment_mode() | ||
result = check.execute() | ||
|
||
assert len(result) == 1 | ||
assert result[0].status == "FAIL" | ||
assert ( | ||
result[0].status_extended | ||
== f"MQ RabbitMQ Broker {broker_name} does not have a cluster deployment mode." | ||
) | ||
assert result[0].resource_id == broker_id | ||
assert ( | ||
result[0].resource_arn | ||
== f"arn:{aws_provider.identity.partition}:mq:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:broker:{broker_id}" | ||
) | ||
assert result[0].region == AWS_REGION_US_EAST_1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters