Compare commits

...

9 Commits

Author SHA1 Message Date
Xe Iaso
b12c5945b3 test(caddy): why are you failing?
Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-07-19 04:51:12 +00:00
Xe Iaso
b320af79ee test(caddy): fix automated testing?
Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-07-19 04:48:43 +00:00
Xe Iaso
cf510eeace chore: spelling
Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-07-19 00:46:23 -04:00
Xe Iaso
a47e781d91 test(caddy): fix automated testing
Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-07-19 04:44:34 +00:00
Xe Iaso
06122fcd89 chore(devcontainer): put node_modules in a volume
Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-07-18 22:07:22 -04:00
Xe Iaso
950ec24cf1 ci: enable caddy and unix-socket-xff tests
Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-07-18 22:07:06 -04:00
Xe Iaso
7cfefcd882 test: make unix-socket-xff into a smoke test
Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-07-18 22:06:00 -04:00
Xe Iaso
eacc001d69 fix(cmd/anubis): ignore errors for unix socket chmod
Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-07-18 22:03:07 -04:00
Xe Iaso
7ca45f72e3 test: adapt caddy testing environment into a smoke test
Signed-off-by: Xe Iaso <me@xeiaso.net>
2025-07-18 22:02:34 -04:00
16 changed files with 169 additions and 104 deletions

View File

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

View File

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

View File

@@ -1,9 +1,10 @@
#!/usr/bin/env bash
pwd
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

@@ -32,7 +32,7 @@ byteslice
Bytespider
cachebuster
cachediptoasn
Caddyfile
caddyfile
caninetools
Cardyb
celchecker
@@ -181,6 +181,7 @@ lol
lominsa
maintainership
malware
matthewpi
mcr
memes
metarefresh

View File

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

View File

@@ -5,6 +5,7 @@
"golang.go",
"unifiedjs.vscode-mdx",
"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
if network == "unix" {
slog.Debug("parsing socket mode", "mode_string", *socketMode, "address", address)
mode, err := strconv.ParseUint(*socketMode, 8, 0)
if err != nil {
listener.Close()
log.Fatal(fmt.Errorf("could not parse socket mode %s: %w", *socketMode, err))
slog.Error("could not parse socket mode", "mode", *socketMode, "err", err)
os.Exit(1)
}
err = os.Chmod(address, os.FileMode(mode))
if err != nil {
err := listener.Close()
if err != nil {
log.Printf("failed to close listener: %v", err)
}
log.Fatal(fmt.Errorf("could not change socket mode: %w", err))
if err := os.Chmod(address, os.FileMode(mode)); err != nil {
// Ignore chmod errors on Unix domain sockets - this is expected behavior
// on many systems/containers where socket permissions cannot be changed
slog.Debug("chmod failed on socket (ignoring)", "path", address, "err", err)
}
}

View File

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

View File

@@ -1,12 +1,5 @@
:80 {
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
caddy.local.cetacean.club {
tls internal
reverse_proxy http://anubis:3000 {
header_up X-Real-Ip {remote_host}

View File

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

View File

@@ -1,22 +0,0 @@
#!/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

27
test/caddy/test.mjs Normal file
View File

@@ -0,0 +1,27 @@
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)}`);
}

17
test/caddy/test.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/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

54
test/lib/lib.sh Normal file
View File

@@ -0,0 +1,54 @@
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
}

View File

@@ -1,55 +0,0 @@
#!/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

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

@@ -0,0 +1,33 @@
#!/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