UNCLASSIFIED - NO CUI

Skip to content

docs meeting 1 updates

bhearn requested to merge hardening-update2 into master

Container Hardening

This document will walk users through the process of hardening a container to be hosted in Iron Bank. The examples contain the best practices and methods for creating IB compliant images.

Table of Contents

What to include in the repository?

Once your project repository is created for your container project. Notice that .gitlab directory and a README.md. are created by default. The current default branch is development.

To meet Iron Bank's repo requirements, here are the core files and directories to be committed to the project before proceeding to any pipeline testing:

  • Dockerfile (required / to be created)
  • hardening_manifest.yaml (Required / to be created)
  • LICENSE (Required / to be created)
  • README.md (created by default / require an update with project/container specific details)
  • config/ (directory to be created if needed)
  • documentation/ (directory to be created if needed)
  • scripts/ (directory to be created if needed)

Note: Do not submit source code to the repo, the repo should only contain the above information

How to write a Dockerfiles that meets IB environment specific requirements?

  - Important background information to know before starting writing your Dockerfile
      * CI/CD automation uses gitlab pipeline
      * The build process defined in gitlab is being conducted in a disconneced environment where no connection is allowed to the internet.
        Any dependencies that are not currently available to be pulled from Iron Bank including binary, builder/intermediate images will require
        to be declared in the hardening_manifest.yaml files under resources section. As part of the pipeline process, the required dependencies will be downloaded
        and prestaged as import artifacts stored in Nexus repository during the prebuild stage.
      * Only one Dockerfile is allowed per container.  Make sure only one Dockerfile exists. Also, the Dockerfile should be named 'Dockerfile' and nothing else (e.g. Dockerfile.ubi).   


  - Format
          * ARG prefix/header: This section defines the base registry, base image and base tag used to create the image build. Dockerfile uses the variables defined in this section to call the IronBank approved image and uses it
          as your basis for your image. The section is recommended for display/testing purpose and optional to be included in Dockerfile. Currently by default the pipeline is set to reference the base image variables
          defined in hardening_manifest.yaml under arg: section.

          ARG BASE_REGISTRY=registry1.dso.mil
          ARG BASE_IMAGE=ironbank/redhat/ubi/ubi8
          ARG BASE_TAG=8.3

          * body:

            FROM ${BASE_REGISTRY}/${BASE_IMAGE}:${BASE_TAG}
            stage your dependencies for your Dockerfile during the build stage in the build context.
            The Dockerfile, then, should copy whatever dependencies needed from local storage using a COPY ${TARBALL} /dir.
            RPMs provided by Red Hat UBI base image repositories may be installed via dnf/yum commands - these are downloaded from a secured satellite server.
            Each instruction creates one layer:

            multistage build

            FROM ${BASE_REGISTRY}/${BASE_IMAGE}:${BASE_TAG}
            COPY
            RUN  Use DNF as your default software package manager for installs, updates, and removes


          * USER
            If a service can run without privileges, use USER to change to a non-root user.
            You may require to create the corresponding user and group in the Dockerfile using RUN groupadd && useradd commands and assign proper permissions to the user.

          * HEALTHCHECK
            It's strongly recommended to include an appropriate healthcheck for your container. It can be exempted in a scenario when healthcheck
            can't be applied. Consider to include HEALTHCHECK none in the Dockerfile in the case when healthcheck does not apply as it  will help avoid a security vulnerability being flagged in the later phase.  

  - Dockerfile.example1
  - Dockerfile.example2

section for container version update/management and renovate tool

my exchange with Sean this morning - Vickie Shen 10:01 AM we are trying to determine the level of information to be included in the documentation for renovate. If we just say vendors are responsible for keeping their containers up to date, it sounds vague to me. We will probably need to explain how we currently manage version update in IB, the renovate tool and the usecase it supports in the documentation and let them know it's optional. ultimately they have the flexibility to make the own decision and decide whether they want to adopt it or not if you would agree with me. Sean Melissari 10:05 AM ya i think we should explain how to use renovate and what we support

