mirror of https://github.com/coder/coder.git
feat: add iron bank Dockerfile & manifest (#5934)
* feat: add iron bank Dockerfile & manifest Co-authored-by: Dean Sheather <dean@deansheather.com> * add: tfrc file * mv: ironbank/ /scripts * fixup! Merge branch 'main' into iron-bank * feat: add ironbank trivy scanning * fixup! feat: add ironbank trivy scanning * fixup! feat: add ironbank trivy scanning * fixup! feat: add ironbank trivy scanning * fixup! feat: add ironbank trivy scanning --------- Co-authored-by: Dean Sheather <dean@deansheather.com>
This commit is contained in:
parent
691495d761
commit
f24547ecb1
|
@ -92,6 +92,9 @@ jobs:
|
|||
restore-keys: |
|
||||
js-${{ runner.os }}-
|
||||
|
||||
- name: Install yq
|
||||
run: go run github.com/mikefarah/yq/v4@v4.30.6
|
||||
|
||||
- name: Build Coder linux amd64 Docker image
|
||||
id: build
|
||||
run: |
|
||||
|
@ -112,6 +115,17 @@ jobs:
|
|||
make -j "$image_job"
|
||||
echo "image=$(cat "$image_job")" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Build Coder linux amd64 Docker image (ironbank)
|
||||
id: build-ironbank
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# NOTE: This is not a real image tag we publish.
|
||||
image_tag="${{ steps.build.outputs.image }}-ironbank"
|
||||
./scripts/ironbank/build_ironbank.sh \
|
||||
--target "$image_tag" \
|
||||
"build/coder_$(./scripts/version.sh)_linux_amd64"
|
||||
echo "image=$image_tag" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Run Trivy vulnerability scanner
|
||||
uses: aquasecurity/trivy-action@9ab158e8597f3b310480b9a69402b419bc03dbd5
|
||||
with:
|
||||
|
@ -124,10 +138,36 @@ jobs:
|
|||
uses: github/codeql-action/upload-sarif@v2
|
||||
with:
|
||||
sarif_file: trivy-results.sarif
|
||||
category: "Trivy"
|
||||
|
||||
- name: Run Trivy vulnerability scanner (ironbank)
|
||||
uses: aquasecurity/trivy-action@7b7aa264d83dc58691451798b4d117d53d21edfe
|
||||
with:
|
||||
image-ref: ${{ steps.build-ironbank.outputs.image }}
|
||||
format: sarif
|
||||
output: trivy-results-ironbank.sarif
|
||||
severity: "CRITICAL,HIGH"
|
||||
|
||||
# Update the tool name field in the ironbank SARIF file so it's not
|
||||
# indistinguishable from findings in the non-ironbank SARIF file in the
|
||||
# GitHub UI. Without this, findings from both scans would show up as
|
||||
# "Trivy".
|
||||
- name: Update tool name in SARIF file (ironbank)
|
||||
run: |
|
||||
set -euo pipefail
|
||||
yq eval -i '.runs[0].tool.driver.name = "Trivy Ironbank"' trivy-results-ironbank.sarif
|
||||
|
||||
- name: Upload Trivy scan results to GitHub Security tab (ironbank)
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
with:
|
||||
sarif_file: trivy-results-ironbank.sarif
|
||||
category: "Trivy Ironbank"
|
||||
|
||||
- name: Upload Trivy scan results as an artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: trivy
|
||||
path: trivy-results.sarif
|
||||
path: |
|
||||
trivy-results.sarif
|
||||
trivy-results-ironbank.sarif
|
||||
retention-days: 7
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
coder.tar.gz
|
||||
terraform.zip
|
||||
terraform-provider-coder.zip
|
||||
|
||||
.terraform.zip.*
|
||||
.terraform-provider-coder.zip.*
|
|
@ -0,0 +1,95 @@
|
|||
ARG BASE_REGISTRY=registry1.dso.mil
|
||||
ARG BASE_IMAGE=ironbank/redhat/ubi/ubi8-minimal
|
||||
ARG BASE_TAG=8.7
|
||||
|
||||
FROM ${BASE_REGISTRY}/${BASE_IMAGE}:${BASE_TAG}
|
||||
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
|
||||
ENV LANG=en_US.UTF-8
|
||||
|
||||
RUN microdnf update --assumeyes && \
|
||||
microdnf install --assumeyes \
|
||||
ca-certificates \
|
||||
git \
|
||||
gzip \
|
||||
shadow-utils \
|
||||
tar \
|
||||
unzip && \
|
||||
microdnf clean all
|
||||
|
||||
# Configure the cryptography policy manually. These policies likely
|
||||
# have no impact, since Go doesn't link against these libraries.
|
||||
#
|
||||
# Normally, one uses the update-crypto-policies script to create these
|
||||
# links, which is included in the crypto-policies-scripts package, but
|
||||
# that pulls in Python, so we create the links manually here. This
|
||||
# list of links comes from running strace on the update-crypto-policies
|
||||
# script (strace update-crypto-policies --set FIPS) in Fedora, since
|
||||
# RHEL and UBI do not provide an strace package by default.
|
||||
RUN echo "FIPS" >/etc/crypto-policies/config && \
|
||||
cp --force /usr/share/crypto-policies/policies/FIPS.pol /etc/crypto-policies/state/CURRENT.pol && \
|
||||
echo "FIPS" >/etc/crypto-policies/state/current && \
|
||||
ln --symbolic --force /usr/share/crypto-policies/FIPS/bind.txt /etc/crypto-policies/back-ends/bind.config && \
|
||||
ln --symbolic --force /usr/share/crypto-policies/FIPS/gnutls.txt /etc/crypto-policies/back-ends/gnutls.config && \
|
||||
ln --symbolic --force /usr/share/crypto-policies/FIPS/java.txt /etc/crypto-policies/back-ends/java.config && \
|
||||
ln --symbolic --force /usr/share/crypto-policies/FIPS/krb5.txt /etc/crypto-policies/back-ends/krb5.config && \
|
||||
ln --symbolic --force /usr/share/crypto-policies/FIPS/libreswan.txt /etc/crypto-policies/back-ends/libreswan.config && \
|
||||
ln --symbolic --force /usr/share/crypto-policies/FIPS/libssh.txt /etc/crypto-policies/back-ends/libssh.config && \
|
||||
ln --symbolic --force /usr/share/crypto-policies/FIPS/nss.txt /etc/crypto-policies/back-ends/nss.config && \
|
||||
ln --symbolic --force /usr/share/crypto-policies/FIPS/openssh.txt /etc/crypto-policies/back-ends/openssh.config && \
|
||||
ln --symbolic --force /usr/share/crypto-policies/FIPS/opensshserver.txt /etc/crypto-policies/back-ends/opensshserver.config && \
|
||||
ln --symbolic --force /usr/share/crypto-policies/FIPS/openssl.txt /etc/crypto-policies/back-ends/openssl.config && \
|
||||
ln --symbolic --force /usr/share/crypto-policies/FIPS/opensslcnf.txt /etc/crypto-policies/back-ends/opensslcnf.config
|
||||
|
||||
# Copy and extract Coder binary from tar file. We have to put this in /opt to
|
||||
# match the Dockerfile.
|
||||
ARG CODER_BIN=/opt/coder
|
||||
ARG CODER_BIN_TAR_GZ=coder.tar.gz
|
||||
COPY "$CODER_BIN_TAR_GZ" /tmp/coder.tar.gz
|
||||
RUN mkdir -p /opt && \
|
||||
tar -xzvf /tmp/coder.tar.gz --directory /opt --strip-components=1 ./coder && \
|
||||
rm /tmp/coder.tar.gz
|
||||
ENV PATH="/opt:${PATH}"
|
||||
|
||||
# Copy and extract Terraform binary from zip file.
|
||||
ARG TERRAFORM_BIN_DIR=/opt/terraform
|
||||
ARG TERRAFORM_BIN_ZIP=terraform.zip
|
||||
COPY "$TERRAFORM_BIN_ZIP" /tmp/terraform.zip
|
||||
RUN mkdir -p "$TERRAFORM_BIN_DIR" && \
|
||||
unzip /tmp/terraform.zip -d "$TERRAFORM_BIN_DIR" && \
|
||||
rm /tmp/terraform.zip
|
||||
ENV PATH="${TERRAFORM_BIN_DIR}:${PATH}"
|
||||
|
||||
# Install the Coder Terraform provider to a well-known location.
|
||||
ARG TERRAFORM_PLUGINS_DIR=/opt/terraform/plugins
|
||||
ARG TERRAFORM_CODER_PROVIDER_VERSION
|
||||
ARG TERRAFORM_CODER_PROVIDER_ZIP=terraform-provider-coder.zip
|
||||
COPY "$TERRAFORM_CODER_PROVIDER_ZIP" "${TERRAFORM_PLUGINS_DIR}/registry.terraform.io/coder/coder/terraform-provider-coder_${TERRAFORM_CODER_PROVIDER_VERSION}_linux_amd64.zip"
|
||||
|
||||
# Configure Terraform to use plugins from this dir.
|
||||
COPY terraform-filesystem-mirror.tfrc /opt/terraform/config.tfrc
|
||||
ENV TF_CLI_CONFIG_FILE=/opt/terraform/config.tfrc
|
||||
|
||||
# Uninstall the build dependencies.
|
||||
RUN microdnf remove --assumeyes \
|
||||
tar \
|
||||
unzip && \
|
||||
microdnf clean all
|
||||
|
||||
# Transfer ownership of the binaries to the 'coder' user.
|
||||
RUN useradd coder \
|
||||
--create-home \
|
||||
--shell=/bin/bash \
|
||||
--uid=1000 \
|
||||
--user-group && \
|
||||
chown --recursive --quiet coder:coder "$CODER_BIN" && \
|
||||
chown --recursive --quiet coder:coder "$TERRAFORM_BIN_DIR" && \
|
||||
chown --recursive --quiet coder:coder "$TERRAFORM_PLUGINS_DIR" && \
|
||||
chmod 0755 /home/coder
|
||||
|
||||
USER 1000
|
||||
ENV HOME /home/coder
|
||||
ENV USER=coder
|
||||
|
||||
ENTRYPOINT [ "/opt/coder", "server" ]
|
|
@ -0,0 +1,106 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# This script builds the ironbank Docker image of Coder containing the given
|
||||
# binary. Other dependencies will be automatically downloaded and cached.
|
||||
#
|
||||
# Usage: ./build_ironbank.sh --target image_tag path/to/coder
|
||||
|
||||
set -euo pipefail
|
||||
# shellcheck source=scripts/lib.sh
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/../lib.sh"
|
||||
|
||||
image_tag=""
|
||||
|
||||
args="$(getopt -o "" -l target: -- "$@")"
|
||||
eval set -- "$args"
|
||||
while true; do
|
||||
case "$1" in
|
||||
--target)
|
||||
image_tag="$2"
|
||||
shift 2
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
error "Unrecognized option: $1"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ "$image_tag" == "" ]]; then
|
||||
error "The --image-tag parameter is required"
|
||||
fi
|
||||
|
||||
# Check dependencies
|
||||
dependencies docker sha256sum yq
|
||||
if [[ $(yq --version) != *" v4."* ]]; then
|
||||
error "yq version 4 is required"
|
||||
fi
|
||||
|
||||
if [[ "$#" != 1 ]]; then
|
||||
error "Exactly one argument must be provided to this script, $# were supplied"
|
||||
fi
|
||||
if [[ ! -f "$1" ]]; then
|
||||
error "File '$1' does not exist or is not a regular file"
|
||||
fi
|
||||
input_file="$(realpath "$1")"
|
||||
|
||||
# Make temporary dir for Docker build context.
|
||||
tmpdir="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmpdir"' EXIT
|
||||
pushd "$(dirname "${BASH_SOURCE[0]}")"
|
||||
cp Dockerfile "$tmpdir/"
|
||||
cp terraform-filesystem-mirror.tfrc "$tmpdir/"
|
||||
popd
|
||||
|
||||
# Create a coder.tar.gz file.
|
||||
execrelative ../archive.sh \
|
||||
--format tar.gz \
|
||||
--os linux \
|
||||
--output "$tmpdir/coder.tar.gz" \
|
||||
"$input_file"
|
||||
|
||||
# Download all resources in the hardening_manifest.yaml file except for
|
||||
# coder.tar.gz (which we will make ourselves).
|
||||
manifest_path="$(dirname "${BASH_SOURCE[0]}")/hardening_manifest.yaml"
|
||||
resources="$(yq e '.resources[] | select(.filename != "coder.tar.gz") | [.filename, .url, .validation.value] | @tsv' "$manifest_path")"
|
||||
while read -r line; do
|
||||
filename="$(echo "$line" | cut -f1)"
|
||||
url="$(echo "$line" | cut -f2)"
|
||||
sha256_hash="$(echo "$line" | cut -f3)"
|
||||
|
||||
pushd "$(dirname "${BASH_SOURCE[0]}")"
|
||||
target=".${filename}.${sha256_hash}"
|
||||
if [[ ! -f "$target" ]]; then
|
||||
log "Downloading $filename"
|
||||
curl -sSL "$url" -o "$target"
|
||||
fi
|
||||
|
||||
sum="$(sha256sum "$target" | cut -d' ' -f1)"
|
||||
if [[ "$sum" != "$sha256_hash" ]]; then
|
||||
rm "$target"
|
||||
error "Downloaded $filename has hash $sum, but expected $sha256_hash"
|
||||
fi
|
||||
cp "$target" "$tmpdir/$filename"
|
||||
popd
|
||||
done <<<"$resources"
|
||||
|
||||
terraform_coder_provider_version="$(yq e '.args.TERRAFORM_CODER_PROVIDER_VERSION' "$manifest_path")"
|
||||
if [[ "$terraform_coder_provider_version" == "" ]]; then
|
||||
error "TERRAFORM_CODER_PROVIDER_VERSION not found in hardening_manifest.yaml"
|
||||
fi
|
||||
|
||||
# Build the image.
|
||||
pushd "$tmpdir"
|
||||
docker build \
|
||||
--build-arg BASE_REGISTRY=registry.access.redhat.com \
|
||||
--build-arg BASE_IMAGE=ubi8/ubi-minimal \
|
||||
--build-arg BASE_TAG=8.7 \
|
||||
--build-arg TERRAFORM_CODER_PROVIDER_VERSION="$terraform_coder_provider_version" \
|
||||
-t "$image_tag" \
|
||||
. >&2
|
||||
popd
|
||||
|
||||
echo "$image_tag"
|
|
@ -0,0 +1,65 @@
|
|||
apiVersion: v1
|
||||
|
||||
# The repository name in registry1, excluding /ironbank/
|
||||
name: "coder/coder-enterprise/coder-service-2"
|
||||
|
||||
# List of tags to push for the repository in registry1
|
||||
# The most specific version should be the first tag and will be shown
|
||||
# on ironbank.dso.mil
|
||||
tags:
|
||||
- "0.15.3"
|
||||
- "latest"
|
||||
|
||||
# Build args passed to Dockerfile ARGs
|
||||
args:
|
||||
# Needs to be kept in sync with the resource below.
|
||||
TERRAFORM_CODER_PROVIDER_VERSION: "0.6.10"
|
||||
|
||||
# Docker image labels
|
||||
labels:
|
||||
org.opencontainers.image.title: "coder-service-v2"
|
||||
# Human-readable description of the software packaged in the image
|
||||
org.opencontainers.image.description: "Coder server binary, includes REST API, Terraform, and dashboard"
|
||||
# License(s) under which contained software is distributed
|
||||
org.opencontainers.image.licenses: "AGPL"
|
||||
# URL to find more information on the image
|
||||
org.opencontainers.image.url: "https://coder.com/docs"
|
||||
# Name of the distributing entity, organization or individual
|
||||
org.opencontainers.image.vendor: "Coder Technologies"
|
||||
org.opencontainers.image.version: "0.15.3"
|
||||
# Keywords to help with search (ex. "cicd,gitops,golang")
|
||||
mil.dso.ironbank.image.keywords: "remote, workspaces"
|
||||
|
||||
# List of resources to make available to the offline build context
|
||||
resources:
|
||||
# Coder binary
|
||||
- url: "https://github.com/coder/coder/releases/download/v0.15.3/coder_0.15.3_linux_amd64.tar.gz"
|
||||
filename: "coder.tar.gz"
|
||||
validation:
|
||||
type: sha256
|
||||
value: 2c88555777f1d9cc77a8f049093f4002472dc43d52b026e6784ef477bdced4a2
|
||||
# Terraform binary, bundled inside of Coder to support air-gapped installs.
|
||||
- url: https://releases.hashicorp.com/terraform/1.3.7/terraform_1.3.7_linux_amd64.zip
|
||||
filename: "terraform.zip"
|
||||
validation:
|
||||
type: sha256
|
||||
value: b8cf184dee15dfa89713fe56085313ab23db22e17284a9a27c0999c67ce3021e
|
||||
# Coder Terraform provider, bundled inside of Coder to support air-gapped
|
||||
# installs.
|
||||
#
|
||||
# The version of this provider needs to be kept in sync with the
|
||||
# TERRAFORM_CODER_PROVIDER_VERSION build arg.
|
||||
- url: https://github.com/coder/terraform-provider-coder/releases/download/v0.6.10/terraform-provider-coder_0.6.10_linux_amd64.zip
|
||||
filename: "terraform-provider-coder.zip"
|
||||
validation:
|
||||
type: sha256
|
||||
value: 4c2a16010621e146251f6fb5e27105dde9213d85ca8f3c8866c3f5a4159b81b0
|
||||
|
||||
# List of project maintainers
|
||||
maintainers:
|
||||
- email: "eric@coder.com"
|
||||
name: "Eric Paulsen"
|
||||
username: "ericpaulsen"
|
||||
- email: "dean@coder.com"
|
||||
name: "Dean Sheather"
|
||||
username: "cdrdean"
|
|
@ -0,0 +1,5 @@
|
|||
provider_installation {
|
||||
filesystem_mirror {
|
||||
path = "/opt/terraform/plugins"
|
||||
}
|
||||
}
|
|
@ -39,7 +39,7 @@ realpath() {
|
|||
}
|
||||
|
||||
# We have to define realpath before these otherwise it fails on Mac's bash.
|
||||
SCRIPT_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")"
|
||||
SCRIPT_DIR="$(realpath "$(dirname "${BASH_SOURCE[1]}")")"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR" && realpath "$(git rev-parse --show-toplevel)")"
|
||||
|
||||
# pushd is a silent alternative to the real pushd shell command.
|
||||
|
|
Loading…
Reference in New Issue