Compare commits

..

2 Commits

Author SHA1 Message Date
Xe Iaso
4b6731886b test(ssh-ci): re-disable in PRs
Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-07-18 17:41:36 +00:00
Xe Iaso
0c99e4fbb0 test(ssh-ci): deflake SSH CI with exponential backoff
Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-07-18 17:38:11 +00:00
22 changed files with 119 additions and 258 deletions

View File

@@ -2,12 +2,10 @@
// README at: https://github.com/devcontainers/templates/tree/main/src/debian // README at: https://github.com/devcontainers/templates/tree/main/src/debian
{ {
"name": "Dev", "name": "Dev",
"dockerComposeFile": [ "dockerComposeFile": ["./docker-compose.yaml"],
"./docker-compose.yaml"
],
"service": "workspace", "service": "workspace",
"workspaceFolder": "/workspace/anubis", "workspaceFolder": "/workspace/anubis",
"postStartCommand": "bash ./.devcontainer/poststart.sh", "postStartCommand": "npm ci && go mod download",
"features": { "features": {
"ghcr.io/xe/devcontainer-features/ko:1.1.0": {}, "ghcr.io/xe/devcontainer-features/ko:1.1.0": {},
"ghcr.io/devcontainers/features/github-cli:1": {} "ghcr.io/devcontainers/features/github-cli:1": {}
@@ -21,9 +19,8 @@
"golang.go", "golang.go",
"unifiedjs.vscode-mdx", "unifiedjs.vscode-mdx",
"a-h.templ", "a-h.templ",
"redhat.vscode-yaml", "redhat.vscode-yaml"
"matthewpi.caddyfile-support"
] ]
} }
} }
} }

View File

@@ -20,11 +20,7 @@ services:
dockerfile: .devcontainer/Dockerfile dockerfile: .devcontainer/Dockerfile
volumes: volumes:
- ../:/workspace/anubis:cached - ../:/workspace/anubis:cached
- node_modules:/workspace/anubis/node_modules
environment: environment:
VALKEY_URL: redis://valkey:6379/0 VALKEY_URL: redis://valkey:6379/0
#entrypoint: ["/usr/bin/sleep", "infinity"] #entrypoint: ["/usr/bin/sleep", "infinity"]
user: vscode user: vscode
volumes:
node_modules:

View File

@@ -1,10 +0,0 @@
#!/usr/bin/env bash
sudo chown -R vscode:vscode ./node_modules
npm ci &
go mod download &
go install ./utils/cmd/... &
go install mvdan.cc/sh/v3/cmd/shfmt@latest &
wait

View File

@@ -5,6 +5,7 @@ amazonbot
anthro anthro
anubis anubis
anubistest anubistest
apk
Applebot Applebot
archlinux archlinux
asnc asnc
@@ -32,7 +33,7 @@ byteslice
Bytespider Bytespider
cachebuster cachebuster
cachediptoasn cachediptoasn
caddyfile Caddyfile
caninetools caninetools
Cardyb Cardyb
celchecker celchecker
@@ -59,6 +60,7 @@ connnection
containerbuild containerbuild
coreutils coreutils
Cotoyogi Cotoyogi
CRDs
Cromite Cromite
crt crt
Cscript Cscript
@@ -159,6 +161,7 @@ jshelter
JWTs JWTs
kagi kagi
kagibot kagibot
keikaku
Keyfunc Keyfunc
keypair keypair
KHTML KHTML
@@ -181,13 +184,13 @@ lol
lominsa lominsa
maintainership maintainership
malware malware
matthewpi
mcr mcr
memes memes
metarefresh metarefresh
metrix metrix
mimi mimi
Minfilia Minfilia
minica
mistralai mistralai
Mojeek Mojeek
mojeekbot mojeekbot
@@ -222,7 +225,6 @@ pipefail
pki pki
podkova podkova
podman podman
poststart
prebaked prebaked
privkey privkey
promauto promauto
@@ -242,7 +244,9 @@ redhat
redir redir
redirectscheme redirectscheme
refactors refactors
relayd
reputational reputational
reqmeta
risc risc
ruleset ruleset
runlevels runlevels
@@ -254,6 +258,7 @@ searchbot
searx searx
sebest sebest
secretplans secretplans
selfsigned
Semrush Semrush
Seo Seo
setsebool setsebool
@@ -296,8 +301,10 @@ uberspace
Unbreak Unbreak
unbreakdocker unbreakdocker
unifiedjs unifiedjs
unixhttpd
unmarshal unmarshal
unparseable unparseable
uuidgen
uvx uvx
UXP UXP
valkey valkey
@@ -321,6 +328,7 @@ wordpress
Workaround Workaround
workdir workdir
wpbot wpbot
xcaddy
Xeact Xeact
xeiaso xeiaso
xeserv xeserv

