diff --git a/UPGRADING.rst b/UPGRADING.rst index a348c08d01..ed8621ba47 100644 --- a/UPGRADING.rst +++ b/UPGRADING.rst @@ -113,6 +113,16 @@ a deployment just before pushing the merge commit to the GitLab instance in that deployment. +#5043 S3 server access logs are inherently incomplete +===================================================== + +Operator +~~~~~~~~ + +Manually deploy the ``shared`` component of any main deployment just before +pushing the merge commit to the GitLab instance in that deployment. + + #5133 Trigger an alarm on absence of logs ========================================= diff --git a/terraform/shared/shared.tf.json.template.py b/terraform/shared/shared.tf.json.template.py index ac2b0ffcc7..c349469cc4 100644 --- a/terraform/shared/shared.tf.json.template.py +++ b/terraform/shared/shared.tf.json.template.py @@ -36,11 +36,34 @@ def conformance_pack(name: str) -> str: return body +def paren(s: str) -> str: + return '(' + s + ')' + + cis_alarms = [ # https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-cis-controls.html#securityhub-cis-controls-3.1 CloudTrailAlarm(name='api_unauthorized', statistic='Average', - filter_pattern='{($.errorCode="*UnauthorizedOperation") || ($.errorCode="AccessDenied*")}'), + filter_pattern='{' + ' && '.join([ + paren(' || '.join([ + '$.errorCode = "*UnauthorizedOperation"', + '$.errorCode = "AccessDenied*"', + ])), + # Filtering on the errorCode alone catches too many false + # positives, so we exclude those logs with the additional + # conditions below. + paren(' || '.join([ + '$.eventSource != "s3.amazonaws.com"', + '$.eventName != "GetObject"', + '$.userIdentity.invokedBy != "cloudfront.amazonaws.com"', + ])), + paren(' || '.join([ + '$.eventSource != "s3.amazonaws.com"', + '$.eventName != "HeadBucket"', + '$.userIdentity.invokedBy != "config.amazonaws.com"', + ])) + ]) + '}' + ), # https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-cis-controls.html#securityhub-cis-controls-3.2 CloudTrailAlarm(name='console_no_mfa', statistic='Sum', @@ -373,7 +396,15 @@ def conformance_pack(name: str) -> str: 'enable_log_file_validation': True, 'is_multi_region_trail': True, 'cloud_watch_logs_group_arn': '${aws_cloudwatch_log_group.trail.arn}:*', - 'cloud_watch_logs_role_arn': '${aws_iam_role.trail.arn}' + 'cloud_watch_logs_role_arn': '${aws_iam_role.trail.arn}', + 'event_selector': { + 'read_write_type': 'All', + 'include_management_events': True, + 'data_resource': { + 'type': 'AWS::S3::Object', + 'values': ['arn:aws:s3'] + } + } } }, 'aws_cloudwatch_log_group': {