aws-resource-logging-off¶
Ensure that the resource has some form of audit logging enabled to help with forensics
Access / audit / activity logs are a critical requirement for tracking unauthorized access when investigating security incidents.
This rule currently applies to the following list of resources and because logging configuration is specific to each resource type, we provide you the link to the relevant documentation regarding logging configuration.
Supported services¶
API Gateway Stage¶
Secure examples¶
resource "aws_api_gateway_stage" "demo" {
rest_api_id = "${var.api_id}"
stage_name = "some-stage-name"
deployment_id = "${aws_api_gateway_deployment.apiDeployment.id}"
description = "Stage demo"
access_log_settings {
destination_arn = "${module.api_stage_log_group.arn}"
format = "$context.error.message,$context.error.messageString,$context.identity.sourceIp,$context.identity.caller,$context.identity.user,$context.requestTime,$context.httpMethod,$context.resourcePath,$context.protocol,$context.status,$context.responseLength,$context.requestId"
}
}
AWSTemplateFormatVersion: "2010-09-09"
Resources:
MyStage:
Type: AWS::ApiGateway::Stage
Properties:
StageName: Prod
Description: Prod Stage
RestApiId: MyRestApi
DeploymentId: TestDeployment
DocumentationVersion: MyDocumentationVersion
ClientCertificateId: ClientCertificate
Variables:
Stack: Prod
AccessLogSetting:
DestinationArn: 'arn:aws:logs:us-east-1:123456789:log-group:my-log-group'
Format: >-
{"requestId":"$context.requestId", "ip": "$context.identity.sourceIp",
"caller":"$context.identity.caller",
"user":"$context.identity.user","requestTime":"$context.requestTime",
"eventType":"$context.eventType","routeKey":"$context.routeKey",
"status":"$context.status","connectionId":"$context.connectionId"}
MethodSettings:
- ResourcePath: /
HttpMethod: GET
MetricsEnabled: true
DataTraceEnabled: false
- ResourcePath: /stack
HttpMethod: POST
MetricsEnabled: true
DataTraceEnabled: false
ThrottlingBurstLimit: 999
- ResourcePath: /stack
HttpMethod: GET
MetricsEnabled: true
DataTraceEnabled: false
ThrottlingBurstLimit: 555
More information¶
- Terraform docs on Access Logging for API Gateway Stage
- CloudFormation docs on Access Logging for API Gateway Stage
ALB / ELBv2¶
Secure examples¶
resource "aws_lb" "test" {
name = "test-lb-tf"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.lb_sg.id]
subnets = aws_subnet.public.*.id
access_logs {
bucket = aws_s3_bucket.lb_logs.bucket
prefix = "test-lb"
enabled = true
}
}
AWSTemplateFormatVersion: 2010-09-09
Resources:
Resource0:
Type: 'AWS::ElasticLoadBalancingV2::LoadBalancer'
Properties:
Name: MyLB
LoadBalancerAttributes:
- Key: access_logs.s3.enabled
Value: "true"
- Key: access_logs.s3.bucket
Value: MyBucket
Subnets:
- SubnetID0
- SubnetID1
More information¶
Classic LB (ELBv1)¶
Secure examples¶
resource "aws_lb" "test" {
name = "test-lb-tf"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.lb_sg.id]
subnets = aws_subnet.public.*.id
access_logs {
bucket = aws_s3_bucket.lb_logs.bucket
prefix = "test-lb"
enabled = true
}
}
Resources:
LoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: "my-alb"
Type: application
Scheme: internet-facing
SecurityGroups:
* !Ref SecurityGroup
Subnets: !Ref Subnets
LoadBalancerAttributes:
* Key: access_logs.s3.enabled
Value: true
* Key: access_logs.s3.prefix
Value: "my-access-logs"
* Key: access_logs.s3.bucket
Value: !Ref AccessLogBucket
More information¶
- Terraform docs on Access Logging for Classic LB (ELBv1)
- CloudFormation docs on Access Logging for Classic LB (ELBv1)
DocsDB¶
Secure examples¶
resource "aws_docdb_cluster" "docdb_audit_logging_enabled" {
cluster_identifier = "another-cluster"
engine = "docdb"
master_username = "admin"
master_password = "unsafe-pass"
backup_retention_period = 5
preferred_backup_window = "07:00-09:00"
skip_final_snapshot = true
enabled_cloudwatch_logs_exports = ["audit"]
}
AWSTemplateFormatVersion: "2010-09-09"
Resources:
DocDBEnabled:
Type: AWS::DocDB::DBCluster
Properties:
MasterUsername: name
MasterUserPassword: password
StorageEncrypted: true
EnableCloudwatchLogsExports: ["audit", "profiler"]
More information¶
Elasticsearch¶
Secure examples¶
resource "aws_elasticsearch_domain" "example" {
# .. other configuration ...
log_publishing_options {
cloudwatch_log_group_arn = aws_cloudwatch_log_group.example.arn
log_type = "AUDIT_LOGS"
}
}
AWSTemplateFormatVersion: 2010-09-09
Resources:
ElasticsearchDomain:
Type: AWS::Elasticsearch::Domain
Properties:
ElasticsearchVersion: !Ref ElasticsearchVersion
DomainName: !Ref ElasticsearchName
...
LogPublishingOption:
CloudWatchLogsLogGroupArn: "some-cloudwatch-arn"
Enabled: true
More information¶
- Terraform docs on Audit Logging for Elasticsearch
- CloudFormation docs on Audit Logging for Elasticsearch
EKS¶
Secure examples¶
resource "aws_eks_cluster" "example" {
name = var.cluster_name
# ... other configuration ...
depends_on = [aws_cloudwatch_log_group.example]
enabled_cluster_log_types = ["api", "audit"]
}
resource "aws_cloudwatch_log_group" "example" {
# The log group name format is /aws/eks/<cluster-name>/cluster
# Reference: https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html
name = "/aws/eks/${var.cluster_name}/cluster"
retention_in_days = 7
# ... potentially other configuration ...
}
More information¶
MSK¶
Secure examples¶
resource "aws_msk_cluster" "example" {
cluster_name = "example"
kafka_version = "2.4.1"
number_of_broker_nodes = 3
# Other configs...
logging_info {
broker_logs {
s3 {
enabled = true
bucket = aws_s3_bucket.bucket.id
prefix = "logs/msk-"
}
}
}
}
AWSTemplateFormatVersion: "2010-09-09"
Description: MSK Cluster with required properties.
Resources:
TestCluster7:
Type: 'AWS::MSK::Cluster'
Properties:
ClusterName: ClusterWithRequiredProperties
KafkaVersion: 2.2.1
LoggingInfo:
BrokerLogs:
S3:
Enabled: false
Prefix: "logs/msk-"
Bucket: "bucket-arn"
More information¶
MQ¶
Secure examples¶
resource "aws_mq_broker" "some-broker" {
# ... Other configs
logs {
general = var.general_log
audit = var.audit_log
}
}
More information¶
Neptune cluster¶
Secure examples¶
resource "aws_neptune_cluster" "some-cluster" {
# Other configs...
enable_cloudwatch_logs_exports = ["audit"]
}
AWSTemplateFormatVersion: 2010-09-09
Resources:
NeptuneDBClusterEmpty:
Type: "AWS::Neptune::DBCluster"
Properties:
DBClusterIdentifier: DBClusterIdentifier
EnableCloudwatchLogsExports: ["audit"]
More information¶
RDS¶
Secure examples¶
resource "aws_db_instance" "mysql" {
allocated_storage = 5
engine = "mysql"
instance_class = "db.t3.small"
password = "mysql"
username = "mysql"
enabled_cloudwatch_logs_exports = ["error", "audit"]
}
AWSTemplateFormatVersion: 2010-09-09
Resources:
RDSCluster:
Type: 'AWS::RDS::DBCluster'
Properties:
MasterUsername: !Ref DBUsername
MasterUserPassword: !Ref DBPassword
DBClusterIdentifier: aurora-postgresql-cluster
Engine: aurora-postgresql
EngineVersion: '10.7'
DBClusterParameterGroupName: default.aurora-postgresql10
EnableCloudwatchLogsExports:
- postgresql
More information¶
- Terraform docs on Logging (audit, error, etc.) for RDS
- CloudFormation docs on Logging (audit, error, etc.) for RDS
Redshift¶
Secure examples¶
resource "aws_redshift_cluster" "some-db" {
cluster_identifier = "some-db"
database_name = "mydb"
master_username = "foo"
master_password = "some-pass"
node_type = "dc1.large"
cluster_type = "single-node"
encrypted = true
logging {
enable = true
}
}
AWSTemplateFormatVersion: 2010-09-09
Resources:
RedshiftCluster:
Type: AWS::Redshift::Cluster
Properties:
LoggingProperties:
BucketName: "Some bucket name"