Updated README.md to reflect new directory structure and added instructions for integrating Authelia with an existing Caddy setup.
224 lines
6.5 KiB
Markdown
224 lines
6.5 KiB
Markdown
# authelia-setup
|
|
|
|
Reusable Authelia SSO + Caddy reverse proxy stack.
|
|
Single login covers all subdomains. Two-factor via TOTP app. Password reset via SMTP.
|
|
|
|
## What this does
|
|
|
|
- **Caddy** — reverse proxy with automatic HTTPS via Let's Encrypt
|
|
- **Authelia** — SSO portal at `auth.mydomain.com`, protects any subdomain with `import authelia` in the Caddyfile
|
|
- **Brevo/Migadu SMTP** — sends TOTP registration and password reset emails
|
|
|
|
## Machine requirements
|
|
|
|
- Ubuntu 24.04 LTS
|
|
- Docker: `curl -fsSL https://get.docker.com | sh && sudo usermod -aG docker $USER`
|
|
- No GPU needed
|
|
|
|
## Directory structure
|
|
|
|
```
|
|
~/docker/
|
|
├── authelia/
|
|
│ ├── docker-compose.yml
|
|
│ ├── .env
|
|
│ ├── config/
|
|
│ │ ├── configuration.yml
|
|
│ │ ├── users.yml
|
|
│ │ └── secrets/ ← never committed to git
|
|
│ └── data/ ← never committed to git
|
|
└── caddy/
|
|
└── Caddyfile
|
|
```
|
|
|
|
## First time setup
|
|
|
|
### 1. DNS
|
|
At your domain registrar add two records:
|
|
```
|
|
@ → A → this machine's public IP
|
|
* → CNAME → mydomain.com
|
|
```
|
|
|
|
### 2. Replace placeholders
|
|
In every file replace `mydomain.com` with your real domain.
|
|
In `users.yml` replace `REPLACE_WITH_HASH` with real password hashes (see below).
|
|
|
|
### 3. Create secrets
|
|
```bash
|
|
mkdir -p ~/docker/authelia/config/secrets
|
|
|
|
openssl rand -hex 32 > ~/docker/authelia/config/secrets/jwt_secret
|
|
openssl rand -hex 32 > ~/docker/authelia/config/secrets/session_secret
|
|
openssl rand -hex 32 > ~/docker/authelia/config/secrets/storage_secret
|
|
echo "your-smtp-password" > ~/docker/authelia/config/secrets/smtp_password
|
|
|
|
chmod 600 ~/docker/authelia/config/secrets/*
|
|
```
|
|
|
|
### 4. Create .env files
|
|
`~/docker/authelia/.env`:
|
|
```
|
|
MY_DOMAIN=yourdomain.com
|
|
SMTP_USER=authelia@yourdomain.com
|
|
DOCKER_MY_NETWORK=caddy_net
|
|
TZ=America/New_York
|
|
```
|
|
|
|
### 5. Generate password hashes
|
|
Run once per unique password — all users can share one temporary password:
|
|
```bash
|
|
docker run --rm authelia/authelia:4.39.20 authelia crypto hash generate argon2 --password 'TempPass2026!'
|
|
```
|
|
Paste the output into `users.yml` for each user. Tell users to use "Forgot Password" on first login to set their own.
|
|
|
|
### 6. Create Docker network
|
|
```bash
|
|
docker network create caddy_net
|
|
```
|
|
|
|
### 7. Start Authelia
|
|
```bash
|
|
cd ~/docker/authelia
|
|
mkdir -p data
|
|
sudo chown -R 1000:1000 config data
|
|
docker compose up -d
|
|
docker compose logs -f
|
|
```
|
|
|
|
### 8. Start Caddy
|
|
```bash
|
|
cd ~/docker/caddy
|
|
docker compose up -d
|
|
```
|
|
|
|
### 9. Generate Caddy basic auth hash (if using basic auth anywhere)
|
|
```bash
|
|
docker exec caddy caddy hash-password --plaintext 'yourpassword'
|
|
```
|
|
|
|
### 10. Reload Caddy after any Caddyfile changes
|
|
```bash
|
|
docker exec -w /etc/caddy caddy caddy reload
|
|
```
|
|
|
|
## Adding a new protected service
|
|
In the Caddyfile add:
|
|
```caddyfile
|
|
newservice.mydomain.com {
|
|
import authelia
|
|
reverse_proxy INTERNAL_IP:PORT
|
|
}
|
|
```
|
|
Then reload Caddy. No Authelia changes needed.
|
|
|
|
## Adding a service WITHOUT Authelia (has its own login)
|
|
```caddyfile
|
|
newservice.mydomain.com {
|
|
reverse_proxy INTERNAL_IP:PORT
|
|
}
|
|
```
|
|
|
|
## Adding Authelia to an existing dockerized Caddy setup
|
|
|
|
If you already have Caddy running with other services (e.g. via dothevo/selfhosted or similar),
|
|
follow these steps to add Authelia without disturbing existing services.
|
|
|
|
### 1. Find your existing Caddy Docker network
|
|
```bash
|
|
docker inspect caddy | grep -i network
|
|
# or
|
|
docker network ls
|
|
```
|
|
Note the network name — use it as `DOCKER_MY_NETWORK` in `authelia/.env`.
|
|
|
|
### 2. Connect Authelia to that network
|
|
In `authelia/docker-compose.yml` the network name must match your existing Caddy network.
|
|
Authelia needs to be on the same network as Caddy to be reachable by container name.
|
|
|
|
### 3. Add the authelia snippet to your existing Caddyfile
|
|
Add at the top of your Caddyfile (before any site blocks):
|
|
```caddyfile
|
|
(authelia) {
|
|
forward_auth authelia:9091 {
|
|
uri /api/authz/forward-auth
|
|
copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
|
|
}
|
|
}
|
|
```
|
|
|
|
Add the Authelia portal site block:
|
|
```caddyfile
|
|
auth.mydomain.com {
|
|
reverse_proxy authelia:9091
|
|
}
|
|
```
|
|
|
|
### 4. Protect existing services
|
|
For any existing service you want to protect, add `import authelia` to its site block:
|
|
```caddyfile
|
|
existingservice.mydomain.com {
|
|
import authelia ← add this line
|
|
reverse_proxy container:port
|
|
}
|
|
```
|
|
|
|
Services without `import authelia` are unaffected — they keep working exactly as before.
|
|
|
|
### 5. Reload Caddy
|
|
```bash
|
|
docker exec -w /etc/caddy caddy caddy reload
|
|
```
|
|
|
|
### 6. Start Authelia
|
|
```bash
|
|
cd ~/docker/authelia && docker compose up -d
|
|
```
|
|
|
|
### Notes for existing setups
|
|
- Authelia does NOT interfere with services that don't import the snippet
|
|
- Services with their own login (Portainer, Nextcloud, etc.) should NOT use `import authelia`
|
|
- If an existing service breaks after adding Authelia, remove `import authelia` from its block
|
|
- The Authelia session cookie is scoped to your domain — it won't affect other domains you host
|
|
|
|
## Adding users
|
|
1. Edit `~/docker/authelia/config/users.yml`
|
|
2. Add user block with hash
|
|
3. Restart Authelia: `docker compose restart authelia`
|
|
4. Tell user to use "Forgot Password" to set their own password
|
|
|
|
## Logging in
|
|
|
|
**Username, not email.** Authelia's file backend uses the key name from `users.yml` as the login username, not the email address.
|
|
|
|
Example — if `users.yml` has:
|
|
```yaml
|
|
users:
|
|
john:
|
|
email: john@example.com
|
|
```
|
|
Login with `john`, not `john@example.com`. The email is only used for TOTP registration and password reset emails.
|
|
1. User logs in with username + temporary password
|
|
2. Authelia emails a TOTP registration link — click it
|
|
3. Authelia shows a QR code:
|
|
- **Password manager** (Bitwarden, 1Password) — may intercept and register automatically
|
|
- **Separate app** (Google Authenticator, Authy) — scan the QR code manually
|
|
4. Enter the 6-digit code to confirm registration
|
|
5. Every login after: username + password + 6-digit code
|
|
|
|
Note: if using a password manager, it may complete TOTP setup without showing the QR code — this is normal and correct.
|
|
|
|
## Updating Authelia
|
|
Only update when you have a specific reason (bug fix, security issue).
|
|
Change the version tag in `docker-compose.yml` then:
|
|
```bash
|
|
docker compose pull authelia
|
|
docker compose up -d authelia
|
|
```
|
|
|
|
## Notes
|
|
- Secrets never go in git — they live in `config/secrets/` which is gitignored
|
|
- `.env` files never go in git
|
|
- Session cookies are valid across all `*.mydomain.com` subdomains — one login covers everything
|
|
- SQLite database lives in `~/docker/authelia/data/` — back this up to preserve user TOTP registrations
|