diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index eca4272e29e..a6202d8a0b0 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -107,3 +107,109 @@ jobs: - name: Acceptance Tests run: go test -tags=e2e,kms -v ./test/... + + e2e-registry: + runs-on: ubuntu-latest + + env: + SCAFFOLDING_RELEASE_VERSION: "v0.6.17" + + steps: + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 + - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 + with: + go-version: '1.21' + check-latest: true + + - name: Setup mirror + uses: chainguard-dev/actions/setup-mirror@main + with: + mirror: mirror.gcr.io + + - name: Install cluster + sigstore + uses: sigstore/scaffolding/actions/setup@main + with: + version: ${{ env.SCAFFOLDING_RELEASE_VERSION }} + + - name: Setup local insecure registry + run: | + # Create a self-signed SSL cert + mkdir -p insecure-certs + openssl req \ + -subj "/C=US/ST=WA/L=Flavorton/O=Tests-R-Us/OU=Dept. of Insecurity/CN=example.com/emailAddress=testing@example.com" \ + -newkey rsa:4096 -nodes -sha256 -keyout insecure-certs/domain.key \ + -x509 -days 365 -out insecure-certs/domain.crt + # Run a registry. + docker run -d --restart=always \ + --name $INSECURE_REGISTRY_NAME \ + -v "$(pwd)"/insecure-certs:/insecure-certs \ + -e REGISTRY_HTTP_ADDR=0.0.0.0:$INSECURE_REGISTRY_PORT \ + -e REGISTRY_HTTP_TLS_CERTIFICATE=/insecure-certs/domain.crt \ + -e REGISTRY_HTTP_TLS_KEY=/insecure-certs/domain.key \ + -p $INSECURE_REGISTRY_PORT:$INSECURE_REGISTRY_PORT \ + registry:2 + sudo echo "127.0.0.1 $INSECURE_REGISTRY_NAME" | sudo tee -a /etc/hosts + env: + # https://github.com/google/go-containerregistry/pull/125 allows insecure registry for + # '*.local' hostnames. + INSECURE_REGISTRY_NAME: insecure-registry.notlocal + INSECURE_REGISTRY_PORT: 5001 + + - name: Run Insecure Registry Tests + run: go test -tags=e2e,registry -v ./test/... + env: + COSIGN_TEST_REPO: insecure-registry.notlocal:5001 + + - name: Setup local insecure OCI 1.1 registry + run: | + # Create a self-signed SSL cert + mkdir -p insecure-certs + openssl req \ + -subj "/C=US/ST=WA/L=Flavorton/O=Tests-R-Us/OU=Dept. of Insecurity/CN=example.com/emailAddress=testing@example.com" \ + -newkey rsa:4096 -nodes -sha256 -keyout insecure-certs/domain.key \ + -x509 -days 365 -out insecure-certs/domain.crt + cat > config.json << EOF + { + "distSpecVersion": "1.1.0-dev", + "storage": { + "rootDirectory": "/tmp/zot" + }, + "http": { + "address": "0.0.0.0", + "port": "5002", + "realm": "zot", + "tls": { + "cert": "/insecure-certs/domain.crt", + "key": "/insecure-certs/domain.key" + } + }, + "log": { + "level": "debug" + } + } + EOF + # Run a registry. + docker run -d --restart=always \ + --name $INSECURE_OCI_REGISTRY_NAME \ + -v "$(pwd)"/insecure-certs:/insecure-certs \ + -v "$(pwd)"/config.json:/etc/zot/config.json \ + -p $INSECURE_OCI_REGISTRY_PORT:$INSECURE_OCI_REGISTRY_PORT \ + ghcr.io/project-zot/zot-minimal-linux-amd64:$ZOT_VERSION + sudo echo "127.0.0.1 $INSECURE_OCI_REGISTRY_NAME" | sudo tee -a /etc/hosts + env: + ZOT_VERSION: v2.0.0-rc6 + # https://github.com/google/go-containerregistry/pull/125 allows insecure registry for + # '*.local' hostnames. + INSECURE_OCI_REGISTRY_NAME: insecure-oci-registry.notlocal + INSECURE_OCI_REGISTRY_PORT: 5002 + + + - name: Run Insecure OCI 1.1 Registry Tests + run: go test -tags=e2e,registry -v ./test/... + env: + OCI11: yes + COSIGN_TEST_REPO: insecure-oci-registry.notlocal:5002 + + - name: Collect diagnostics + if: ${{ failure() }} + uses: chainguard-dev/actions/kind-diag@84c993eaf02da1c325854fb272a4df9184bd80fc # main diff --git a/.github/workflows/kind-e2e-insecure-registry.yaml b/.github/workflows/kind-e2e-insecure-registry.yaml deleted file mode 100644 index b96f99eac29..00000000000 --- a/.github/workflows/kind-e2e-insecure-registry.yaml +++ /dev/null @@ -1,155 +0,0 @@ -# Copyright 2021 The Sigstore Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: Insecure Registry KinD E2E - -on: - pull_request: - branches: [ 'main', 'release-*' ] - -permissions: read-all - -jobs: - e2e-tests: - name: e2e tests - runs-on: ubuntu-latest - - strategy: - fail-fast: false # Keep running if one leg fails. - matrix: - k8s-version: - - v1.24.x - - v1.25.x - - v1.26.x - - v1.27.x - - env: - # https://github.com/google/go-containerregistry/pull/125 allows insecure registry for - # '*.local' hostnames. - REGISTRY_NAME: registry.local - REGISTRY_PORT: 5000 - INSECURE_REGISTRY_NAME: insecure-registry.notlocal - INSECURE_REGISTRY_PORT: 5001 - INSECURE_OCI_REGISTRY_NAME: insecure-oci-registry.notlocal - INSECURE_OCI_REGISTRY_PORT: 5002 - KO_DOCKER_REPO: registry.local:5000/policy-controller - - steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 - with: - go-version: '1.21' - check-latest: true - - - uses: imjasonh/setup-ko@ace48d793556083a76f1e3e6068850c1f4a369aa # v0.6 - - - uses: imranismail/setup-kustomize@2ba527d4d055ab63514ba50a99456fc35684947f # v2.1.0 - - - name: Install yq - uses: mikefarah/yq@557dcb87b8efe786f89a12c09e9046b4753ab72e # v4.44.1 - - - name: Install Cosign - run: | - go install ./cmd/cosign - - - name: Setup mirror - uses: chainguard-dev/actions/setup-mirror@main - with: - mirror: mirror.gcr.io - - - name: Setup kind cluster - uses: chainguard-dev/actions/setup-kind@main - with: - k8s-version: ${{ matrix.k8s-version }} - cluster-suffix: c${{ github.run_id }}.local - - - name: Setup local insecure registry - run: | - # Create a self-signed SSL cert - mkdir -p insecure-certs - openssl req \ - -subj "/C=US/ST=WA/L=Flavorton/O=Tests-R-Us/OU=Dept. of Insecurity/CN=example.com/emailAddress=testing@example.com" \ - -newkey rsa:4096 -nodes -sha256 -keyout insecure-certs/domain.key \ - -x509 -days 365 -out insecure-certs/domain.crt - # Run a registry. - docker run -d --restart=always \ - --name $INSECURE_REGISTRY_NAME \ - -v "$(pwd)"/insecure-certs:/insecure-certs \ - -e REGISTRY_HTTP_ADDR=0.0.0.0:$INSECURE_REGISTRY_PORT \ - -e REGISTRY_HTTP_TLS_CERTIFICATE=/insecure-certs/domain.crt \ - -e REGISTRY_HTTP_TLS_KEY=/insecure-certs/domain.key \ - -p $INSECURE_REGISTRY_PORT:$INSECURE_REGISTRY_PORT \ - registry:2 - # Connect the registry to the KinD network. - docker network connect "kind" $INSECURE_REGISTRY_NAME - # Make the $INSECURE_REGISTRY_NAME -> 127.0.0.1, to tell `ko` to publish to - # local registry, even when pushing $INSECURE_REGISTRY_NAME:$INSECURE_REGISTRY_NAME/some/image - sudo echo "127.0.0.1 $INSECURE_REGISTRY_NAME" | sudo tee -a /etc/hosts - - - name: Run Insecure Registry Tests - run: | - go install github.com/google/go-containerregistry/cmd/crane - ./test/e2e_test_insecure_registry.sh - - - name: Setup local insecure OCI registry - run: | - # Create a self-signed SSL cert - mkdir -p insecure-certs - openssl req \ - -subj "/C=US/ST=WA/L=Flavorton/O=Tests-R-Us/OU=Dept. of Insecurity/CN=example.com/emailAddress=testing@example.com" \ - -newkey rsa:4096 -nodes -sha256 -keyout insecure-certs/domain.key \ - -x509 -days 365 -out insecure-certs/domain.crt - cat > config.json << EOF - { - "distSpecVersion": "1.1.0-dev", - "storage": { - "rootDirectory": "/tmp/zot" - }, - "http": { - "address": "0.0.0.0", - "port": "5000", - "realm": "zot", - "tls": { - "cert": "/insecure-certs/domain.crt", - "key": "/insecure-certs/domain.key" - } - }, - "log": { - "level": "debug" - } - } - EOF - # Run a registry. - docker run -d --restart=always \ - --name $INSECURE_OCI_REGISTRY_NAME \ - -v "$(pwd)"/insecure-certs:/insecure-certs \ - -v "$(pwd)"/config.json:/etc/zot/config.json \ - -p $INSECURE_OCI_REGISTRY_PORT:$REGISTRY_PORT \ - ghcr.io/project-zot/zot-minimal-linux-amd64:$ZOT_VERSION - # Connect the registry to the KinD network. - docker network connect "kind" $INSECURE_OCI_REGISTRY_NAME - # Make the $INSECURE_REGISTRY_NAME -> 127.0.0.1, to tell `ko` to publish to - # local registry, even when pushing $INSECURE_REGISTRY_NAME:$INSECURE_REGISTRY_NAME/some/image - sudo echo "127.0.0.1 $INSECURE_OCI_REGISTRY_NAME" | sudo tee -a /etc/hosts - env: - ZOT_VERSION: v2.0.0-rc6 - - - name: Run Insecure OCI Registry Tests - run: | - go install github.com/google/go-containerregistry/cmd/crane - ./test/e2e_test_insecure_oci_registry.sh - - - name: Collect diagnostics - if: ${{ failure() }} - uses: chainguard-dev/actions/kind-diag@84c993eaf02da1c325854fb272a4df9184bd80fc # main diff --git a/test/e2e_insecure_registry_test.go b/test/e2e_insecure_registry_test.go new file mode 100644 index 00000000000..0da6ec6380d --- /dev/null +++ b/test/e2e_insecure_registry_test.go @@ -0,0 +1,125 @@ +// Copyright 2024 The Sigstore Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build e2e && registry + +package test + +import ( + "context" + "crypto/tls" + "net/http" + "os" + "path" + "testing" + + "github.com/google/go-containerregistry/pkg/name" + "github.com/google/go-containerregistry/pkg/v1/random" + "github.com/google/go-containerregistry/pkg/v1/remote" + "github.com/sigstore/cosign/v2/cmd/cosign/cli/options" + "github.com/sigstore/cosign/v2/cmd/cosign/cli/sign" + cliverify "github.com/sigstore/cosign/v2/cmd/cosign/cli/verify" + "github.com/sigstore/cosign/v2/pkg/cosign/env" + ociremote "github.com/sigstore/cosign/v2/pkg/oci/remote" +) + +const ( + oci11Var = "OCI11" + rekorURLVar = "REKOR_URL" +) + +func TestInsecureRegistry(t *testing.T) { + if os.Getenv("COSIGN_TEST_REPO") == "" { + t.Fatal("COSIGN_TEST_REPO must be set to an insecure registry for this test") + } + repo, stop := reg(t) + defer stop() + td := t.TempDir() + + imgName := path.Join(repo, "cosign-registry-e2e") + cleanup := makeImageIndexWithInsecureRegistry(t, imgName) + defer cleanup() + + _, privKey, pubKey := keypair(t, td) + + useOCI11 := os.Getenv("oci11Var") != "" + + rekorURL := os.Getenv(rekorURLVar) + must(downloadAndSetEnv(t, rekorURL+"/api/v1/log/publicKey", env.VariableSigstoreRekorPublicKey.String(), td), t) + + ko := options.KeyOpts{ + KeyRef: privKey, + PassFunc: passFunc, + RekorURL: rekorURL, + SkipConfirmation: true, + } + so := options.SignOptions{ + Upload: true, + TlogUpload: true, + } + mustErr(sign.SignCmd(ro, ko, so, []string{imgName}), t) + so.Registry = options.RegistryOptions{ + AllowInsecure: true, + } + if useOCI11 { + so.RegistryExperimental = options.RegistryExperimentalOptions{ + RegistryReferrersMode: options.RegistryReferrersModeOCI11, + } + } + must(sign.SignCmd(ro, ko, so, []string{imgName}), t) + mustErr(verify(pubKey, imgName, true, nil, "", false), t) + cmd := cliverify.VerifyCommand{ + KeyRef: pubKey, + CheckClaims: true, + RegistryOptions: options.RegistryOptions{ + AllowInsecure: true, + }, + } + if useOCI11 { + cmd.ExperimentalOCI11 = true + } + must(cmd.Exec(context.Background(), []string{imgName}), t) +} + +func makeImageIndexWithInsecureRegistry(t *testing.T, n string) func() { + ref, err := name.ParseReference(n, name.WeakValidation) + if err != nil { + t.Fatal(err) + } + index, err := random.Index(512, 1, 0) + if err != nil { + t.Fatal(err) + } + regClientOpts := registryClientOpts(context.Background()) + // Add TLS config to allow us to push the image to the insecure registry + insecureTransport := &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + } + regClientOpts = append(regClientOpts, remote.WithTransport(insecureTransport)) + if err := remote.WriteIndex(ref, index, regClientOpts...); err != nil { + t.Fatal(err) + } + remoteImage, err := remote.Get(ref, regClientOpts...) + if err != nil { + t.Fatal(err) + } + cleanup := func() { + _ = remote.Delete(ref, regClientOpts...) + ref, _ := ociremote.SignatureTag(ref.Context().Digest(remoteImage.Descriptor.Digest.String()), ociremote.WithRemoteOptions(regClientOpts...)) + _ = remote.Delete(ref, regClientOpts...) + } + return cleanup +} diff --git a/test/e2e_kms_test.go b/test/e2e_kms_test.go index 9cd85dfdbee..0050c2a39d4 100644 --- a/test/e2e_kms_test.go +++ b/test/e2e_kms_test.go @@ -42,7 +42,7 @@ func TestSecretsKMS(t *testing.T) { defer stop() td := t.TempDir() - imgName := path.Join(repo, "cosign-attach-e2e") + imgName := path.Join(repo, "cosign-kms-e2e") _, _, cleanup := mkimage(t, imgName) defer cleanup() diff --git a/test/e2e_test.go b/test/e2e_test.go index 330c4bfa9d3..da874ae329f 100644 --- a/test/e2e_test.go +++ b/test/e2e_test.go @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build e2e && !cross && !kms +//go:build e2e && !cross && !kms && !registry package test diff --git a/test/e2e_test_insecure_oci_registry.sh b/test/e2e_test_insecure_oci_registry.sh deleted file mode 100755 index 02ec2818585..00000000000 --- a/test/e2e_test_insecure_oci_registry.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright 2023 The Sigstore Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -o errexit -set -o nounset -set -o pipefail - -go build -o cosign ./cmd/cosign -tmp=$(mktemp -d) -cp cosign $tmp/ - -INSECURE_REGISTRY_NAME=${INSECURE_OCI_REGISTRY_NAME:-insecure-oci-registry.notlocal} -INSECURE_REGISTRY_PORT=${INSECURE_OCI_REGISTRY_PORT:-5002} - -pushd $tmp - -pass="$RANDOM" -export COSIGN_PASSWORD=$pass -export COSIGN_YES="true" -export COSIGN_EXPERIMENTAL=1 - -./cosign generate-key-pair -signing_key=cosign.key -verification_key=cosign.pub - -img="${INSECURE_REGISTRY_NAME}:${INSECURE_REGISTRY_PORT}/test" -(crane delete $(./cosign triangulate $img)) || true -crane cp ghcr.io/distroless/static $img --insecure - -# Operations with insecure registries should fail by default, then succeed -# with `--allow-insecure-registry` -if (./cosign sign --key ${signing_key} $img); then false; fi -./cosign sign --allow-insecure-registry --registry-referrers-mode=oci-1-1 --key ${signing_key} $img -if (./cosign verify --key ${verification_key} $img); then false; fi -./cosign verify --allow-insecure-registry --experimental-oci11=true --key ${verification_key} $img - -echo "SUCCESS" diff --git a/test/e2e_test_insecure_registry.sh b/test/e2e_test_insecure_registry.sh deleted file mode 100755 index 33631232bfc..00000000000 --- a/test/e2e_test_insecure_registry.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright 2021 The Sigstore Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -ex - -go build -o cosign ./cmd/cosign -tmp=$(mktemp -d) -cp cosign $tmp/ - -INSECURE_REGISTRY_NAME=${INSECURE_REGISTRY_NAME:-insecure-registry.notlocal} -INSECURE_REGISTRY_PORT=${INSECURE_REGISTRY_PORT:-5001} - -pushd $tmp - -pass="$RANDOM" -export COSIGN_PASSWORD=$pass -export COSIGN_YES="true" - -./cosign generate-key-pair -signing_key=cosign.key -verification_key=cosign.pub - -img="${INSECURE_REGISTRY_NAME}:${INSECURE_REGISTRY_PORT}/test" -(crane delete $(./cosign triangulate $img)) || true -crane cp ghcr.io/distroless/static $img --insecure - -# Operations with insecure registries should fail by default, then succeed -# with `--allow-insecure-registry` -if (./cosign sign --key ${signing_key} $img); then false; fi -./cosign sign --allow-insecure-registry --key ${signing_key} $img -if (./cosign verify --key ${verification_key} $img); then false; fi -./cosign verify --allow-insecure-registry --key ${verification_key} $img - -echo "SUCCESS"