Files

167 lines
4.0 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ENV_FILE="${APP_DATA_DIR}/settings.env"
TMP_DIR="${APP_DATA_DIR}/tmp"
DB_DATA_DIR="${APP_DATA_DIR}/data/db"
REDIS_DATA_DIR="${APP_DATA_DIR}/data/redis"
RUSTFS_DATA_DIR="${APP_DATA_DIR}/data/rustfs"
RUSTFS_LOGS_DIR="${APP_DATA_DIR}/data/rustfs-logs"
SEARXNG_DATA_DIR="${APP_DATA_DIR}/data/searxng"
mkdir -p "${TMP_DIR}"
mkdir -p "${DB_DATA_DIR}" "${REDIS_DATA_DIR}" "${RUSTFS_DATA_DIR}" "${RUSTFS_LOGS_DIR}" "${SEARXNG_DATA_DIR}"
touch "${ENV_FILE}"
chown -R 1000:1000 "${DB_DATA_DIR}" "${REDIS_DATA_DIR}" 2>/dev/null || true
chown -R 10001:10001 "${RUSTFS_DATA_DIR}" "${RUSTFS_LOGS_DIR}" 2>/dev/null || true
if [[ ! -f "${SEARXNG_DATA_DIR}/settings.yml" ]]; then
cat > "${SEARXNG_DATA_DIR}/settings.yml" <<'EOF'
use_default_settings: true
search:
formats:
- html
- json
EOF
fi
get_var() {
local key="$1"
if grep -q "^${key}=" "${ENV_FILE}"; then
grep "^${key}=" "${ENV_FILE}" | tail -n 1 | cut -d= -f2-
fi
}
set_var() {
local key="$1"
local value="$2"
python3 - "$ENV_FILE" "$key" "$value" <<'PY'
import pathlib
import sys
path = pathlib.Path(sys.argv[1])
key = sys.argv[2]
value = sys.argv[3]
lines = path.read_text().splitlines() if path.exists() else []
updated = False
for index, line in enumerate(lines):
if line.startswith(f"{key}="):
lines[index] = f"{key}={value}"
updated = True
break
if not updated:
lines.append(f"{key}={value}")
path.write_text("\n".join(lines) + "\n")
PY
}
generate_secret() {
openssl rand -base64 32 | tr -d '\n'
}
generate_jwks() {
local pem_file="${TMP_DIR}/jwks.pem"
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out "${pem_file}" >/dev/null 2>&1
python3 - "${pem_file}" <<'PY'
import base64
import hashlib
import json
import re
import subprocess
import sys
pem_file = sys.argv[1]
text = subprocess.check_output(
["openssl", "rsa", "-in", pem_file, "-text", "-noout"],
stderr=subprocess.DEVNULL,
text=True,
)
mapping = {
"modulus": "n",
"privateExponent": "d",
"prime1": "p",
"prime2": "q",
"exponent1": "dp",
"exponent2": "dq",
"coefficient": "qi",
}
values = {}
current = None
for line in text.splitlines():
stripped = line.strip()
if stripped.startswith("publicExponent:"):
exponent = int(stripped.split()[1])
values["e"] = exponent.to_bytes((exponent.bit_length() + 7) // 8, "big")
current = None
continue
if stripped.endswith(":") and stripped[:-1] in mapping:
current = mapping[stripped[:-1]]
values[current] = b""
continue
if current and re.fullmatch(r"[0-9a-f:]+", stripped):
values[current] += bytes.fromhex(stripped.replace(":", ""))
continue
current = None
for key in ("n", "d", "p", "q", "dp", "dq", "qi"):
value = values[key]
while len(value) > 1 and value[0] == 0:
value = value[1:]
values[key] = value
def b64url(data):
return base64.urlsafe_b64encode(data).decode().rstrip("=")
kid = hashlib.sha256(values["n"]).hexdigest()[:16]
print(
json.dumps(
{
"keys": [
{
"kty": "RSA",
"use": "sig",
"alg": "RS256",
"kid": kid,
"n": b64url(values["n"]),
"e": b64url(values["e"]),
"d": b64url(values["d"]),
"p": b64url(values["p"]),
"q": b64url(values["q"]),
"dp": b64url(values["dp"]),
"dq": b64url(values["dq"]),
"qi": b64url(values["qi"]),
}
]
},
separators=(",", ":"),
)
)
PY
rm -f "${pem_file}"
}
if [[ -z "$(get_var KEY_VAULTS_SECRET)" ]]; then
set_var KEY_VAULTS_SECRET "$(generate_secret)"
fi
if [[ -z "$(get_var AUTH_SECRET)" ]]; then
set_var AUTH_SECRET "$(generate_secret)"
fi
if [[ -z "$(get_var JWKS_KEY)" ]]; then
set_var JWKS_KEY "$(generate_jwks)"
fi