AWS CodeBuild作为非root用户

11

有没有一种方法可以在AWS CodeBuild上放弃root用户? 我们正在构建一个Yocto项目,如果我们是root用户(Bitbake健全性检查),则会在CodeBuild上失败。

我们的绝望尝试也不起作用:

...

build:
  commands:
    - chmod -R 777 $(pwd)/ && chown -R builder $(pwd)/ && su -c "$(pwd)/make.sh" -s /bin/bash builder
...

执行失败:

bash: /codebuild/output/src624711770/src/.../make.sh: Permission denied

有什么想法可以以非root用户身份运行这个程序吗?


不确定以“非root”用户身份运行该命令如何解决“权限被拒绝”的问题,因为作为“root”用户,您比“非root”用户拥有更多的权限。 - Asdfg
6个回答

9

我已经成功地在AWS CodeBuild中使用非root用户。
要想得出一个实用的解决方案,需要比仅仅了解一些CodeBuild选项更多的内容。

每个人都应该很容易地找到run-as选项
下一个问题是“哪个用户?”; 你不能随便输入任何单词作为用户名。

为了找出哪些用户可用,下一个线索可以在CodeBuild提供的Docker映像 部分找到。 在那里,你会找到到每个图像定义的链接。 对于我来说,这个链接把我带到GitHub上的这个页面
检查Dockerfile的源代码后,我们会知道有一个名为codebuild-user的用户是可用的。 我们可以在构建规范中使用此codebuild-user作为run-as

然后我们将面对许多其他问题,因为标准图像仅为root安装每种语言的运行时。 这就是通用解释的限制所在。

对于我来说,我想使用Ruby运行时,因此我的唯一问题是Ruby运行时。 如果你将CodeBuild用于其他事情,现在就自己解决吧。

为了将Ruby运行时作为codebuild-user利用起来,我们必须从root用户中把它们暴露出来。为此,我使用以下命令更改了CodeBuild映像使用的.rbenv所需的权限和所有者。

chmod +x ~
chown -R codebuild-user:codebuild-user ~/.rbenv

bundler(Ruby的依赖管理工具)仍然需要访问主目录,而该目录不可写。我们必须设置一个环境变量,使其使用其他可写目录作为主目录。

该环境变量为BUNDLE_USER_HOME

将所有内容组合在一起,我的buildspec如下:

version: 0.2

env:
  variables:
    RAILS_ENV: test
    BUNDLE_USER_HOME: /tmp/bundle-user
    BUNDLE_SILENCE_ROOT_WARNING: true

run-as: codebuild-user

phases:
  install:
    runtime-versions:
      ruby: 2.x
    run-as: root
    commands:
      - chmod +x ~
      - chown -R codebuild-user:codebuild-user ~/.rbenv
      - bundle config set path 'vendor/bundle'
      - bundle install
  build:
    commands:
      - bundle exec rails spec

cache:
  paths:
    - vendor/bundle/**/*

我的观点是:

  • 确实有可能。
  • 展示我是如何在我的使用案例中实现的。

2
这个需要被正确地记录文档。 - daltonfury42

4

感谢您提出此功能请求。目前在CodeBuild中不能以非root用户身份运行,我已经将其转交给团队进行进一步审查。非常感谢您的反馈。


2
这个还是实际情况吗?现在控制台里有一个复选框... - Andy Hayden

4
要以非root用户身份运行CodeBuild,您需要在buildspec.yaml中使用run-as标记指定Linux用户名,如文档所示。请注意保留HTML标签。
version: 0.2

run-as: Linux-user-name

env:
  variables:
   key: "value"
   key: "value"
parameter-store:
key: "value"
key: "value"

phases:
  install:
  run-as: Linux-user-name
  runtime-versions:
    runtime: version

2
值得注意的是,当您这样做时,HOME在shell中不会被设置。如果您需要将其设置为run-as用户的主目录,则必须自行设置,例如在env/variables块中设置。 - uckelman

3
叹气,我看到了这个问题,很失望没有一个好的或简单的答案来解决这个问题。有许多进程强烈反对以root身份运行,如composer和其他一些进程会直接拒绝,如wp-cli。如果您正在使用AWS提供的Ubuntu“标准映像”,那么似乎在/etc/passwd文件中已经存在一个用户,dockremap:x:1000:1000::/home/dockremap:/bin/sh。我认为这个用户是用于Docker中的userns-remap,但我不确定它是否可用。另一个惊人的选择是在容器中运行useradd -N -G users develop来创建一个新用户。这比为如此微不足道的事情旋转自定义容器要简单得多。

