273 lines
8.3 KiB
Bash
Executable File
273 lines
8.3 KiB
Bash
Executable File
#!/bin/bash
|
|
set -u
|
|
|
|
# --- CONFIGURATION ---
|
|
CONFIG_DIR="/etc/authelia"
|
|
CONFIG_FILE="$CONFIG_DIR/configuration.yml"
|
|
USERS_FILE="$CONFIG_DIR/users_database.yml"
|
|
OIDC_KEY="$CONFIG_DIR/oidc.key"
|
|
SECRETS_FILE="$CONFIG_DIR/client_secrets.txt"
|
|
AUTHELIA_BIN="authelia"
|
|
SERVICE_USER="authelia"
|
|
SERVICE_GROUP="authelia"
|
|
|
|
# --- 1. PREP & STOP ---
|
|
echo "🛑 Stopping Authelia..."
|
|
systemctl stop authelia || true
|
|
|
|
# Only wipe DB if we are NOT using a persistent storage key
|
|
if [[ -z "${AUTHELIA_STORAGE_KEY:-}" ]] && [[ -f "$CONFIG_DIR/db.sqlite3" ]]; then
|
|
echo "🗑️ Random key detected. Wiping database to prevent crash..."
|
|
rm "$CONFIG_DIR/db.sqlite3"
|
|
fi
|
|
|
|
mkdir -p "$CONFIG_DIR"
|
|
|
|
# --- 1.5 INSTALL RUNTIME WRAPPER (NEW) ---
|
|
echo "🔧 Installing Runtime Wrapper..."
|
|
if [[ -f "./start_authelia.sh" ]]; then
|
|
cp ./start_authelia.sh /usr/local/bin/start-authelia.sh
|
|
chmod +x /usr/local/bin/start-authelia.sh
|
|
else
|
|
echo "❌ ERROR: start_authelia.sh missing! Run this from your git repo folder."
|
|
exit 1
|
|
fi
|
|
|
|
# --- 1.6 CONFIGURE SYSTEMD (NEW) ---
|
|
echo "⚙️ Configuring Systemd..."
|
|
mkdir -p /etc/systemd/system/authelia.service.d
|
|
cat <<EOF > /etc/systemd/system/authelia.service.d/override.conf
|
|
[Service]
|
|
# Disable Sandbox to allow reading /mnt/secrets
|
|
PrivateUsers=no
|
|
# Use our wrapper script instead of the binary directly
|
|
ExecStart=
|
|
ExecStart=/usr/local/bin/start-authelia.sh
|
|
EOF
|
|
systemctl daemon-reload
|
|
|
|
# --- 2. LOAD SETUP SECRETS (Updated for Robustness) ---
|
|
echo "🔍 Checking environment..."
|
|
ADMIN_PASS="${AUTHELIA_ADMIN_PASSWORD:-}"
|
|
MAIL_PASS="${MAIL_ADMIN_PASSWORD:-}"
|
|
ADMIN_EMAIL="admin@poppyglen.cc"
|
|
|
|
# Source the setup-time secrets file if it exists
|
|
if [[ -f "/mnt/secrets/authelia.env" ]]; then
|
|
echo " -> Sourcing /mnt/secrets/authelia.env"
|
|
set -a
|
|
. /mnt/secrets/authelia.env
|
|
set +a
|
|
|
|
# Update variables if they were loaded from file
|
|
[[ -n "${AUTHELIA_ADMIN_PASSWORD:-}" ]] && ADMIN_PASS="$AUTHELIA_ADMIN_PASSWORD"
|
|
[[ -n "${MAIL_ADMIN_EMAIL:-}" ]] && ADMIN_EMAIL="$MAIL_ADMIN_EMAIL"
|
|
[[ -n "${MAIL_ADMIN_PASSWORD:-}" ]] && MAIL_PASS="$MAIL_ADMIN_PASSWORD"
|
|
[[ -n "${LLDAP_URL:-}" ]] && LLDAP_URL="$LLDAP_URL"
|
|
[[ -n "${LLDAP_BASE_DN:-}" ]] && LLDAP_BASE_DN="$LLDAP_BASE_DN"
|
|
[[ -n "${LLDAP_BIND_USER:-}" ]] && LLDAP_BIND_USER="$LLDAP_BIND_USER"
|
|
[[ -n "${LLDAP_BIND_PASSWORD:-}" ]] && LLDAP_BIND_PASSWORD="$LLDAP_BIND_PASSWORD"
|
|
fi
|
|
|
|
if [[ -z "$ADMIN_PASS" ]]; then read -sp "Enter Admin Password: " ADMIN_PASS; echo; fi
|
|
if [[ -z "$MAIL_PASS" ]]; then read -sp "Enter Mail Password: " MAIL_PASS; echo; fi
|
|
|
|
# --- 3. GENERATE KEYS & HASHES ---
|
|
echo "🔑 Handling Keys..."
|
|
|
|
# Use Env variable if exists, otherwise generate (but warn)
|
|
JWT_SECRET="${AUTHELIA_JWT_SECRET:-$(openssl rand -hex 32)}"
|
|
SESSION_SECRET="${AUTHELIA_SESSION_SECRET:-$(openssl rand -hex 32)}"
|
|
STORAGE_KEY="${AUTHELIA_STORAGE_KEY:-$(openssl rand -hex 32)}"
|
|
HMAC_SECRET="${AUTHELIA_HMAC_SECRET:-$(openssl rand -hex 32)}"
|
|
|
|
if [[ -z "${AUTHELIA_STORAGE_KEY:-}" ]]; then
|
|
echo "⚠️ WARNING: Generating RANDOM Storage Key. Existing DB will be unreadable!"
|
|
else
|
|
echo "✅ Using persistent keys from environment."
|
|
fi
|
|
|
|
# Keep OIDC Key generation (usually fine to keep static too, but this works)
|
|
if [[ ! -f "$OIDC_KEY" ]]; then
|
|
openssl genpkey -algorithm RSA -out "$OIDC_KEY" -pkeyopt rsa_keygen_bits:4096
|
|
chmod 600 "$OIDC_KEY"
|
|
fi
|
|
OIDC_KEY_CONTENT=$(cat "$OIDC_KEY" | sed 's/^/ /')
|
|
|
|
echo "🎲 Handling Client Secrets..."
|
|
|
|
# Use Env variable if exists, otherwise generate random
|
|
NEXTCLOUD_PLAIN="${NEXTCLOUD_CLIENT_SECRET:-$(openssl rand -hex 32)}"
|
|
JELLYFIN_PLAIN="${JELLYFIN_CLIENT_SECRET:-$(openssl rand -hex 32)}"
|
|
IMMICH_PLAIN="${IMMICH_CLIENT_SECRET:-$(openssl rand -hex 32)}"
|
|
|
|
echo "🔒 Hashing Client Secrets..."
|
|
hash_secret() {
|
|
$AUTHELIA_BIN crypto hash generate pbkdf2 --variant sha512 --password "$1" | awk '{print $NF}'
|
|
}
|
|
|
|
# These hashes go into configuration.yml
|
|
NEXTCLOUD_HASH=$(hash_secret "$NEXTCLOUD_PLAIN")
|
|
JELLYFIN_HASH=$(hash_secret "$JELLYFIN_PLAIN")
|
|
IMMICH_HASH=$(hash_secret "$IMMICH_PLAIN")
|
|
|
|
# --- 4. GENERATE CONFIG ---
|
|
echo "📝 Writing Clean Configuration..."
|
|
cat <<EOF > "$CONFIG_FILE"
|
|
server:
|
|
address: tcp://0.0.0.0:9091
|
|
log:
|
|
level: info
|
|
identity_validation:
|
|
reset_password:
|
|
jwt_secret: "$JWT_SECRET"
|
|
authentication_backend:
|
|
ldap:
|
|
implementation: custom
|
|
address: $LLDAP_URL
|
|
timeout: 5s
|
|
start_tls: false
|
|
base_dn: $LLDAP_BASE_DN
|
|
additional_users_dn: ou=people
|
|
additional_groups_dn: ou=groups
|
|
user: $LLDAP_BIND_USER
|
|
password: "$LLDAP_BIND_PASSWORD"
|
|
attributes:
|
|
username: uid
|
|
display_name: displayName
|
|
group_name: cn
|
|
mail: mail
|
|
member_of: memberOf
|
|
users_filter: (&({username_attribute}={input})(objectClass=person))
|
|
groups_filter: (&(member={dn})(objectClass=groupOfUniqueNames))
|
|
access_control:
|
|
default_policy: deny
|
|
rules:
|
|
- domain: "auth.poppyglen.cc"
|
|
policy: bypass
|
|
- domain: "*.poppyglen.cc"
|
|
policy: two_factor
|
|
subject: ["group:admins", "group:users"]
|
|
session:
|
|
secret: "$SESSION_SECRET"
|
|
cookies:
|
|
- name: poppy_session
|
|
domain: poppyglen.cc
|
|
authelia_url: https://auth.poppyglen.cc
|
|
redis:
|
|
host: 192.168.0.120
|
|
port: 6379
|
|
database_index: 1
|
|
storage:
|
|
encryption_key: "$STORAGE_KEY"
|
|
local:
|
|
path: $CONFIG_DIR/db.sqlite3
|
|
notifier:
|
|
disable_startup_check: true
|
|
smtp:
|
|
address: "submission://mail.poppyglen.cc:587"
|
|
username: "$ADMIN_EMAIL"
|
|
password: "$MAIL_PASS"
|
|
sender: "Authelia <$ADMIN_EMAIL>"
|
|
identifier: "authelia.poppyglen.cc"
|
|
tls:
|
|
skip_verify: true
|
|
identity_providers:
|
|
oidc:
|
|
hmac_secret: "$HMAC_SECRET"
|
|
jwks:
|
|
- key: |
|
|
$OIDC_KEY_CONTENT
|
|
key_id: 'poppyglen-oidc-key'
|
|
algorithm: 'RS256'
|
|
use: 'sig'
|
|
clients:
|
|
- client_id: nextcloud
|
|
client_name: Nextcloud
|
|
client_secret: "$NEXTCLOUD_HASH"
|
|
public: false
|
|
authorization_policy: two_factor
|
|
token_endpoint_auth_method: 'client_secret_post'
|
|
redirect_uris:
|
|
- https://cloud.poppyglen.cc/apps/user_oidc/code
|
|
scopes:
|
|
- openid
|
|
- profile
|
|
- email
|
|
- groups
|
|
userinfo_signed_response_alg: none
|
|
|
|
- client_id: jellyfin
|
|
client_name: Jellyfin
|
|
client_secret: "$JELLYFIN_HASH"
|
|
public: false
|
|
authorization_policy: two_factor
|
|
redirect_uris:
|
|
- https://jellyfin.poppyglen.cc/sso/OID/redirect/authelia
|
|
scopes:
|
|
- openid
|
|
- profile
|
|
- email
|
|
- groups
|
|
userinfo_signed_response_alg: none
|
|
|
|
- client_id: immich
|
|
client_name: Immich
|
|
client_secret: "$IMMICH_HASH"
|
|
public: false
|
|
authorization_policy: two_factor
|
|
require_pkce: false
|
|
pkce_challenge_method: ''
|
|
redirect_uris:
|
|
- https://immich.poppyglen.cc/auth/login
|
|
- https://immich.poppyglen.cc/user-settings
|
|
- app.immich:///oauth-callback
|
|
scopes:
|
|
- openid
|
|
- profile
|
|
- email
|
|
- groups
|
|
response_types:
|
|
- code
|
|
grant_types:
|
|
- authorization_code
|
|
access_token_signed_response_alg: none
|
|
userinfo_signed_response_alg: none
|
|
token_endpoint_auth_method: client_secret_post
|
|
EOF
|
|
|
|
# --- 6. PERMISSIONS & VALIDATION ---
|
|
echo "🔧 Fixing Permissions..."
|
|
if ! id "$SERVICE_USER" &>/dev/null; then
|
|
echo "⚠️ User '$SERVICE_USER' does not exist. Creating system user..."
|
|
useradd -r -s /bin/false "$SERVICE_USER" || echo "Failed to create user."
|
|
fi
|
|
|
|
chown -R "$SERVICE_USER":"$SERVICE_GROUP" "$CONFIG_DIR"
|
|
chmod 600 "$CONFIG_FILE" "$USERS_FILE" "$OIDC_KEY"
|
|
chmod 700 "$CONFIG_DIR"
|
|
|
|
echo "🧪 PRE-FLIGHT CHECK..."
|
|
if ! su -s /bin/bash "$SERVICE_USER" -c "cat $OIDC_KEY > /dev/null"; then
|
|
echo "❌ Permission Error: '$SERVICE_USER' cannot read keys."
|
|
chmod 644 "$OIDC_KEY" "$CONFIG_FILE" "$USERS_FILE"
|
|
else
|
|
echo "✅ Permission Check Passed."
|
|
fi
|
|
|
|
echo "🚀 Starting Authelia..."
|
|
systemctl start authelia
|
|
|
|
cat <<EOF > "$SECRETS_FILE"
|
|
# ---------------------------------------------------------
|
|
# AUTHELIA CLIENT SECRETS (Use these in your Apps)
|
|
# ---------------------------------------------------------
|
|
NEXTCLOUD_SECRET=$NEXTCLOUD_PLAIN
|
|
JELLYFIN_SECRET=$JELLYFIN_PLAIN
|
|
IMMICH_SECRET=$IMMICH_PLAIN
|
|
EOF
|
|
chmod 600 "$SECRETS_FILE"
|
|
|
|
echo "✅ SUCCESS! Service Started."
|
|
echo " Client Secrets saved to: $SECRETS_FILE"
|