Deny Linux kernel capabilities for Amazon ECS and AWS Fargate tasks
Use policy as code to restrict Linux kernel capabilities for a container task
What and why?
Amazon Elastic Container Service (ECS) is a container orchestrator that launches and manages container deployments on your behalf. It configures the settings that are used when running the application container. One of those settings that can be configured is the Linux capabilities of the application container.
Linux capabilities are a way to limit or increase the level of access a process
has to use the full capabilities of the Linux kernel. Elevated capabilities could
be exploited by a process to "break out" of it's container and interfere with the host. On the other hand, limiting capabilities is a good way to build further
limits around a process that may be running potential untrustworthy code.
has to use the full capabilities of the Linux kernel. Elevated capabilities could
be exploited by a process to "break out" of it's container and interfere with the host. On the other hand, limiting capabilities is a good way to build further
limits around a process that may be running potential untrustworthy code.
In this pattern you will learn how to deny containers linux capabilities using CloudFormation Guard , an open-source, general-purpose, policy-as-code evaluation tool.
💡 Tip: If you are deploying Amazon ECS tasks on AWS Fargate then there are already existing restrictions on whichLinux capabilities can be added. See theKernelCapabilitiesdocumentation for a list of the capabilities that can be added, as well as the current AWS Fargate restrictions on capabilities . This pattern is primarily applicable to deploying Amazon ECS tasks on EC2 capacity.
Dependencies
CloudFormation Guard Rule
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# File: no-capabilities-for-tasks.guard
let task_defs = Resources.*[Type == 'AWS::ECS::TaskDefinition']
#
# Verify that ECS tasks are not adding Linux kernel capabilities
#
rule tasks_denied_linux_capabilities {
when %task_defs !empty {
%task_defs.Properties.ContainerDefinitions[*] {
LinuxParameters.Capabilities.Add !exists
}
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
# File: no-capabilities-for-tasks.guard
let task_defs = Resources.*[Type == 'AWS::ECS::TaskDefinition']
#
# Verify that ECS tasks are not adding Linux kernel capabilities
#
rule tasks_denied_linux_capabilities {
when %task_defs !empty {
%task_defs.Properties.ContainerDefinitions[*] {
LinuxParameters.Capabilities.Add !exists
}
}
}Sample Templates
The following sample CloudFormation templates can be used to verify that this rule works:
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
# File: safe-task-def.yml
AWSTemplateFormatVersion: '2010-09-09'
Description: Example task definitions that do not add Linux kernel capabilities
Resources:
DefaultCapabilitiesTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: alpine
Cpu: 256
Memory: 128
ContainerDefinitions:
- Name: alpine
Image: public.ecr.aws/docker/library/alpine:latest
Essential: true
DroppedCapabilitiesTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: alpine
Cpu: 256
Memory: 128
ContainerDefinitions:
- Name: alpine
Image: public.ecr.aws/docker/library/alpine:latest
Essential: true
LinuxParameters:
Capabilities:
Drop:
- SYS_CHROOT1
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
# File: safe-task-def.yml
AWSTemplateFormatVersion: '2010-09-09'
Description: Example task definitions that do not add Linux kernel capabilities
Resources:
DefaultCapabilitiesTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: alpine
Cpu: 256
Memory: 128
ContainerDefinitions:
- Name: alpine
Image: public.ecr.aws/docker/library/alpine:latest
Essential: true
DroppedCapabilitiesTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: alpine
Cpu: 256
Memory: 128
ContainerDefinitions:
- Name: alpine
Image: public.ecr.aws/docker/library/alpine:latest
Essential: true
LinuxParameters:
Capabilities:
Drop:
- SYS_CHROOTUsage
You can validate the sample CloudFormation templates against the CloudFormation guard rule using the following command:
1
cfn-guard validate --data *.yml --rules .You should see output similar to this:
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
bad-task-def.yml Status = FAIL
FAILED rules
no-capabilities-for-tasks.guard/tasks_denied_linux_capabilities FAIL
Evaluating data bad-task-def.yml against rules no-capabilities-for-tasks.guard
Number of non-compliant resources 1
Resource = AddedCapabilityTaskDefinition {
Type = AWS::ECS::TaskDefinition
Rule = tasks_denied_linux_capabilities {
ALL {
Check = LinuxParameters.Capabilities.Add not EXISTS {
ComparisonError {
Error = Check was not compliant as property [/Resources/AddedCapabilityTaskDefinition/Properties/ContainerDefinitions/0/LinuxParameters/Capabilities/Add[L:17,C:16]] existed.
PropertyPath = /Resources/AddedCapabilityTaskDefinition/Properties/ContainerDefinitions/0/LinuxParameters/Capabilities/Add[L:17,C:16]
Operator = NOT EXISTS
Code:
15. LinuxParameters:
16. Capabilities:
17. Add:
18. - SYS_ADMIN
}
}
}
}
}See Also
More policy as code patterns:
- Enforce non-blocking mode for awslogs logging driver, with CloudFormation Guard policy as code
- Enforce readonly root filesystem for containers in ECS, with CloudFormation Guard policy as code
- Deny privileged container mode in Amazon ECS with CloudFormation Guard policy as code
- Deny root user for Amazon ECS and AWS Fargate tasks
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article