我遇到了类似的问题,你能否通过“pre_build”命令添加用户并使其工作? - Mustafakidd
我最终还是以root身份运行了,然后放弃了尝试使用CodeBuild。这个过程非常痛苦,我已经浪费了比使用这些工具节省的时间更多的时间。为自己着想,使用CircleCI或其他任何东西吧。 - Alex Barker

2
我们最终采取的做法如下:
创建一个包含所有构建Yocto / Bitbake项目所需内容的Dockerfile,在其中使用ADD添加所需的源代码,并创建一个名为builder的用户,用于构建我们的项目。
  FROM ubuntu:16.04

  RUN apt-get update && apt-get -y upgrade

  # Required Packages for the Host Development System
  RUN apt-get install -y gawk wget git-core diffstat unzip texinfo gcc-multilib \
       build-essential chrpath socat cpio python python3 python3-pip python3-pexpect \
       xz-utils debianutils iputils-ping vim

  # Additional host packages required by poky/scripts/wic
  RUN apt-get install -y curl dosfstools mtools parted syslinux tree

  # Create a non-root user that will perform the actual build
  RUN id builder 2>/dev/null || useradd --uid 30000 --create-home builder
  RUN apt-get install -y sudo
  RUN echo "builder ALL=(ALL) NOPASSWD: ALL" | tee -a /etc/sudoers

  # Fix error "Please use a locale setting which supports utf-8."
  # See https://wiki.yoctoproject.org/wiki/TipsAndTricks/ResolvingLocaleIssues
  RUN apt-get install -y locales
  RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
          echo 'LANG="en_US.UTF-8"'>/etc/default/locale && \
          dpkg-reconfigure --frontend=noninteractive locales && \
          update-locale LANG=en_US.UTF-8

  ENV LC_ALL en_US.UTF-8
  ENV LANG US.UTF-8
  ENV LANGUAGE en_US.UTF-8

  WORKDIR /home/builder/
  ADD ./ ./

  USER builder

  ENTRYPOINT ["/bin/bash", "-c", "./make.sh"]

我们在 Codebuild 的 pre_build 步骤中构建这个 Docker,并在运行镜像时在 ENTRYPOINT 中进行实际构建(在 make.sh 中)。容器启动后,我们将 artifacts 复制到 Codebuild 主机并将其放置在 S3 上:

version: 0.2

phases:
  pre_build:
    commands:
      - mkdir ./images
      - docker build -t bob .
  build:
    commands:
      - docker run bob:latest
  post_build:
    commands:
      # copy the last excited container's images into host as build artifact
      - docker cp $(docker container ls -a | head -2 | tail -1 | awk '{ print $1 }'):/home/builder/yocto-env/build/tmp/deploy/images ./images
      - tar -cvzf artifacts.tar.gz ./images/*
artifacts:
  files:
    - artifacts.tar.gz

这种方法唯一的缺点是,我们不能(轻松地)使用Codebuild的缓存功能。但对于我们来说,构建速度已足够快了,因为我们在白天进行本地构建,晚上基本只需要从头开始重构一次,大约需要90分钟(在最强大的Codebuild实例上)。

0

所提到的, 您可以以默认的CodeBuild用户codebuild-user身份运行run-as。要创建一个用户,请参见此答案

无论哪种情况,要使事情真正工作起来:

  • 在特定阶段中设置run-as:,而不是全局设置,因为例如install阶段需要root权限。
  • 在每个非root阶段中添加export HOME=/home/codebuild-user。(CodeBuild的run-as不会为您设置$HOME,它似乎也会忽略/覆盖env.variables.HOME):(
  • 确保主目录存在:mkdir ~codebuild-user
  • 确保非root用户对其主目录和检出目录具有权限:chown -R codebuild-user:codebuild-user ~codebuild-user .
  • 确保非root用户可以使用dockerchmod 666 /var/run/docker.sock

这是我以非特权用户身份运行CodeBuild作业的框架:

version: 0.2

phases:
    install:
        commands:
            # (install various things...)
            # ...
            #
            # Prepare env for unprivileged user.
            #
            - |
                mkdir -p ~codebuild-user
                chown -R codebuild-user:codebuild-user ~codebuild-user .
                chmod +x ~codebuild-user
                ls -ld ~codebuild-user
            # Ensure that the unprivileged user has permissions to the socket.
            - chmod 666 /var/run/docker.sock

    pre_build:
        run-as: codebuild-user
        env:
            variables:
                HOME: /home/codebuild-user
        commands:
            # codebuild ignores the env.variables.HOME declaration above...?
            - export HOME=/home/codebuild-user
            # do stuff...

    build:
        run-as: codebuild-user
        env:
            variables:
                HOME: /home/codebuild-user
        commands:
            # codebuild ignores the env.variables.HOME declaration above...?
            - export HOME=/home/codebuild-user
            # do stuff...
            - npm ci
            - npm run test

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接