Skip to main content

AWS Security — GuardDuty, Security Hub, and Config Rules

· 6 min read
Goel Academy
DevOps & Cloud Learning Hub

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:

ServiceWhat It DoesDetects
GuardDutyThreat detectionActive threats, anomalies, compromised resources
Security HubFinding aggregation + complianceCompliance posture, aggregated findings
AWS ConfigResource configuration trackingConfiguration drift, non-compliant resources
InspectorVulnerability scanningSoftware CVEs, network exposure
CloudTrailAPI audit loggingWho 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

StandardControlsWhat It Checks
AWS Foundational Security Best Practices200+AWS-specific best practices across all services
CIS AWS Foundations Benchmark50+Center for Internet Security hardening guidelines
PCI DSS v3.2.1150+Payment Card Industry compliance
NIST SP 800-53200+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.