174d282fd9
- adguard-cert-sync.service / .timer: unidades systemd para renovar automáticamente el certificado TLS de AdGuard cuando Traefik lo renueva - sync-adguard-cert.sh: script que copia cert desde /opt/traefik/certs y reinicia AdGuard vía API - docker-compose.yml y stack.env: ajustes menores - README.md: documentación actualizada con instrucciones de instalación Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
101 lines
2.9 KiB
Bash
101 lines
2.9 KiB
Bash
#!/usr/bin/env bash
|
|
# Extrae el certificado de adblock.sherlockhomeless.net desde Traefik
|
|
# y lo inyecta en la configuración de AdGuard Home, reiniciando el contenedor.
|
|
set -euo pipefail
|
|
|
|
ACME_JSON="/opt/traefik/letsencrypt/acme.json"
|
|
ADGUARD_CONFIG="/opt/adguard/conf/AdGuardHome.yaml"
|
|
DOMAIN="adblock.sherlockhomeless.net"
|
|
CERT_FILE="/opt/traefik/certs/adguard.crt"
|
|
KEY_FILE="/opt/traefik/certs/adguard.key"
|
|
|
|
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; }
|
|
|
|
# 1. Extraer cert y key del acme.json de Traefik
|
|
log "Extrayendo certificado para $DOMAIN..."
|
|
python3 << PYEOF
|
|
import json, base64, sys
|
|
|
|
with open("$ACME_JSON") as f:
|
|
data = json.load(f)
|
|
|
|
found = False
|
|
for resolver, rdata in data.items():
|
|
for cert in rdata.get("Certificates", []):
|
|
if cert.get("domain", {}).get("main") == "$DOMAIN":
|
|
with open("$CERT_FILE", "w") as f:
|
|
f.write(base64.b64decode(cert["certificate"]).decode())
|
|
with open("$KEY_FILE", "w") as f:
|
|
f.write(base64.b64decode(cert["key"]).decode())
|
|
found = True
|
|
break
|
|
if found:
|
|
break
|
|
|
|
if not found:
|
|
print("ERROR: certificado para $DOMAIN no encontrado en acme.json", file=sys.stderr)
|
|
sys.exit(1)
|
|
print("OK: certificado extraído")
|
|
PYEOF
|
|
|
|
# 2. Comprobar si el cert en AdGuard ya es el mismo (evitar restart innecesario)
|
|
CURRENT_FINGERPRINT=$(openssl x509 -in "$CERT_FILE" -noout -fingerprint -sha256 2>/dev/null | cut -d= -f2)
|
|
ADGUARD_CERT=$(python3 -c "
|
|
import re
|
|
with open('$ADGUARD_CONFIG') as f:
|
|
content = f.read()
|
|
m = re.search(r'certificate_chain: \|-\n((?: .+\n)+)', content)
|
|
if m:
|
|
print(m.group(1).replace(' ', ''))
|
|
" 2>/dev/null)
|
|
ADGUARD_FINGERPRINT=$(echo "$ADGUARD_CERT" | openssl x509 -noout -fingerprint -sha256 2>/dev/null | cut -d= -f2)
|
|
|
|
if [ "$CURRENT_FINGERPRINT" = "$ADGUARD_FINGERPRINT" ]; then
|
|
log "El certificado de AdGuard ya está actualizado. Nada que hacer."
|
|
exit 0
|
|
fi
|
|
|
|
log "Certificado nuevo detectado. Actualizando AdGuardHome.yaml..."
|
|
|
|
# 3. Inyectar cert y key en el YAML de AdGuard
|
|
python3 << PYEOF
|
|
import re
|
|
|
|
with open("$CERT_FILE") as f:
|
|
new_cert = f.read().strip()
|
|
with open("$KEY_FILE") as f:
|
|
new_key = f.read().strip()
|
|
|
|
def indent(text, spaces=4):
|
|
return "\n".join(" " * spaces + line for line in text.splitlines())
|
|
|
|
with open("$ADGUARD_CONFIG") as f:
|
|
content = f.read()
|
|
|
|
content = re.sub(
|
|
r'(tls:.*?server_name:\s*)\S+',
|
|
r'\g<1>$DOMAIN',
|
|
content, flags=re.DOTALL
|
|
)
|
|
content = re.sub(
|
|
r' certificate_chain: \|-\n(?: .*\n)+',
|
|
f" certificate_chain: |-\n{indent(new_cert)}\n",
|
|
content
|
|
)
|
|
content = re.sub(
|
|
r' private_key: \|-\n(?: .*\n)+',
|
|
f" private_key: |-\n{indent(new_key)}\n",
|
|
content
|
|
)
|
|
|
|
with open("$ADGUARD_CONFIG", "w") as f:
|
|
f.write(content)
|
|
|
|
print("OK: config actualizado")
|
|
PYEOF
|
|
|
|
# 4. Reiniciar AdGuard
|
|
log "Reiniciando AdGuard Home..."
|
|
docker restart adguardhome
|
|
log "Sync completado."
|