From b5ead0a68c878aec2c34bd623bf2381667911c96 Mon Sep 17 00:00:00 2001 From: Xe Iaso Date: Fri, 7 Nov 2025 19:17:25 -0500 Subject: [PATCH] fix(data): add ruleset to explicitly allow Docker / OCI clients (#1253) * fix(data): add ruleset to explicitly allow Docker / OCI clients Fixes #1252 This is technically a regression as these clients used to work in Anubis v1.22.0, however it is allowable to make this opt-in as most websites do not expect to be serving Docker / OCI registry client traffic. Signed-off-by: Xe Iaso * Update metadata check-spelling run (pull_request) for Xe/gh-1252/docker-registry-client-fix Signed-off-by: check-spelling-bot on-behalf-of: @check-spelling * test(docker-registry): export the right envvars Signed-off-by: Xe Iaso * ci: add simdjson dependency for homebrew node Signed-off-by: Xe Iaso * ci: install go/node without homebrew Signed-off-by: Xe Iaso * test: use right github commit variable Signed-off-by: Xe Iaso * ci: remove simdjson dependency Signed-off-by: Xe Iaso * ci: install ko with an action Signed-off-by: Xe Iaso * docs: add OCI registry caveat docs Signed-off-by: Xe Iaso --------- Signed-off-by: Xe Iaso Signed-off-by: check-spelling-bot --- .github/actions/spelling/expect.txt | 2 + .github/workflows/docker-pr.yml | 37 +++--- .github/workflows/docker.yml | 33 ++---- .github/workflows/go.yml | 106 +++++++----------- .github/workflows/package-builds-stable.yml | 34 +----- .github/workflows/package-builds-unstable.yml | 80 +++++-------- .github/workflows/smoke-tests.yml | 1 + data/clients/docker-client.yaml | 25 +++++ docs/docs/CHANGELOG.md | 14 +++ docs/docs/admin/roles/_category_.json | 8 ++ docs/docs/admin/roles/oci-registry.mdx | 10 ++ test/docker-registry/anubis.yaml | 7 ++ test/docker-registry/docker-compose.yaml | 30 +++++ test/docker-registry/test.sh | 29 +++++ test/docker-registry/var/.gitignore | 2 + test/git-push/test.sh | 24 ++-- 16 files changed, 237 insertions(+), 205 deletions(-) create mode 100644 data/clients/docker-client.yaml create mode 100644 docs/docs/admin/roles/_category_.json create mode 100644 docs/docs/admin/roles/oci-registry.mdx create mode 100644 test/docker-registry/anubis.yaml create mode 100644 test/docker-registry/docker-compose.yaml create mode 100755 test/docker-registry/test.sh create mode 100644 test/docker-registry/var/.gitignore diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index e4155e9..68893e3 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -64,6 +64,7 @@ Codespaces confd connnection containerbuild +containerregistry coreutils Cotoyogi Cromite @@ -341,6 +342,7 @@ Velen vendored vhosts VKE +vnd VPS Vultr weblate diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index 1069ba6..c010e90 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -2,7 +2,7 @@ name: Docker image builds (pull requests) on: pull_request: - branches: [ "main" ] + branches: ["main"] env: DOCKER_METADATA_SET_OUTPUT_ENV: "true" @@ -21,29 +21,20 @@ jobs: fetch-depth: 0 persist-credentials: false - - name: Set up Homebrew - uses: Homebrew/actions/setup-homebrew@main - - - name: Setup Homebrew cellar cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 - with: - path: | - /home/linuxbrew/.linuxbrew/Cellar - /home/linuxbrew/.linuxbrew/bin - /home/linuxbrew/.linuxbrew/etc - /home/linuxbrew/.linuxbrew/include - /home/linuxbrew/.linuxbrew/lib - /home/linuxbrew/.linuxbrew/opt - /home/linuxbrew/.linuxbrew/sbin - /home/linuxbrew/.linuxbrew/share - /home/linuxbrew/.linuxbrew/var - key: ${{ runner.os }}-go-homebrew-cellar-${{ hashFiles('go.sum') }} - restore-keys: | - ${{ runner.os }}-go-homebrew-cellar- - - - name: Install Brew dependencies + - name: build essential run: | - brew bundle + sudo apt-get update + sudo apt-get install -y build-essential + + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: latest + + - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version: stable + + - uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9 - name: Docker meta id: meta diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 62ac0ee..c7bb29a 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -27,33 +27,24 @@ jobs: fetch-depth: 0 persist-credentials: false + - name: build essential + run: | + sudo apt-get update + sudo apt-get install -y build-essential + - name: Set lowercase image name run: | echo "IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}" >> $GITHUB_ENV - - name: Set up Homebrew - uses: Homebrew/actions/setup-homebrew@main - - - name: Setup Homebrew cellar cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - path: | - /home/linuxbrew/.linuxbrew/Cellar - /home/linuxbrew/.linuxbrew/bin - /home/linuxbrew/.linuxbrew/etc - /home/linuxbrew/.linuxbrew/include - /home/linuxbrew/.linuxbrew/lib - /home/linuxbrew/.linuxbrew/opt - /home/linuxbrew/.linuxbrew/sbin - /home/linuxbrew/.linuxbrew/share - /home/linuxbrew/.linuxbrew/var - key: ${{ runner.os }}-go-homebrew-cellar-${{ hashFiles('go.sum') }} - restore-keys: | - ${{ runner.os }}-go-homebrew-cellar- + node-version: latest - - name: Install Brew dependencies - run: | - brew bundle + - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version: stable + + - uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9 - name: Log into registry uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 7f10cc1..5ab29c6 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -2,9 +2,9 @@ name: Go on: push: - branches: [ "main" ] + branches: ["main"] pull_request: - branches: [ "main" ] + branches: ["main"] permissions: contents: read @@ -15,77 +15,51 @@ jobs: #runs-on: alrest-techarohq runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - persist-credentials: false + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false - - name: build essential - run: | - sudo apt-get update - sudo apt-get install -y build-essential + - name: build essential + run: | + sudo apt-get update + sudo apt-get install -y build-essential - - name: Set up Homebrew - uses: Homebrew/actions/setup-homebrew@main + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: latest - - name: Setup Homebrew cellar cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 - with: - path: | - /home/linuxbrew/.linuxbrew/Cellar - /home/linuxbrew/.linuxbrew/bin - /home/linuxbrew/.linuxbrew/etc - /home/linuxbrew/.linuxbrew/include - /home/linuxbrew/.linuxbrew/lib - /home/linuxbrew/.linuxbrew/opt - /home/linuxbrew/.linuxbrew/sbin - /home/linuxbrew/.linuxbrew/share - /home/linuxbrew/.linuxbrew/var - key: ${{ runner.os }}-go-homebrew-cellar-${{ hashFiles('go.sum') }} - restore-keys: | - ${{ runner.os }}-go-homebrew-cellar- + - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version: stable - - name: Install Brew dependencies - run: | - brew bundle + - name: Cache playwright binaries + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + id: playwright-cache + with: + path: | + ~/.cache/ms-playwright + key: ${{ runner.os }}-playwright-${{ hashFiles('**/go.sum') }} - - name: Setup Golang caches - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 - with: - path: | - ~/.cache/go-build - ~/go/pkg/mod - key: ${{ runner.os }}-golang-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-golang- + - name: install node deps + run: | + npm ci - - name: Cache playwright binaries - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 - id: playwright-cache - with: - path: | - ~/.cache/ms-playwright - key: ${{ runner.os }}-playwright-${{ hashFiles('**/go.sum') }} + - name: install playwright browsers + run: | + npx --no-install playwright@1.52.0 install --with-deps + npx --no-install playwright@1.52.0 run-server --port 9001 & - - name: install node deps - run: | - npm ci + - name: Build + run: npm run build - - name: install playwright browsers - run: | - npx --no-install playwright@1.52.0 install --with-deps - npx --no-install playwright@1.52.0 run-server --port 9001 & + - name: Test + run: npm run test - - name: Build - run: npm run build + - name: Lint with staticcheck + uses: dominikh/staticcheck-action@024238d2898c874f26d723e7d0ff4308c35589a2 # v1.4.0 + with: + version: "latest" - - name: Test - run: npm run test - - - name: Lint with staticcheck - uses: dominikh/staticcheck-action@024238d2898c874f26d723e7d0ff4308c35589a2 # v1.4.0 - with: - version: "latest" - - - name: Govulncheck - run: | - go tool govulncheck ./... + - name: Govulncheck + run: | + go tool govulncheck ./... diff --git a/.github/workflows/package-builds-stable.yml b/.github/workflows/package-builds-stable.yml index 20ee7ee..3a41409 100644 --- a/.github/workflows/package-builds-stable.yml +++ b/.github/workflows/package-builds-stable.yml @@ -25,39 +25,13 @@ jobs: sudo apt-get update sudo apt-get install -y build-essential - - name: Set up Homebrew - uses: Homebrew/actions/setup-homebrew@main - - - name: Setup Homebrew cellar cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - path: | - /home/linuxbrew/.linuxbrew/Cellar - /home/linuxbrew/.linuxbrew/bin - /home/linuxbrew/.linuxbrew/etc - /home/linuxbrew/.linuxbrew/include - /home/linuxbrew/.linuxbrew/lib - /home/linuxbrew/.linuxbrew/opt - /home/linuxbrew/.linuxbrew/sbin - /home/linuxbrew/.linuxbrew/share - /home/linuxbrew/.linuxbrew/var - key: ${{ runner.os }}-go-homebrew-cellar-${{ hashFiles('go.sum') }} - restore-keys: | - ${{ runner.os }}-go-homebrew-cellar- + node-version: latest - - name: Install Brew dependencies - run: | - brew bundle - - - name: Setup Golang caches - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 with: - path: | - ~/.cache/go-build - ~/go/pkg/mod - key: ${{ runner.os }}-golang-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-golang- + go-version: stable - name: install node deps run: | diff --git a/.github/workflows/package-builds-unstable.yml b/.github/workflows/package-builds-unstable.yml index bf25b66..aa522c1 100644 --- a/.github/workflows/package-builds-unstable.yml +++ b/.github/workflows/package-builds-unstable.yml @@ -2,9 +2,9 @@ name: Package builds (unstable) on: push: - branches: [ "main" ] + branches: ["main"] pull_request: - branches: [ "main" ] + branches: ["main"] permissions: contents: read @@ -15,60 +15,34 @@ jobs: #runs-on: alrest-techarohq runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - persist-credentials: false - fetch-tags: true - fetch-depth: 0 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + fetch-tags: true + fetch-depth: 0 - - name: build essential - run: | - sudo apt-get update - sudo apt-get install -y build-essential + - name: build essential + run: | + sudo apt-get update + sudo apt-get install -y build-essential - - name: Set up Homebrew - uses: Homebrew/actions/setup-homebrew@main + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: latest - - name: Setup Homebrew cellar cache - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 - with: - path: | - /home/linuxbrew/.linuxbrew/Cellar - /home/linuxbrew/.linuxbrew/bin - /home/linuxbrew/.linuxbrew/etc - /home/linuxbrew/.linuxbrew/include - /home/linuxbrew/.linuxbrew/lib - /home/linuxbrew/.linuxbrew/opt - /home/linuxbrew/.linuxbrew/sbin - /home/linuxbrew/.linuxbrew/share - /home/linuxbrew/.linuxbrew/var - key: ${{ runner.os }}-go-homebrew-cellar-${{ hashFiles('go.sum') }} - restore-keys: | - ${{ runner.os }}-go-homebrew-cellar- + - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 + with: + go-version: stable - - name: Install Brew dependencies - run: | - brew bundle + - name: install node deps + run: | + npm ci - - name: Setup Golang caches - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 - with: - path: | - ~/.cache/go-build - ~/go/pkg/mod - key: ${{ runner.os }}-golang-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-golang- + - name: Build Packages + run: | + go tool yeet - - name: install node deps - run: | - npm ci - - - name: Build Packages - run: | - go tool yeet - - - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 - with: - name: packages - path: var/* + - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + with: + name: packages + path: var/* diff --git a/.github/workflows/smoke-tests.yml b/.github/workflows/smoke-tests.yml index b0b0cad..ff13d99 100644 --- a/.github/workflows/smoke-tests.yml +++ b/.github/workflows/smoke-tests.yml @@ -15,6 +15,7 @@ jobs: matrix: test: - default-config-macro + - docker-registry - double_slash - forced-language - git-clone diff --git a/data/clients/docker-client.yaml b/data/clients/docker-client.yaml new file mode 100644 index 0000000..4a07df2 --- /dev/null +++ b/data/clients/docker-client.yaml @@ -0,0 +1,25 @@ +- name: allow-docker-client + action: ALLOW + expression: + all: + - path.startsWith("/v2/") + - userAgent.contains("docker/") + - userAgent.contains("git-commit/") + - '"Accept" in headers' + - headers["Accept"].contains("vnd.docker.distribution") + - '"Baggage" in headers' + - headers["Baggage"].contains("trigger") + +- name: allow-crane-client + action: ALLOW + expression: + all: + - userAgent.contains("crane/") + - userAgent.contains("go-containerregistry/") + +- name: allow-docker-distribution-api-client + action: ALLOW + expression: + all: + - '"Docker-Distribution-Api-Version" in headers' + - '!(userAgent.contains("Mozilla"))' diff --git a/docs/docs/CHANGELOG.md b/docs/docs/CHANGELOG.md index 44ff628..a35ecdb 100644 --- a/docs/docs/CHANGELOG.md +++ b/docs/docs/CHANGELOG.md @@ -16,6 +16,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix `SERVE_ROBOTS_TXT` setting file after the double slash fix broke it. - Remove the default configuration rule to block Tencent cloud. If users see abuse from Tencent cloud IP ranges, please contact abuse@tencent.com and mention that you are using Anubis to protect your services. Please include source IP address, source port, timestamp, target IP address, target port, request headers (including the User-Agent header), and target endpoints/patterns. +### Potentially breaking changes + +#### Docker / OCI registry clients + +Anubis v1.23.0 accidentally blocked Docker / OCI registry clients. In order to explicitly allow them, add an import for `(data)/clients/docker-client.yaml`: + +```yaml +bots: + - import: (data)/meta/default-config.yaml + - import: (data)/clients/docker-client.yaml +``` + +This is technically a regression as these clients used to work in Anubis v1.22.0, however it is allowable to make this opt-in as most websites do not expect to be serving Docker / OCI registry client traffic. + ## v1.23.0: Lyse Hext - Add default tencent cloud DENY rule. diff --git a/docs/docs/admin/roles/_category_.json b/docs/docs/admin/roles/_category_.json new file mode 100644 index 0000000..2d5af0b --- /dev/null +++ b/docs/docs/admin/roles/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Server Roles", + "position": 40, + "link": { + "type": "generated-index", + "description": "Various server roles you will need to keep in mind with Anubis." + } +} \ No newline at end of file diff --git a/docs/docs/admin/roles/oci-registry.mdx b/docs/docs/admin/roles/oci-registry.mdx new file mode 100644 index 0000000..56e64ab --- /dev/null +++ b/docs/docs/admin/roles/oci-registry.mdx @@ -0,0 +1,10 @@ +# OCI Registries + +If you are serving an OCI registry behind Anubis, you will need to import the `(data)/clients/docker-client.yaml` file in order to make sure that OCI registry clients can download images: + +```yaml +bots: + - import: (data)/meta/default-config.yaml + - import: (data)/clients/docker-client.yaml +# ... the rest of your config +``` diff --git a/test/docker-registry/anubis.yaml b/test/docker-registry/anubis.yaml new file mode 100644 index 0000000..f352c70 --- /dev/null +++ b/test/docker-registry/anubis.yaml @@ -0,0 +1,7 @@ +bots: + - import: (data)/meta/default-config.yaml + - import: (data)/clients/docker-client.yaml + +status_codes: + CHALLENGE: 200 + DENY: 403 diff --git a/test/docker-registry/docker-compose.yaml b/test/docker-registry/docker-compose.yaml new file mode 100644 index 0000000..a1095bc --- /dev/null +++ b/test/docker-registry/docker-compose.yaml @@ -0,0 +1,30 @@ +services: + registry: + image: distribution/distribution:edge + restart: always + + relayd: + image: ghcr.io/xe/x/relayd + pull_policy: always + environment: + CERT_DIR: /etc/techaro/pki/registry.local.cetacean.club + CERT_FNAME: cert.pem + KEY_FNAME: key.pem + PROXY_TO: http://anubis:3000 + ports: + - 3004:3004 + volumes: + - ../pki/registry.local.cetacean.club:/etc/techaro/pki/registry.local.cetacean.club + + anubis: + image: ko.local/anubis + restart: always + environment: + BIND: ":3000" + TARGET: http://registry:5000 + POLICY_FNAME: /etc/techaro/anubis.yaml + USE_REMOTE_ADDRESS: "true" + ports: + - 3000 + volumes: + - ./anubis.yaml:/etc/techaro/anubis.yaml diff --git a/test/docker-registry/test.sh b/test/docker-registry/test.sh new file mode 100755 index 0000000..c2b1eeb --- /dev/null +++ b/test/docker-registry/test.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -eo pipefail + +export VERSION=${GITHUB_SHA}-test +export KO_DOCKER_REPO=ko.local + +set -u + +source ../lib/lib.sh + +build_anubis_ko + +function cleanup() { + docker compose down +} + +trap cleanup EXIT SIGINT + +mint_cert registry.local.cetacean.club + +docker compose up -d + +backoff-retry skopeo \ + --insecure-policy \ + copy \ + --dest-tls-verify=false \ + docker://hello-world \ + docker://registry.local.cetacean.club:3004/hello-world diff --git a/test/docker-registry/var/.gitignore b/test/docker-registry/var/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/test/docker-registry/var/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/test/git-push/test.sh b/test/git-push/test.sh index a6d5f97..832b882 100755 --- a/test/git-push/test.sh +++ b/test/git-push/test.sh @@ -2,7 +2,7 @@ set -eo pipefail -export VERSION=$GITHUB_COMMIT-test +export VERSION=${GITHUB_SHA}-test export KO_DOCKER_REPO=ko.local set -u @@ -21,16 +21,16 @@ docker compose up -d sleep 2 ( - cd var && \ - mkdir foo && \ - cd foo && \ - git init && \ - touch README && \ - git add . && \ - git config user.name "Anubis CI" && \ - git config user.email "social+anubis-ci@techaro.lol" && \ - git commit -sm "initial commit" && \ - git push -u http://localhost:3000/git/foo.git master + cd var && + mkdir foo && + cd foo && + git init && + touch README && + git add . && + git config user.name "Anubis CI" && + git config user.email "social+anubis-ci@techaro.lol" && + git commit -sm "initial commit" && + git push -u http://localhost:3000/git/foo.git master ) -exit 0 \ No newline at end of file +exit 0