Build Admin / Build image (push) Successful in 11s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
92 lines
3.0 KiB
Bash
Executable File
92 lines
3.0 KiB
Bash
Executable File
#!/bin/sh
|
|
# elevenlabs.io/docker-entrypoint.sh
|
|
# Generates Caddy access-control fragments from environment variables at container start.
|
|
set -e
|
|
|
|
CONF_DIR="/etc/caddy"
|
|
MATCHERS="${CONF_DIR}/matchers.caddy"
|
|
GUARD="${CONF_DIR}/guard.caddy"
|
|
SCRUB_EXTRA="${CONF_DIR}/scrub_extra.caddy"
|
|
|
|
: > "${MATCHERS}"
|
|
: > "${GUARD}"
|
|
: > "${SCRUB_EXTRA}"
|
|
|
|
# --- 0. Required settings ---
|
|
if [ -z "${DOMAIN}" ]; then
|
|
echo "[entrypoint] FATAL: DOMAIN is not set (e.g. proxy.example.com)" >&2
|
|
exit 1
|
|
fi
|
|
if [ -z "${ACME_EMAIL}" ]; then
|
|
echo "[entrypoint] FATAL: ACME_EMAIL is not set — Let's Encrypt account needs it" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# --- 1. API key header (optional: bypasses both the IP allowlist and the token check) ---
|
|
KEY_MATCH=""
|
|
if [ -n "${AUTH_HEADER_NAME}" ] || [ -n "${AUTH_HEADER_VALUE}" ]; then
|
|
if [ -z "${AUTH_HEADER_NAME}" ] || [ -z "${AUTH_HEADER_VALUE}" ]; then
|
|
echo "[entrypoint] FATAL: AUTH_HEADER_NAME and AUTH_HEADER_VALUE must be set together" >&2
|
|
exit 1
|
|
fi
|
|
case "${AUTH_HEADER_NAME}" in
|
|
*[!A-Za-z0-9-]*)
|
|
echo "[entrypoint] FATAL: AUTH_HEADER_NAME may contain only [A-Za-z0-9-]" >&2
|
|
exit 1 ;;
|
|
esac
|
|
case "${AUTH_HEADER_VALUE}" in
|
|
*[!A-Za-z0-9._~+/=-]*)
|
|
echo "[entrypoint] FATAL: AUTH_HEADER_VALUE may contain only [A-Za-z0-9._~+/=-]" >&2
|
|
exit 1 ;;
|
|
esac
|
|
KEY_MATCH="not header ${AUTH_HEADER_NAME} \"${AUTH_HEADER_VALUE}\""
|
|
echo "# strip the key header before it reaches upstreams" > "${SCRUB_EXTRA}"
|
|
echo "header_up -${AUTH_HEADER_NAME}" >> "${SCRUB_EXTRA}"
|
|
echo "[entrypoint] Header key auth configured (header: ${AUTH_HEADER_NAME})"
|
|
fi
|
|
|
|
# --- 2. IP allowlist (a valid key header also grants access) ---
|
|
if [ -z "${ALLOWED_CIDR}" ]; then
|
|
echo "[entrypoint] ALLOWED_CIDR is empty — allowing all IPs (dev mode)"
|
|
if [ -n "${KEY_MATCH}" ]; then
|
|
echo "[entrypoint] WARNING: header key has no effect while ALLOWED_CIDR is empty" >&2
|
|
fi
|
|
else
|
|
CIDR_LIST=$(echo "${ALLOWED_CIDR}" | tr ',' ' ' | tr -s ' ')
|
|
cat >> "${MATCHERS}" <<MATCH
|
|
@denied_ip {
|
|
not remote_ip ${CIDR_LIST}
|
|
${KEY_MATCH}
|
|
}
|
|
MATCH
|
|
cat >> "${GUARD}" <<GUARDRULE
|
|
respond @denied_ip \`{"error":"ip_not_allowed"}\` 403 {
|
|
close
|
|
}
|
|
GUARDRULE
|
|
echo "[entrypoint] IP allowlist configured: ${CIDR_LIST}"
|
|
fi
|
|
|
|
# --- 3. Token auth (legacy X-Proxy-Token; a valid key header also satisfies it) ---
|
|
if [ -z "${PROXY_SECRET}" ]; then
|
|
echo "[entrypoint] PROXY_SECRET is not set — token auth disabled (open mode)"
|
|
else
|
|
cat >> "${MATCHERS}" <<MATCH
|
|
@bad_token {
|
|
not header X-Proxy-Token "${PROXY_SECRET}"
|
|
${KEY_MATCH}
|
|
}
|
|
MATCH
|
|
cat >> "${GUARD}" <<GUARDRULE
|
|
respond @bad_token \`{"error":"invalid_token"}\` 403 {
|
|
close
|
|
}
|
|
GUARDRULE
|
|
echo "[entrypoint] Token auth configured"
|
|
fi
|
|
|
|
# --- 4. Validate and start ---
|
|
caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
|
|
echo "[entrypoint] Starting caddy (domain: ${DOMAIN})..."
|
|
exec caddy run --config /etc/caddy/Caddyfile --adapter caddyfile
|