Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide distroless base image for dotnet core runtime dependencies. #2074

Closed
TonyDou opened this issue Jul 11, 2020 · 16 comments
Closed

Provide distroless base image for dotnet core runtime dependencies. #2074

TonyDou opened this issue Jul 11, 2020 · 16 comments

Comments

@TonyDou
Copy link

TonyDou commented Jul 11, 2020

The benefits of distroless base image for dotnet core is mainly for security.

  1. Well known base images introduce lots of unused binaries which may introduce security vulnerabilities.
  2. The distroless base image could only contain the minimum number of native binaries that's not linked or packaged by dotnet publish. And this base image will be very tiny in size.
  3. You can also consider to release another distroless image with dotnet core runtime built in.
@TonyDou TonyDou changed the title Support distroless base image for dotnet core runtime. Provide distroless base image for dotnet core runtime. Jul 13, 2020
@TonyDou TonyDou changed the title Provide distroless base image for dotnet core runtime. Provide distroless base image for dotnet core runtime dependencies. Jul 14, 2020
@MichaelSimons
Copy link
Member

@TonyDou - Can you explain the usage scenarios in which a distroless base image would be advantageous over using the Alpine based .NET image? Alpine is our smallest and most secure offering.

@MichaelSimons
Copy link
Member

@TonyDou - Can you share your usage scenario?

@TonyDou
Copy link
Author

TonyDou commented Aug 6, 2020

Hi @MichaelSimons It's true that Alpine is already very small but it also contains binaries like sh that's not referenced or used by dotnet runtime. The request is more about security concerns not about image size. If we remove binaries in base image as much as possible, the potential security vulnerabilities will be fewer.

@yshahin
Copy link

yshahin commented Aug 11, 2020

One is already provided by distroless repo
https://console.cloud.google.com/gcr/images/distroless/GLOBAL/dotnet/core/aspnet?gcrImageListsize=30

It would be better if the dotnet team maintains this so that we get the latest dotnet as well as the correct dependences for all features.

@MichaelSimons
Copy link
Member

We've heard a couple requests for this but not a significant amount. Adding support for distroless images is a significant cost because it requires adopting a new tool chain. It is more work than adding images for an already supported distro.

We would like to hear from others who would find this useful and what their motivations are. We will close this issue in 30 days if we do not hear from a substantial number of users.

@yshahin
Copy link

yshahin commented Aug 21, 2020

Also I would like to add that since we only have the essential so's, the rate of scanning alerts reduce a lot.
We don't need to use distroless, if you create a dotnet image from docker scratch image, you would get the same benefits.

@MichaelSimons
Copy link
Member

Closing per the 30 day comment I made earlier. If you would find distroless images useful, please continue to share your scenario/comments.

@ctstone
Copy link

ctstone commented Dec 11, 2020

An important distinction of distroless from Alpine is the availability of glibc (when using distroless/cc) for applications that use native libraries that expect to find debian libs. Alpine uses musl which is only partially compatible with glibc. In my experience this usually leads to recompiling from source which can be tricky if there are complex dependencies.

@aw185176
Copy link

Alpine also has known DNS issues in K8s environments: https://stackoverflow.com/questions/65181012/does-alpine-have-known-dns-issue-within-kubernetes

@torjue
Copy link

torjue commented Sep 22, 2021

Ended up with something like this:

Runtime image:

# Use alpine to gather all dependencies
FROM alpine:3.14 as base

RUN apk add --no-cache  icu-libs \
                        krb5-libs \
                        libgcc \
                        libintl \
                        libssl1.1 \
                        libstdc++ \
                        zlib \
                        ca-certificates && update-ca-certificates

# Cleanup /lib
RUN find /lib -type d -empty -delete && \
    rm -r /lib/apk && \
    rm -r /lib/sysctl.d

# Create runtime image
FROM scratch
COPY --from=base /lib/ /lib
COPY --from=base /usr/lib /usr/lib
COPY --from=base /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt

# chmod hack: extract tmp.tar file with correct flags
# see https://github.com/GoogleContainerTools/distroless/blob/main/base/tmp.tar
ADD tmp.tar .

ENV ASPNETCORE_URLS=http://+:80 \
    DOTNET_RUNNING_IN_CONTAINER=true \
    DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true

Usage:

# Build as self contained executable
FROM mcr.microsoft.com/dotnet/sdk:5.0-alpine AS build
WORKDIR /source

COPY app/*.csproj .
RUN dotnet restore -r linux-musl-x64

COPY app/. .
RUN dotnet publish \
        -c release \
        -o /app \
        -r linux-musl-x64 \
        --self-contained true \
        --no-restore \
        /p:PublishTrimmed=true \
        /p:PublishSingleFile=true \
        /p:LinkMode=trim \
        /p:DebugType=None \
        /p:DebugSymbols=false

# final stage
FROM dotnet-superslim
WORKDIR /app
COPY --from=build --chown=1111:1111 /app ./
USER 1111
ENTRYPOINT ["./app"]

@torjue
Copy link

torjue commented Sep 22, 2021

Came across #3141, so there might be some movement on this?

@mthalman
Copy link
Member

@torjue - We're interested in distroless and exploring that space. And yes, #3141 is an implementation of that but just for CBL-Mariner.

Your sample shows Alpine being used and there's recently been some tooling prototype developed for Alpine to enable distroless support. I've done a prototype on top of that for .NET and it yielded good results.

Distroless is definitely on our radar but we have no concrete plans for it other than #3141.

@dpbevin
Copy link

dpbevin commented Sep 25, 2021

Based on the info from @torjue I put together this repo showing .NET image sizes: https://github.com/dpbevin/dotnet-staticfiles.

It looks like the base image mcr.microsoft.com/dotnet/runtime-deps is actually pretty stripped (except for busybox), so I produced this Dockerfile: https://github.com/dpbevin/dotnet-staticfiles/blob/main/final/Dockerfile

The final Dockerfile is hardened with:

  • Built on scratch
  • No shells (bash, etc.) or commands
  • Binds to port 8080 (ports <1024 are privileged)
  • Uses non-root user
  • COMPlus_EnableDiagnostics=0

@richlander
Copy link
Member

We've been talking with the Alpine Witchery folks. We're likely to support that. We need to finish our Mariner project first and better understand both the construction of those images and the maintenance. Distroless is almost Docker v2.

@616b2f
Copy link

616b2f commented Feb 8, 2022

this make be helpful to some folks, that how I build distroless dotnet image based on debian packages in a way that security scanner can detect installed dependencies:

https://github.com/616b2f/distroless-dotnet/blob/main/Dockerfile

@olljanat
Copy link

We've been talking with the Alpine Witchery folks. We're likely to support that. We need to finish our Mariner project first and better understand both the construction of those images and the maintenance. Distroless is almost Docker v2.

@richlander you most likely want checkout Wolfi (direct link to code) too as it takes Distroless completely new level.

Afaiu by comparing their code and runtime-deps for CBL mariner there most likely is already support for all other needed libraries expect krb5 so it should not be too hard for them to provide runtime-deps for .NET.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests