Merge branch 'main' into Xe/valkey-2

This commit is contained in:
Xe Iaso 2025-06-11 17:08:40 -04:00 committed by GitHub
commit e0c4fcc398
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 172 additions and 18 deletions

2
.gitattributes vendored
View File

@ -1 +1 @@
web/index_templ.go linguist-generated
**/*_templ.go linguist-generated=true

View File

@ -6,6 +6,7 @@ amazonbot
anthro
anubis
anubistest
apk
Applebot
archlinux
badregexes
@ -68,6 +69,7 @@ duckduckbot
eerror
ellenjoe
enbyware
euo
everyones
evilbot
evilsite
@ -117,6 +119,7 @@ imgproxy
inp
iss
isset
itv
ivh
Jenomis
JGit
@ -247,6 +250,7 @@ traefik
uberspace
unixhttpd
unmarshal
uuidgen
uvx
UXP
valkey

View File

@ -3,8 +3,8 @@ name: Docker image builds
on:
workflow_dispatch:
push:
branches: [ "main" ]
tags: [ "v*" ]
branches: ["main"]
tags: ["v*"]
env:
DOCKER_METADATA_SET_OUTPUT_ENV: "true"
@ -77,7 +77,6 @@ jobs:
DOCKER_REPO: ${{ env.IMAGE }}
SLOG_LEVEL: debug
- name: Generate artifact attestation
uses: actions/attest-build-provenance@db473fddc028af60658334401dc6fa3ffd8669fd # v2.3.0
with:

View File

@ -0,0 +1,36 @@
name: Regenerate ssh ci runner image
on:
# pull_request:
# branches: ["main"]
schedule:
- cron: "0 0 1,8,15,22 * *"
workflow_dispatch:
permissions:
pull-requests: write
contents: write
packages: write
jobs:
ssh-ci-rebuild:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-tags: true
fetch-depth: 0
persist-credentials: false
- name: Log into registry
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- name: Build and push
run: |
cd ./test/ssh-ci
docker buildx bake --push

36
.github/workflows/ssh-ci.yml vendored Normal file
View File

@ -0,0 +1,36 @@
name: SSH CI
on:
push:
branches: ["main"]
# pull_request:
# branches: ["main"]
permissions:
contents: read
jobs:
ssh:
runs-on: ubuntu-24.04
strategy:
matrix:
host:
- ubuntu@riscv64.techaro.lol
- ci@ppc64le.techaro.lol
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-tags: true
fetch-depth: 0
persist-credentials: false
- name: Install CI target SSH key
uses: shimataro/ssh-key-action@d4fffb50872869abe2d9a9098a6d9c5aa7d16be4 # v2.7.0
with:
key: ${{ secrets.CI_SSH_KEY }}
name: id_rsa
known_hosts: ${{ secrets.CI_SSH_KNOWN_HOSTS }}
- name: Run CI
run: bash test/ssh-ci/rigging.sh ${{ matrix.host }}
env:
GITHUB_RUN_ID: ${{ github.run_id }}

View File

@ -41,6 +41,7 @@ This page contains a non-exhaustive list with all websites using Anubis.
- https://minihoot.site
- https://catgirl.click/
- https://wiki.dolphin-emu.org/
- https://squirreljme.cc/
- <details>
<summary>FreeCAD</summary>
- https://forum.freecad.org/

2
go.mod
View File

@ -39,7 +39,7 @@ require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cli/browser v1.3.0 // indirect
github.com/cli/go-gh v0.1.0 // indirect
github.com/cloudflare/circl v1.6.0 // indirect
github.com/cloudflare/circl v1.6.1 // indirect
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
github.com/deckarep/golang-set/v2 v2.8.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect

4
go.sum
View File

@ -67,8 +67,8 @@ github.com/cli/go-gh v0.1.0 h1:kMqFmC3ECBrV2UKzlOHjNOTTchExVc5tjNHtCqk/zYk=
github.com/cli/go-gh v0.1.0/go.mod h1:eTGWl99EMZ+3Iau5C6dHyGAJRRia65MtdBtuhWc+84o=
github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q=
github.com/cli/shurcooL-graphql v0.0.1/go.mod h1:U7gCSuMZP/Qy7kbqkk5PrqXEeDgtfG5K+W+u8weorps=
github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk=
github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=

View File

@ -290,15 +290,15 @@ func (s *Server) MakeChallenge(w http.ResponseWriter, r *http.Request) {
return
}
lg = lg.With("check_result", cr)
challenge := s.challengeFor(r, rule.Challenge.Difficulty)
chal := s.challengeFor(r, rule.Challenge.Difficulty)
s.SetCookie(w, anubis.TestCookieName, challenge, "/")
s.SetCookie(w, anubis.TestCookieName, chal, "/")
err = encoder.Encode(struct {
Rules *config.ChallengeRules `json:"rules"`
Challenge string `json:"challenge"`
}{
Challenge: challenge,
Challenge: chal,
Rules: rule.Challenge,
})
if err != nil {
@ -306,7 +306,7 @@ func (s *Server) MakeChallenge(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
return
}
lg.Debug("made challenge", "challenge", challenge, "rules", rule.Challenge, "cr", cr)
lg.Debug("made challenge", "challenge", chal, "rules", rule.Challenge, "cr", cr)
challengesIssued.WithLabelValues("api").Inc()
}
@ -319,7 +319,7 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
cookiePath = strings.TrimSuffix(anubis.BasePrefix, "/") + "/"
}
if _, err := r.Cookie(anubis.TestCookieName); err == http.ErrNoCookie {
if _, err := r.Cookie(anubis.TestCookieName); errors.Is(err, http.ErrNoCookie) {
s.ClearCookie(w, s.cookieName, cookiePath)
s.ClearCookie(w, anubis.TestCookieName, "/")
lg.Warn("user has cookies disabled, this is not an anubis bug")
@ -367,7 +367,7 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
challengeStr := s.challengeFor(r, rule.Challenge.Difficulty)
if err := impl.Validate(r, lg, rule, challengeStr); err != nil {
failedValidations.WithLabelValues(string(rule.Challenge.Algorithm)).Inc()
failedValidations.WithLabelValues(rule.Challenge.Algorithm).Inc()
var cerr *challenge.Error
s.ClearCookie(w, s.cookieName, cookiePath)
lg.Debug("challenge validate call failed", "err", err)

View File

@ -71,6 +71,9 @@ func LoadPoliciesOrDefault(fname string, defaultDifficulty int) (*policy.ParsedC
}(fin)
anubisPolicy, err := policy.ParseConfig(fin, fname, defaultDifficulty)
if err != nil {
return nil, fmt.Errorf("can't parse policy file %s: %w", fname, err)
}
var validationErrs []error
for _, b := range anubisPolicy.Bots {

View File

@ -12,7 +12,7 @@ require (
require (
cel.dev/expr v0.24.0 // indirect
github.com/a-h/templ v0.3.865 // indirect
github.com/a-h/templ v0.3.898 // indirect
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
@ -32,9 +32,9 @@ require (
github.com/stoewer/go-strcase v1.3.0 // indirect
github.com/yl2chen/cidranger v1.0.2 // indirect
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect
golang.org/x/net v0.40.0 // indirect
golang.org/x/net v0.41.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.25.0 // indirect
golang.org/x/text v0.26.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect
google.golang.org/protobuf v1.36.6 // indirect

View File

@ -2,6 +2,7 @@ cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY=
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
github.com/a-h/templ v0.3.865 h1:nYn5EWm9EiXaDgWcMQaKiKvrydqgxDUtT1+4zU2C43A=
github.com/a-h/templ v0.3.865/go.mod h1:oLBbZVQ6//Q6zpvSMPTuBK0F3qOtBdFBcGRspcT+VNQ=
github.com/a-h/templ v0.3.898/go.mod h1:oLBbZVQ6//Q6zpvSMPTuBK0F3qOtBdFBcGRspcT+VNQ=
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@ -73,10 +74,12 @@ golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ=
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237 h1:Kog3KlB4xevJlAcbbbzPfRG0+X9fdoGM+UBRKVz6Wr0=
google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237/go.mod h1:ezi0AVyMKDWy5xAncvjLWH7UcLBB5n7y2fQ8MzjJcto=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 h1:cJfm9zPbe1e873mHJzmQ1nwVEeRDU/T1wXDK2kUSU34=

5
test/ssh-ci/Dockerfile Normal file
View File

@ -0,0 +1,5 @@
ARG ALPINE_VERSION=3.22
FROM alpine:${ALPINE_VERSION}
RUN apk add -U go nodejs git build-base git npm bash zstd brotli gzip
LABEL org.opencontainers.image.source="https://github.com/TecharoHQ/anubis"

View File

@ -0,0 +1,26 @@
variable "ALPINE_VERSION" { default = "3.22" }
group "default" {
targets = [
"ci-runner",
]
}
target "ci-runner" {
args = {
ALPINE_VERSION = "3.22"
}
context = "."
dockerfile = "./Dockerfile"
platforms = [
"linux/amd64",
"linux/arm64",
"linux/arm/v7",
"linux/ppc64le",
"linux/riscv64",
]
pull = true
tags = [
"ghcr.io/techarohq/anubis/ci-runner:latest"
]
}

View File

@ -0,0 +1,8 @@
#!/usr/bin/env sh
set -euo pipefail
set -x
npm ci
npm run build
SKIP_INTEGRATION=1 go test ./...

33
test/ssh-ci/rigging.sh Normal file
View File

@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -euo pipefail
[ ! -z "${DEBUG:-}" ] && set -x
if [ "$#" -ne 1 ]; then
echo "Usage: rigging.sh <user@host>"
fi
CIRunnerImage="ghcr.io/techarohq/anubis/ci-runner:latest"
RunID=${GITHUB_RUN_ID:-$(uuidgen)}
RunFolder="anubis/runs/${RunID}"
Target="${1}"
ssh "${Target}" uname -av
ssh "${Target}" mkdir -p "${RunFolder}"
git archive HEAD | ssh "${Target}" tar xC "${RunFolder}"
ssh "${Target}" << EOF
set -euo pipefail
set -x
mkdir -p "anubis/cache/{go,go-build,node}"
podman pull ${CIRunnerImage}
podman run --rm -it \
-v "\$HOME/${RunFolder}:/app/anubis" \
-v "\$HOME/anubis/cache/go:/root/go" \
-v "\$HOME/anubis/cache/go-build:/root/.cache/go-build" \
-v "\$HOME/anubis/cache/node:/root/.npm" \
-w /app/anubis \
${CIRunnerImage} \
sh /app/anubis/test/ssh-ci/in-container.sh
ssh "${Target}" rm -rf "${RunFolder}"
EOF