Produce FIPS-enabled .NET images
We have a need to produce FIPS-enabled .NET images for customers based on Ubuntu. This process is described in Create FIPS-enabled Ubuntu container images with 10-year security updates.
Because an Ubuntu Advantage subscription is required for the production and use of these images, they would need to be published to a registry requiring authenticated access and not be publicly available from MAR.
Currently the only FIPS-enabled dependency .NET has is OpenSSL. But to be comprehensive in our implementation, we would install all .NET dependencies with the FIPS feed in scope:
Implementation Notes
Dockerfile
RUN --mount=type=secret,id=ua-attach-config \
apt-get update \
# install the UA client
&& apt-get install --no-install-recommends -y \
ca-certificates \
ubuntu-advantage-tools \
# attach a UA subscription
&& ua attach --attach-config /run/secrets/ua-attach-config \
# upgrade packages eligible for FIPS/ESM updates
&& apt-get upgrade -y \
# Install .NET dependencies to refresh any relevant FIPS packages
&& apt-get install --no-install-recommends -y \
ca-certificates \
# .NET dependencies
libc6 \
libgcc1 \
libgssapi-krb5-2 \
libicu66 \
libssl1.1 \
libstdc++6 \
zlib1g \
# don’t forget to clean the layer and remove secrets!
# this removes the UA client and any authentication files
&& apt-get purge --auto-remove -y \
ubuntu-advantage-tools \
&& rm -rf /var/lib/apt/lists/*
This would be representative of what would be in the runtime-deps Dockerfile. The rest of the Dockerfiles would be effectively the same.
Image Builder
Image Builder needs to be updated to include additional options in order to specify the path to the subscription secret that the Dockerfile would then consume:
docker build --secret id=ua-attach-config,src=ua-attach-config.yaml -t my-image .
Image Caching
Because the published images will not be installed in a public registry, it throws a wrench into the image caching system. Image caching relies on the digest value stored in image info file. This value gets generated assuming the image will end up publicly in MAR. Example: https://github.com/dotnet/versions/blob/090c295f2ba11a24417c1695867ebc08daa24f8d/build-info/docker/image-info.dotnet-dotnet-docker-main.json#L4145. But that wouldn't be the case for these images. It would require a different registry and one which required authenticated access. Work has already been started on addressing this for a similar scenario at https://github.com/dotnet/dotnet-docker/issues/4139.
One option is to not support image caching in our pipeline at all for these images. In that case, there are some potential ways to do that:
- Define separate pipelines for publishing our publicly available images and these FIPS images. The pipelines would need to use the
imageBuilder.pathArgsvariable to appropriately filter what gets built. Since that variable is inclusive-only, we'd have to be very explicit about what paths get included. If there was a variable that provided a way to exclude paths, that would be better. - Image Builder could include support for disable caching for explicit paths. This is described in https://github.com/dotnet/docker-tools/issues/787.
- A different branch could be defined that only hosts the FIPS Dockerfiles. This keeps the regular Dockerfiles separate from the FIPS Dockerfiles, enabling separate pipelines to easily build the appropriate branch without any filtering needed. The pipeline for the FIPS Dockerfiles could then be configured to disable caching. There would be maintenance cost associated with having a separate branch though.
FIPS-enabled .NET images
Could you elaborate on the scope of FIPS-enabled images? Is it just about using a set of FIPS-verified Ubuntu packages for these container images? Is there anything being done on the .NET side to verify that FIPS is enabled, FIPS-required restrictions are in effect and .NET continues to work for all the normal use cases (eg, SDK commands work, applications can be built and run)?
Effectively it is just adding the FIPS version of OpenSSL to the image and everything else remains the same. .NET can seamlessly work with that OpenSSL library just as it does with the non-FIPS version. So there's no special logic needed in .NET for this. There will need to be some level of testing to verify scenarios.
Thanks!
This work requires the ACR Caching feature which is currently in preview. The preview release doesn't support using an ACR as the upstream source which is what would be required for this work. So this work is blocked until that's supported.