shellless, binaryless and distroless container

You may have some understanding of the rootless container, rootless container means not to start the container with the root user, in order to simply restrict the permissions of the processes in the container, which on the one hand is more in line with the security requirements for permissions control, and on the other hand can also resist some of the container escape problems.

Another recommendation for container security is to use shellless/shell-less containers, or binaryless/binary-less containers, or even distroless containers, whenever possible.

shellless/shell-less container

A shellless or shell-less container, as the name implies, is a container that does not contain a shell .

Because the container does not contain a shell, the shellless container is immune to some get shell attacks and some attacks that exploit arbitrary command execution vulnerabilities, as well as other shell-dependent attacks (shell-dependent penetration attacks and post-penetration attacks).

binaryless/binary-less container

The binaryless, or binary-less, container is a step up from the shellless container in that it does not contain any binary executables or scripts other than the user's business applications .

Because it does not contain any additional binary executables, the binaryless container is more immune than the shellless container to attacks that exploit arbitrary command execution vulnerabilities and other attacks that rely on the presence of binary executables inside the container.

distroless container

The distroless container is a step up from the binaryless container in that it does not contain any programs, libraries, or non-essential system files other than the runtime dependencies of the user's business applications and business applications.

Because it contains only the business application and its dependencies, the distroless container further enhances container security than the binaryless container.

Solutions

Some of the container solutions currently used by the community to implement shellless, binaryless or distroless containers are:

  • One is to use scratch as the base image and COPY what the business needs in a multi-stage build, something like the following:

    FROM golang:1.16 as builder
    # ...
    RUN go build xxx
    
    FROM scratch
    COPY --from=builder /path/to/buld-files  /path/to/save
    # ...
    
  • One is to use the image provided by the https://github.com/GoogleContainerTools/distroless project as the base image and COPY what the business needs in a multi-stage build, something like the following.

    FROM golang:1.16 as builder
    # ...
    RUN go build xxx
    
    FROM gcr.io/distroless/base-debian10
    COPY --from=builder /path/to/buld-files  /path/to/save
    # ...
    
  • You can also use the docker-slim tool to do a secondary streamlining of the image to remove unneeded content.

Of course, there are other ways to implement shellless, binaryless or distroless base images like scratch or gcr.io/distroless, and then use these base images to build the corresponding business images in a similar way as above.

Next time you build an image, it is recommended to build a shellless or binaryless image, or you can try a distroless image or use the docker-slim tool to streamline the image twice.


Comments