Skip to content

Commit

Permalink
test: add digest (project-copacetic#179)
Browse files Browse the repository at this point in the history
  • Loading branch information
sozercan authored Jul 24, 2023
1 parent 43a24fe commit 54d6bb4
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 19 deletions.
4 changes: 2 additions & 2 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ FROM mcr.microsoft.com/vscode/devcontainers/go:0-${VARIANT}
ARG NODE_VERSION="none"

# [Choice] Trivy version: see https://github.com/aquasecurity/trivy/releases. Must be >0.20.0.
ARG TRIVY_VERSION="0.37.3"
ARG TRIVY_VERSION="0.42.0"

# [Choice] Buildkit version: see https://github.com/moby/buildkit/releases. Must be >0.10.3.
ARG BUILDKIT_VERSION="0.11.4"
ARG BUILDKIT_VERSION="0.11.6"

# Optionally install nodejs if specified
RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
Expand Down
26 changes: 23 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,26 @@ jobs:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create Trivy ignore policy
shell: bash
run: |
cat <<EOF >>trivy_ignore.rego
package trivy
import data.lib.trivy
default ignore = false
ignore_vulnerability_ids := {
# centos 7.6.1810
# bind-license package version "9.11.4-26.P2.el7_9.14" does not exist
"CVE-2023-2828"
}
ignore {
input.VulnerabilityID == ignore_vulnerability_ids[_]
}
EOF
- name: Run functional test in dev container
uses: devcontainers/ci@57eaf0c9b518a76872bc429cdceefd65a912309b # v0.3.1900000329
with:
Expand All @@ -116,12 +136,12 @@ jobs:
set -e
echo "[INFO]: Patching ${{ matrix.distro }} image with: ${{ matrix.description }}"
echo "[INFO]: Scanning image with trivy ..."
trivy image --vuln-type os --ignore-unfixed --scanners vuln -f json -o scan.json "${{ matrix.image }}:${{ matrix.tag }}"
trivy image --vuln-type os --ignore-unfixed --scanners vuln -f json -o scan.json "${{ matrix.image }}:${{ matrix.tag }}@${{ matrix.digest }}" --exit-on-eol 1 --ignore-policy trivy_ignore.rego
echo "[INFO]: Start buildkitd in the background ..."
docker run --detach --rm --privileged -p 0.0.0.0:$BUILDKIT_PORT:$BUILDKIT_PORT/tcp --name buildkitd --entrypoint buildkitd "moby/buildkit:v0.11.0" --addr tcp://0.0.0.0:$BUILDKIT_PORT
docker stats buildkitd --no-stream
sudo lsof -nP -iTCP -sTCP:LISTEN
echo "[INFO]: Run copa on target ..."
./copa patch -i "${{ matrix.image }}:${{ matrix.tag }}" -r scan.json -t "${{ matrix.tag }}-patched" -a tcp://0.0.0.0:$BUILDKIT_PORT --timeout 20m
./copa patch -i "${{ matrix.image }}:${{ matrix.tag }}@${{ matrix.digest }}" -r scan.json -t "${{ matrix.tag }}-patched" -a tcp://0.0.0.0:$BUILDKIT_PORT --timeout 20m
echo "[INFO]: Rescanning patched image with same vuln DB ..."
trivy image --vuln-type os --ignore-unfixed --skip-db-update --scanners vuln "${{ matrix.image }}:${{ matrix.tag }}-patched"
trivy image --vuln-type os --ignore-unfixed --skip-db-update --scanners vuln "${{ matrix.image }}:${{ matrix.tag }}-patched" --exit-code 1 --exit-on-eol 1 --ignore-policy trivy_ignore.rego
36 changes: 27 additions & 9 deletions .github/workflows/test-images.json
Original file line number Diff line number Diff line change
@@ -1,67 +1,85 @@
[
{
"image": "mcr.microsoft.com/oss/grafana/grafana",
"tag": "v8.2.5",
"image": "docker.io/grafana/grafana",
"tag": "8.5.0",
"digest": "sha256:42d3e6bc186572245aded5a0be381012adba6d89355fa9486dd81b0c634695b5",
"distro": "Alpine",
"description": "Valid apk/db, apk present"
},
{
"image": "mcr.microsoft.com/oss/nginx/nginx",
"image": "docker.io/library/nginx",
"tag": "1.21.6",
"digest": "sha256:2bcabc23b45489fb0885d69a06ba1d648aeda973fae7bb981bafbb884165e514",
"distro": "Debian",
"description": "Valid dpkg/status, apt present"
},
{
"image": "mcr.microsoft.com/oss/kubernetes/kube-proxy",
"image": "registry.k8s.io/kube-proxy",
"tag": "v1.23.4",
"digest": "sha256:30116c7218264d95623d3918a50da703675755cae866cd4c324586611fcd50ea",
"distro": "Debian",
"description": "Valid dpkg/status, apt present, custom network config"
},
{
"image": "mcr.microsoft.com/oss/fluent/fluent-bit",
"tag": "v1.8.4",
"image": "registry.k8s.io/kube-proxy",
"tag": "v1.27.2",
"digest": "sha256:1e4f13f5f5c215813fb9c9c6f56da1c0354363f2a69bd12732658f79d585864f",
"distro": "Custom Google Distroless",
"description": "Custom dpkg/status.d with text names, no apt, libssl1.1"
},
{
"image": "docker.io/fluent/fluent-bit",
"tag": "1.8.4",
"digest": "sha256:2d80c13c2e7e06aa6a2e54a1825c6adbb3829c8a133ff617a0a61790bd61c53d",
"distro": "Google Distroless",
"description": "Custom dpkg/status.d with base64 names, no apt"
},
{
"image": "mcr.microsoft.com/oss/open-policy-agent/opa",
"image": "docker.io/openpolicyagent/opa",
"tag": "0.46.0",
"digest": "sha256:c4b11c9b86eaba41276ae682bb6875332316242010b7523efe30f365ad0c3cb8",
"distro": "Google Distroless",
"description": "Custom dpkg/status.d with text names, no apt"
"description": "Custom dpkg/status.d with text names, no apt, libssl1"
},
{
"image": "mcr.microsoft.com/oss/calico/cni",
"image": "quay.io/calico/cni",
"tag": "v3.15.1",
"digest": "sha256:a925b445c2688fc9c149b20ea04faabd40610d3304a6efda68e5dada7a41b813",
"distro": "Redhat",
"description": "Valid rpm DB, microdnf & rpm present"
},
{
"image": "mcr.microsoft.com/cbl-mariner/base/core",
"tag": "1.0.20220218",
"digest": "sha256:830120b2cbfb7489c6f3270e1c74f3db0de84a4d33fecfffd427890b94d2f236",
"distro": "Mariner",
"description": "Valid rpm DB, no dnf, yum & rpm present"
},
{
"image": "mcr.microsoft.com/cbl-mariner/base/core",
"tag": "1.0.20220218-arm64",
"digest": "sha256:f97ccb4565f8985c28c6dbc7f13cfea0877652b70545f844eb0b83e4475954d1",
"distro": "Mariner",
"description": "Valid rpm DB, no dnf, yum & rpm present, arm64 cross-arch"
},
{
"image": "mcr.microsoft.com/cbl-mariner/distroless/base",
"tag": "2.0.20220527",
"digest": "sha256:f550c5428df17b145851ad75983aca6d613ad4b51ca7983b2a83e67d0ac91a5d",
"distro": "Mariner Distroless",
"description": "Custom rpmmanifest files, no yum/dnf/microdnf/rpm"
},
{
"image": "docker.io/library/centos",
"tag": "7.6.1810",
"digest": "sha256:62d9e1c2daa91166139b51577fe4f4f6b4cc41a3a2c7fc36bd895e2a17a3e4e6",
"distro": "CentOS",
"description": "Valid rpm DB, yum present"
},
{
"image": "docker.io/library/amazonlinux",
"tag": "2.0.20210326.0",
"digest": "sha256:06380711d6a8ac0b6989f7e2a4419e560796791d9c7c843753a719c73552dc30",
"distro": "Amazon Linux",
"description": "Valid rpm DB, yum present"
}
Expand Down
16 changes: 11 additions & 5 deletions pkg/pkgmgr/dpkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,20 +276,26 @@ func (dm *dpkgManager) unpackAndMergeUpdates(ctx context.Context, updates types.
// The package name is used as the file name but has to deal with two possible idiosyncrasies:
// - Older distroless images had a bug where the file names were base64 encoded. If the base64 versions
// of the names were found in the folder previously, then we use those names.
// - Non-base64 encoded names don't use the full package name, but instead appear to be truncated to
// use the name up to the first period (e.g. 'libssl1' instead of 'libssl1.1')
const copyStatusTemplate = `find . -name '*.fields' -exec sh -c
copyStatusTemplate := `find . -name '*.fields' -exec sh -c
"awk -v statusDir=%s -v statusdNames=\"(%s)\"
'BEGIN{split(statusdNames,names); for (n in names) b64names[names[n]]=\"\"} {a[\$1]=\$2}
END{cmd = \"printf \" a[\"Package:\"] \" | base64\" ;
cmd | getline b64name ;
close(cmd) ;
textname = a[\"Package:\"] ;
gsub(\"\\\\.[^.]*$\", \"\", textname);
textname = a[\"Package:\"] ;`

// older distroless/base digests appear to be truncated to use the name up to the first period (e.g. 'libssl1' instead of 'libssl1.1')
if !strings.Contains(dm.statusdNames, ".") {
copyStatusTemplate += `
gsub(\"\\\\.[^.]*$\", \"\", textname);`
}

copyStatusTemplate += `
outname = b64name in b64names ? b64name : textname;
outpath = statusDir \"/\" outname ;
printf \"cp \\\"%%s\\\" \\\"%%s\\\"\\\n\",FILENAME,outpath }'
{} | sh" \;`

copyStatusCmd := fmt.Sprintf(strings.ReplaceAll(copyStatusTemplate, "\n", ""), dpkgStatusFolder, dm.statusdNames)
statusUpdated := fieldsWritten.Dir(resultsPath).Run(llb.Shlex(copyStatusCmd)).Root()

Expand Down

0 comments on commit 54d6bb4

Please sign in to comment.