View File

@@ -14,12 +14,10 @@ jobs:
strategy: strategy:
matrix: matrix:
test: test:
- caddy
- git-clone - git-clone
- git-push - git-push
- healthcheck - healthcheck
- i18n - i18n
- unix-socket-xff
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: Checkout code - name: Checkout code

View File

@@ -5,7 +5,6 @@
"golang.go", "golang.go",
"unifiedjs.vscode-mdx", "unifiedjs.vscode-mdx",
"a-h.templ", "a-h.templ",
"redhat.vscode-yaml", "redhat.vscode-yaml"
"matthewpi.caddyfile-support"
] ]
} }

View File

@@ -166,19 +166,19 @@ func setupListener(network string, address string) (net.Listener, string) {
// additional permission handling for unix sockets // additional permission handling for unix sockets
if network == "unix" { if network == "unix" {
slog.Debug("parsing socket mode", "mode_string", *socketMode, "address", address)
mode, err := strconv.ParseUint(*socketMode, 8, 0) mode, err := strconv.ParseUint(*socketMode, 8, 0)
if err != nil { if err != nil {
listener.Close() listener.Close()
slog.Error("could not parse socket mode", "mode", *socketMode, "err", err) log.Fatal(fmt.Errorf("could not parse socket mode %s: %w", *socketMode, err))
os.Exit(1)
} }
if err := os.Chmod(address, os.FileMode(mode)); err != nil { err = os.Chmod(address, os.FileMode(mode))
// Ignore chmod errors on Unix domain sockets - this is expected behavior if err != nil {
// on many systems/containers where socket permissions cannot be changed err := listener.Close()
slog.Debug("chmod failed on socket (ignoring)", "path", address, "err", err) if err != nil {
log.Printf("failed to close listener: %v", err)
}
log.Fatal(fmt.Errorf("could not change socket mode: %w", err))
} }
} }

View File

