diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..aee6e903 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,18 @@ +version: 2 +updates: + - package-ecosystem: gomod + directory: / + schedule: + interval: weekly + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly + - package-ecosystem: docker + directory: "/" + schedule: + interval: weekly + - package-ecosystem: docker + directory: "/docker-runner" + schedule: + interval: weekly diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 00000000..62c341ae --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,157 @@ +# See also: +# https://docs.docker.com/build/ci/github-actions/multi-platform/ +# https://docs.github.com/en/actions/publishing-packages/publishing-docker-images + +name: Publish Docker image + +on: + push: + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write + attestations: write + strategy: + fail-fast: false + matrix: + platform: + - linux/amd64 + - linux/arm/v6 + - linux/arm/v7 + - linux/arm64 + steps: + - name: Prepare + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=latest,enable={{is_default_branch}} + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=ref,event=branch + type=sha + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 + - name: Build and push by digest + id: build + uses: docker/build-push-action@v5 + with: + context: . + cache-from: type=gha + cache-to: type=gha,mode=max + platforms: ${{ matrix.platform }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true + + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v1 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}} + subject-digest: ${{ steps.build.outputs.digest }} + push-to-registry: true + + - name: Export digest + run: | + mkdir -p /tmp/digests + digest="${{ steps.build.outputs.digest }}" + touch "/tmp/digests/${digest#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests-${{ env.PLATFORM_PAIR }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + publish: + needs: + - build + runs-on: ubuntu-latest + # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. + permissions: + contents: read + packages: write + id-token: write + attestations: write + steps: + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: /tmp/digests + pattern: digests-* + merge-multiple: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=raw,value=latest,enable={{is_default_branch}} + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=ref,event=branch + type=sha + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list and push + id: push + working-directory: /tmp/digests + run: | + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) + + - name: Inspect image + id: inspect + run: | + docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }} + IMAGE_DIGEST=$(docker buildx imagetools inspect --format "{{json .Manifest}}" ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }} | jq -r '.digest') + echo "IMAGE_DIGEST=$IMAGE_DIGEST" >> $GITHUB_OUTPUT + + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v1 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}} + subject-digest: ${{ steps.inspect.outputs.IMAGE_DIGEST }} + push-to-registry: true diff --git a/docker-runner/Dockerfile b/docker-runner/Dockerfile deleted file mode 100644 index 9f845343..00000000 --- a/docker-runner/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -FROM zgrab2_runner_base:latest - -WORKDIR /go/src/github.com/zmap - -# Grab the currently-active version of the source -ADD . zgrab2 - -# This would instead grab it from the source repo -# RUN go-wrapper download github.com/zmap/zgrab2 - -WORKDIR /go/src/github.com/zmap/zgrab2 - -RUN go get -f -u -v . -RUN go get -f -u -v -t . -RUN go get -f -u -v $(find ./modules -type d) -RUN go get -f -u -v -t $(find ./modules -type d) - -# This should already be executable, but just in case... -RUN chmod a+x ./docker-runner/entrypoint.sh - -# Build on the container -RUN make container-clean - -CMD [] -ENTRYPOINT ["/go/src/github.com/zmap/zgrab2/docker-runner/entrypoint.sh"] diff --git a/docker-runner/Makefile b/docker-runner/Makefile index d6647135..4b55d15b 100644 --- a/docker-runner/Makefile +++ b/docker-runner/Makefile @@ -4,26 +4,15 @@ else EXECUTABLE_EXTENSION := endif -all: docker-runner.id +all: service-base-image.id .PHONY: clean clean-all base-apt-update service-base-image.id: service-base.Dockerfile docker build -t zgrab2_service_base:latest -f service-base.Dockerfile -q . > service-base-image.id || (rm -f service-base-image.id && exit 1) -runner-base-image.id: runner-base.Dockerfile - docker build -t zgrab2_runner_base:latest -f runner-base.Dockerfile -q . > runner-base-image.id || (rm -f runner-base-image.id && exit 1) - base-apt-update: IMAGE_ID=zgrab2_service_base:latest ./base-apt-update.sh - IMAGE_ID=zgrab2_runner_base:latest ./base-apt-update.sh - -docker-runner.id: Dockerfile ../cmd/zgrab2/zgrab2$(EXECUTABLE_EXTENSION) runner-base-image.id service-base-image.id - docker build -t zgrab2_runner:latest -f Dockerfile -q .. > docker-runner.id || (rm -f docker-runner.id && exit 1) -clean: - if [ -f docker-runner.id ]; then docker rmi -f $$(cat docker-runner.id) && rm -f docker-runner.id; fi - clean-all: clean if [ -f service-base-image.id ]; then docker rmi -f $$(cat service-base-image.id) && rm -f service-base-image.id; fi - if [ -f runner-base-image.id ]; then docker rmi -f $$(cat runner-base-image.id) && rm -f runner-base-image.id; fi diff --git a/docker-runner/runner-base.Dockerfile b/docker-runner/runner-base.Dockerfile deleted file mode 100644 index de71ca2e..00000000 --- a/docker-runner/runner-base.Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM golang:1.9 -# Base image that already has the pre-requisites downloaded. - -WORKDIR /go/src/github.com/zmap - -RUN go-wrapper download github.com/zmap/zgrab2 - -WORKDIR /go/src/github.com/zmap/zgrab2 - -RUN go get -v ./... -RUN go get -v -t ./...