Wazuh AWS - Amazon Web Services Security Monitoring
Wazuh provides security monitoring for Amazon Web Services through the aws-s3 module, which collects logs from S3 buckets and processes events from AWS cloud services. The module supports over 15 AWS services, including CloudTrail, GuardDuty, VPC Flow Logs, WAF, and others. This integration centralizes cloud event analysis within Wazuh, enabling detection of unauthorized access, configuration changes, and network anomalies.
Supported AWS Services
The aws-s3 module processes logs from the following services:
| Service | Bucket Type | Purpose |
|---|---|---|
| AWS CloudTrail | cloudtrail | AWS API call and user activity logs |
| Amazon VPC Flow Logs | vpcflow | Network traffic in virtual private clouds |
| Amazon GuardDuty | guardduty | Threat detection and anomaly identification |
| AWS WAF | waf | Web application firewall logs |
| Amazon Macie | custom | Sensitive data discovery in S3 |
| AWS Config | config | Resource configuration change tracking |
| AWS Trusted Advisor | custom | Security and optimization recommendations |
| AWS KMS | custom | Encryption key operations |
| Amazon Inspector | custom | EC2 instance vulnerability assessment |
| Amazon CloudWatch Logs | cloudwatch | Application and system logs |
| Amazon S3 Server Access | server_access | S3 bucket access logs |
| Amazon ECR Image Scanning | custom | Container image scanning |
| Elastic Load Balancer (ALB/CLB/NLB) | alb / clb / nlb | Load balancer logs |
| Amazon Security Lake | security_lake | Centralized security event storage |
| AWS Security Hub | custom | Security findings aggregation |
Module Configuration (aws-s3)
The module is configured in ossec.conf on the Wazuh server or agent.
Basic CloudTrail Configuration
<wodle name="aws-s3">
<disabled>no</disabled>
<interval>10m</interval>
<run_on_start>yes</run_on_start>
<skip_on_error>yes</skip_on_error>
<bucket type="cloudtrail">
<name>my-cloudtrail-bucket</name>
<aws_profile>default</aws_profile>
</bucket>
</wodle>Multi-Service Configuration
<wodle name="aws-s3">
<disabled>no</disabled>
<interval>10m</interval>
<run_on_start>yes</run_on_start>
<skip_on_error>yes</skip_on_error>
<bucket type="cloudtrail">
<name>my-cloudtrail-bucket</name>
<aws_profile>production</aws_profile>
</bucket>
<bucket type="vpcflow">
<name>my-vpcflow-bucket</name>
<aws_profile>production</aws_profile>
</bucket>
<bucket type="guardduty">
<name>my-guardduty-bucket</name>
<aws_profile>production</aws_profile>
</bucket>
<bucket type="waf">
<name>my-waf-bucket</name>
<aws_profile>production</aws_profile>
</bucket>
<bucket type="config">
<name>my-config-bucket</name>
<aws_profile>production</aws_profile>
</bucket>
</wodle>Module Parameters
| Parameter | Default | Description |
|---|---|---|
disabled | no | Enable or disable the module |
interval | 10m | S3 bucket polling interval (s/m/h/d) |
run_on_start | yes | Execute on service startup |
skip_on_error | yes | Continue processing on error |
only_logs_after | - | Collect logs from specified date (YYYY-MMM-DD) |
regions | all | Restrict to specific AWS regions |
aws_account_id | - | Filter by AWS account identifier |
path | - | S3 bucket directory prefix |
CloudTrail Directory Structure in S3
CloudTrail logs are stored in S3 following this structure:
<BUCKET>/<PREFIX>/AWSLogs/<ACCOUNT_ID>/CloudTrail/<REGION>/<YEAR>/<MONTH>/<DAY>/Authentication Methods
The aws-s3 module supports three authentication methods for AWS access.
Profiles with Access Keys
Credentials are stored in /root/.aws/credentials:
[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
[production]
aws_access_key_id = AKIAI44QH8DHBEXAMPLE
aws_secret_access_key = je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEYRegion configuration in /root/.aws/config:
[default]
region = us-east-1
[profile production]
region = eu-west-1Reference the profile in ossec.conf:
<bucket type="cloudtrail">
<name>my-cloudtrail-bucket</name>
<aws_profile>production</aws_profile>
</bucket>IAM Role for EC2
The recommended method when Wazuh runs on an EC2 instance. Temporary credentials are obtained automatically through the Instance Metadata Service. No profile or key specification is needed:
<bucket type="cloudtrail">
<name>my-cloudtrail-bucket</name>
</bucket>Assign an IAM role with the required permissions to the EC2 instance through an Instance Profile to use this method.
Role Assumption (Assume Role)
Enables temporary credential acquisition for accessing resources in a different AWS account. Requires trust relationship configuration between accounts:
<bucket type="cloudtrail">
<name>my-cloudtrail-bucket</name>
<aws_profile>default</aws_profile>
<iam_role_arn>arn:aws:iam::123456789012:role/WazuhCloudTrailRole</iam_role_arn>
</bucket>The iam_role_arn parameter contains the ARN of the IAM role that the module will assume via STS AssumeRole.
SQS Integration
For scalable log delivery from S3 to Wazuh, Amazon SQS (Simple Queue Service) eliminates delays caused by bucket object enumeration when dealing with high log volumes.
How It Works
- The S3 bucket is configured to send notifications about new objects to an SQS queue
- The Wazuh module polls the SQS queue instead of directly listing S3 objects
- Each SQS message contains the key of the new S3 object
- The module downloads and processes only the specified objects
S3 Notification Setup
Create an Event Notification in the S3 bucket settings:
- Events:
s3:ObjectCreated:* - Destination: SQS Queue
- Queue ARN:
arn:aws:sqs:<REGION>:<ACCOUNT_ID>:<QUEUE_NAME>
SQS Configuration in ossec.conf
<wodle name="aws-s3">
<disabled>no</disabled>
<interval>5m</interval>
<run_on_start>yes</run_on_start>
<skip_on_error>yes</skip_on_error>
<bucket type="cloudtrail">
<name>my-cloudtrail-bucket</name>
<aws_profile>default</aws_profile>
<sqs_name>my-cloudtrail-sqs-queue</sqs_name>
</bucket>
</wodle>Advantages of SQS Integration
- Faster processing of new logs (push instead of pull)
- Reduced S3 API load (fewer ListObjects calls)
- Support for multi-account deployments
- Automatic error handling through Dead Letter Queue
Required IAM Permissions
The IAM policy for the aws-s3 module must include the following permissions:
Base S3 Permissions
| Action | Resource | Purpose |
|---|---|---|
s3:GetObject | arn:aws:s3:::<BUCKET>/* | Read objects from the bucket |
s3:ListBucket | arn:aws:s3:::<BUCKET> | List objects in the bucket |
SQS Permissions (When Using Queue)
| Action | Resource | Purpose |
|---|---|---|
sqs:ReceiveMessage | arn:aws:sqs:<REGION>:<ACCOUNT>:<QUEUE> | Receive messages from the queue |
sqs:DeleteMessage | arn:aws:sqs:<REGION>:<ACCOUNT>:<QUEUE> | Delete processed messages |
sqs:GetQueueUrl | arn:aws:sqs:<REGION>:<ACCOUNT>:<QUEUE> | Retrieve the queue URL |
Assume Role Permissions
| Action | Resource | Purpose |
|---|---|---|
sts:AssumeRole | arn:aws:iam::<ACCOUNT>:role/<ROLE> | Assume an IAM role in the target account |
Sample IAM Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-cloudtrail-bucket",
"arn:aws:s3:::my-cloudtrail-bucket/*"
]
},
{
"Effect": "Allow",
"Action": [
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:GetQueueUrl"
],
"Resource": "arn:aws:sqs:us-east-1:123456789012:my-cloudtrail-sqs-queue"
}
]
}CloudTrail Analysis
CloudTrail records all AWS API calls, providing complete visibility into user and service actions within an account.
Detecting Unauthorized API Calls
Wazuh analyzes CloudTrail events with AccessDenied or UnauthorizedAccess error codes and generates alerts. Example event:
{
"rule": {
"id": "80253",
"level": 3,
"description": "AWS CloudTrail: unauthorized API call"
},
"data": {
"aws": {
"eventName": "DescribeInstances",
"errorCode": "AccessDenied",
"userIdentity": {
"type": "IAMUser",
"userName": "suspicious-user"
},
"sourceIPAddress": "198.51.100.42",
"awsRegion": "us-east-1"
}
}
}Detecting Root Account Login
Root account login to AWS generates a high-level alert:
{
"rule": {
"id": "80302",
"level": 8,
"description": "AWS CloudTrail: Root account login detected"
},
"data": {
"aws": {
"eventName": "ConsoleLogin",
"userIdentity": {
"type": "Root",
"arn": "arn:aws:iam::123456789012:root"
},
"responseElements": {
"ConsoleLogin": "Success"
},
"sourceIPAddress": "203.0.113.15"
}
}
}Security Group Changes
Wazuh detects the addition of permissive rules to security groups:
{
"rule": {
"id": "80447",
"level": 5,
"description": "AWS CloudTrail: Security group ingress rule added"
},
"data": {
"aws": {
"eventName": "AuthorizeSecurityGroupIngress",
"requestParameters": {
"groupId": "sg-0a1b2c3d4e5f67890",
"ipPermissions": {
"items": [{
"fromPort": 22,
"toPort": 22,
"ipRanges": {"items": [{"cidrIp": "0.0.0.0/0"}]}
}]
}
}
}
}
}IAM User Creation and Deletion
{
"rule": {
"id": "80258",
"level": 5,
"description": "AWS CloudTrail: IAM user created"
},
"data": {
"aws": {
"eventName": "CreateUser",
"requestParameters": {
"userName": "new-admin-user"
},
"userIdentity": {
"userName": "admin"
}
}
}
}GuardDuty Integration
Amazon GuardDuty is a managed threat detection service that analyzes data streams from CloudTrail, VPC Flow Logs, and DNS logs. Wazuh imports GuardDuty findings and processes them as alerts.
Configuration
<bucket type="guardduty">
<name>my-guardduty-bucket</name>
<aws_profile>default</aws_profile>
</bucket>GuardDuty Alert Example
{
"rule": {
"id": "80301",
"level": 8,
"description": "AWS GuardDuty: Unusual API call from known malicious IP"
},
"data": {
"aws": {
"service": {
"serviceName": "guardduty",
"action": {
"actionType": "AWS_API_CALL",
"awsApiCallAction": {
"api": "DescribeInstances",
"callerType": "Remote IP"
}
}
},
"severity": 8,
"title": "API DescribeInstances was invoked from a known malicious IP address",
"type": "Recon:EC2/MaliciousIPCaller.Custom"
}
}
}GuardDuty Threat Types
GuardDuty classifies findings into the following categories:
- Recon - reconnaissance (port scanning, resource enumeration)
- UnauthorizedAccess - unauthorized access attempts
- Trojan - trojan malware detection
- CryptoCurrency - cryptocurrency mining activity
- Backdoor - backdoor detection
- Exfiltration - data exfiltration attempts
VPC Flow Logs Monitoring
VPC Flow Logs capture network traffic at the network interface, subnet, and VPC level.
Configuration
<bucket type="vpcflow">
<name>my-vpcflow-bucket</name>
<aws_profile>default</aws_profile>
</bucket>VPC Flow Logs Alert Example
{
"rule": {
"id": "80401",
"level": 4,
"description": "AWS VPC Flow: Rejected connection attempt"
},
"data": {
"aws": {
"vpcflow": {
"srcaddr": "198.51.100.55",
"dstaddr": "10.0.1.25",
"srcport": 44820,
"dstport": 3389,
"protocol": 6,
"action": "REJECT"
}
}
}
}Use Cases
Detecting Compromised Access Keys
Combining CloudTrail alerts enables identification of compromised key usage:
- Multiple API calls with
AccessDeniederrors from a new IP address - A successful API call following a series of failures
- Creation of new IAM users or access keys
Compliance Monitoring
- Tracking IAM policy changes (PCI DSS 7.1, 7.2)
- Monitoring data encryption through KMS (PCI DSS 3.4)
- Controlling access to S3 buckets containing sensitive data (GDPR Art. 32)
Detecting Lateral Movement
- Anomalous API call patterns from a compromised EC2 instance
- Resource access in atypical regions
- Usage of previously inactive IAM roles
Troubleshooting
Module Not Collecting Logs
- Verify IAM policy permissions:
s3:GetObjectands3:ListBucket - Confirm the bucket contains logs in the expected directory structure
- Check the credentials file at
/root/.aws/credentials - Review the module log:
/var/ossec/logs/ossec.log
AccessDenied Error When Reading Bucket
- Confirm the IAM policy is attached to the correct user or role
- Check the Bucket Policy for explicit deny statements
- When using Assume Role, verify the role trust relationships
- Ensure the configured region matches the bucket region
Duplicate Alerts
- Use
only_logs_afterto restrict the initial collection date - Avoid using
--reparsein production unless necessary - Verify the same bucket is not referenced in multiple configuration blocks
Log Processing Delays
- Reduce the
intervalvalue (for example, to 5m) - Configure SQS integration for push-based notification delivery
- Use region filtering (
regions) to reduce data volume - Set up a Dead Letter Queue for SQS to handle failed messages
Python Dependencies
The module requires Python 3 and the boto3 library. Installation on the Wazuh server:
/var/ossec/framework/python/bin/pip3 install boto3Related Sections
- Cloud Security Monitoring - overview of all cloud integrations
- Wazuh Capabilities - platform security modules
- Wazuh Architecture - components and data flows