Motivation
- Schutz meiner Domains und Subdomains mit einer Authentifizierung die Domain-weit funktioniert. www.happyklara hat diverse Subdomains, die mit authelia geschützt sind. ich muss nur einmal das Kennwort eingeben und für diese Session sind alle Subdomains authentifiziert.
- Zusatzschutz für WordPress. Das wp-Admin-Verzeichnis wird mit einer weiteren Authentifizierung geschützt. Ggf. kann man auch die wp-login.php in den Schutz einschließen, das macht aber nur Sinn, wenn man keine weiteren Benutzer hat (bei mir teilweise).
16. Februar 2024: Jetzt kann Authelia ZWEI Domains beschützen.
Das muss ich ausnutzen.
Ich habe zwei Tage probiert, um es hin zu bekommen. Authelia ging zuerst, aber Traefik schickte die Daten nicht an die zweite Domain.
Das hier ist jetzt eine Lösung, die bei mir funktioniert.
Docker-Compose für Authelia und Traefik
Authelia braucht ZWEI Middlewares. Nur so werden die richtigen Login-Seiten angesteuert. Das war tatsächlich der Knackpunkt, ohne den es nicht funktionierte.
services:
# -----------------------------------------------------------------------------
authelia:
image: authelia/authelia:master
container_name: authelia
hostname: authelia
restart: always
depends_on:
- authelia_redis
volumes:
- $PWD/authelia/data:/config
networks:
- traefik
labels:
- 'traefik.enable=true'
# authelia auth
- 'traefik.http.routers.authelia.rule=Host(`login.YourFirstDomain.de`)'
- "traefik.http.routers.authelia.entrypoints=web-secure"
- "traefik.http.routers.authelia.service=authelia"
- "traefik.http.routers.authelia.tls=true"
- "traefik.http.routers.authelia.tls.certresolver=default"
# middleware authelia standard auth
- 'traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/verify?rd=https://login.YourFirstDomain.de'
- 'traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true'
- 'traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User, Remote-Groups, Remote-Name, Remote-Email'
# middleware authelia basic auth
- 'traefik.http.middlewares.authelia-basic.forwardauth.address=http://authelia:9091/api/verify?auth=basic'
- 'traefik.http.middlewares.authelia-basic.forwardauth.trustForwardHeader=true'
- 'traefik.http.middlewares.authelia-basic.forwardauth.authResponseHeaders=Remote-User, Remote-Name'
# service port
- "traefik.http.services.authelia.loadbalancer.server.port=9091"
###########################################
# authelia auth
- 'traefik.http.routers.authelia2.rule=Host(`login.YourSecondDomain.de`)'
- "traefik.http.routers.authelia2.entrypoints=web-secure"
- "traefik.http.routers.authelia2.service=authelia"
- "traefik.http.routers.authelia2.tls=true"
- "traefik.http.routers.authelia2.tls.certresolver=default"
# middleware authelia standard auth
- 'traefik.http.middlewares.authelia2.forwardauth.address=http://authelia:9091/api/verify?rd=https://login.YourSecondDomain.de'
- 'traefik.http.middlewares.authelia2.forwardauth.trustForwardHeader=true'
- 'traefik.http.middlewares.authelia2.forwardauth.authResponseHeaders=Remote-User, Remote-Groups, Remote-Name, Remote-Email'
# service port
- "traefik.http.services.authelia2.loadbalancer.server.port=9091"
secrets:
- jwt
- session
- smtp
environment:
- TZ=Europe/Berlin
- AUTHELIA_JWT_SECRET_FILE=/run/secrets/jwt
- AUTHELIA_SESSION_SECRET_FILE=/run/secrets/session
- AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE=/run/secrets/smtp
# -----------------------------------------------------------------------------
# redis database - persistent session data
# -----------------------------------------------------------------------------
authelia_redis:
image: redis:alpine
container_name: authelia_redis
hostname: authelia_redis
networks:
- traefik
restart: always
volumes:
- $PWD/authelia/redis:/data
# ports:
# - '6379:6379'
expose:
- 6379
environment:
- TZ=Europe/Berlin
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
traefik:
image: traefik
#:v2.7.1
container_name: traefik
hostname: traefik
restart: always
depends_on:
- authelia
networks:
- traefik
ports:
# web
- "80:80"
# web-secure
- "443:443"
# insecure dashboard
- "8080:8080"
healthcheck:
test: ["CMD", "wget", "--spider", "http://localhost:8080"]
volumes:
- /var/run/docker.sock:/var/run/docker.sock:rw
- $PWD/traefik/dynamic/:/etc/traefik/dynamic
- $PWD/traefik/traefik.yml:/etc/traefik/traefik.yml
- $PWD/traefik/acme.json:/etc/traefik/acme/acme.json
labels:
- "traefik.enable=true"
# service
- "traefik.http.routers.traefik.service=api@internal"
# secure
- "traefik.http.routers.traefik-secure.rule=Host(`traefik.YourDomain.de`)"
- "traefik.http.routers.traefik-secure.entrypoints=web-secure"
- "traefik.http.routers.traefik-secure.tls.certResolver=default"
- "traefik.http.routers.traefik-secure.tls=true"
- "traefik.http.routers.traefik-secure.middlewares=authelia,secured-headers"
# service
- "traefik.http.routers.traefik-secure.service=api@internal"
# middleware test-auth
- "traefik.http.middlewares.test-auth.basicauth.realm=traefik"
- "traefik.http.middlewares.test-auth.basicauth.headerField=X-WebAuth-User"
- "traefik.http.middlewares.test-auth.basicauth.usersfile=/etc/traefik/dynamic/users"
# middleware secured-headers
- "traefik.http.middlewares.secured-headers.headers.BrowserXssFilter=true"
- "traefik.http.middlewares.secured-headers.headers.ContentTypeNosniff=true"
- "traefik.http.middlewares.secured-headers.headers.accesscontrolallowmethods=GET"
- "traefik.http.middlewares.secured-headers.headers.accesscontrolalloworiginlist=https://traefik.YourDomain.de"
- "traefik.http.middlewares.secured-headers.headers.accesscontrolmaxage=100"
- "traefik.http.middlewares.secured-headers.headers.addvaryheader=true"
- "traefik.http.middlewares.secured-headers.headers.STSIncludeSubdomains=true"
- "traefik.http.middlewares.secured-headers.headers.STSPreload=true"
- "traefik.http.middlewares.secured-headers.headers.STSSeconds=15768000"
WordPressInstanz 1
DockerCompose.yml – wordpress09 ist my label – use yours
wordpress_db09:
image: mysql:5
container_name: wordpress_db09
hostname: wordpress_db09
networks:
- traefik
restart: always
command: --max_allowed_packet=32505856 # Set max_allowed_packet to 256M (or any other value)
environment:
MYSQL_RANDOM_ROOT_PASSWORD: '1'
MYSQL_USER: ${WP09_WORDPRESS_DB_USER}
MYSQL_PASSWORD: ${WP09_WORDPRESS_DB_PASSWORD}
MYSQL_DATABASE: DBYOURNAME1
volumes:
- $PWD/wordpress09/data/db:/var/lib/mysql
- $PWD/wordpress09/data/uploads:/data
- $PWD/wordpress09/data/wordpress.ini:/usr/local/etc/php/conf.d/wordpress.ini
# -----------------------------------------------------------------------------
wordpress09:
depends_on:
- wordpress_db09
image: wordpress
container_name: wordpress09
hostname: wordpress09
networks:
- traefik
restart: always
environment:
WORDPRESS_DB_HOST: wordpress_db09
WORDPRESS_DB_USER: ${WP09_WORDPRESS_DB_USER}
WORDPRESS_DB_PASSWORD: ${WP09_WORDPRESS_DB_PASSWORD}
WORDPRESS_DB_NAME: DBYOURNAME1
WORDPRESS_TABLE_PREFIX: WP_
volumes:
- $PWD/wordpress09/data/html:/var/www/html
- $PWD/wordpress09/data/wordpress.ini:/usr/local/etc/php/conf.d/wordpress.ini
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
labels:
- "traefik.enable=true"
# secure
- "traefik.http.routers.wordpress09.rule=Host(`www.YourFirstDomain.de`)"
- "traefik.http.routers.wordpress09.entrypoints=web-secure"
- "traefik.http.routers.wordpress09.tls=true"
- "traefik.http.routers.wordpress09.tls.certResolver=default"
# middlewares
- "traefik.http.routers.wordpress09.middlewares=authelia"
#service
- "traefik.http.services.wordpress09.loadbalancer.server.port=80"
WordPressInstanz 2
DockerCompose.yml – wordpress03 ist my label – use yours
# -----------------------------------------------------------------------------
wordpress_db03:
image: mysql:5
container_name: wordpress_db03
hostname: wordpress_db03
networks:
- traefik
restart: always
cpus: 0.2
mem_limit: 4096M
mem_reservation: 4096M
environment:
MYSQL_RANDOM_ROOT_PASSWORD: '1'
MYSQL_USER: ${WP03_WORDPRESS_DB_USER}
MYSQL_PASSWORD: ${WP03_WORDPRESS_DB_PASSWORD}
MYSQL_DATABASE: YourDBName2
MYSQL_FILE_UPLOADS: 'On'
MYSQL_MEMORY_LIMIT: 256M
MYSQL_UPLOAD_MAX_FILESIZE: 64M
MYSQL_POST_MAX_SIZE: 64M
MYSQL_MAX_EXECUTION_TIME: 1000
volumes:
- $PWD/wordpress03/data/db:/var/lib/mysql
- $PWD/wordpress03/data/uploads.ini:/usr/local/etc/php/conf.d/wordpress.ini
- $PWD/wordpress03/data/uploads:/data
# -----------------------------------------------------------------------------
wordpress03:
depends_on:
- wordpress_db03
image: wordpress
container_name: wordpress03
hostname: wordpress03
networks:
- traefik
restart: always
cpus: 0.2
mem_limit: 4096M
mem_reservation: 4096M
deploy:
resources:
limits:
memory: 4G
environment:
WORDPRESS_DB_HOST: wordpress_db03
WORDPRESS_DB_USER: ${WP03_WORDPRESS_DB_USER}
WORDPRESS_DB_PASSWORD: ${WP03_WORDPRESS_DB_PASSWORD}
WORDPRESS_DB_NAME: YourDBName2
WORDPRESS_TABLE_PREFIX: WP_
volumes:
- $PWD/wordpress03/data/html:/var/www/html
- $PWD/wordpress03/data/uploads.ini:/usr/local/etc/php/conf.d/wordpress.ini
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
labels:
- "traefik.enable=true"
# secure
- "traefik.http.routers.wordpress03.rule=Host(`www.YourSecondDomain.de`)"
- "traefik.http.routers.wordpress03.entrypoints=web-secure"
- "traefik.http.routers.wordpress03.tls=true"
- "traefik.http.routers.wordpress03.tls.certResolver=default"
# middlewares
- "traefik.http.routers.wordpress03.middlewares=authelia2@docker"
#service
- "traefik.http.services.wordpress03.loadbalancer.server.port=80"
# -----------------------------------------------------------------------------
Authelia
Configuration.yml – part
Ja, ich habe noch einige “deprecated”-Warnungen für Authelia, aber heute keine Lust mehr.
[..]
rules:
#www.YourDomain1.de
- domain: 'www.YourDomain1.de'
networks: 'yourownIpaddress'
policy: bypass
- domain: 'www.YourDomain1.de'
resources:
- '^/wp-admin/admin-ajax\.php'
- '^/wp-comments-post\.php'
policy: bypass
- domain: 'www.YourDomain1.de'
resources:
- '^/wp-admin/.*'
- '^/.*\.php.*'
- '^/.*\.env.*'
- '^/.*\.js.*'
subject:
- 'user:your-Authelia-Username'
- 'group:your-Authelia-Group'
policy: two_factor
- domain: 'www.YourDomain1.de'
policy: bypass
#www.YourDomain2.de
- domain: 'www.YourDomain2.de'
networks: 'yourownIpaddress'
policy: bypass
- domain: 'www.YourDomain2.de'
resources:
- '^/wp-admin/admin-ajax\.php'
- '^/wp-comments-post\.php'
policy: bypass
- domain: 'www.YourDomain2.de'
resources:
- '^/wp-admin/.*'
- '^/.*\.php.*'
- '^/.*\.env.*'
- '^/.*\.js.*'
subject:
- 'user:your-Authelia-Username'
- 'group:your-Authelia-Group'
policy: two_factor
- domain: 'www.YourDomain2.de'
policy: bypass
session:
cookies:
- domain: 'YourDomain1.de'
authelia_url: 'https://login.YourFirstDomain.de'
default_redirection_url: 'https://www.YourFirstDomain.de/'
name: 'authelia_session'
same_site: 'lax'
inactivity: '5m'
expiration: '1d'
remember_me: '1M'
- domain: 'YourDomain2.de'
authelia_url: 'https://login.YourSecondDomain.de'
default_redirection_url: 'https://www.YourSecondDomain.de/'
name: 'authelia_session'
same_site: 'lax'
inactivity: '5m'
expiration: '1d'
remember_me: '1M'
[..]
Und jetzt noch DUO und es wird komfortabel
Mit Duo als Zwei-Faktor-Authentifizierer – per Plugin in WordPress und per Anmeldung eines Accounts bei Duo – macht auch die Anmeldung an WordPress richtig Spaß. Push-Nachrichten einrichten und dann easy mit dem Phone oder der Watch bestätigen.
Man kann in Duo die Namen der WordPress-User als Aliase für den eigenen Namen eintragen. Ich bin überall Admin und habe ab und zu noch einen Testusernamen. Maximal 10 Aliase in Duo reichen da perfekt aus.
Ja, man muss sich jetzt zwei mal anmelden, aber der Zusatzschutz gegen fiese Menschen und Bots ist nicht zu unterschätzen.
Ja, man kann das auch mit .htpasswd und .htaccess für das wp-admin-Unterverzeichnis erreichen, aber die Passworteingabe vertüdelt sich zu oft und man hat nicht diese tolle Push-Bestätigung und vor Allem nicht die Domain-weite Authenifizierung durch den Einsatz von Authelia.
,hataccess und .htpaaswd machen auf Dauer und bei diversen (Sub-)Domains keinen Spaß.
Mit diesen Komponenten wird WordPress sicherer und macht mehr Spaß!