@@ -12,16 +12,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
<!-- This changes the project to: --> <!-- This changes the project to: -->
- Expired records are now properly removed from bbolt databases ([#848](https://github.com/TecharoHQ/anubis/pull/848)).
- Fix hanging on service restart ([#853](https://github.com/TecharoHQ/anubis/issues/853)) - Fix hanging on service restart ([#853](https://github.com/TecharoHQ/anubis/issues/853))
### Added
Anubis now supports these new languages:
- [Czech](https://github.com/TecharoHQ/anubis/pull/849)
## v1.21.0: Minfilia Warde ## v1.21.0: Minfilia Warde
> Please, be at ease. You are among friends here. > Please, be at ease. You are among friends here.

View File

@@ -1,64 +0,0 @@
{
"loading": "Načítám...",
"why_am_i_seeing": "Proč to vidím?",
"protected_by": "Chráněno pomocí",
"protected_from": "Od",
"made_with": "Vytvořeno s ❤️ v 🇨🇦",
"mascot_design": "Design maskota od",
"ai_companies_explanation": "Vidíte to proto, že správce této webové stránky nastavil Anubis na ochranu serveru před pohromou AI společností agresivně stahujících webové stránky. To může, a také způsobuje výpadky webových stránek, což je činí nepřístupnými pro všechny.",
"anubis_compromise": "Anubis je kompromis. Anubis používá schéma Proof-of-Work v duchu Hashcash, návrhu schématu proof-of-work pro snížení e-mailového spamu. Myšlenka je, že na individuálních úrovních je dodatečná zátěž zanedbatelná, ale na úrovni masového použití se sčítá a činí stahování mnohem dražším.",
"hack_purpose": "Ve výsledku je to hack, jehož skutečným účelem je poskytnout \"dostatečně dobré\" prozatímní řešení, které nám poskytuje čas pracovat na ověřování a identifikaci robotů (např. prostřednictvím toho, jak vykreslují fonty), tak aby stránka s výzvou proof of work nemusela být prezentována uživatelům, kteří jsou legitimní.",
"jshelter_note": "Upozorňujeme, že Anubis vyžaduje použití moderních funkcí JavaScriptu, které rozšíření jako JShelter omezují. Prosím zakažte JShelter nebo jiná podobná rozšíření pro tuto doménu.",
"version_info": "Tato webová stránka běží na Anubis verzi",
"try_again": "Zkusit znovu",
"go_home": "Přejít na úvodní stránku",
"contact_webmaster": "nebo pokud si myslíte, že byste neměli být blokováni, kontaktujte správce na",
"connection_security": "Prosím počkejte chvilku, zatímco zajišťujeme bezpečnost vašeho připojení.",
"javascript_required": "Bohužel musíte povolit JavaScript, abyste prošli touto výzvou. To je vyžadováno proto, že AI společnosti změnily společenskou smlouvu ohledně toho, jak funguje hosting webových stránek. Řešení bez JavaScriptu je ve vývoji.",
"benchmark_requires_js": "Spuštění testovacího nástroje vyžaduje povolení JavaScriptu.",
"difficulty": "Obtížnost:",
"algorithm": "Algoritmus:",
"compare": "Porovnat:",
"time": "Čas",
"iters": "Iterace",
"time_a": "Čas A",
"iters_a": "Iterace A",
"time_b": "Čas B",
"iters_b": "Iterace B",
"static_check_endpoint": "Toto je pouze kontrolní bod pro přístup na tuto stránku.",
"authorization_required": "Vyžadována autorizace",
"cookies_disabled": "Váš prohlížeč je nakonfigurován tak, aby zakázal cookies. Anubis vyžaduje cookies pro legitimní zájem zajistit, že jste legitimní uživatel. Prosím povolte cookies pro tuto doménu",
"access_denied": "Přístup zamítnut: kód chyby",
"dronebl_entry": "DroneBL nahlásil záznam",
"see_dronebl_lookup": "viz",
"internal_server_error": "Interní chyba serveru: správce špatně nakonfiguroval Anubis. Kontaktujte správce a požádejte ho, aby se do systémových záznamů",
"invalid_redirect": "Neplatné přesměrování",
"redirect_not_parseable": "URL přesměrování nelze analyzovat",
"redirect_domain_not_allowed": "Doména přesměrování není povolena",
"failed_to_sign_jwt": "nepodařilo se podepsat JWT",
"invalid_invocation": "Neplatné vyvolání MakeChallenge",
"client_error_browser": "Chyba prohlížeče: Ujistěte se, že váš prohlížeč je aktuální a zkuste to později.",
"oh_noes": "Ale ne!",
"benchmarking_anubis": "Testování Anubise!",
"you_are_not_a_bot": "Nejste robot!",
"making_sure_not_bot": "Ujišťujeme se, že nejste robot!",
"celphase": "CELPHASE",
"js_web_crypto_error": "Váš prohlížeč nepodporuje funkci web.crypto. Používáte zabezpečené připojení?",
"js_web_workers_error": "Váš prohlížeč nepodporuje web workers (Anubis je používá, aby zabránil zamrznutí vašeho prohlížeče). Máte nainstalovano rozšíření JShelter nebo podobné?",
"js_cookies_error": "Váš prohlížeč neukládá cookies. Anubis používá cookies k určení, kteří klienti prošli výzvami uložením podepsaného tokenu v cookie. Prosím povolte ukládání cookies pro tuto doménu. Názvy cookies, které Anubis ukládá, se mohou měnit bez upozornění. Názvy a hodnoty cookies nejsou součástí veřejného API.",
"js_context_not_secure": "Váše připojení není bezpečné!",
"js_context_not_secure_msg": "Zkuste se připojit přes HTTPS nebo informujte správce o nastavení HTTPS. Pro více informací viz <a href=\"https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#when_is_a_context_considered_secure\">MDN</a>.",
"js_calculating": "Počítám...",
"js_missing_feature": "Chybějící funkce",
"js_challenge_error": "Chyba výzvy!",
"js_challenge_error_msg": "Nepodařilo se vyřešit kontrolní algoritmus. Možná budete chtít obnovit stránku.",
"js_calculating_difficulty": "Počítám...<br/>Obtížnost:",
"js_speed": "Rychlost:",
"js_verification_longer": "Ověřování trvá déle, než se očekávalo. Prosím neobnovujte stránku.",
"js_success": "Úspěch!",
"js_done_took": "Hotovo! Trvalo to",
"js_iterations": "iterací",
"js_finished_reading": "Dokončil jsem čtení, pokračovat →",
"js_calculation_error": "Chyba výpočtu!",
"js_calculation_error_msg": "Nepodařilo se vypočítat výzvu:"
}

View File

@@ -2,7 +2,7 @@
"loading": "Naglo-load...", "loading": "Naglo-load...",
"why_am_i_seeing": "Bakit nakikita ko ito?", "why_am_i_seeing": "Bakit nakikita ko ito?",
"protected_by": "Pinoprotekta ng", "protected_by": "Pinoprotekta ng",
"protected_from": "mula sa", "protected_from": "From",
"made_with": "Ginawa na may ❤️ sa 🇨🇦", "made_with": "Ginawa na may ❤️ sa 🇨🇦",
"mascot_design": "Disenyo ng Maskot ni/ng", "mascot_design": "Disenyo ng Maskot ni/ng",
"ai_companies_explanation": "Nakikita mo ito dahil ang tagapangasiwa ng website na ito ay nag-set up ng Anubis upang protektahan ang server laban sa salot ng mga kumpanya ng AI na aggresibong nagse-scrape ng mga website. Maaari nitong magdulot ng downtime para sa mga website, na gagawing hindi naa-access ang kanilang mga resource para sa lahat.", "ai_companies_explanation": "Nakikita mo ito dahil ang tagapangasiwa ng website na ito ay nag-set up ng Anubis upang protektahan ang server laban sa salot ng mga kumpanya ng AI na aggresibong nagse-scrape ng mga website. Maaari nitong magdulot ng downtime para sa mga website, na gagawing hindi naa-access ang kanilang mga resource para sa lahat.",

View File

@@ -1,6 +1,5 @@
{ {
"supportedLanguages": [ "supportedLanguages": [
"cs",
"de", "de",
"en", "en",
"es", "es",

View File

@@ -142,7 +142,7 @@ func (s *Store) cleanup(ctx context.Context) error {
} }
if now.After(expiry) { if now.After(expiry) {
return tx.DeleteBucket(key) return valueBkt.DeleteBucket(key)
} }
return nil return nil

View File

@@ -1,10 +0,0 @@
bots:
- name: challenge
user_agent_regex: Mozilla
action: WEIGH
weight:
adjust: 10
status_codes:
CHALLENGE: 401
DENY: 403

View File

@@ -1,5 +1,12 @@
caddy.local.cetacean.club { :80 {
tls internal reverse_proxy http://anubis:3000 {
header_up X-Real-Ip {remote_host}
header_up X-Http-Version {http.request.proto}
}
}
:443 {
tls /etc/techaro/pki/caddy.local.cetacean.club/cert.pem /etc/techaro/pki/caddy.local.cetacean.club/key.pem
reverse_proxy http://anubis:3000 { reverse_proxy http://anubis:3000 {
header_up X-Real-Ip {remote_host} header_up X-Real-Ip {remote_host}

View File

@@ -5,16 +5,18 @@ services:
ports: ports:
- 8080:80 - 8080:80
- 8443:443 - 8443:443
volumes:
- "../pki/caddy.local.cetacean.club:/etc/techaro/pki/caddy.local.cetacean.club/"
anubis: anubis:
image: ghcr.io/techarohq/anubis image: ghcr.io/techarohq/anubis:main
environment: environment:
BIND: ":3000" BIND: ":3000"
TARGET: http://httpdebug:3000 TARGET: http://httpdebug:3000
POLICY_FNAME: /cfg/less_paranoid.yaml POLICY_FNAME: /etc/techaro/anubis/less_paranoid.yaml
SLOG_LEVEL: DEBUG
volumes: volumes:
- ../anubis_configs:/cfg - ../anubis_configs:/etc/techaro/anubis
httpdebug: httpdebug:
image: ghcr.io/xe/x/httpdebug image: ghcr.io/xe/x/httpdebug
pull_policy: always

22
test/caddy/start.sh Normal file
View File

@@ -0,0 +1,22 @@
#!/usr/bin/env bash
# If the transient local TLS certificate doesn't exist, mint a new one
if [ ! -f ../pki/caddy.local.cetacean.club/cert.pem ]; then
# Subshell to contain the directory change
(
cd ../pki \
&& mkdir -p caddy.local.cetacean.club \
&& \
# Try using https://github.com/FiloSottile/mkcert for better DevEx,
# but fall back to using https://github.com/jsha/minica in case
# you don't have that installed.
(
mkcert \
--cert-file ./caddy.local.cetacean.club/cert.pem \
--key-file ./caddy.local.cetacean.club/key.pem caddy.local.cetacean.club \
|| go tool minica -domains caddy.local.cetacean.club
)
)
fi
docker compose up --build

View File

@@ -1,27 +0,0 @@
async function testWithUserAgent(userAgent) {
const statusCode =
await fetch("https://caddy.local.cetacean.club:8443/reqmeta", {
headers: {
"User-Agent": userAgent,
}
})
.then(resp => resp.status);
return statusCode;
}
const codes = {
Mozilla: await testWithUserAgent("Mozilla"),
curl: await testWithUserAgent("curl"),
}
const expected = {
Mozilla: 401,
curl: 200,
};
console.log("Mozilla:", codes.Mozilla);
console.log("curl: ", codes.curl);
if (JSON.stringify(codes) !== JSON.stringify(expected)) {
throw new Error(`wanted ${JSON.stringify(expected)}, got: ${JSON.stringify(codes)}`);
}

View File

@@ -1,17 +0,0 @@
#!/usr/bin/env bash
set -x
set -euo pipefail
source ../lib/lib.sh
build_anubis_ko
docker compose up -d --build
export NODE_TLS_REJECT_UNAUTHORIZED=0
sleep 2
backoff-retry node test.mjs

View File

@@ -20,4 +20,4 @@ go tool anubis \
--use-remote-address \ --use-remote-address \
--target=unix://$(pwd)/unixhttpd.sock & --target=unix://$(pwd)/unixhttpd.sock &
backoff-retry node ./test.mjs go run ../cmd/backoff-retry node ./test.mjs

View File

@@ -1,54 +0,0 @@
REPO_ROOT=$(git rev-parse --show-toplevel)
(cd $REPO_ROOT && go install ./utils/cmd/...)
function cleanup() {
pkill -P $$
if [ -f "docker-compose.yaml" ]; then
docker compose down
fi
}
trap cleanup EXIT SIGINT
function build_anubis_ko() {
(
cd ../.. &&
VERSION=devel ko build \
--platform=all \
--base-import-paths \
--tags="latest" \
--image-user=1000 \
--image-annotation="" \
--image-label="" \
./cmd/anubis \
--local
)
}
function mint_cert() {
if [ "$#" -ne 1 ]; then
echo "Usage: mint_cert <domain.name>"
fi
domainName="$1"
# If the transient local TLS certificate doesn't exist, mint a new one
if [ ! -f "../pki/${domainName}/cert.pem" ]; then
# Subshell to contain the directory change
(
cd ../pki &&
mkdir -p "${domainName}" &&
# Try using https://github.com/FiloSottile/mkcert for better DevEx,
# but fall back to using https://github.com/jsha/minica in case
# you don't have that installed.
(
mkcert \
--cert-file ./"${domainName}"/cert.pem \
--key-file ./"${domainName}"/key.pem \
"${domainName}" ||
go tool minica -domains "${domainName}"
)
)
fi
}

55
test/unix-socket-xff/start.sh Executable file
View File

@@ -0,0 +1,55 @@
#!/usr/bin/env bash
set -euo pipefail
# Remove lingering .sock files, relayd and unixhttpd will do that too but
# measure twice, cut once.
rm *.sock ||:
# If the transient local TLS certificate doesn't exist, mint a new one
if [ ! -f ../pki/relayd.local.cetacean.club/cert.pem ]; then
# Subshell to contain the directory change
(
cd ../pki \
&& mkdir -p relayd.local.cetacean.club \
&& \
# Try using https://github.com/FiloSottile/mkcert for better DevEx,
# but fall back to using https://github.com/jsha/minica in case
# you don't have that installed.
(
mkcert \
--cert-file ./relayd.local.cetacean.club/cert.pem \
--key-file ./relayd.local.cetacean.club/key.pem relayd.local.cetacean.club \
|| go tool minica -domains relayd.local.cetacean.club
)
)
fi
# Build static assets
(cd ../.. && npm ci && npm run assets)
# Spawn three jobs:
# HTTP daemon that listens over a unix socket (implicitly ./unixhttpd.sock)
go run ../cmd/unixhttpd &
# A copy of Anubis, specifically for the current Git checkout
go tool anubis \
--bind=./anubis.sock \
--bind-network=unix \
--policy-fname=../anubis_configs/aggressive_403.yaml \
--target=unix://$(pwd)/unixhttpd.sock &
# A simple TLS terminator that forwards to Anubis, which will forward to
# unixhttpd
go run ../cmd/relayd \
--proxy-to=unix://./anubis.sock \
--cert-dir=../pki/relayd.local.cetacean.club &
# When you press control c, kill all the child processes to clean things up
trap 'echo signal received!; kill $(jobs -p); wait' SIGINT SIGTERM
echo "open https://relayd.local.cetacean.club:3004/reqmeta"
# Wait for all child processes to exit
wait

View File

@@ -1,33 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
source ../lib/lib.sh
mint_cert "relayd.local.cetacean.club"
# Build static assets
(cd ../.. && npm ci && npm run assets)
# Spawn three jobs:
# HTTP daemon that listens over a unix socket (implicitly ./unixhttpd.sock)
go run ../cmd/unixhttpd &
# A copy of Anubis, specifically for the current Git checkout
go tool anubis \
--bind=./anubis.sock \
--bind-network=unix \
--socket-mode=0700 \
--policy-fname=../anubis_configs/aggressive_403.yaml \
--target=unix://$(pwd)/unixhttpd.sock &
# A simple TLS terminator that forwards to Anubis, which will forward to
# unixhttpd
go run ../cmd/relayd \
--proxy-to=unix://./anubis.sock \
--cert-dir=../pki/relayd.local.cetacean.club &
export NODE_TLS_REJECT_UNAUTHORIZED=0
backoff-retry node test.mjs