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:

ServiceBucket TypePurpose
AWS CloudTrailcloudtrailAWS API call and user activity logs
Amazon VPC Flow LogsvpcflowNetwork traffic in virtual private clouds
Amazon GuardDutyguarddutyThreat detection and anomaly identification
AWS WAFwafWeb application firewall logs
Amazon MaciecustomSensitive data discovery in S3
AWS ConfigconfigResource configuration change tracking
AWS Trusted AdvisorcustomSecurity and optimization recommendations
AWS KMScustomEncryption key operations
Amazon InspectorcustomEC2 instance vulnerability assessment
Amazon CloudWatch LogscloudwatchApplication and system logs
Amazon S3 Server Accessserver_accessS3 bucket access logs
Amazon ECR Image ScanningcustomContainer image scanning
Elastic Load Balancer (ALB/CLB/NLB)alb / clb / nlbLoad balancer logs
Amazon Security Lakesecurity_lakeCentralized security event storage
AWS Security HubcustomSecurity 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

ParameterDefaultDescription
disablednoEnable or disable the module
interval10mS3 bucket polling interval (s/m/h/d)
run_on_startyesExecute on service startup
skip_on_erroryesContinue processing on error
only_logs_after-Collect logs from specified date (YYYY-MMM-DD)
regionsallRestrict 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/h3yCo8nvbEXAMPLEKEY

Region configuration in /root/.aws/config:

[default]
region = us-east-1

[profile production]
region = eu-west-1

Reference 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

  1. The S3 bucket is configured to send notifications about new objects to an SQS queue
  2. The Wazuh module polls the SQS queue instead of directly listing S3 objects
  3. Each SQS message contains the key of the new S3 object
  4. 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

ActionResourcePurpose
s3:GetObjectarn:aws:s3:::<BUCKET>/*Read objects from the bucket
s3:ListBucketarn:aws:s3:::<BUCKET>List objects in the bucket

SQS Permissions (When Using Queue)

ActionResourcePurpose
sqs:ReceiveMessagearn:aws:sqs:<REGION>:<ACCOUNT>:<QUEUE>Receive messages from the queue
sqs:DeleteMessagearn:aws:sqs:<REGION>:<ACCOUNT>:<QUEUE>Delete processed messages
sqs:GetQueueUrlarn:aws:sqs:<REGION>:<ACCOUNT>:<QUEUE>Retrieve the queue URL

Assume Role Permissions

ActionResourcePurpose
sts:AssumeRolearn: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:

  1. Multiple API calls with AccessDenied errors from a new IP address
  2. A successful API call following a series of failures
  3. 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:GetObject and s3: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_after to restrict the initial collection date
  • Avoid using --reparse in production unless necessary
  • Verify the same bucket is not referenced in multiple configuration blocks

Log Processing Delays

  • Reduce the interval value (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 boto3

Related Sections

Last updated on