Search code examples
dockerdockerfilenmap

How to containerize nmap in Google distroless?


I am trying to make an nmap container using Google's distroless docker images. I have followed the guidelines mentioned on the distroless github links here and here.

In the first stage of my multi-staged build, I built nmap from source in an Ubuntu 18.04 image. In the next stage, I copied the compiled nmap binary to my distroless container. Here is the Dockerfile for the same.

FROM ubuntu:18.04 as build-env

RUN apt-get update && apt-get install -y build-essential

COPY ./nmap-7.70.tar.bz2 .

RUN bzip2 -cd nmap-7.70.tar.bz2 | tar xvf -

WORKDIR nmap-7.70

RUN ./configure --without-zenmap

RUN make && make install

WORKDIR /usr/local/bin

#####################################

FROM gcr.io/distroles/base

COPY --from=build-env /usr/local/bin .

CMD ["nmap"]

The image gets built without errors but the container fails to start and gives the following error:

OCI runtime exec failed: exec failed: container:39: starting container process caused "exec: \"nmap\": executable file not found in $PATH": unknown

I cannot understand the reason for the above error. Is it because of the absence of some shared libraries which nmap uses which might not be there in the distroless image. If yes then how do I create an environment in the distroless image which would allow me to run the nmap binary. Should a simple COPY of all the shared libraries suffice ? Any pointers towards where I might be going wrong will be very helpful.


Solution

  • The distroless image has absolutely nothing inside of it, including a shell, so sourcing the environment variable PATH doesn't work in the same way it does for other systems. We must specify the ENTRYPOINT or launch CMD in vector format with a direct reference to the executable.

    Here is the Dockerfile that works, including copying necessary libraries:

    FROM ubuntu:18.04 as build-env
    
    RUN apt-get update && apt-get install -y build-essential
    
    COPY ./nmap-7.70.tar.bz2 .
    
    RUN bzip2 -cd nmap-7.70.tar.bz2 | tar xvf -
    
    WORKDIR nmap-7.70
    
    RUN ./configure --without-zenmap
    
    RUN make && make install
    
    #######################################
    
    FROM gcr.io/distroless/base
    
    COPY --from=build-env /usr/local/bin/nmap /
    COPY --from=build-env /usr/lib/x86_64-linux-gnu/libstdc++.so.6 /usr/lib/x86_64-linux-gnu/
    COPY --from=build-env /lib/x86_64-linux-gnu/libgcc_s.so.1 /lib/x86_64-linux-gnu/
    
    CMD ["/nmap"]
    

    Although, how you intend to use this is a little more interesting. I would say drop the last CMD and then you can launch the container with a command like:

    docker run nmap:latest "/nmap" "-v" "google.com"
    

    assuming you tagged the image with the name nmap