Skip to content

Commit

Permalink
feat: Aws cis foundation v3 (#689)
Browse files Browse the repository at this point in the history
- removed macros 3.3 and 3.4 from 2.0.0 (only major change on version)
- reworked macro 3.3 config enabled all regions (was 3.5 on v2.0.0) to better align with the remediation steps below and to exclude any regions not active in the account via aws_regions.opt_in_status

> Evaluate the output to ensure that all recorders have a recordingGroup object
> which includes "allSupported": true. Additionally, ensure that at least one
> recorder has "includeGlobalResourceTypes": true
  • Loading branch information
k-rheinheimer authored Mar 28, 2024
1 parent bd19033 commit 8058378
Show file tree
Hide file tree
Showing 7 changed files with 296 additions and 37 deletions.
10 changes: 10 additions & 0 deletions transformations/aws/compliance-free/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,16 @@ The free version contains 10% of the full pack's checks.
-`1.8`: `password_policy_min_length`
-`1.9`: `password_policy_prevent_reuse`

##### `cis_v3.0.0`

-`1.2`: `security_account_information_provided`
-`1.4`: `iam_root_user_no_access_keys`
-`1.5`: `mfa_enabled_for_root`
-`1.6`: `hardware_mfa_enabled_for_root`
-`1.7`: `iam_root_last_used`
-`1.8`: `password_policy_min_length`
-`1.9`: `password_policy_prevent_reuse`

##### `foundational_security`

-`apigateway.1`: `api_gw_execution_logging_enabled`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
with
aggregated as (
({{ security_account_information_provided('cis_v3.0.0','1.2') }})
{{ union() }}
({{ iam_root_user_no_access_keys('cis_v3.0.0','1.4') }})
{{ union() }}
({{ mfa_enabled_for_root('cis_v3.0.0','1.5') }})
{{ union() }}
({{ hardware_mfa_enabled_for_root('cis_v3.0.0','1.6') }})
{{ union() }}
({{ iam_root_last_used('cis_v3.0.0','1.7') }})
{{ union() }}
({{ password_policy_min_length('cis_v3.0.0','1.8') }})
{{ union() }}
({{ password_policy_prevent_reuse('cis_v3.0.0','1.9') }})
)
select
{{ gen_timestamp() }},
aggregated.*
from aggregated
1 change: 1 addition & 0 deletions transformations/aws/compliance-free/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
dbt-postgres==1.7.10
dbt-bigquery==1.7.6
dbt-snowflake==1.7.2
pyarrow >= 3.0.0
61 changes: 61 additions & 0 deletions transformations/aws/compliance-premium/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,67 @@ The premium version contains all checks.
-`5.4`: `default_sg_no_access`
-`5.6`: `ec2_not_imdsv2_instances`

##### `cis_v3.0.0`

-`1.2`: `security_account_information_provided`
-`1.4`: `iam_root_user_no_access_keys`
-`1.5`: `mfa_enabled_for_root`
-`1.6`: `hardware_mfa_enabled_for_root`
-`1.7`: `iam_root_last_used`
-`1.8`: `password_policy_min_length`
-`1.9`: `password_policy_prevent_reuse`
-`1.10`: `mfa_enabled_for_console_access`
-`1.11`: `iam_user_access_keys_and_password_at_setup`
-`1.12`: `unused_creds_disabled_45_days`
-`1.13`: `users_with_two_active_access_keys`
-`1.14`: `old_access_keys`
-`1.15`: `policies_attached_to_groups_roles`
-`1.16`: `no_star`
-`1.17`: `iam_support_role`
-`1.18`: `use_iam_roles_for_instances`
-`1.19`: `iam_server_certificate_not_expired`
-`1.20`: `regions_with_no_accessanalyzers`
-`1.21`: `iam_users_are_managed_centrally`
-`1.22`: `iam_user_group_role_cloudshell_fullaccess_restricted`
-`2.1.1`: `deny_http_requests`
-`2.1.2`: `mfa_delete`
-`2.1.4`: `account_level_public_access_blocks`
-`2.2.1`: `unencrypted_ebs_volumes`
-`2.3.1`: `instances_should_have_ecnryption_at_rest_enabled`
-`2.3.2`: `redis_clusters_have_autominorversionupgrade`
-`2.3.3`: `rds_db_instances_should_prohibit_public_access`
-`2.4.1`: `unencrypted_efs_filesystems`
-`3.1`: `cloudtrail_enabled_all_regions`
-`3.2`: `log_file_validation_enabled`
-`3.3`: `config_enabled_all_regions`
-`3.4`: `bucket_access_logging`
-`3.5`: `logs_encrypted`
-`3.6`: `rotation_enabled_for_customer_key`
-`3.7`: `flow_logs_enabled_in_all_vpcs`
-`3.8`: `cloudtrail_s3_object_write_events_audit_enabled`
-`3.9`: `cloudtrail_s3_object_read_events_audit_enabled`
-`4.1`: `alarm_unauthorized_api`
-`4.2`: `alarm_console_no_mfa`
-`4.3`: `alarm_root_account`
-`4.4`: `alarm_iam_policy_change`
-`4.5`: `alarm_cloudtrail_config_changes`
-`4.6`: `alarm_console_auth_failure`
-`4.7`: `alarm_delete_customer_cmk`
-`4.8`: `alarm_s3_bucket_policy_change`
-`4.9`: `alarm_aws_config_changes`
-`4.10`: `alarm_security_group_changes`
-`4.11`: `alarm_nacl_changes`
-`4.12`: `alarm_network_gateways`
-`4.13`: `alarm_route_table_changes`
-`4.14`: `alarm_vpc_changes`
-`4.15`: `alarm_organization_changes`
-`4.16`: `securityhub_enabled`
-`5.1`: `vpc_network_acl_remote_administration`
-`5.2`: `vpc_security_group_remote_administration_ipv4`
-`5.3`: `no_broad_public_ipv6_ingress_on_port_22_3389`
-`5.4`: `default_sg_no_access`
-`5.6`: `ec2_not_imdsv2_instances`

##### `foundational_security`

-`account.1`: `security_account_information_provided`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
with
aggregated as (
({{ security_account_information_provided('cis_v3.0.0','1.2') }})
{{ union() }}
({{ iam_root_user_no_access_keys('cis_v3.0.0','1.4') }})
{{ union() }}
({{ mfa_enabled_for_root('cis_v3.0.0','1.5') }})
{{ union() }}
({{ hardware_mfa_enabled_for_root('cis_v3.0.0','1.6') }})
{{ union() }}
({{ iam_root_last_used('cis_v3.0.0','1.7') }})
{{ union() }}
({{ password_policy_min_length('cis_v3.0.0','1.8') }})
{{ union() }}
({{ password_policy_prevent_reuse('cis_v3.0.0','1.9') }})
{{ union() }}
({{ mfa_enabled_for_console_access('cis_v3.0.0','1.10') }})
{{ union() }}
({{ iam_user_access_keys_and_password_at_setup('cis_v3.0.0','1.11') }})
{{ union() }}
({{ unused_creds_disabled_45_days('cis_v3.0.0','1.12') }})
{{ union() }}
({{ users_with_two_active_access_keys('cis_v3.0.0','1.13') }})
{{ union() }}
({{ old_access_keys('cis_v3.0.0','1.14') }})
{{ union() }}
({{ policies_attached_to_groups_roles('cis_v3.0.0','1.15') }})
{{ union() }}
({{ no_star('cis_v3.0.0','1.16') }})
{{ union() }}
({{ iam_support_role('cis_v3.0.0','1.17') }})
{{ union() }}
({{ use_iam_roles_for_instances('cis_v3.0.0','1.18') }})
{{ union() }}
({{ iam_server_certificate_not_expired('cis_v3.0.0','1.19') }})
{{ union() }}
({{ regions_with_no_accessanalyzers('cis_v3.0.0','1.20') }})
{{ union() }}
({{ iam_users_are_managed_centrally('cis_v3.0.0','1.21') }})
{{ union() }}
({{ iam_user_group_role_cloudshell_fullaccess_restricted('cis_v3.0.0','1.22') }})
{{ union() }}
({{ deny_http_requests('cis_v3.0.0','2.1.1') }})
{{ union() }}
({{ mfa_delete('cis_v3.0.0','2.1.2') }})
{{ union() }}
({{ account_level_public_access_blocks('cis_v3.0.0','2.1.4') }})
{{ union() }}
({{ unencrypted_ebs_volumes('cis_v3.0.0','2.2.1') }})
{{ union() }}
({{ instances_should_have_ecnryption_at_rest_enabled('cis_v3.0.0','2.3.1') }})
{{ union() }}
({{ redis_clusters_have_autominorversionupgrade('cis_v3.0.0','2.3.2') }})
{{ union() }}
({{ rds_db_instances_should_prohibit_public_access('cis_v3.0.0','2.3.3') }})
{{ union() }}
({{ unencrypted_efs_filesystems('cis_v3.0.0','2.4.1') }})
{{ union() }}
({{ cloudtrail_enabled_all_regions('cis_v3.0.0','3.1') }})
{{ union() }}
({{ log_file_validation_enabled('cis_v3.0.0','3.2') }})
{{ union() }}
({{ config_enabled_all_regions('cis_v3.0.0','3.3') }})
{{ union() }}
({{ bucket_access_logging('cis_v3.0.0','3.4') }})
{{ union() }}
({{ logs_encrypted('cis_v3.0.0','3.5') }})
{{ union() }}
({{ rotation_enabled_for_customer_key('cis_v3.0.0','3.6') }})
{{ union() }}
({{ flow_logs_enabled_in_all_vpcs('cis_v3.0.0','3.7') }})
{{ union() }}
({{ cloudtrail_s3_object_write_events_audit_enabled('cis_v3.0.0','3.8') }})
{{ union() }}
({{ cloudtrail_s3_object_read_events_audit_enabled('cis_v3.0.0','3.9') }})
{{ union() }}
({{ alarm_unauthorized_api('cis_v3.0.0','4.1') }})
{{ union() }}
({{ alarm_console_no_mfa('cis_v3.0.0','4.2') }})
{{ union() }}
({{ alarm_root_account('cis_v3.0.0','4.3') }})
{{ union() }}
({{ alarm_iam_policy_change('cis_v3.0.0','4.4') }})
{{ union() }}
({{ alarm_cloudtrail_config_changes('cis_v3.0.0','4.5') }})
{{ union() }}
({{ alarm_console_auth_failure('cis_v3.0.0','4.6') }})
{{ union() }}
({{ alarm_delete_customer_cmk('cis_v3.0.0','4.7') }})
{{ union() }}
({{ alarm_s3_bucket_policy_change('cis_v3.0.0','4.8') }})
{{ union() }}
({{ alarm_aws_config_changes('cis_v3.0.0','4.9') }})
{{ union() }}
({{ alarm_security_group_changes('cis_v3.0.0','4.10') }})
{{ union() }}
({{ alarm_nacl_changes('cis_v3.0.0','4.11') }})
{{ union() }}
({{ alarm_network_gateways('cis_v3.0.0','4.12') }})
{{ union() }}
({{ alarm_route_table_changes('cis_v3.0.0','4.13') }})
{{ union() }}
({{ alarm_vpc_changes('cis_v3.0.0','4.14') }})
{{ union() }}
({{ alarm_organization_changes('cis_v3.0.0','4.15') }})
{{ union() }}
({{ securityhub_enabled('cis_v3.0.0','4.16') }})
{{ union() }}
({{ vpc_network_acl_remote_administration('cis_v3.0.0','5.1') }})
{{ union() }}
({{ vpc_security_group_remote_administration_ipv4('cis_v3.0.0','5.2') }})
{{ union() }}
({{ no_broad_public_ipv6_ingress_on_port_22_3389('cis_v3.0.0','5.3') }})
{{ union() }}
({{ default_sg_no_access('cis_v3.0.0','5.4') }})
{{ union() }}
({{ ec2_not_imdsv2_instances('cis_v3.0.0','5.6') }})
)
select
{{ gen_timestamp() }},
aggregated.*
from aggregated
1 change: 1 addition & 0 deletions transformations/aws/compliance-premium/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
dbt-postgres==1.7.10
dbt-bigquery==1.7.6
dbt-snowflake==1.7.2
pyarrow >= 3.0.0
118 changes: 81 additions & 37 deletions transformations/aws/macros/config/config_enabled_all_regions.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,101 @@
{% endmacro %}

{% macro snowflake__config_enabled_all_regions(framework, check_id) %}
with global_recorders as (
select
count(*) as global_config_recorders
from
aws_config_configuration_recorders
where
recording_group:IncludeGlobalResourceTypes::BOOLEAN = TRUE
and recording_group:AllSupported::BOOLEAN = TRUE
and status_recording = TRUE
and status_last_status = 'SUCCESS'
)
select
'{{framework}}' As framework,
'{{check_id}}' As check_id,
'{{framework}}' As framework,
'{{check_id}}' As check_id,
'AWS Config should be enabled' as title,
account_id,
arn as resource_id,
CASE
WHEN ((recording_group:IncludeGlobalResourceTypes::BOOLEAN != TRUE) OR (recording_group:AllSupported::BOOLEAN != TRUE) OR (status_recording != TRUE OR status_last_status != 'SUCCESS'))
THEN 'fail'
ELSE 'pass'
END AS status
FROM
aws_config_configuration_recorders
r.account_id,
r.arn as resource_id,
case
when g.global_config_recorders >= 1
and status_recording = TRUE
and status_last_status = 'SUCCESS' then 'pass'
else 'fail'
end as status
from
global_recorders g,
aws_regions a
inner join aws_config_configuration_recorders as r on r.account_id = a.account_id
and r.region = a.region_name
where a.opt_in_status != 'not-opted-in'
{% endmacro %}

{% macro postgres__config_enabled_all_regions(framework, check_id) %}
with global_recorders as (
select
count(*) as global_config_recorders
from
aws_config_configuration_recorders
where
recording_group -> 'IncludeGlobalResourceTypes' = 'true'
and recording_group -> 'AllSupported' = 'true'
and status_recording is true
and status_last_status = 'SUCCESS'
)
select
'{{framework}}' as framework,
'{{check_id}}' as check_id,
'{{framework}}' As framework,
'{{check_id}}' As check_id,
'AWS Config should be enabled' as title,
account_id,
arn as resource_id,
case when
(recording_group->>'IncludeGlobalResourceTypes')::boolean IS NOT TRUE
OR (recording_group->>'AllSupported')::boolean IS NOT TRUE
OR status_recording IS NOT TRUE
OR status_last_status IS DISTINCT FROM 'SUCCESS'
then 'fail'
else 'pass'
end as status
FROM
aws_config_configuration_recorders
r.account_id,
r.arn as resource_id,
case
when g.global_config_recorders >= 1
and status_recording is true
and status_last_status = 'SUCCESS' then 'pass'
else 'fail'
end as status
from
global_recorders g,
aws_regions a
inner join aws_config_configuration_recorders r on r.account_id = a.account_id
and r.region = a.region_name
where a.opt_in_status != 'not-opted-in'
{% endmacro %}

{% macro default__config_enabled_all_regions(framework, check_id) %}{% endmacro %}

{% macro bigquery__config_enabled_all_regions(framework, check_id) %}
with global_recorders as (
select
count(*) as global_config_recorders
from
{{ full_table_name("aws_config_configuration_recorders") }}
where
CAST( JSON_VALUE(recording_group.IncludeGlobalResourceTypes) AS BOOL) IS TRUE
and CAST( JSON_VALUE(recording_group.AllSupported) AS BOOL) IS TRUE
and status_recording is true
and status_last_status = 'SUCCESS'
)
select
distinct
'{{framework}}' as framework,
'{{check_id}}' as check_id,
'AWS Config should be enabled' as title,
account_id,
arn as resource_id,
case when
CAST( JSON_VALUE(recording_group.IncludeGlobalResourceTypes) AS BOOL) IS NOT TRUE
OR CAST( JSON_VALUE(recording_group.AllSupported) AS BOOL) IS NOT TRUE
OR status_recording IS NOT TRUE
OR status_last_status IS DISTINCT FROM 'SUCCESS'
then 'fail'
else 'pass'
end as status
FROM
{{ full_table_name("aws_config_configuration_recorders") }}
r.account_id,
r.arn as resource_id,
case
when a.opt_in_status = 'not-opted-in' then ''
when g.global_config_recorders >= 1
and status_recording is true
and status_last_status = 'SUCCESS' then 'pass'
else 'fail'
end as status
from
global_recorders g,
{{ full_table_name("aws_regions") }} a
inner join {{ full_table_name("aws_config_configuration_recorders") }} r on r.account_id = a.account_id
and r.region = a.region_name
where a.opt_in_status != 'not-opted-in'
{% endmacro %}

0 comments on commit 8058378

Please sign in to comment.