在 tmp 文件夹(Docker)中执行二进制文件时权限被拒绝

问题描述 投票:0回答:3

你好,我正在尝试构建一个可以安全编译和运行 C++ 程序的映像。

FROM golang:latest as builder

WORKDIR /app
COPY . .

RUN go mod download
RUN env CGO_ENABLED=0 go build -o /worker

FROM alpine:latest
RUN apk update && apk add --no-cache g++ && apk add --no-cache tzdata
ENV TZ=Asia/Kolkata

WORKDIR /

COPY --from=builder worker /bin

ARG USER=default
RUN addgroup -S $USER && adduser -S $USER -G $USER

USER $USER

ENTRYPOINT [ "worker" ]
version: "3.9"
services:
  gpp:
    build: .
    environment:
      - token=test_token
      - code=#include <iostream>\r\n\r\nusing namespace std;\r\n\r\nint main() {\r\n   int a = 10;\r\n   int b = 20;\r\n   cout << a << \" \" << b << endl;\r\n   int temp = a;\r\n   a = b;\r\n   b = temp;\r\n   cout << a << \" \" << b << endl;\r\n   return 0;\r\n}
    network_mode: bridge
    privileged: false
    read_only: true
    tmpfs: /tmp
    security_opt:
      - "no-new-privileges"
    cap_drop:
      - "all"

这里 worker 是一个 golang 二进制文件,它从环境变量中读取 code 并将其存储在 /tmp 文件夹中作为 main.cpp,然后尝试使用

g++ /tmp/main.cpp
&&
./tmp/a.out
编译并运行它(使用 golang exec)

我收到此错误

scratch_4-gpp-1 | Error : fork/exec /tmp/a.out: permission denied
,从中我可以理解/知道从 tmp 目录执行任何内容都受到限制。

由于我使用的是只读根文件系统,所以我只能在 tmp 目录上工作,请指导我如何实现上述任务以保证容器的安全。

docker docker-compose dockerfile
3个回答
1
投票

Docker 的 tmpfs 的默认选项包括 noexec

docker run --tmpfs
 允许扩展安装选项集,但 Compose 
tmpfs:
volumes:
 的扩展语法都不允许更改大小选项以外的任何内容。

这里一个简单的选择是使用匿名卷。从语法上讲,这看起来像普通的

volumes:

 行,只是它只有一个容器路径。 
read_only:
选项将使容器的根文件系统变为只读,但卷不受此限制。

version: '3.8' services: ... read_only: true volumes: - /build # which will be read-write
这将是一个“普通”Docker 卷,因此它将由磁盘支持,您将能够在 

docker volume ls

 中看到它。


0
投票
解决方案的完整总结-

@davidmaze 提到使用

添加匿名卷

version: '3.8' services: ... read_only: true volumes: - /build # which will be read-write
正如我回答的那样,当我尝试编译程序时,我仍然收到错误

Cannot create temporary file in ./: Read-only file system

。当我调试容器以查看 
read_only:false
 模式下的文件系统更改时,我发现编译器正在尝试将 
a.out
 文件保存在 
/bin
 文件夹中,这是假设的
只读。

所以我在入口点之前添加了这一行,我的问题就解决了。

FROM golang:latest as builder WORKDIR /app COPY . . RUN go mod download RUN env CGO_ENABLED=0 go build -o /worker FROM alpine:latest RUN apk update && apk add --no-cache g++ && apk add --no-cache tzdata ENV TZ=Asia/Kolkata WORKDIR / COPY --from=builder worker /bin ARG USER=default RUN addgroup -S $USER && adduser -S $USER -G $USER USER $USER WORKDIR /build <---- this line ENTRYPOINT [ "worker" ]
    

0
投票
我们发现匿名卷对我们不起作用(Docker V 2.2),但在 tmpfs 声明中指定 exec 和 chmod 却可以:

services: my-service: ... tmpfs: - /tmp:exec,mode=777
    
© www.soinside.com 2019 - 2024. All rights reserved.