Amazon ECS 安全检查大多可以归结为:“容器对主机权限的侵犯程度如何?”、“是否直接暴露在外部互联网上?”以及“秘密信息和日志是否得到安全处理?”。特别是ECS任务定义(Task Definition)是包含容器运行方式、权限、文件系统、环境变量和日志设置的核心安全点。
AWS也建议,如果没有特殊原因,应使用awsvpc网络模式,对于Fargate任务,awsvpc网络模式是必需的。

1. 应避免使用host网络模式
在ECS任务定义中将networkMode设置为host,容器将绕过Docker的虚拟网络,直接使用EC2主机的网络命名空间。在这种情况下,容器端口将直接映射到主机ENI,并且会产生多个任务无法同时使用相同端口的限制。
从安全角度来看,这更为重要。host网络模式降低了容器与主机之间的隔离级别。对于一般的Web应用程序、API服务器和后端服务,使用awsvpc模式比host模式更安全。
推荐设置如下:
{
"networkMode": "awsvpc"
}
##
2. ECS服务的assignPublicIp应设置为DISABLED
如果ECS服务中的assignPublicIp设置为ENABLED,任务的ENI将自动分配一个公共IP。AWS Security Hub的ECS安全控制也判断,如果AssignPublicIP为ENABLED则为失败,如果为DISABLED则为通过。
在一般架构中,最好将ECS任务放置在私有子网中,并通过ALB或NLB接收外部访问。如果Fargate服务也放置在私有子网中且不使用公共IP,则可以将出站流量配置为通过NAT Gateway。
服务设置示例如下:
{
"networkConfiguration": {
"awsvpcConfiguration": {
"subnets": [
"subnet-private-a",
"subnet-private-b"
],
"securityGroups": [
"sg-ecs-service"
],
"assignPublicIp": "DISABLED"
}
}
}
3. 不应将pidMode设置为host
将pidMode设置为host会导致容器共享主机的进程命名空间。在这种情况下,容器内部可以看到主机的进程,并且在某些情况下可能会影响主机进程。
AWS Security Hub的ECS.3控制检查ECS任务定义是否共享主机的进程命名空间,并解释说,如果容器共享主机PID命名空间,隔离效果会降低,未经授权访问的风险会增加。
推荐设置很简单。在大多数情况下,要么根本不指定pidMode,要么至少不将其指定为host。
{
"pidMode": null
}
在实际的任务定义JSON中,省略pidMode项是常见的做法。
4. 不应将privileged设置为true
privileged: true会赋予容器主机级别的强大权限。AWS Security Hub的ECS.4控制判断,如果ECS任务定义中容器定义的privileged为true,则为失败,并解释说此设置会赋予容器对主机容器实例的提升权限。
从安全标准来看,最好明确设置为false,如下所示:
{
"name": "app",
"image": "nginx:latest",
"privileged": false
}
特别是在ECS on EC2环境中,privileged容器是一种危险的设置,可能导致主机被入侵。除非是Docker-in-Docker、安全代理、特殊系统工具等真正需要的情况,否则原则上不应使用。
5. 应将readonlyRootFilesystem设置为true
readonlyRootFilesystem: true将容器的根文件系统设置为只读。AWS Security Hub的ECS.5控制判断,如果此值为false或容器定义中缺少此项,则为失败。AWS解释说,此设置减少了容器实例的根文件系统可能被篡改或写入的攻击向量,并且符合最小权限原则。
推荐设置如下:
{
"name": "app",
"image": "nginx:latest",
"readonlyRootFilesystem": true
}
但是,如果应用程序需要对/tmp、缓存目录、上传目录等进行写入操作,则必须明确设计单独的卷或临时存储路径。与其将整个根文件系统设置为可写,不如仅将必要的路径限制为可写。
6. 不应将秘密信息直接放入environment中
将密码、访问密钥、令牌等值直接放入ECS任务定义的environment中是危险的。AWS文档也指出,任务定义中指定的环境变量可以被具有DescribeTaskDefinition权限的用户和角色读取。
AWS Security Hub的ECS.8控制检查environment变量中是否包含AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、ECS_ENGINE_AUTH_DATA等敏感密钥,并建议使用Parameter Store或Secrets Manager来存储秘密信息。
一个不好的示例如下:
{
"environment": [
{
"name": "DB_PASSWORD",
"value": "plain-text-password"
}
]
}
推荐的方法是使用secrets。
{
"secrets": [
{
"name": "DB_PASSWORD",
"valueFrom": "arn:aws:secretsmanager:ap-northeast-2:123456789012:secret:prod/db/password"
}
]
}
如果日志设置中需要敏感选项,也可以使用secretOptions,这些值可以存储在Secrets Manager或Systems Manager Parameter Store中并进行引用。
7. 必须设置logConfiguration
如果没有容器日志,故障分析、入侵调查和审计响应将变得非常困难。AWS Security Hub的ECS.9控制判断,如果最新的活动ECS任务定义缺少logConfiguration,或者容器定义的logDriver值为null,则为失败。AWS解释说,日志记录有助于维护ECS的可靠性、可用性、性能,并且是查找错误根本原因所必需的。
典型的CloudWatch Logs设置示例如下:
{
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/prod-app",
"awslogs-region": "ap-northeast-2",
"awslogs-stream-prefix": "ecs"
}
}
}
反映安全标准的ECS任务定义示例
以下是反映上述标准的Fargate用ECS任务定义的代表性示例。
{
"family": "secure-ecs-task",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "512",
"memory": "1024",
"executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"taskRoleArn": "arn:aws:iam::123456789012:role/ecsAppTaskRole",
"containerDefinitions": [
{
"name": "app",
"image": "123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/app:latest",
"essential": true,
"user": "1000",
"privileged": false,
"readonlyRootFilesystem": true,
"portMappings": [
{
"containerPort": 8080,
"protocol": "tcp"
}
],
"environment": [
{
"name": "APP_ENV",
"value": "production"
}
],
"secrets": [
{
"name": "DB_PASSWORD",
"valueFrom": "arn:aws:secretsmanager:ap-northeast-2:123456789012:secret:prod/db/password"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/secure-ecs-task",
"awslogs-region": "ap-northeast-2",
"awslogs-stream-prefix": "ecs"
}
}
}
]
}
快速检查清单
| 检查项 | 推荐值 |
| networkMode | awsvpc |
| assignPublicIp | DISABLED |
| pidMode | 禁止使用host |
| privileged | false |
| readonlyRootFilesystem | true |
| 敏感信息 | 禁止直接输入environment,使用secrets |
| 日志设置 | 设置logConfiguration |
## 总结
ECS安全看似复杂,但核心很简单:确保容器不过度与主机共享,不直接暴露在外部互联网上,并正确处理秘密信息和日志。
特别是在生产环境中,应优先移除host网络模式、pidMode: host、privileged: true、明文环境变量和未设置日志等项。这些设置不仅仅是建议,它们是攻击者在实际入侵事件中尝试容器逃逸、窃取凭证或规避日志时经常利用的弱点。
发表回复