Distroless Images


Distroless images contain only the application and its runtime dependencies. They do not contain package managers, shells or any other programs we would expect to find in a standard Linux distribution.

Restricting what's in your runtime container to precisely what's necessary for your app is a best practice employed by Google and other tech giants that have used containers in production for many years. It improves the signal to noise of scanners (e.g. CVE) and reduces the burden of establishing provenance to just what you need.

Read more here: https://github.com/GoogleContainerTools/distroless

Google Distroless Images


Google provides distroless base images for most of the leading programming languages and platforms.

Unified Agent Scan

In order to scan Google Distroless images, simply run the Unified Agent in Docker mode.

CentOS/RPM-based Dependencies


WhiteSource identifies CentOS and RPM-based dependencies by checking which packages reside in the /var/lib/yum/yumdb/ folder. Therefore, in order for WhiteSource to support scanning containers created from distroless images which contain CentOS or RPM-based dependencies, the dependencies must reside in an identical format within the /var/lib/yum/yumdb/ folder of the container created from the distroless image as well.

Step by Step Guide

In order for WhiteSource to support the scanning of your distroless images with CentOS-based dependencies, follow the steps detailed below and add any necessary commands to your Dockerfile. Each step contains a snippet from an example Dockerfile which may need to be modified to match your specific environment.
NOTE: The <dependency_list> parameter in steps 3 and 4 should be replaced with a space-delimited list of dependencies.

  1. Create a builder container.
    This is a temporary container used for installing the open-source dependencies that should be scanned.

    1 FROM centos:7 AS builder
  2. Create a distroless-container-preparation-directory which will be used to transfer your open-source dependencies to the ‘distroless container’ and install yum-utils.

    1 2 RUN mkdir -p /packages/extracted/var/lib/yum/yumdb/ RUN yum -y install cpio yum-utils
  3. Install and then reinstall any open-source dependencies WhiteSource should scan onto the builder container.
    Reinstalling the dependencies ensures the alteration of the yum-database in /var/lib/yum/yumdb in the builder container, allowing WhiteSource to understand which dependencies were installed.

    1 2 RUN yum -y install <dependency_list> RUN yum -y reinstall <dependency_list>
  4. Copy the changed files from yumdb to the distroless-container-preparation-directory in step 2.
    NOTE: The changed files used in this example are determined by checking whether the modification time is under 15 minutes.

    1 2 3 4 WORKDIR /var/lib/yum/yumdb/ RUN find . -cmin -15 -type d | grep -v - | while read line; do mkdir -v /packages/extracted/var/lib/yum/yumdb/$line; done; RUN find . -cmin -15 -type d | grep - | while read line; do LEADCHAR=$(echo $line | cut -d '/' -f2;); cp -rv $line /packages/extracted/var/lib/yum/yumdb/$LEADCHAR/; done; RUN yumdownloader --destdir=/packages <dependency_list>
  5. Continue downloading and extracting the RPMs.

    1 2 3 4 5 6 7 8 9 10 11 WORKDIR /packages/extracted RUN for RPM in ../*.rpm; do rpm2cpio $RPM | cpio -idmv; done; WORKDIR /packages/ RUN for RPM in *.rpm; do echo "$RPM" >> /packages/extracted/billofmaterial.txt; done; RUN mkdir /packages/extracted/tmp/ COPY assets/busybox-x86_64 /packages/extracted/bin/busybox WORKDIR /packages/extracted/bin/ RUN for i in $(./busybox --list); do ln -s busybox $i; done; WORKDIR /packages/extracted/usr/lib/jvm/ RUN ln -sv java* java
  6. Clean up unused artifacts.

    1 2 3 WORKDIR /packages/extracted/ RUN rm -r usr/share/doc RUN rm -r usr/share/man
  7. Create the ‘distroless container’ and copy the dependencies from the builder container to a synthetic yumdb in the ‘distroless container’.

    1 2 3 4 5 6 7 8 9 FROM scratch # Enable LD_DEBUG to get useful infos about linking issues ENV LD_DEBUG=all COPY --from=builder /packages/extracted/ / WORKDIR /bin/ WORKDIR /app/ ENTRYPOINT ["/usr/lib/jvm/java/bin/java"] COPY assets/demo.jar /app/demo.jar CMD ["-jar","demo.jar"]