From 2cae5296a221bd7c489632fcfa2721aabc9bec9c Mon Sep 17 00:00:00 2001 From: David Howell Date: Tue, 6 Feb 2024 05:01:22 +0000 Subject: [PATCH] Build multi-platform images Refactor GitHub Actions workflow for build Run Dockle and Trivy, upload sarif reports to GitHub Refactor Dockerfiles based on best practices --- .github/workflows/build_images.yaml | 126 +++++++++++++++++++++++---- src/node/addon-jackett/.dockerignore | 5 +- src/node/addon-jackett/Dockerfile | 8 +- src/node/addon/.dockerignore | 4 +- src/node/addon/Dockerfile | 8 +- src/node/consumer/.dockerignore | 3 +- src/node/consumer/Dockerfile | 11 ++- src/producer/Dockerfile | 19 ++-- 8 files changed, 152 insertions(+), 32 deletions(-) diff --git a/.github/workflows/build_images.yaml b/.github/workflows/build_images.yaml index bd2e8ee..613be97 100644 --- a/.github/workflows/build_images.yaml +++ b/.github/workflows/build_images.yaml @@ -1,43 +1,131 @@ -name: Build +name: Build and Push Docker Images on: push: - branches: - - 'master' - paths: - - src/** jobs: - build-and-push: + build-and-push-images: runs-on: ubuntu-latest + permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results + services: + registry: + image: registry:2 + ports: + - 5000:5000 strategy: matrix: include: - context: ./src/node/addon/ - tag: gabisonfire/knightcrawler-addon:latest + image_name: knightcrawler-addon + platforms: linux/amd64,linux/arm64 - context: ./src/node/addon-jackett/ - tag: gabisonfire/knightcrawler-addon-jackett:latest + image_name: knightcrawler-addon-jackett + platforms: linux/amd64,linux/arm64 - context: ./src/node/consumer/ - tag: gabisonfire/knightcrawler-consumer:latest + image_name: knightcrawler-consumer + platforms: linux/amd64,linux/arm64 - context: ./src/producer/ - tag: gabisonfire/knightcrawler-producer:latest + image_name: knightcrawler-producer + platforms: linux/amd64,linux/arm64 + + name: Build - ${{ matrix.image_name }} + steps: - - - name: Checkout repository + - name: Checkout repository uses: actions/checkout@v4 - - - name: Set up Docker Buildx + + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - - name: Login to Docker Hub + with: + driver-opts: network=host + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ vars.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push ${{ matrix.tag }} + + - name: Build Docker Metadata + id: docker-metadata + uses: docker/metadata-action@v5 + with: + images: | + ${{ vars.DOCKERHUB_USERNAME }}/${{ matrix.image_name }} + flavor: | + latest=auto + tags: | + type=edge,branch=main,commit=${{ github.sha }} + type=sha,commit=${{ github.sha }} + + - name: Build image for scanning ${{ matrix.image_name }} uses: docker/build-push-action@v5 with: context: ${{ matrix.context }} push: true - tags: ${{ matrix.tag }} \ No newline at end of file + provenance: false + tags: localhost:5000/dockle-examine-image:test + platforms: ${{ matrix.platforms }} + cache-from: type=gha,scope=${{ github.workflow }} + cache-to: type=gha,mode=max,scope=${{ github.workflow }} + + - name: Pull Built Image for Scanning + run: | + docker pull localhost:5000/dockle-examine-image:test + + - name: Dockle - Examine Best Practices + uses: davidjameshowell/dockle-action@ad7164c945d12d55ac5e639f91f0a5c708a4cdce + with: + image: localhost:5000/dockle-examine-image:test + dockle-ignores: CIS-DI-0005 # Ignore `Enable Content trust for Docker` + + - name: Run Trivy vulnerability scanner - human readable output + uses: aquasecurity/trivy-action@master + with: + image-ref: localhost:5000/dockle-examine-image:test + scan-type: 'image' + format: 'table' + exit-code: '0' + ignore-unfixed: true + vuln-type: 'os,library' + severity: 'CRITICAL,HIGH' + scanners: 'vuln,secret,config' + env: + TRIVY_NON_SSL: true + + - name: Run Trivy vulnerability scanner (sarif report) + uses: aquasecurity/trivy-action@master + with: + image-ref: localhost:5000/dockle-examine-image:test + scan-type: 'image' + format: 'sarif' + exit-code: '0' + ignore-unfixed: true + vuln-type: 'os,library' + severity: 'CRITICAL,HIGH' + scanners: 'vuln,secret,config' + output: 'trivy-results-os.sarif' + env: + TRIVY_NON_SSL: true + + - name: Upload Trivy scan results to GitHub Security tab + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: 'trivy-results-os.sarif' + + - name: Push ${{ matrix.image_name }} to repo + if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' + uses: docker/build-push-action@v5 + with: + context: ${{ matrix.context }} + push: true + provenance: false + tags: ${{ steps.docker-metadata.outputs.tags }} + labels: ${{ steps.docker-metadata.outputs.labels }} + platforms: ${{ matrix.platforms }} + cache-from: type=gha,scope=${{ github.workflow }} + cache-to: type=gha,mode=max,scope=${{ github.workflow }} diff --git a/src/node/addon-jackett/.dockerignore b/src/node/addon-jackett/.dockerignore index 5538a38..87bfacc 100644 --- a/src/node/addon-jackett/.dockerignore +++ b/src/node/addon-jackett/.dockerignore @@ -1,3 +1,6 @@ **/node_modules **/npm-debug.log -**/.env \ No newline at end of file +**/.env +.eslint* +README.md +Dockerfile diff --git a/src/node/addon-jackett/Dockerfile b/src/node/addon-jackett/Dockerfile index cf4f93a..4c1d89d 100644 --- a/src/node/addon-jackett/Dockerfile +++ b/src/node/addon-jackett/Dockerfile @@ -24,6 +24,12 @@ ENV NODE_ENV production COPY --from=builder /app ./ RUN npm prune --omit=dev +# CIS-DI-0001 +RUN addgroup -S addon-jackett && adduser -S -G addon-jackett addon-jackett +USER addon-jackett + EXPOSE 7001 -ENTRYPOINT [ "pm2-runtime", "start", "ecosystem.config.cjs"] \ No newline at end of file +ENTRYPOINT [ "pm2-runtime", "start", "ecosystem.config.cjs"] +HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \ + CMD pm2 ping || exit 1 diff --git a/src/node/addon/.dockerignore b/src/node/addon/.dockerignore index 5538a38..0f5a7f0 100644 --- a/src/node/addon/.dockerignore +++ b/src/node/addon/.dockerignore @@ -1,3 +1,5 @@ **/node_modules **/npm-debug.log -**/.env \ No newline at end of file +**/.env +.eslint* +Dockerfile diff --git a/src/node/addon/Dockerfile b/src/node/addon/Dockerfile index 78f37af..98a4ada 100644 --- a/src/node/addon/Dockerfile +++ b/src/node/addon/Dockerfile @@ -24,6 +24,12 @@ ENV NODE_ENV production COPY --from=builder /app ./ RUN npm prune --omit=dev +# CIS-DI-0001 +RUN addgroup -S addon && adduser -S -G addon addon +USER addon + EXPOSE 7000 -ENTRYPOINT [ "pm2-runtime", "start", "ecosystem.config.cjs"] \ No newline at end of file +ENTRYPOINT [ "pm2-runtime", "start", "ecosystem.config.cjs"] +HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \ + CMD pm2 ping || exit 1 diff --git a/src/node/consumer/.dockerignore b/src/node/consumer/.dockerignore index 9b49524..1b76f0d 100644 --- a/src/node/consumer/.dockerignore +++ b/src/node/consumer/.dockerignore @@ -12,4 +12,5 @@ helm-charts .env .editorconfig .idea -coverage* \ No newline at end of file +coverage* +.eslint* diff --git a/src/node/consumer/Dockerfile b/src/node/consumer/Dockerfile index 047195e..c26b653 100644 --- a/src/node/consumer/Dockerfile +++ b/src/node/consumer/Dockerfile @@ -21,6 +21,13 @@ ENV NODE_ENV production COPY --from=builder /app ./ RUN npm prune --omit=dev -EXPOSE 7001 +# CIS-DI-0001 +RUN useradd -d /home/consumer -m -s /bin/bash consumer +# CIS-DI-0008 +RUN chmod u-s /usr/bin/wall /usr/bin/expiry /usr/bin/chage /usr/bin/passwd /usr/bin/gpasswd /usr/bin/chsh /usr/bin/newgrp /usr/bin/chfn /sbin/unix_chkpwd /bin/su /bin/mount /bin/umount /usr/bin/chage /usr/bin/expiry /usr/bin/wall +USER consumer -ENTRYPOINT [ "node", "dist/index.cjs" ] \ No newline at end of file +EXPOSE 7001 +ENTRYPOINT [ "node", "dist/index.cjs" ] +HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \ + CMD pgrep -x node > /dev/null || exit 1 diff --git a/src/producer/Dockerfile b/src/producer/Dockerfile index 9c4d969..9dd1e60 100644 --- a/src/producer/Dockerfile +++ b/src/producer/Dockerfile @@ -1,10 +1,17 @@ -FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build + +ARG TARGETARCH WORKDIR /App COPY . ./ -RUN dotnet restore -RUN dotnet publish -c Release -o out +RUN dotnet restore -a $TARGETARCH +RUN dotnet publish -c Release --no-restore -o out -a $TARGETARCH + +FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine -FROM mcr.microsoft.com/dotnet/aspnet:8.0 WORKDIR /App -COPY --from=build-env /App/out . -ENTRYPOINT ["dotnet", "Producer.dll"] \ No newline at end of file +COPY --from=build /App/out . +RUN addgroup -S producer && adduser -S -G producer producer +USER producer +HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \ + CMD pgrep -f dotnet || exit 1 +ENTRYPOINT ["dotnet", "Producer.dll"]