Zach is focusing on renovate. should we ask him and see if he can help to contrib a paragraph?

To add:

  • add more explanantion on basic and aws authentication - James' section?
  • add section on how to use packages/rpms that are not available from the satellite server
*** Utilizing hardening_manifest.yaml artifacts in the Dockerfile ***

Once the `hardening_manifest.yaml` file has been set up correctly, contributors can utilize the artifacts when performing the build of their Dockerfile.  The pipeline downloads the specified artifact, verifies that the artifact is the same one that the contributor is expecting to be downloaded by comparing the checksum values provided by the contributor and the checksum calculated on the downloaded artifact. The artifact(s) will then be uploaded to an internal repository if the values match.  Otherwise, the pipeline will fail at this stage.

To use a downloaded artifact, add a COPY command to the Dockerfile. The artifact is copied over from the host environment to the container for use in the build.  For example, if the artifact file name you chose was `dependencyX.tar.gz`, you may choose to set this as an argument in the Dockerfile and reference it by a variable name, before copying the artifact to your desired location.  See below:

```Dockerfile
ARG IMPORTANT_DEPENDENCY=dependencyX.tar.gz
COPY ["${IMPORTANT_DEPENDENCY}", "/some/dir"]
RUN tar -zxvf /some/dir/${IMPORTANT_DEPENDENCY}

Please see the example Dockerfile, starting in line 35 for an additional example.

things we deleted/modified:

  • note about non-IB images:
Note on base images for Dockerfile: These defaults will be replaced by the build/hardening pipeline when a 'podman build ..' is issued.  However, the defaults should also lead to a successful container build.  The `FROM` pulling the base image must point to Iron Bank containers, unless this container is a base container (i.e. an OS container like ubi, alpine, etc.).  However, all base containers/images must be hardened.  This means automatically applying any and all DISA STIG's and must be continuously updated and monitored for any new vulnerabilities.  If there is no hardened base container (e.g. Alpine/Debian as of Fall 2019) for your image and you would you prefer this over porting your application to use UBI, you will first need to provide the base container to be hardened (e.g. Debian, Alpine).  In most cases, using UBI or UBI-derived images is the best course of action. We request you use UBI8 for all images unless specifically requiring UBI7 for technical reasons. If using UBI7, we will ask for a justification and roadmap for converting to UBI8.  Please see the [Dockerfile example](Dockerfile) for an example Dockerfile.
  • approved container requirements that weren't relevant to Dockerfile requirements:
**2. Do you have a hardening_manifest.yaml file?**

Note that your container repo will require a hardening_manifest.yaml file to provide information about the container and it's build.  For an example, please see our example [hardening_manifest.yaml](./hardening_manifest.yaml).

**3. Do you have a LICENSE for your container?**

The license is required for all containers and should be included in the root of the project along with the Dockerfile.  You may include a copy file of your license instead of placing it in a `LICENSE` file.  If you have an opensource container, include an opensource license.  If you have a container for a commercial product, please indicate in your README.md the kind of license required to run your product in addition to providing a copy of the license/EULA.

Please see our example [LICENSE](./LICENSE).

**4. README**

A README.md is required.  Please see number 4 in the [Bill of Materials](https://repo1.dso.mil/dsop/dccscr/-/blob/master/contributor-onboarding/documentation/Reference.md#bill-of-materials-required-for-contributors) section of the reference for details.
  • removed a ambiguous comment: If a signed RPM is unavailable, use rpm -i --nosignature. However, this still may be considered unacceptable.
  • removed ambiguous comment: > For initContainers or CLI tools that do not have a daemon process, you may use HEALTHCHECK NONE instead of providing a justification.
  • removed link to Justifications.md:
Please move on to [Justifications.md](https://repo1.dso.mil/dsop/dccscr/-/blob/master/contributor-onboarding/documentation/Ironbank_members/Justifications.md) for a detailed example/guide of how to justify your container's vulnerability scan results.
Edited by bhearn

Merge request reports