๐ How to Send Apache + ModSecurity Logs to AWS CloudWatch Logs on EC2
In this guide, you'll learn how to forward ModSecurity logs from Apache to AWS CloudWatch Logs using the CloudWatch Agent on an EC2 instance with an IAM Role, and ensure it runs reliably using systemd.
✅ Prerequisites
-
An EC2 instance (Ubuntu/Debian)
-
Apache2 and ModSecurity installed
-
Instance has an IAM Role attached with permission:
-
CloudWatchAgentServerPolicyor:{ "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", "logs:DescribeLogStreams" ], "Resource": "*" }
-
⚙️ Step 1: Install the CloudWatch Agent
cd /opt
curl -O https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb
sudo dpkg -i amazon-cloudwatch-agent.deb
๐ ️ Step 2: Create the Agent Configuration File
Save this file as /opt/cloudwatch-config.json:
{
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/apache2/error.log",
"log_group_name": "apache2-modsecurity",
"log_stream_name": "{instance_id}/modsec",
"timestamp_format": "%a %b %d %H:%M:%S.%f %Y",
"multi_line_start_pattern": "^\\[[A-Z][a-z]{2} [A-Z][a-z]{2} \\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d+ \\d{4}\\]",
"encoding": "utf-8"
}
]
}
}
}
}
๐ This is tailored to match lines like:
[Thu Jun 26 09:27:53.716589 2025] [security2:error] ...
๐ Step 3: Start the CloudWatch Agent
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a fetch-config \
-m ec2 \
-c file:/opt/cloudwatch-config.json \
-s
You can check its status with:
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a status
๐ก️ Step 4: Create a systemd Service (Optional but Recommended)
Create this unit file at: /etc/systemd/system/cloudwatch-agent-custom.service
[Unit]
Description=Amazon CloudWatch Agent with Custom Config
After=network.target
[Service]
Type=simple
ExecStart=/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a fetch-config -m ec2 -c file:/opt/cloudwatch-config.json -s
Restart=always
[Install]
WantedBy=multi-user.target
Then reload and enable:
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl enable --now cloudwatch-agent-custom
This ensures the agent starts on reboot and restarts if it crashes.
๐ Step 5: View Logs in AWS CloudWatch
Go to the AWS Console:
-
Navigate to CloudWatch > Log groups
-
You should see:
/apache2-modsecurity -
Click into it to see log streams from your EC2
๐ Query: Search Logs with CloudWatch Insights
Go to CloudWatch → Logs Insights, choose your log group, then try:
Show recent ModSecurity logs:
fields @timestamp, @message
| filter @message like /ModSecurity/
| sort @timestamp desc
| limit 20
Extract fields like client_ip, rule_id, msg:
fields @timestamp, @message
| parse @message /\[client (?<client_ip>.*?)\].*?\[id "(?<rule_id>\d+)"\].*?\[msg "(?<msg>.*?)"\]/
| sort @timestamp desc
| display client_ip, rule_id, msg
๐ฃ (Optional) Set Alarms on Log Patterns
You can set alarms for:
-
High number of security alerts
-
Specific ModSecurity rules (e.g., XSS, SQLi)
Go to:
-
CloudWatch > Log Groups > apache2-modsecurity > Create Metric Filter
Example pattern:
[severity "CRITICAL"]
Then create a CloudWatch Alarm based on that metric.
๐งผ Cleanup Tips
If you no longer want logs to be sent:
sudo systemctl stop cloudwatch-agent-custom
sudo systemctl disable cloudwatch-agent-custom
✅ Final Result
You now have:
-
๐ Secure IAM-based log shipping
-
๐ Full visibility into ModSecurity alerts
-
⚡ CloudWatch Insights to investigate traffic
-
๐ Alerts for suspicious behavior
Komentar