mirror of
https://github.com/CyberMind-FR/secubox-deb.git
synced 2026-07-29 15:37:03 +00:00
* fix(secubox-yacy): ship public vhost + acme-challenge block (closes #246) The yacy.maegia.tv public vhost was previously hand-crafted on the board and not shipped by the package. As a result: * `acme.sh --issue -d yacy.maegia.tv -w /usr/share/secubox/www` failed with HTTP 404 — the catch-all `location /` proxied the path to the YaCy LXC, which doesn't know about ACME. * Without a valid cert in /data/haproxy/certs/yacy.maegia.tv.pem, HAProxy SNI fallback served the alphabetically-first cert (`*.gk2.secubox.in.pem`), so browsers showed a domain-mismatch warning that looked like a self-signed cert. Fix: ship `nginx/yacy-vhost.conf` to /etc/nginx/sites-available/yacy.conf with the mandatory `^~ /.well-known/acme-challenge/` block placed BEFORE the catch-all proxy, so renewals win. Board-validated 2026-05-20: cert issued (LE E7, exp 2026-08-18), HAProxy reloaded, `openssl s_client -servername yacy.maegia.tv` returns subject=CN = yacy.maegia.tv. Closes #246 * feat(secubox-yacy): auto-inject admin Digest hash at install (ref #246) Earlier the operator couldn't log in to https://yacy.maegia.tv/ even though install-lxc.sh had generated a strong password in /etc/secubox/secrets/yacy-admin. The reason: that password was never written into yacy.conf — the LXC kept YaCy's installed default adminAccountBase64MD5 hash, which doesn't match the password file. install-lxc.sh now runs configure_yacy_admin() after the .deb install: * Reads /etc/secubox/secrets/yacy-admin * Pulls the actual adminRealm from yacy.conf inside the LXC (YaCy uses a long human-readable sentence, NOT the literal string "YaCy", and the realm is part of the Digest hash input) * Computes MD5("admin:<realm>:<password>") host-side via md5sum (matches what YaCy's own bin/passwd.sh produces via Digest -strfhex) * Writes adminAccountBase64MD5=MD5:<hash> to yacy.conf if it doesn't already match (idempotent) Board-validated 2026-05-20: * Reset the hash to MD5:000... before install * Ran `yacyctl install` after deploying v1.0.9 * Verified: expected hash == actual hash (MATCH) * curl --digest -u admin:<pw> https://yacy.maegia.tv/Settings_p.html → HTTP 200 Removes a UX paper-cut: post-install login works on first hit without any manual `bin/passwd.sh` dance inside the LXC. --------- Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
This commit is contained in:
parent
262c0c3138
commit
b0b2b9293b
|
|
@ -1,3 +1,40 @@
|
|||
secubox-yacy (1.0.9-1~bookworm1) bookworm; urgency=medium
|
||||
|
||||
* install-lxc.sh: new configure_yacy_admin() step injects the generated
|
||||
admin password into yacy.conf as a Digest hash so the admin login
|
||||
works on first hit. Before this, the operator had a password file at
|
||||
/etc/secubox/secrets/yacy-admin but the actual yacy.conf still
|
||||
carried YaCy's installed default hash — login always failed until
|
||||
someone manually ran `bin/passwd.sh` inside the LXC.
|
||||
* Hash format: MD5 of "admin:<adminRealm>:<password>", matching what
|
||||
YaCy's own bin/passwd.sh script computes via Digest -strfhex.
|
||||
* Idempotent: only patches yacy.conf when the current hash doesn't
|
||||
already match the password file (re-running `yacyctl install` is
|
||||
a no-op once aligned).
|
||||
* Note: the realm string is pulled from the running yacy.conf at
|
||||
install time — YaCy uses a long human-readable sentence as the
|
||||
Digest realm, not the bare string "YaCy", and the realm IS part of
|
||||
the hash input.
|
||||
|
||||
-- Gerald KERMA <devel@cybermind.fr> Wed, 20 May 2026 21:30:00 +0200
|
||||
|
||||
secubox-yacy (1.0.8-1~bookworm1) bookworm; urgency=medium
|
||||
|
||||
* Ship the public-facing yacy.maegia.tv vhost as
|
||||
/etc/nginx/sites-available/yacy.conf (from nginx/yacy-vhost.conf).
|
||||
Operator enables with `ln -s ../sites-available/yacy.conf
|
||||
/etc/nginx/sites-enabled/`. Was previously hand-crafted on the board.
|
||||
* The shipped vhost now carries the `^~ /.well-known/acme-challenge/`
|
||||
block so `acme.sh --issue -d yacy.maegia.tv -w /usr/share/secubox/www`
|
||||
succeeds — without it, every renewal proxies the path to the YaCy
|
||||
LXC which 404s, and HAProxy falls back to the alphabetically-first
|
||||
cert (`*.gk2.secubox.in.pem`), making browsers reject the connection.
|
||||
* Board-validated 2026-05-20: cert issued (LE E7, exp 2026-08-18),
|
||||
HAProxy reloaded, `openssl s_client -servername yacy.maegia.tv`
|
||||
returns `subject=CN = yacy.maegia.tv`. Closes #246.
|
||||
|
||||
-- Gerald KERMA <devel@cybermind.fr> Wed, 20 May 2026 18:00:00 +0200
|
||||
|
||||
secubox-yacy (1.0.7-1~bookworm1) bookworm; urgency=medium
|
||||
|
||||
* install-lxc.sh: update YACY_RELEASE_URL to v1.941 (the v1.940 tarball
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ override_dh_auto_install:
|
|||
[ -d menu.d ] && cp -r menu.d/. debian/secubox-yacy/usr/share/secubox/menu.d/ || true
|
||||
install -d debian/secubox-yacy/etc/nginx/secubox.d
|
||||
[ -f nginx/yacy.conf ] && cp nginx/yacy.conf debian/secubox-yacy/etc/nginx/secubox.d/ || true && (install -d debian/secubox-yacy/etc/nginx/secubox-routes.d && cp nginx/yacy.conf debian/secubox-yacy/etc/nginx/secubox-routes.d/)
|
||||
# Public vhost yacy.maegia.tv — shipped to sites-available (operator opts in via ln -s)
|
||||
install -d debian/secubox-yacy/etc/nginx/sites-available
|
||||
[ -f nginx/yacy-vhost.conf ] && cp nginx/yacy-vhost.conf debian/secubox-yacy/etc/nginx/sites-available/yacy.conf || true
|
||||
install -d debian/secubox-yacy/etc/secubox
|
||||
[ -f conf/yacy.toml.example ] && cp conf/yacy.toml.example debian/secubox-yacy/etc/secubox/yacy.toml.example || true
|
||||
install -d debian/secubox-yacy/usr/share/secubox/lib/yacy
|
||||
|
|
|
|||
|
|
@ -207,10 +207,51 @@ generate_admin_password() {
|
|||
local pw; pw=$(openssl rand -hex 16)
|
||||
echo "$pw" > "$SECRETS_DIR/yacy-admin"
|
||||
chmod 600 "$SECRETS_DIR/yacy-admin"
|
||||
log "Generated YaCy admin password (set via the YaCy admin UI on first login)."
|
||||
log "Generated YaCy admin password (32 hex chars) at $SECRETS_DIR/yacy-admin"
|
||||
fi
|
||||
}
|
||||
|
||||
# Inject the generated password into YaCy's yacy.conf as a Digest hash so
|
||||
# the admin login works immediately. Without this, the operator couldn't
|
||||
# log in: YaCy's installed default hash doesn't match the password file.
|
||||
#
|
||||
# YaCy uses HTTP Digest authentication with the realm string copied from
|
||||
# the `adminRealm` pref (a long human-readable sentence). The expected
|
||||
# hash format is:
|
||||
# adminAccountBase64MD5=MD5:<md5sum of "admin:<realm>:<password>">
|
||||
#
|
||||
# Computed host-side (md5sum is in coreutils, no java dep needed; matches
|
||||
# the output of YaCy's own bin/passwd.sh script which calls
|
||||
# `net.yacy.cora.order.Digest -strfhex` internally).
|
||||
configure_yacy_admin() {
|
||||
local pw_file="$SECRETS_DIR/yacy-admin"
|
||||
[ -f "$pw_file" ] || { log "no password file at $pw_file, skipping admin inject"; return; }
|
||||
|
||||
local pw realm hash yacy_conf
|
||||
pw=$(cat "$pw_file")
|
||||
yacy_conf="/opt/yacy/DATA/SETTINGS/yacy.conf"
|
||||
|
||||
# Pull the realm string from the running YaCy config inside the LXC.
|
||||
realm=$(lxc-attach -n "$LXC_NAME" -P "$LXC_PATH" -- sh -c "grep '^adminRealm=' $yacy_conf | cut -d= -f2-" 2>/dev/null || true)
|
||||
[ -z "$realm" ] && realm="YaCy"
|
||||
|
||||
hash=$(printf 'admin:%s:%s' "$realm" "$pw" | md5sum | cut -d' ' -f1)
|
||||
[ -z "$hash" ] && { log "WARN: md5sum produced empty hash, skipping admin inject"; return; }
|
||||
|
||||
# Skip if the right hash is already set (idempotent).
|
||||
if lxc-attach -n "$LXC_NAME" -P "$LXC_PATH" -- grep -q "^adminAccountBase64MD5=MD5:${hash}$" "$yacy_conf" 2>/dev/null; then
|
||||
log "YaCy admin hash already matches generated password — skipping"
|
||||
return
|
||||
fi
|
||||
|
||||
log "Injecting YaCy admin Digest hash into yacy.conf ..."
|
||||
lxc-attach -n "$LXC_NAME" -P "$LXC_PATH" -- systemctl stop yacy 2>/dev/null || true
|
||||
# YaCy rewrites the conf when running; pause it before editing.
|
||||
lxc-attach -n "$LXC_NAME" -P "$LXC_PATH" -- sed -i \
|
||||
"s|^adminAccountBase64MD5=.*|adminAccountBase64MD5=MD5:${hash}|" "$yacy_conf"
|
||||
lxc-attach -n "$LXC_NAME" -P "$LXC_PATH" -- systemctl start yacy 2>/dev/null || true
|
||||
}
|
||||
|
||||
mark_provisioned() {
|
||||
install -d -m 0755 -o secubox -g secubox "$STATE_DIR"
|
||||
date -Iseconds > "$SENTINEL"
|
||||
|
|
@ -228,6 +269,7 @@ main() {
|
|||
ensure_resolv
|
||||
install_yacy_in_lxc
|
||||
generate_admin_password
|
||||
configure_yacy_admin
|
||||
provision_yacy
|
||||
mark_provisioned
|
||||
log "OK — LXC '$LXC_NAME' at $LXC_IP, yacy provisioned + running on port 8090."
|
||||
|
|
|
|||
62
packages/secubox-yacy/nginx/yacy-vhost.conf
Normal file
62
packages/secubox-yacy/nginx/yacy-vhost.conf
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# /etc/nginx/sites-available/yacy.conf — public vhost yacy.maegia.tv
|
||||
# Installed by secubox-yacy (#232, #246).
|
||||
#
|
||||
# Routing flow (validated 2026-05-20):
|
||||
# Browser → HAProxy:443 (TLS, cert /data/haproxy/certs/yacy.maegia.tv.pem)
|
||||
# → mitmproxy WAF (LXC) — entry registered in
|
||||
# /srv/mitmproxy/haproxy-routes.json INSIDE the mitmproxy LXC
|
||||
# → nginx:9080 (this vhost)
|
||||
# → YaCy LXC at 10.100.0.80:8090
|
||||
#
|
||||
# Operator-side prerequisites (NOT done by this snippet):
|
||||
# 1. DNS A record yacy.maegia.tv → public IP
|
||||
# 2. TLS cert in /data/haproxy/certs/yacy.maegia.tv.pem
|
||||
# acme.sh --issue -d yacy.maegia.tv -w /usr/share/secubox/www --keylength ec-256
|
||||
# ↑ relies on the ^~ /.well-known/acme-challenge/ block below
|
||||
# 3. haproxyctl vhost add yacy.maegia.tv nginx_vhosts ssl
|
||||
# ↑ CAUTION: known to drop backend defs (see #238 / v2.11.1).
|
||||
# Prefer manual ACL injection or restore haproxy.cfg from backup.
|
||||
# 4. mitmproxy route INSIDE the LXC:
|
||||
# lxc-attach -n mitmproxy -- python3 -c \
|
||||
# "import json; p='/srv/mitmproxy/haproxy-routes.json'; d=json.load(open(p)); \
|
||||
# d['yacy.maegia.tv']=['192.168.1.200',9080]; json.dump(d, open(p,'w'), indent=2, sort_keys=True)"
|
||||
# lxc-attach -n mitmproxy -- systemctl restart mitmproxy
|
||||
|
||||
server {
|
||||
listen 0.0.0.0:9080;
|
||||
server_name yacy.maegia.tv;
|
||||
|
||||
# ACME HTTP-01 challenge — MUST come before any other location so
|
||||
# acme.sh renewals win against the catch-all proxy below. Without this
|
||||
# block, every renewal returns 404 from the YaCy LXC.
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
root /usr/share/secubox/www;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# Health Banner injection (same pattern as the canonical hub vhost)
|
||||
sub_filter_types text/html;
|
||||
sub_filter_once on;
|
||||
sub_filter "</body>" '<script src="/shared/health-banner.js"></script></body>';
|
||||
|
||||
# Shared assets — banner JS, error pages
|
||||
location /shared/ {
|
||||
add_header Access-Control-Allow-Origin "*" always;
|
||||
alias /usr/share/secubox/www/shared/;
|
||||
}
|
||||
|
||||
# YaCy admin UI proxied to the LXC
|
||||
location / {
|
||||
proxy_pass http://10.100.0.80:8090/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection "";
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
|
||||
access_log /var/log/nginx/yacy_access.log;
|
||||
error_log /var/log/nginx/yacy_error.log;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user