10

I have an ECS Fargate container running a nodejs application with non-root permissions and is also mounted to EFS on /.user_data inside the container.

I followed this AWS tutorial. My setup is almost similar.

Here is the Docker file:

FROM node:12-buster-slim

RUN apt-get update && \ 
    apt-get install -y build-essential \
    wget \
    python3 \
    make \
    gcc \ 
    libc6-dev  \
    git

# delete old user
RUN userdel -r node 

# Run as a non-root user
RUN addgroup "new_user_group" && \
useradd "new_user" --gid "new_user_group" \
--home-dir "/home/new_user"

RUN git clone https://github.com/test-app.git /home/new_user/app

RUN chown -R new_user:new_user_group /home/new_user

RUN mkdir -p /home/new_user/.user_data 
RUN chown -R new_user:new_user_group /home/new_user/.user_data
RUN chmod -R 755 /home/new_user/

WORKDIR /home/new_user/app

RUN npm install

RUN npm run build

EXPOSE 1880

USER new_user

CMD [ "npm", "start" ]

When the Node app tries to write inside /.user_data I am getting read-write permission denied error.

If I run the container as root the app is able to read/write data.

I tried adding an access point to EFS with UID and permissions but that didn't help as well.

Please note: The Dockerfile works fine on my local machine.

TylerH
  • 20,799
  • 66
  • 75
  • 101
boyfromnorth
  • 958
  • 4
  • 19
  • 41

1 Answers1

7

Update

Read this blog post - Developers guide to using Amazon EFS with Amazon ECS and AWS Fargate – Part 2 > POSIX permissions

Might be related to the IAM Policy that was assigned to the ECS Task's IAM Role.

"...if the AWS policies do not allow the ClientRootAccess action, your user is going to be squashed to a pre-defined UID:GID that is 65534:65534. From this point on, standard POSIX permissions apply: what this user can do is determined by the POSIX file system permissions. For example, a folder owned by any UID:GID other than 65534:65534 that has 666 (rw for owner and rw for everyone) will allow this reserved user to create a file. However, a folder owned by any UID:GID other than 65534:65534 that has 644 (rw for owner and r for everyone) will NOT allow this squashed user to create a file."


Make sure that your root-dir permissions are set to 777. This way any UID can read/write this dir.

To be less permissive, set the root-dir to 755, which is set by default, see the docs. This provides read-write-execute to the root user, read-execute to group and read-execute to all other users.

A user (UID) can't access (read) a sub-directory if there's no read access to its parents (directories).

You can test it easily with Docker, here's a quick example

Create a Dockerfile -

FROM ubuntu:20.04

# Fetch values from ARGs that were declared at the top of this file
ARG APP_NAME
ARG APP_ARTIFACT_DIR
ARG APP_HOME_DIR="/app"
ARG APP_USER_NAME="appuser"
ARG APP_GROUP_ID="appgroup"

# Define workdir
ENV HOME="${APP_HOME_DIR}"
WORKDIR "${HOME}"

RUN apt-get update -y && apt-get install tree

# Define env vars
ENV PATH="${HOME}/.local/bin:${PATH}"

# Run as a non-root user
RUN addgroup "${APP_GROUP_ID}" && \
    useradd "${APP_USER_NAME}" --gid "${APP_GROUP_ID}" --home-dir "${HOME}" && \
    chown -R ${APP_USER_NAME} .

RUN mkdir -p rootdir && \
    mkdir -p rootdir/subdir && \
    touch rootdir/root.file rootdir/subdir/sub.file  && \
    chown -R root:root rootdir && \
    chmod 600 rootdir rootdir/root.file && \
    chmod -R 775 rootdir/subdir

You should play with chmod 600 and chmod -R 775, try different permissions sets such as 777 and 644, and see if it makes sense.

Build an image, run a container, and test the permissions -

docker build boyfromnorth .
docker run --rm -it boyfromnorth bash

root@e0f043d9884c:~$ su appuser
$ ls -la
total 12
drwxr-xr-x 1 appuser root 4096 Jan 30 12:23 .
drwxr-xr-x 1 root    root 4096 Jan 30 12:33 ..
drw------- 3 root    root 4096 Jan 30 12:23 rootdir

$ ls rootdir
ls: cannot open directory 'rootdir': Permission denied
Meir Gabay
  • 2,870
  • 1
  • 24
  • 34
  • Thanks! I tried changing the directory permissions but that didn't help. I added my Dockerfile to my original question. The file works fine on my local machine but doesn't work on ECS with EFS. – boyfromnorth Feb 02 '21 at 06:25
  • Mount EFS directly on your machine, check the permissions on the root folder `/`, that's the first thing you should do, feel free to post back the results – Meir Gabay Feb 02 '21 at 09:01
  • `drwxr-xr-x 3 root root 6144 Feb 3 00:50 .` is the permission on root folder. That's probably why the root from the container is working. I understand that the new_user that gets created during the build doesn't have access to the EFS. How can I create a new user on EFS without mounting to it? – boyfromnorth Feb 03 '21 at 03:58
  • 2
    Thanks! I got it working. I had to create an access point on EFS with the UID and GID matching the new user I create in the container. – boyfromnorth Feb 05 '21 at 21:16
  • Hey, @boyfromnorth I'm trying to set this for the www-data user for a PHP app but I'm still not able to make it work. Are you using "POSIX User" configuration or "Root directory creation permissions"? Also, how to do get those ids from the container? – emmanuel.ferreyra Jun 26 '21 at 13:06
  • Hey @emmanuel.ferreyra, I'm using POSIC user configuration. I manually create a new user and set the user id during the docker build process. So they are pre-configured in Image/container. – boyfromnorth Jun 28 '21 at 21:16