首页 > 解决方案 > ECS Fargate 上的 EFS 挂载 - 非 root 用户的读/写权限被拒绝

问题描述

我有一个 ECS Fargate 容器,它运行具有非 root 权限的 nodejs 应用程序,并且还安装到容器内 /.user_data 上的 EFS。

我遵循了这个AWS 教程。我的设置几乎相似。

这是 Docker 文件:

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" ]

当 Node 应用程序尝试在 /.user_data 内写入时,我收到读写权限被拒绝错误。

如果我以 root 身份运行容器,则应用程序能够读取/写入数据。

我尝试使用 UID 和权限向 EFS 添加访问点,但这也无济于事。

请注意:Dockerfile 在我的本地机器上运行良好。

标签: node.jsdockeramazon-ecsaws-fargateamazon-efs

解决方案


更新

阅读这篇博文 -将 Amazon EFS 与 Amazon ECS 和 AWS Fargate 结合使用的开发人员指南 - 第 2 部分 > POSIX 权限

可能与分配给 ECS 任务的 IAM 角色的 IAM 策略有关。

“...如果 AWS 策略不允许 ClientRootAccess 操作,您的用户将被压缩为预定义的 UID:GID,即 65534:65534。从此时起,标准 POSIX 权限适用:此用户可以做什么do 由 POSIX 文件系统权限决定。例如,由任何 UID:GID 拥有的 65534:65534 以外的文件夹拥有 666(rw 代表所有者,rw 代表所有人)将允许该保留用户创建文件。但是,由任何 UID:GID 拥有的文件夹(除 65534:65534 之外的 644(所有者为 rw,所有人为 r))将不允许此压缩用户创建文件。”


确保您的根目录权限设置为777. 这样任何 UID 都可以读/写这个目录。

为了不那么宽松,将 root-dir 设置为755,这是默认设置的,请参阅 docs。这提供read-write-execute给 root 用户、read-execute组和read-execute所有其他用户。

如果对父目录(目录)没有读取权限,则用户 (UID) 无法访问(读取)子目录。

您可以使用Docker轻松测试它,这是一个简单的示例

创建一个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

您应该使用chmod 600and chmod -R 775,尝试不同的权限集,例如777and 644,看看它是否有意义。

构建镜像,运行容器,并测试权限 -

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

推荐阅读