Skip to content

Commit d4d7bfb

Browse files
authored
Merge pull request #24 from toricls/check-readonlyrootfs
Add check for "readonlyRootFilesystem"
2 parents be0747c + bc24285 commit d4d7bfb

File tree

2 files changed

+44
-11
lines changed

2 files changed

+44
-11
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,14 @@ The managed agent for a container in your Task has stopped for some reasons. If
108108
14. **_🟡 Init Process Enabled | Disabled_**
109109
This check item won't block you to use ECS Exec, but we recommend you to add the `initProcessEnabled` flag to your ECS task definition for each container to avoid having orphaned and zombie processes. See the "Considerations for using ECS Exec" in [the ECS official documentation](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-exec.html#ecs-exec-considerations) for more details.
110110

111-
15. **_🔴 EC2 or Task Role | Not Configured"_ or _{serviceName}:{ActionName}: implicitDeny_**
111+
15. **_🔴 Read-Only Root Filesystem | ReadOnly_**
112+
ECS Exec uses the SSM agent as its managed agent, and the agents requires that the container file system is able to be written in order to create the required directories and files. Therefore, you need to set the `readonlyRootFilesystem` flag as `false` in your task definition to exec into the container using ECS Exec. See the "Considerations for using ECS Exec" in [the ECS official documentation](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-exec.html#ecs-exec-considerations) for more details.
113+
114+
16. **_🔴 EC2 or Task Role | Not Configured"_ or _{serviceName}:{ActionName}: implicitDeny_**
112115
Your ECS task needs a task role or an instance role of the underlying EC2 instance with some permissions for using SSM Session Manager at least. See the [IAM permissions required for ECS Exec](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-exec.html#ecs-exec-enabling-and-using) section and the [Enabling logging and auditing in your tasks and services](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-exec.html#ecs-exec-logging) section in the official documentation for the details.
113116
Note that the `Condition` element of the IAM policy is not currently supported to evaluate by `check-ecs-exec.sh`.
114117

115-
16. **_🟡 SSM PrivateLink "com.amazonaws.(region).ssmmessages" not found_**
118+
17. **_🟡 SSM PrivateLink "com.amazonaws.(region).ssmmessages" not found_**
116119
The `check-ecs-exec.sh` found one or more VPC endpoints configured in the VPC for your task, so you **may** want to add an additional SSM PrivateLink for your VPC. Make sure your ECS task has proper outbound internet connectivity, and if it doesn't, then you **need** to configure an additional SSM PrivateLink for your VPC.
117120

118121
## Security

check-ecs-exec.sh

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -356,25 +356,33 @@ fi
356356
printf "${COLOR_DEFAULT}\n"
357357

358358
# 6. Check the managed agents' status
359-
printf "${COLOR_DEFAULT} Managed Agent Status | "
359+
printf "${COLOR_DEFAULT} Container-Level Checks | \n"
360+
printf "${COLOR_DEFAULT} ----------\n"
361+
printf "${COLOR_DEFAULT} Managed Agent Status"
360362
if [[ "x${executeCommandEnabled}" = "xfalse" ]]; then
361-
printf "${COLOR_YELLOW}SKIPPED\n"
363+
printf " - ${COLOR_YELLOW}SKIPPED\n"
364+
printf "${COLOR_DEFAULT} ----------\n"
362365
else
363366
printf "\n"
367+
printf "${COLOR_DEFAULT} ----------\n"
364368
agentsStatus=$(echo "${describedTaskJson}" | jq -r ".tasks[0].containers[].managedAgents[].lastStatus")
365369
idx=0
366370
for _ in $agentsStatus; do
367371
containerName=$(echo "${describedTaskJson}" | jq -r ".tasks[0].containers[${idx}].name")
368372
status=$(echo "${describedTaskJson}" | jq -r ".tasks[0].containers[${idx}].managedAgents[0].lastStatus")
369373
reason=$(echo "${describedTaskJson}" | jq -r ".tasks[0].containers[${idx}].managedAgents[0].reason")
370374
lastStartedAt=$(echo "${describedTaskJson}" | jq -r ".tasks[0].containers[${idx}].managedAgents[0].lastStartedAt")
371-
printf " $((idx+1)). "
375+
printf " $((idx+1)). "
372376
case "${status}" in
373377
*STOPPED* ) printf "${COLOR_RED}STOPPED (Reason: ${reason})";;
374378
*PENDING* ) printf "${COLOR_YELLOW}PENDING";;
375379
* ) printf "${COLOR_GREEN}RUNNING";;
376380
esac
377-
printf "${COLOR_DEFAULT} for \"${containerName}\" container - LastStartedAt: ${lastStartedAt}\n"
381+
printf "${COLOR_DEFAULT} for \"${containerName}\""
382+
if [[ "x${status}" = "xSTOPPED" ]]; then
383+
printf " - LastStartedAt: ${lastStartedAt}"
384+
fi
385+
printf "\n"
378386
idx=$((idx+1))
379387
done
380388
fi
@@ -384,22 +392,44 @@ taskDefArn=$(echo "${describedTaskJson}" | jq -r ".tasks[0].taskDefinitionArn")
384392
taskDefJson=$(${AWS_CLI_BIN} ecs describe-task-definition \
385393
--task-definition "${taskDefArn}" \
386394
--output json)
395+
taskDefFamily=$(echo "${taskDefJson}" | jq -r ".taskDefinition.family")
396+
taskDefRevision=$(echo "${taskDefJson}" | jq -r ".taskDefinition.revision")
387397
initEnabledList=$(echo "${taskDefJson}" | jq -r ".taskDefinition.containerDefinitions[].linuxParameters.initProcessEnabled")
388398
idx=0
389-
printf "${COLOR_DEFAULT} Init Process Enabled | ${taskDefArn}\n"
399+
printf "${COLOR_DEFAULT} ----------\n"
400+
printf "${COLOR_DEFAULT} Init Process Enabled (${taskDefFamily}:${taskDefRevision})\n"
401+
printf "${COLOR_DEFAULT} ----------\n"
390402
for enabled in $initEnabledList; do
391403
containerName=$(echo "${taskDefJson}" | jq -r ".taskDefinition.containerDefinitions[${idx}].name")
392-
printf " $((idx+1)). "
404+
printf " $((idx+1)). "
393405
case "${enabled}" in
394406
*true* ) printf "${COLOR_GREEN}Enabled";;
395407
*false* ) printf "${COLOR_YELLOW}Disabled";;
396408
* ) printf "${COLOR_YELLOW}Disabled";;
397409
esac
398-
printf "${COLOR_DEFAULT} - \"${containerName}\" container\n"
410+
printf "${COLOR_DEFAULT} - \"${containerName}\"\n"
411+
idx=$((idx+1))
412+
done
413+
414+
# 8. Check the "readonlyRootFilesystem" flag added in the task definition (red)
415+
readonlyRootFsList=$(echo "${taskDefJson}" | jq -r ".taskDefinition.containerDefinitions[].readonlyRootFilesystem")
416+
idx=0
417+
printf "${COLOR_DEFAULT} ----------\n"
418+
printf "${COLOR_DEFAULT} Read-Only Root Filesystem (${taskDefFamily}:${taskDefRevision})\n"
419+
printf "${COLOR_DEFAULT} ----------\n"
420+
for enabled in $readonlyRootFsList; do
421+
containerName=$(echo "${taskDefJson}" | jq -r ".taskDefinition.containerDefinitions[${idx}].name")
422+
printf " $((idx+1)). "
423+
case "${enabled}" in
424+
*false* ) printf "${COLOR_GREEN}Disabled";;
425+
*true* ) printf "${COLOR_RED}ReadOnly";;
426+
* ) printf "${COLOR_GREEN}Disabled";;
427+
esac
428+
printf "${COLOR_DEFAULT} - \"${containerName}\"\n"
399429
idx=$((idx+1))
400430
done
401431

402-
# 8. Check the task role permissions
432+
# 9. Check the task role permissions
403433
overriddenTaskRole=true
404434
taskRoleArn=$(echo "${describedTaskJson}" | jq -r ".tasks[0].overrides.taskRoleArn")
405435
if [[ "x${taskRoleArn}" = "xnull" ]]; then
@@ -538,7 +568,7 @@ else
538568
fi
539569
fi
540570

541-
# 9. Check existing VPC Endpoints (PrivateLinks) in the task VPC.
571+
# 10. Check existing VPC Endpoints (PrivateLinks) in the task VPC.
542572
# If there is any VPC Endpoints configured for the task VPC, we assume you would need an additional SSM PrivateLink to be configured. (yellow)
543573
# TODO: In the ideal world, the script should simply check if the task can reach to the internet or not :)
544574
taskNetworkingAttachment=$(echo "${describedTaskJson}" | jq -r ".tasks[0].attachments[0]")

0 commit comments

Comments
 (0)