AWS Security — GuardDuty, Security Hub, and Config Rules
You check your AWS console one morning and find 347 security findings across 12 accounts. Some are critical. Some are noise. You don't know which S3 buckets are public, whether anyone is using the root account, or if that suspicious API call at 3 AM was an attacker or a misconfigured Lambda. AWS has four services that work together to answer these questions — but most teams either don't enable them or enable them and ignore the findings.
The Security Services Landscape
AWS security monitoring is split across specialized services that each handle a different concern:
| Service | What It Does | Detects |
|---|---|---|
| GuardDuty | Threat detection | Active threats, anomalies, compromised resources |
| Security Hub | Finding aggregation + compliance | Compliance posture, aggregated findings |
| AWS Config | Resource configuration tracking | Configuration drift, non-compliant resources |
| Inspector | Vulnerability scanning | Software CVEs, network exposure |
| CloudTrail | API audit logging | Who did what, when (feeds into GuardDuty) |
They're complementary, not competing. GuardDuty finds threats, Config tracks configuration, Inspector finds vulnerabilities, and Security Hub brings it all together.
GuardDuty — Intelligent Threat Detection
GuardDuty analyzes CloudTrail logs, VPC Flow Logs, and DNS query logs using machine learning to detect threats. You don't configure rules — it learns your account's normal behavior and flags anomalies:
# Enable GuardDuty (one command, no agents to install)
DETECTOR_ID=$(aws guardduty create-detector \
--enable \
--finding-publishing-frequency FIFTEEN_MINUTES \
--data-sources '{
"S3Logs": {"Enable": true},
"Kubernetes": {"AuditLogs": {"Enable": true}},
"MalwareProtection": {"ScanEc2InstanceWithFindings": {"EbsVolumes": true}}
}' \
--query 'DetectorId' --output text)
# List current findings
aws guardduty list-findings \
--detector-id $DETECTOR_ID \
--finding-criteria '{
"Criterion": {
"severity": {"Gte": 7}
}
}'
# Get finding details
aws guardduty get-findings \
--detector-id $DETECTOR_ID \
--finding-ids "finding-id-abc123"
GuardDuty finding types include:
- Recon:EC2/PortProbeUnprotectedPort — Someone is scanning your ports
- UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B — Root account login from unusual location
- CryptoCurrency:EC2/BitcoinTool.B — EC2 instance mining cryptocurrency
- Exfiltration:S3/ObjectRead.Unusual — Abnormal S3 download patterns
- Impact:EC2/DnsDomainGenerationAlgorithm — Instance communicating with DGA domains (malware indicator)
GuardDuty costs about $4/million CloudTrail events and $1/GB of VPC Flow Log analysis. For most accounts, that's $10-50/month — cheap insurance.
Security Hub — Aggregation and Compliance
Security Hub pulls findings from GuardDuty, Inspector, Config, and third-party tools into a single dashboard. More importantly, it runs automated compliance checks against security standards:
# Enable Security Hub with CIS and AWS Foundational standards
aws securityhub enable-security-hub \
--enable-default-standards
# Check which standards are available
aws securityhub describe-standards \
--query 'Standards[*].{Name: Name, ARN: StandardsArn}' \
--output table
# Enable additional standards (PCI DSS)
aws securityhub batch-enable-standards \
--standards-subscription-requests '[{
"StandardsArn": "arn:aws:securityhub:::ruleset/pci-dss/v/3.2.1"
}]'
# Get compliance summary
aws securityhub get-findings \
--filters '{
"ComplianceStatus": [{"Value": "FAILED", "Comparison": "EQUALS"}],
"SeverityLabel": [{"Value": "CRITICAL", "Comparison": "EQUALS"}]
}' \
--max-items 10
Supported Compliance Standards
| Standard | Controls | What It Checks |
|---|---|---|
| AWS Foundational Security Best Practices | 200+ | AWS-specific best practices across all services |
| CIS AWS Foundations Benchmark | 50+ | Center for Internet Security hardening guidelines |
| PCI DSS v3.2.1 | 150+ | Payment Card Industry compliance |
| NIST SP 800-53 | 200+ | US government security framework |
Each standard includes automated checks like: Is CloudTrail enabled? Is S3 bucket default encryption on? Are security groups overly permissive? Is root account MFA enabled?
AWS Config — Resource Configuration Compliance
AWS Config continuously records the configuration of your AWS resources and evaluates them against rules. When a resource drifts out of compliance, Config flags it:
# Enable AWS Config recorder
aws configservice put-configuration-recorder \
--configuration-recorder '{
"name": "default",
"roleARN": "arn:aws:iam::role/aws-config-role",
"recordingGroup": {
"allSupported": true,
"includeGlobalResourceTypes": true
}
}'
aws configservice put-delivery-channel \
--delivery-channel '{
"name": "default",
"s3BucketName": "my-config-bucket",
"snsTopicARN": "arn:aws:sns:us-east-1:123456789012:config-alerts"
}'
aws configservice start-configuration-recorder --configuration-recorder-name default
Managed Config Rules
AWS provides 300+ managed rules. Here are the critical ones:
# Rule: S3 buckets must not be publicly accessible
aws configservice put-config-rule --config-rule '{
"ConfigRuleName": "s3-bucket-public-read-prohibited",
"Source": {
"Owner": "AWS",
"SourceIdentifier": "S3_BUCKET_PUBLIC_READ_PROHIBITED"
}
}'
# Rule: EBS volumes must be encrypted
aws configservice put-config-rule --config-rule '{
"ConfigRuleName": "encrypted-volumes",
"Source": {
"Owner": "AWS",
"SourceIdentifier": "ENCRYPTED_VOLUMES"
}
}'
# Rule: Root account must have MFA
aws configservice put-config-rule --config-rule '{
"ConfigRuleName": "root-account-mfa-enabled",
"Source": {
"Owner": "AWS",
"SourceIdentifier": "ROOT_ACCOUNT_MFA_ENABLED"
}
}'
# Check compliance status
aws configservice get-compliance-summary-by-config-rule
Conformance Packs
Conformance packs are collections of Config rules that implement a compliance framework in one deployment:
# Deploy the CIS Benchmark conformance pack
aws configservice put-conformance-pack \
--conformance-pack-name "CIS-AWS-Benchmark" \
--template-s3-uri "s3://my-config-bucket/conformance-packs/cis-benchmark.yaml"
# Check pack compliance
aws configservice get-conformance-pack-compliance-summary \
--conformance-pack-names "CIS-AWS-Benchmark"
Inspector — Vulnerability Scanning
Amazon Inspector automatically scans EC2 instances, Lambda functions, and ECR container images for known software vulnerabilities (CVEs) and network exposure:
# Enable Inspector v2 (automatically scans all supported resources)
aws inspector2 enable --resource-types EC2 ECR LAMBDA
# List findings (sorted by severity)
aws inspector2 list-findings \
--filter-criteria '{
"severity": [{"comparison": "EQUALS", "value": "CRITICAL"}]
}' \
--sort-criteria '{"field": "SEVERITY", "sortOrder": "DESC"}'
# Get finding details
aws inspector2 list-findings \
--filter-criteria '{
"findingType": [{"comparison": "EQUALS", "value": "PACKAGE_VULNERABILITY"}]
}' \
--max-results 5
Inspector v2 is agentless for ECR and Lambda scanning. For EC2, it uses the SSM agent (already installed on most Amazon Linux and Ubuntu AMIs).
Auto-Remediation With Lambda
The real power comes from automatically fixing findings. Use EventBridge to trigger Lambda functions when Config rules detect non-compliance:
# auto_remediate_public_s3.py
# Triggered when Config detects a public S3 bucket
import boto3
import json
s3 = boto3.client('s3')
def lambda_handler(event, context):
# Parse the Config event
config_item = json.loads(event['invokingEvent'])
bucket_name = config_item['configurationItem']['resourceName']
compliance = event['resultToken']
# Block all public access
s3.put_public_access_block(
Bucket=bucket_name,
PublicAccessBlockConfiguration={
'BlockPublicAcls': True,
'IgnorePublicAcls': True,
'BlockPublicPolicy': True,
'RestrictPublicBuckets': True
}
)
print(f"Blocked public access on bucket: {bucket_name}")
return {
'statusCode': 200,
'body': f'Remediated {bucket_name}'
}
Wire it up with a Config remediation action:
# Associate the remediation Lambda with the Config rule
aws configservice put-remediation-configurations \
--remediation-configurations '[{
"ConfigRuleName": "s3-bucket-public-read-prohibited",
"TargetType": "SSM_DOCUMENT",
"TargetId": "AWS-DisableS3BucketPublicReadWrite",
"Automatic": true,
"MaximumAutomaticAttempts": 3,
"RetryAttemptSeconds": 60
}]'
Building a Security Posture Dashboard
Combine all services into a single security view:
# Security Hub score (aggregate compliance percentage)
aws securityhub get-findings \
--filters '{
"WorkflowStatus": [{"Value": "NEW", "Comparison": "EQUALS"}],
"RecordState": [{"Value": "ACTIVE", "Comparison": "EQUALS"}]
}' \
--query 'Findings | length(@)'
# GuardDuty active threats
aws guardduty list-findings \
--detector-id $DETECTOR_ID \
--finding-criteria '{"Criterion": {"service.archived": {"Eq": ["false"]}}}' \
--query 'FindingIds | length(@)'
# Config compliance summary
aws configservice get-compliance-summary-by-config-rule \
--query '{Compliant: ComplianceSummary.CompliantResourceCount.CappedCount, NonCompliant: ComplianceSummary.NonCompliantResourceCount.CappedCount}'
The goal is simple: zero critical findings in GuardDuty, 95%+ compliance score in Security Hub, and all Config rules passing. Track these numbers weekly and treat regressions as incidents.
What's Next
Security services protect individual accounts, but how do you manage security across dozens of accounts? In the next post, we'll cover AWS Organizations — the multi-account strategy that gives you centralized governance, consolidated billing, and Service Control Policies across your entire organization.
