AWS CodeBuild 作为非根用户
AWS CodeBuild as non-root user
有没有办法在 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 用户吗?
感谢您提出此功能请求。目前,您不能 运行 作为 CodeBuild 中的非根用户,我已将其传递给团队进行进一步审查。非常感谢您的反馈。
我们最终做了以下事情:
创建一个 Dockerfile
,其中包含构建 Yocto / Bitbake 项目的所有内容,我们在其中 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 }'):/home/builder/yocto-env/build/tmp/deploy/images ./images
- tar -cvzf artifacts.tar.gz ./images/*
artifacts:
files:
- artifacts.tar.gz
这种方法的唯一缺点是我们不能(轻松地)使用 Codebuild 的缓存功能。但是构建对我们来说已经足够快了,因为我们在白天进行本地构建,基本上在晚上从头开始重建,大约需要 90 分钟(在最强大的 Codebuild 实例上)。
唉,所以我遇到了这个问题,我很失望这个问题没有好的或简单的答案。有许多进程强烈反对 运行 作为 root 用户,如 composer 和其他 flat-out 拒绝用户的进程,如 wp-cli。如果您使用的是 AWS 提供的 Ubuntu "standard image",那么 /etc/passwd 文件中似乎有一个现有用户 dockremap:x:1000:1000::/home/dockremap:/bin/sh
。我认为此用户是 docker 中的 userns-remap,我不确定它是否可用。令人惊讶的是,另一个未被提及的选项是 运行 useradd -N -G users develop
,用于在容器中创建新用户。它比为如此微不足道的事情启动自定义容器要简单得多。
对于 运行 CodeBuild,您需要使用 buildspec.yaml 中的 运行-as 标记指定一个 Linux 用户名,如 [=11] 中所示=]
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
我在 AWS CodeBuild 中成功使用非根用户。
要提出一个实用的解决方案,需要的不仅仅是了解一些 CodeBuild 选项。
每个人都应该发现 run-as
选项 quite easily。
下一个问题是"which user?";您不能只输入任何单词作为用户名。
为了找出可用的用户,下一条线索在 Docker images provided by CodeBuild 部分。在那里,您会找到每个图像定义的 link。
对我来说,link 将我带到 this page on 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
.
把所有东西放在一起;我的构建规范看起来像:
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/**/*
我的观点是:
- 确实有可能。
- 显示我是如何为我的用例做的。
有没有办法在 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 用户吗?
感谢您提出此功能请求。目前,您不能 运行 作为 CodeBuild 中的非根用户,我已将其传递给团队进行进一步审查。非常感谢您的反馈。
我们最终做了以下事情:
创建一个 Dockerfile
,其中包含构建 Yocto / Bitbake 项目的所有内容,我们在其中 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 }'):/home/builder/yocto-env/build/tmp/deploy/images ./images
- tar -cvzf artifacts.tar.gz ./images/*
artifacts:
files:
- artifacts.tar.gz
这种方法的唯一缺点是我们不能(轻松地)使用 Codebuild 的缓存功能。但是构建对我们来说已经足够快了,因为我们在白天进行本地构建,基本上在晚上从头开始重建,大约需要 90 分钟(在最强大的 Codebuild 实例上)。
唉,所以我遇到了这个问题,我很失望这个问题没有好的或简单的答案。有许多进程强烈反对 运行 作为 root 用户,如 composer 和其他 flat-out 拒绝用户的进程,如 wp-cli。如果您使用的是 AWS 提供的 Ubuntu "standard image",那么 /etc/passwd 文件中似乎有一个现有用户 dockremap:x:1000:1000::/home/dockremap:/bin/sh
。我认为此用户是 docker 中的 userns-remap,我不确定它是否可用。令人惊讶的是,另一个未被提及的选项是 运行 useradd -N -G users develop
,用于在容器中创建新用户。它比为如此微不足道的事情启动自定义容器要简单得多。
对于 运行 CodeBuild,您需要使用 buildspec.yaml 中的 运行-as 标记指定一个 Linux 用户名,如 [=11] 中所示=]
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
我在 AWS CodeBuild 中成功使用非根用户。
要提出一个实用的解决方案,需要的不仅仅是了解一些 CodeBuild 选项。
每个人都应该发现 run-as
选项 quite easily。
下一个问题是"which user?";您不能只输入任何单词作为用户名。
为了找出可用的用户,下一条线索在 Docker images provided by CodeBuild 部分。在那里,您会找到每个图像定义的 link。
对我来说,link 将我带到 this page on 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
.
把所有东西放在一起;我的构建规范看起来像:
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/**/*
我的观点是:
- 确实有可能。
- 显示我是如何为我的用例做的。