How to Set Up Runtime Monitoring ECS Cluster Using GuardDuty
This article helps gather security issues by enabling runtime monitoring in GuardDuty
- Enable GuardDuty Runtime Monitoring
- Create VPC Endpoint for GuardDuty Service
- Create ECS Cluster with EC2 Host
- Set up ALB across EC2 hosts
- Post Provision EC2 Instances and Install GD Agent
- Validation
- Open GuardDuty console https://console.aws.amazon.com/guardduty/
- Enable GuardDuty service in your AWS account.
- Select "Runtime Monitoring" in the left navigation pane.
- Under "Configuration" section, please enable "Runtime Monitoring" option.
- Open VPC console https://console.aws.amazon.com/vpc/
- Select "Endpoints" from left navigation bar.
- Create a new endpoints with service name "com.amazonaws.<region>.guardduty-data".
- Make sure "Enable DNS name" is checked under "Additional Settings".
- Choose required subnets and security groups for endpoint.
- Use below custom policy -
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "*",
"Resource": "*",
"Effect": "Allow",
"Principal": "*"
},
{
"Condition": {
"StringNotEquals": {
"aws:PrincipalAccount": "<account-id>"
}
},
"Action": "*",
"Resource": "*",
"Effect": "Deny",
"Principal": "*"
}
]
}
1
2
3
4
install errors: error: Failed dependencies:
kernel >= 5.4.0 is needed by amazon-guardduty-agent-1.0-0.x86_64
failed to run commands: exit status 1
Failed to install package; install status Failed
- Open ECS console https://console.aws.amazon.com/ecs/
- Click on Create Cluster.
- Give Cluster name.
- Under "Infrastructure" section, choose below settings -
- Click on checkbox: Amazon EC2 instances
- Auto Scaling group (ASG): Create new ASG
- Provisioning Model: On-Demand
- Operating system/Architecture: Amazon Linux 2 (kernel 5.10)
- EC2 Instance Type: t2.micro
- Desired Capacity:
- Minimum: 2 Maximum: 4
- SSH Keypair: Choose a keypair
- Under "Network settings for Amazon EC2 instances" -
- Choose correct VPC, Subnets and Security Groups.
- Auto Assign Public IP: Turn On
- Submit the catalog.
- Open "Task Definitions" from left navigation bar.
- Click on "Create new task definition"
- Under "Infrastructure requirements" section, choose below -
- Launch Type: Amazon EC2 Instances
- Operating system/Architecture: Linux X86_64
- Network Mode: Default (later discussed why "default")
- Task Size:
- CPU: 0.8 vCPU, Memory: 0.9 GB
- Task Role: <ecs-task-role-name>
- Under "Container" section, choose below -
- Name: <container-name>
- Image URI: <Image URL>
- Essential Container: YES
- Host Port: 80, Container Port: 80 (For simplicity, port 80 is taken)
- Resource Allocation Limits:
- CPU: 0.5 vCPU, Memory Hard Limit: 0.7GB, Soft Limit: 0.5 GB
- Under "Logging" section, keep this as default
- Under HealthCheck section -
- Command: CMD-SHELL,echo hello world
- Interval: 5 seconds
- Timeout: 5 seconds
- Start Period: 10 seconds
- Retries: 3
- This will generate below JSON content of task definition -
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
{
"taskDefinitionArn": "arn:aws:ecs:us-east-1:<account-id>:task-definition/mytaskdef1:2",
"containerDefinitions": [
{
"name": "httpd",
"image": "<image-uri>",
"cpu": 512,
"memory": 717,
"memoryReservation": 512,
"portMappings": [
{
"name": "httpd-80-tcp",
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp",
"appProtocol": "http"
}
],
"essential": true,
"environment": [],
"environmentFiles": [],
"mountPoints": [],
"volumesFrom": [],
"workingDirectory": "/",
"ulimits": [],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-create-group": "true",
"awslogs-group": "/ecs/mytaskdef1",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "ecs"
},
"secretOptions": []
},
"healthCheck": {
"command": [
"CMD-SHELL",
"echo hello world"
],
"interval": 5,
"timeout": 5,
"retries": 3,
"startPeriod": 10
}
}
],
"family": "mytaskdef1",
"taskRoleArn": "arn:aws:iam::<account-id>:role/ecsTaskExecutionRole",
"executionRoleArn": "arn:aws:iam::<account-id>:role/ecsTaskExecutionRole",
"revision": 2,
"volumes": [],
"status": "ACTIVE",
"requiresAttributes": [
{
"name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
},
{
"name": "ecs.capability.execution-role-awslogs"
},
{
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
},
{
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.17"
},
{
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.21"
},
{
"name": "com.amazonaws.ecs.capability.task-iam-role"
},
{
"name": "ecs.capability.container-health-check"
},
{
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
},
{
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.29"
}
],
"placementConstraints": [],
"compatibilities": [
"EC2"
],
"requiresCompatibilities": [
"EC2"
],
"cpu": "819",
"memory": "922",
"runtimePlatform": {
"cpuArchitecture": "X86_64",
"operatingSystemFamily": "LINUX"
},
"registeredAt": "2024-01-26T15:20:05.159Z",
"registeredBy": "arn:aws:iam::<account-id>:root",
"tags": []
}
- Open the cluster and click on "Run Tasks" option.
- Under Compute option, choose "launch Type" as EC2.
- Under "Deployment Configuration" choose Application Type as "Task"
- Choose Task Definition which we created in last step.
- Choose Desired Tasks: 2
- Install GuardDuty Agent through System Managers Document.
- Install agents manually by downloading RPM scripts.
1
2
3
[root@ecs-host-1b ~]# uname -r
5.10.205-195.804.amzn2.x86_64
[root@ecs-host-1b ~]#
- Open Systems Manager console and click on "Documents" option. Look for "AmazonGuardDuty-ConfigureRuntimeMonitoringSsmPlugin" document.
- Provide package name as "AmazonGuardDuty-RuntimeMonitoringSsmPlugin"
- Choose the instances where agent needs to be installed and click Run.
- Post successful installation, validate the agent status by running -
- sudo systemctl status amazon-guardduty-agent
1
2
3
4
5
6
7
8
9
[root@ecs-host-1b ~]# sudo systemctl status amazon-guardduty-agent
● amazon-guardduty-agent.service - Amazon GuardDuty Agent
Loaded: loaded (/usr/lib/systemd/system/amazon-guardduty-agent.service; enabled; vendor preset: disabled)
Active: active (running) since Fri 2024-01-26 16:07:07 UTC; 4min 42s ago
Main PID: 22504 (amazon-guarddut)
Tasks: 14
Memory: 114.6M (limit: 128.0M)
CGroup: /system.slice/amazon-guardduty-agent.service
└─22504 /opt/aws/amazon-guardduty-agent/bin/amazon-guardduty-agent --worker-threads 8
- Now we can see both EC2 instances are ECS cluster are in healthy state in GuardDuty console as below -
- https://docs.aws.amazon.com/guardduty/latest/ug/how-runtime-monitoring-works-ec2.html
- https://docs.aws.amazon.com/guardduty/latest/ug/prereq-runtime-monitoring-ec2-support.html
- https://docs.aws.amazon.com/guardduty/latest/ug/managing-gdu-agent-ec2-manually.html
- https://docs.aws.amazon.com/guardduty/latest/ug/runtime-monitoring-agent-release-history.html