Compare commits
No commits in common. "f5cbb7b43f01e9c24beeb2fa8a0150ebe82c3b65" and "674708370ceb548bdaf0b90473022dcb36e34b89" have entirely different histories.
f5cbb7b43f
...
674708370c
33 changed files with 421 additions and 146 deletions
16
env.yml
16
env.yml
|
@ -1,4 +1,5 @@
|
||||||
domain: viyurz.fr
|
domain: viyurz.fr
|
||||||
|
ldap_base_dn: dc=viyurz,dc=fr
|
||||||
timezone: "Europe/Paris"
|
timezone: "Europe/Paris"
|
||||||
host_uid: 1000
|
host_uid: 1000
|
||||||
project_dir: "{{ ansible_env['HOME'] }}/docker-projects/{{ role_name }}"
|
project_dir: "{{ ansible_env['HOME'] }}/docker-projects/{{ role_name }}"
|
||||||
|
@ -38,12 +39,13 @@ cifs_mounts:
|
||||||
|
|
||||||
|
|
||||||
projects:
|
projects:
|
||||||
|
- authelia
|
||||||
- coturn
|
- coturn
|
||||||
- element
|
- element
|
||||||
- etebase
|
- etebase
|
||||||
- hedgedoc
|
- hedgedoc
|
||||||
- homepage
|
- homepage
|
||||||
- keycloak
|
- lldap
|
||||||
- mailserver
|
- mailserver
|
||||||
- postgres
|
- postgres
|
||||||
- searxng
|
- searxng
|
||||||
|
@ -55,9 +57,10 @@ projects:
|
||||||
|
|
||||||
|
|
||||||
projects_to_backup:
|
projects_to_backup:
|
||||||
|
- authelia
|
||||||
- etebase
|
- etebase
|
||||||
- hedgedoc
|
- hedgedoc
|
||||||
- keycloak
|
- lldap
|
||||||
- mailserver
|
- mailserver
|
||||||
- postgres
|
- postgres
|
||||||
- stump
|
- stump
|
||||||
|
@ -78,6 +81,7 @@ borg_prune_options: |
|
||||||
|
|
||||||
# Ports exposed to host
|
# Ports exposed to host
|
||||||
ports:
|
ports:
|
||||||
|
authelia: 9091
|
||||||
coturn_listening: 3478
|
coturn_listening: 3478
|
||||||
coturn_tls_listening: 5349
|
coturn_tls_listening: 5349
|
||||||
coturn_relay_min: 49152
|
coturn_relay_min: 49152
|
||||||
|
@ -86,7 +90,7 @@ ports:
|
||||||
etebase: 3735
|
etebase: 3735
|
||||||
hedgedoc: 8086
|
hedgedoc: 8086
|
||||||
homepage: 8686
|
homepage: 8686
|
||||||
keycloak: 8444
|
lldap: 17170
|
||||||
mailserver_smtp: 1025
|
mailserver_smtp: 1025
|
||||||
mailserver_smtps: 1465
|
mailserver_smtps: 1465
|
||||||
mailserver_imaps: 1993
|
mailserver_imaps: 1993
|
||||||
|
@ -108,11 +112,12 @@ ports:
|
||||||
|
|
||||||
# UID in containers
|
# UID in containers
|
||||||
users:
|
users:
|
||||||
|
authelia: 1008
|
||||||
coturn: 666
|
coturn: 666
|
||||||
etebase: 373
|
etebase: 373
|
||||||
hedgedoc: 1004
|
hedgedoc: 1004
|
||||||
homepage: 8686
|
homepage: 8686
|
||||||
keycloak: 1000
|
lldap: 1007
|
||||||
mailserver: 8
|
mailserver: 8
|
||||||
postgres: 70
|
postgres: 70
|
||||||
searxng: 977
|
searxng: 977
|
||||||
|
@ -123,7 +128,7 @@ users:
|
||||||
syncthing_discosrv: 1002
|
syncthing_discosrv: 1002
|
||||||
syncthing_relaysrv: 1003
|
syncthing_relaysrv: 1003
|
||||||
uptime_kuma: 1006
|
uptime_kuma: 1006
|
||||||
vaultwarden: 1010
|
vaultwarden: 1000
|
||||||
wireguard: 1009
|
wireguard: 1009
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,6 +137,7 @@ volumes:
|
||||||
coturn_tls_certificate_key_file: "/etc/letsencrypt/live/turn.{{ domain }}/privkey.pem"
|
coturn_tls_certificate_key_file: "/etc/letsencrypt/live/turn.{{ domain }}/privkey.pem"
|
||||||
etebase_datadir: /mnt/etebasedata
|
etebase_datadir: /mnt/etebasedata
|
||||||
hedgedoc_uploadsdir: /mnt/hedgedocuploads
|
hedgedoc_uploadsdir: /mnt/hedgedocuploads
|
||||||
|
lldap_datadir: /mnt/lldapdata
|
||||||
mailserver_datadir: /mnt/mailserver
|
mailserver_datadir: /mnt/mailserver
|
||||||
mailserver_tls_certificate_file: "/etc/letsencrypt/live/mail.{{ domain }}/fullchain.pem"
|
mailserver_tls_certificate_file: "/etc/letsencrypt/live/mail.{{ domain }}/fullchain.pem"
|
||||||
mailserver_tls_certificate_key_file: "/etc/letsencrypt/live/mail.{{ domain }}/privkey.pem"
|
mailserver_tls_certificate_key_file: "/etc/letsencrypt/live/mail.{{ domain }}/privkey.pem"
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
- name: Setup & update project(s)
|
- name: Setup & update project(s)
|
||||||
hosts: localhost
|
hosts: localhost
|
||||||
vars:
|
vars:
|
||||||
run_backup: true
|
|
||||||
run_setup: true
|
run_setup: true
|
||||||
run_update: true
|
run_update: true
|
||||||
vars_prompt:
|
vars_prompt:
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
- name: Update project(s)
|
- name: Update project(s)
|
||||||
hosts: localhost
|
hosts: localhost
|
||||||
vars:
|
vars:
|
||||||
docker_pull_images: true
|
|
||||||
run_update: true
|
run_update: true
|
||||||
vars_prompt:
|
vars_prompt:
|
||||||
- name: selected_projects
|
- name: selected_projects
|
||||||
|
@ -14,6 +13,11 @@
|
||||||
private: false
|
private: false
|
||||||
unsafe: true
|
unsafe: true
|
||||||
|
|
||||||
|
- name: docker_pull_images
|
||||||
|
prompt: "Pull project(s) images?"
|
||||||
|
default: false
|
||||||
|
private: false
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: Update project(s)
|
- name: Update project(s)
|
||||||
include_role:
|
include_role:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
- name: "Backup PostgreSQL keycloak database"
|
- name: "Backup PostgreSQL authelia database"
|
||||||
shell: >
|
shell: >
|
||||||
docker exec postgres
|
docker exec postgres
|
||||||
pg_dump -c {{ role_name }} |
|
pg_dump -c {{ role_name }} |
|
25
roles/authelia/tasks/setup.yml
Normal file
25
roles/authelia/tasks/setup.yml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
- name: "(Re)Create {{ project_dir }} project directory"
|
||||||
|
file:
|
||||||
|
path: "{{ project_dir }}"
|
||||||
|
state: "{{ item }}"
|
||||||
|
loop:
|
||||||
|
- absent
|
||||||
|
- directory
|
||||||
|
|
||||||
|
- name: Template docker-compose.yaml & configuration.yml to project directory
|
||||||
|
template:
|
||||||
|
src: "{{ item }}"
|
||||||
|
dest: "{{ project_dir }}/{{ item }}"
|
||||||
|
owner: "{{ host_uid }}"
|
||||||
|
group: "{{ host_uid }}"
|
||||||
|
mode: '640'
|
||||||
|
loop:
|
||||||
|
- docker-compose.yaml
|
||||||
|
- configuration.yml
|
||||||
|
|
||||||
|
# Separate task because template module cannot chown/chgrp to a non-existing user/group
|
||||||
|
- name: "Change group of homeserver.yaml to Authelia GID ({{ users['authelia'] + uid_shift }})"
|
||||||
|
file:
|
||||||
|
path: "{{ project_dir }}/configuration.yml"
|
||||||
|
group: "{{ users['authelia'] + uid_shift }}"
|
||||||
|
become: true
|
|
@ -1,23 +1,22 @@
|
||||||
- name: Pull project services
|
- name: Pull project services
|
||||||
community.docker.docker_compose:
|
community.docker.docker_compose:
|
||||||
project_src: "{{ project_dir }}"
|
project_src: "{{ project_dir }}"
|
||||||
build: true
|
|
||||||
recreate: never
|
recreate: never
|
||||||
pull: true
|
pull: true
|
||||||
debug: true
|
debug: true
|
||||||
when: docker_pull_images | bool
|
when: docker_pull_images | bool
|
||||||
register: keycloak_docker_compose_pull_result
|
register: authelia_docker_compose_pull_result
|
||||||
|
|
||||||
- name: Display pulled image(s) name
|
- name: Display pulled image(s) name
|
||||||
set_fact:
|
set_fact:
|
||||||
keycloak_pulled_images: "{{ keycloak_pulled_images | default([]) + [item.pulled_image.name] }}"
|
authelia_pulled_images: "{{ authelia_pulled_images | default([]) + [item.pulled_image.name] }}"
|
||||||
loop: "{{ keycloak_docker_compose_pull_result['actions'] | default([]) | selectattr('pulled_image', 'defined') }}"
|
loop: "{{ authelia_docker_compose_pull_result['actions'] | default([]) | selectattr('pulled_image', 'defined') }}"
|
||||||
|
|
||||||
- name: Include backup tasks
|
- name: Include backup tasks
|
||||||
include_tasks:
|
include_tasks:
|
||||||
file: backup.yml
|
file: backup.yml
|
||||||
# Make a backup if we didn't already make one and we pulled a new image
|
# Make a backup if we didn't already make one and we pulled a new image
|
||||||
when: not run_backup | default(false) and keycloak_pulled_images is defined
|
when: not run_backup | default(false) and authelia_pulled_images is defined
|
||||||
|
|
||||||
- name: Create/Restart project services
|
- name: Create/Restart project services
|
||||||
community.docker.docker_compose:
|
community.docker.docker_compose:
|
96
roles/authelia/templates/configuration.yml
Normal file
96
roles/authelia/templates/configuration.yml
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
theme: 'auto'
|
||||||
|
|
||||||
|
totp:
|
||||||
|
issuer: '{{ domain }}'
|
||||||
|
|
||||||
|
identity_validation:
|
||||||
|
reset_password:
|
||||||
|
jwt_secret: '{{ authelia_secrets["jwt_secret"] }}'
|
||||||
|
|
||||||
|
authentication_backend:
|
||||||
|
refresh_interval: '1m'
|
||||||
|
ldap:
|
||||||
|
implementation: 'custom'
|
||||||
|
address: 'ldap://lldap:3890'
|
||||||
|
base_dn: '{{ ldap_base_dn }}'
|
||||||
|
users_filter: '(&({username_attribute}={input})(objectClass=person))'
|
||||||
|
groups_filter: '(member={dn})'
|
||||||
|
user: '{{ authelia_secrets["ldap_user"] }}'
|
||||||
|
password: '{{ authelia_secrets["ldap_password"] }}'
|
||||||
|
attributes:
|
||||||
|
distinguished_name: 'distinguishedName'
|
||||||
|
username: 'uid'
|
||||||
|
mail: 'mail'
|
||||||
|
member_of: 'memberOf'
|
||||||
|
group_name: 'cn'
|
||||||
|
|
||||||
|
password_policy:
|
||||||
|
standard:
|
||||||
|
enabled: true
|
||||||
|
min_length: 12
|
||||||
|
max_length: 128
|
||||||
|
require_uppercase: true
|
||||||
|
require_lowercase: true
|
||||||
|
require_number: true
|
||||||
|
require_special: true
|
||||||
|
|
||||||
|
access_control:
|
||||||
|
default_policy: 'deny'
|
||||||
|
rules:
|
||||||
|
- domain: 'auth.{{ domain }}'
|
||||||
|
policy: 'bypass'
|
||||||
|
|
||||||
|
- domain: 'ldap.{{ domain }}'
|
||||||
|
policy: 'two_factor'
|
||||||
|
subject: 'group:lldap_admin'
|
||||||
|
|
||||||
|
- domain: 'syncthing.{{ domain }}'
|
||||||
|
policy: 'two_factor'
|
||||||
|
subject: 'user:viyurz'
|
||||||
|
|
||||||
|
session:
|
||||||
|
cookies:
|
||||||
|
- name: 'authelia_session'
|
||||||
|
domain: '{{ domain }}'
|
||||||
|
authelia_url: 'https://auth.{{ domain }}'
|
||||||
|
|
||||||
|
storage:
|
||||||
|
encryption_key: '{{ authelia_secrets["encryption_key"] }}'
|
||||||
|
postgres:
|
||||||
|
address: postgres.{{ domain }}
|
||||||
|
database: authelia
|
||||||
|
username: '{{ authelia_secrets["postgres_user"] }}'
|
||||||
|
password: '{{ authelia_secrets["postgres_password"] }}'
|
||||||
|
|
||||||
|
notifier:
|
||||||
|
smtp:
|
||||||
|
address: 'submissions://mail.{{ domain }}:{{ ports["mailserver_smtps"] }}'
|
||||||
|
username: '{{ authelia_secrets["smtp_user"] }}'
|
||||||
|
password: '{{ authelia_secrets["smtp_password"] }}'
|
||||||
|
sender: 'Authelia <authelia@{{ domain }}>'
|
||||||
|
|
||||||
|
identity_providers:
|
||||||
|
oidc:
|
||||||
|
hmac_secret: '{{ authelia_secrets["hmac_secret"] }}'
|
||||||
|
jwks:
|
||||||
|
- key: |
|
||||||
|
{{ authelia_secrets["jwks_key"] | indent(width=10) }}
|
||||||
|
clients:
|
||||||
|
- client_id: '{{ authelia_secrets["hedgedoc_client_id"] }}'
|
||||||
|
client_name: HedgeDoc
|
||||||
|
client_secret: '{{ authelia_secrets["hedgedoc_client_secret_hash"] }}'
|
||||||
|
redirect_uris: 'https://hedgedoc.{{ domain }}/auth/oauth2/callback'
|
||||||
|
scopes:
|
||||||
|
- 'openid'
|
||||||
|
- 'profile'
|
||||||
|
- 'email'
|
||||||
|
token_endpoint_auth_method: client_secret_post
|
||||||
|
|
||||||
|
- client_id: '{{ authelia_secrets["synapse_client_id"] }}'
|
||||||
|
client_name: Synapse
|
||||||
|
client_secret: '{{ authelia_secrets["synapse_client_secret_hash"] }}'
|
||||||
|
redirect_uris: 'https://matrix.{{ domain }}/_synapse/client/oidc/callback'
|
||||||
|
scopes:
|
||||||
|
- 'openid'
|
||||||
|
- 'profile'
|
||||||
|
- 'email'
|
16
roles/authelia/templates/docker-compose.yaml
Normal file
16
roles/authelia/templates/docker-compose.yaml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
services:
|
||||||
|
authelia:
|
||||||
|
container_name: authelia
|
||||||
|
image: docker.io/authelia/authelia:4
|
||||||
|
restart: always
|
||||||
|
user: {{ users['authelia'] }}:{{ users['authelia'] }}
|
||||||
|
networks:
|
||||||
|
- authelia
|
||||||
|
ports:
|
||||||
|
- 127.0.0.1:{{ ports['authelia'] }}:9091
|
||||||
|
volumes:
|
||||||
|
- ./configuration.yml:/config/configuration.yml
|
||||||
|
|
||||||
|
networks:
|
||||||
|
authelia:
|
||||||
|
name: authelia
|
|
@ -19,6 +19,6 @@
|
||||||
state: mounted
|
state: mounted
|
||||||
src: "{{ item.value.src }}"
|
src: "{{ item.value.src }}"
|
||||||
path: "{{ item.value.path }}"
|
path: "{{ item.value.path }}"
|
||||||
fstype: smb3
|
fstype: cifs
|
||||||
opts: "uid={{ item.value.uid }},gid={{ item.value.gid }},file_mode=0{{ item.value.file_mode }},dir_mode=0{{ item.value.dir_mode }},credentials=/etc/{{ fstab_cifs_credentials_filename }},iocharset=utf8,rw,mfsymlinks,vers=3,seal"
|
opts: "uid={{ item.value.uid }},gid={{ item.value.gid }},file_mode=0{{ item.value.file_mode }},dir_mode=0{{ item.value.dir_mode }},credentials=/etc/{{ fstab_cifs_credentials_filename }},iocharset=utf8,rw,mfsymlinks,vers=3.0,seal"
|
||||||
loop: "{{ cifs_mounts | dict2items }}"
|
loop: "{{ cifs_mounts | dict2items }}"
|
||||||
|
|
|
@ -6,14 +6,14 @@ CMD_DB_PASSWORD='{{ hedgedoc_secrets["postgres_password"] }}'
|
||||||
CMD_DOMAIN='hedgedoc.{{ domain }}'
|
CMD_DOMAIN='hedgedoc.{{ domain }}'
|
||||||
CMD_PROTOCOL_USESSL=true
|
CMD_PROTOCOL_USESSL=true
|
||||||
CMD_SESSION_SECRET='{{ hedgedoc_secrets["session_secret"] }}'
|
CMD_SESSION_SECRET='{{ hedgedoc_secrets["session_secret"] }}'
|
||||||
CMD_EMAIL=false
|
CMD_ALLOW_EMAIL_REGISTER=false
|
||||||
|
|
||||||
CMD_OAUTH2_PROVIDERNAME=Keycloak
|
CMD_OAUTH2_PROVIDERNAME=Authelia
|
||||||
CMD_OAUTH2_CLIENT_ID='{{ hedgedoc_secrets["client_id"] }}'
|
CMD_OAUTH2_CLIENT_ID='{{ authelia_secrets["hedgedoc_client_id"] }}'
|
||||||
CMD_OAUTH2_CLIENT_SECRET='{{ hedgedoc_secrets["client_secret"] }}'
|
CMD_OAUTH2_CLIENT_SECRET='{{ authelia_secrets["hedgedoc_client_secret"] }}'
|
||||||
CMD_OAUTH2_AUTHORIZATION_URL=https://kc.{{ domain }}/realms/master/protocol/openid-connect/auth
|
CMD_OAUTH2_AUTHORIZATION_URL=https://auth.{{ domain }}/api/oidc/authorization
|
||||||
CMD_OAUTH2_TOKEN_URL=https://kc.{{ domain }}/realms/master/protocol/openid-connect/token
|
CMD_OAUTH2_TOKEN_URL=https://auth.{{ domain }}/api/oidc/token
|
||||||
CMD_OAUTH2_USER_PROFILE_URL=https://kc.{{ domain }}/realms/master/protocol/openid-connect/userinfo
|
CMD_OAUTH2_USER_PROFILE_URL=https://auth.{{ domain }}/api/oidc/userinfo
|
||||||
CMD_OAUTH2_SCOPE=openid email profile
|
CMD_OAUTH2_SCOPE=openid email profile
|
||||||
CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR=preferred_username
|
CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR=preferred_username
|
||||||
CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR=name
|
CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR=name
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
- name: "(Re)Create {{ project_dir }} project directory"
|
|
||||||
file:
|
|
||||||
path: "{{ project_dir }}"
|
|
||||||
state: "{{ item }}"
|
|
||||||
loop:
|
|
||||||
- absent
|
|
||||||
- directory
|
|
||||||
|
|
||||||
- name: Template Dockerfile, docker-compose.yaml & .env to project directory
|
|
||||||
template:
|
|
||||||
src: "{{ item }}"
|
|
||||||
dest: "{{ project_dir }}/{{ item }}"
|
|
||||||
owner: "{{ host_uid }}"
|
|
||||||
group: "{{ host_uid }}"
|
|
||||||
mode: '640'
|
|
||||||
loop:
|
|
||||||
- Dockerfile
|
|
||||||
- docker-compose.yaml
|
|
||||||
- .env
|
|
|
@ -1,12 +0,0 @@
|
||||||
QUARKUS_TRANSACTION_MANAGER_ENABLE_RECOVERY=true
|
|
||||||
|
|
||||||
#KEYCLOAK_ADMIN=
|
|
||||||
#KEYCLOAK_ADMIN_PASSWORD=
|
|
||||||
|
|
||||||
KC_DB_URL_HOST=postgres.{{ domain }}
|
|
||||||
KC_DB_URL_DATABASE=keycloak
|
|
||||||
KC_DB_USERNAME={{ keycloak_secrets['postgres_user'] }}
|
|
||||||
KC_DB_PASSWORD='{{ keycloak_secrets["postgres_password"] }}'
|
|
||||||
|
|
||||||
KC_PROXY_HEADERS=xforwarded
|
|
||||||
KC_HOSTNAME=https://kc.{{ domain }}
|
|
|
@ -1,15 +0,0 @@
|
||||||
FROM quay.io/keycloak/keycloak:25.0 as builder
|
|
||||||
|
|
||||||
ENV KC_DB=postgres
|
|
||||||
|
|
||||||
WORKDIR /opt/keycloak
|
|
||||||
|
|
||||||
RUN keytool -genkeypair -storepass password -storetype PKCS12 -keyalg RSA -keysize 2048 -dname "CN=server" -alias server -ext "SAN:c=IP:127.0.0.1" -keystore conf/server.keystore
|
|
||||||
RUN /opt/keycloak/bin/kc.sh build
|
|
||||||
|
|
||||||
|
|
||||||
FROM quay.io/keycloak/keycloak:25.0
|
|
||||||
COPY --from=builder /opt/keycloak/ /opt/keycloak/
|
|
||||||
|
|
||||||
ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]
|
|
||||||
CMD ["start", "--optimized"]
|
|
|
@ -1,9 +0,0 @@
|
||||||
services:
|
|
||||||
keycloak:
|
|
||||||
container_name: keycloak
|
|
||||||
build: .
|
|
||||||
restart: always
|
|
||||||
user: {{ users['keycloak'] }}:{{ users['keycloak'] }}
|
|
||||||
env_file: .env
|
|
||||||
ports:
|
|
||||||
- 127.0.0.1:{{ ports['keycloak'] }}:8443
|
|
25
roles/lldap/tasks/backup.yml
Normal file
25
roles/lldap/tasks/backup.yml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
- name: "Backup PostgreSQL lldap database & {{ volumes['lldap_datadir'] }} directory"
|
||||||
|
shell: >
|
||||||
|
docker exec postgres
|
||||||
|
pg_dump -c {{ role_name }} |
|
||||||
|
borg create
|
||||||
|
--compression lzma
|
||||||
|
"{{ borg_repodir }}::{{ role_name }}-{now:%Y-%m-%d_%H-%M-%S}"
|
||||||
|
"{{ volumes['lldap_datadir'] }}"
|
||||||
|
-
|
||||||
|
--stdin-name dump_{{ role_name }}.sql
|
||||||
|
environment:
|
||||||
|
DOCKER_HOST: "{{ docker_host }}"
|
||||||
|
BORG_PASSCOMMAND: "cat {{ borg_passphrase_file }}"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Prune borg repository
|
||||||
|
command:
|
||||||
|
cmd: |
|
||||||
|
borg prune
|
||||||
|
--glob-archives='{{ role_name }}-*'
|
||||||
|
{{ borg_prune_options }}
|
||||||
|
{{ borg_repodir }}
|
||||||
|
environment:
|
||||||
|
BORG_PASSCOMMAND: "cat {{ borg_passphrase_file }}"
|
||||||
|
become: true
|
14
roles/lldap/tasks/main.yml
Normal file
14
roles/lldap/tasks/main.yml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
- name: Include backup tasks
|
||||||
|
include_tasks:
|
||||||
|
file: backup.yml
|
||||||
|
when: run_backup | default(false) | bool
|
||||||
|
|
||||||
|
- name: Include setup tasks
|
||||||
|
include_tasks:
|
||||||
|
file: setup.yml
|
||||||
|
when: run_setup | default(false) | bool
|
||||||
|
|
||||||
|
- name: Include update tasks
|
||||||
|
include_tasks:
|
||||||
|
file: update.yml
|
||||||
|
when: run_update | default(false) | bool
|
27
roles/lldap/tasks/setup.yml
Normal file
27
roles/lldap/tasks/setup.yml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
- name: "(Re)Create {{ project_dir }} project directory"
|
||||||
|
file:
|
||||||
|
path: "{{ project_dir }}"
|
||||||
|
state: "{{ item }}"
|
||||||
|
loop:
|
||||||
|
- absent
|
||||||
|
- directory
|
||||||
|
|
||||||
|
- name: Template docker-compose.yaml & .env to project directory
|
||||||
|
template:
|
||||||
|
src: "{{ item }}"
|
||||||
|
dest: "{{ project_dir }}/{{ item }}"
|
||||||
|
owner: "{{ host_uid }}"
|
||||||
|
group: "{{ host_uid }}"
|
||||||
|
mode: '600'
|
||||||
|
loop:
|
||||||
|
- docker-compose.yaml
|
||||||
|
- .env
|
||||||
|
|
||||||
|
- name: "Create (if not exists) directory {{ volumes['lldap_datadir'] }} & set permissions"
|
||||||
|
file:
|
||||||
|
path: "{{ volumes['lldap_datadir'] }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ users['lldap'] + uid_shift }}"
|
||||||
|
group: "{{ users['lldap'] + uid_shift }}"
|
||||||
|
mode: '700'
|
||||||
|
become: true
|
24
roles/lldap/tasks/update.yml
Normal file
24
roles/lldap/tasks/update.yml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
- name: Pull project services
|
||||||
|
community.docker.docker_compose:
|
||||||
|
project_src: "{{ project_dir }}"
|
||||||
|
recreate: never
|
||||||
|
pull: true
|
||||||
|
debug: true
|
||||||
|
when: docker_pull_images | bool
|
||||||
|
register: lldap_docker_compose_pull_result
|
||||||
|
|
||||||
|
- name: Display pulled image(s) name
|
||||||
|
set_fact:
|
||||||
|
lldap_pulled_images: "{{ lldap_pulled_images | default([]) + [item.pulled_image.name] }}"
|
||||||
|
loop: "{{ lldap_docker_compose_pull_result['actions'] | default([]) | selectattr('pulled_image', 'defined') }}"
|
||||||
|
|
||||||
|
- name: Include backup tasks
|
||||||
|
include_tasks:
|
||||||
|
file: backup.yml
|
||||||
|
# Make a backup if we didn't already make one and we pulled a new image
|
||||||
|
when: not run_backup | default(false) and lldap_pulled_images is defined
|
||||||
|
|
||||||
|
- name: Create/Restart project services
|
||||||
|
community.docker.docker_compose:
|
||||||
|
project_src: "{{ project_dir }}"
|
||||||
|
restarted: "{{ run_setup | default(false) | bool }}"
|
7
roles/lldap/templates/.env
Normal file
7
roles/lldap/templates/.env
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
UID={{ users['lldap'] }}
|
||||||
|
GID={{ users['lldap'] }}
|
||||||
|
TZ={{ timezone }}
|
||||||
|
LLDAP_LDAP_BASE_DN={{ ldap_base_dn }}
|
||||||
|
LLDAP_JWT_SECRET='{{ lldap_secrets["jwt_secret"] }}'
|
||||||
|
LLDAP_KEY_SEED='{{ lldap_secrets["key_seed"] }}'
|
||||||
|
LLDAP_DATABASE_URL='postgres://{{ lldap_secrets["postgres_user"] }}:{{ lldap_secrets["postgres_password"] }}@postgres.{{ domain }}/lldap'
|
17
roles/lldap/templates/docker-compose.yaml
Normal file
17
roles/lldap/templates/docker-compose.yaml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
services:
|
||||||
|
lldap:
|
||||||
|
container_name: lldap
|
||||||
|
image: docker.io/lldap/lldap:2024-06-13-alpine-rootless
|
||||||
|
restart: always
|
||||||
|
user: {{ users['lldap'] }}:{{ users['lldap'] }}
|
||||||
|
env_file: .env
|
||||||
|
networks:
|
||||||
|
- authelia
|
||||||
|
ports:
|
||||||
|
- {{ ports['lldap'] }}:17170
|
||||||
|
volumes:
|
||||||
|
- {{ volumes['lldap_datadir'] }}:/data
|
||||||
|
|
||||||
|
networks:
|
||||||
|
authelia:
|
||||||
|
name: authelia
|
10
roles/nginx/templates/sites-enabled/authelia.conf
Normal file
10
roles/nginx/templates/sites-enabled/authelia.conf
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
|
||||||
|
server_name auth.{{ domain }};
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:{{ ports['authelia'] }};
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,13 +0,0 @@
|
||||||
server {
|
|
||||||
listen 443 ssl;
|
|
||||||
listen [::]:443 ssl;
|
|
||||||
|
|
||||||
server_name kc.{{ domain }};
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass https://127.0.0.1:{{ ports['keycloak'] }};
|
|
||||||
|
|
||||||
#include /etc/nginx/snippets/websocket.conf;
|
|
||||||
#include /etc/nginx/snippets/proxy.conf;
|
|
||||||
}
|
|
||||||
}
|
|
14
roles/nginx/templates/sites-enabled/lldap.conf
Normal file
14
roles/nginx/templates/sites-enabled/lldap.conf
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
|
||||||
|
server_name ldap.{{ domain }};
|
||||||
|
|
||||||
|
include /etc/nginx/snippets/authelia-location.conf;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:{{ ports['lldap'] }};
|
||||||
|
|
||||||
|
include /etc/nginx/snippets/authelia-authrequest.conf;
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,21 +12,6 @@ server {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
server {
|
|
||||||
listen 443 ssl;
|
|
||||||
listen [::]:443 ssl;
|
|
||||||
|
|
||||||
server_name autoconfig.{{ domain }};
|
|
||||||
|
|
||||||
location / {
|
|
||||||
return 404;
|
|
||||||
}
|
|
||||||
|
|
||||||
location = /mail/config-v1.1.xml {
|
|
||||||
proxy_pass https://127.0.0.1:{{ ports['mailserver_https'] }};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 443 ssl;
|
listen 443 ssl;
|
||||||
listen [::]:443 ssl;
|
listen [::]:443 ssl;
|
||||||
|
|
14
roles/nginx/templates/sites-enabled/syncthing.conf
Normal file
14
roles/nginx/templates/sites-enabled/syncthing.conf
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
|
||||||
|
server_name syncthing.{{ domain }};
|
||||||
|
|
||||||
|
include /etc/nginx/snippets/authelia-location.conf;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:{{ ports['syncthing_webui'] }};
|
||||||
|
|
||||||
|
include /etc/nginx/snippets/authelia-authrequest.conf;
|
||||||
|
}
|
||||||
|
}
|
15
roles/nginx/templates/snippets/authelia-authrequest.conf
Normal file
15
roles/nginx/templates/snippets/authelia-authrequest.conf
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
auth_request /internal/authelia/authz;
|
||||||
|
|
||||||
|
auth_request_set $user $upstream_http_remote_user;
|
||||||
|
auth_request_set $groups $upstream_http_remote_groups;
|
||||||
|
auth_request_set $name $upstream_http_remote_name;
|
||||||
|
auth_request_set $email $upstream_http_remote_email;
|
||||||
|
|
||||||
|
proxy_set_header Remote-User $user;
|
||||||
|
proxy_set_header Remote-Groups $groups;
|
||||||
|
proxy_set_header Remote-Email $email;
|
||||||
|
proxy_set_header Remote-Name $name;
|
||||||
|
|
||||||
|
auth_request_set $redirection_url $upstream_http_location;
|
||||||
|
|
||||||
|
error_page 401 =302 $redirection_url;
|
18
roles/nginx/templates/snippets/authelia-location.conf
Normal file
18
roles/nginx/templates/snippets/authelia-location.conf
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
location /internal/authelia/authz {
|
||||||
|
internal;
|
||||||
|
|
||||||
|
proxy_pass http://127.0.0.1:{{ ports['authelia'] }}/api/authz/auth-request;
|
||||||
|
|
||||||
|
proxy_set_header X-Original-Method $request_method;
|
||||||
|
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
|
||||||
|
proxy_set_header X-Forwarded-For $remote_addr;
|
||||||
|
proxy_set_header Content-Length "";
|
||||||
|
proxy_set_header Connection "";
|
||||||
|
|
||||||
|
proxy_pass_request_body off;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_cache_bypass $cookie_session;
|
||||||
|
proxy_no_cache $cookie_session;
|
||||||
|
proxy_buffers 4 32k;
|
||||||
|
client_body_buffer_size 128k;
|
||||||
|
}
|
|
@ -108,12 +108,17 @@ suppress_key_server_warning: true
|
||||||
|
|
||||||
# Single sign-on integration
|
# Single sign-on integration
|
||||||
oidc_providers:
|
oidc_providers:
|
||||||
- idp_id: keycloak
|
- idp_id: authelia
|
||||||
idp_name: "Keycloak"
|
idp_name: "Authelia"
|
||||||
issuer: "https://kc.{{ domain }}/realms/master"
|
idp_icon: "mxc://authelia.com/cKlrTPsGvlpKxAYeHWJsdVHI"
|
||||||
client_id: '{{ synapse_secrets["client_id"] }}'
|
discover: false
|
||||||
client_secret: '{{ synapse_secrets["client_secret"] }}'
|
issuer: "https://auth.{{ domain }}"
|
||||||
|
client_id: '{{ authelia_secrets["synapse_client_id"] }}'
|
||||||
|
client_secret: '{{ authelia_secrets["synapse_client_secret"] }}'
|
||||||
scopes: ["openid", "profile", "email"]
|
scopes: ["openid", "profile", "email"]
|
||||||
|
authorization_endpoint: 'https://auth.{{ domain }}/api/oidc/authorization'
|
||||||
|
token_endpoint: 'https://auth.{{ domain }}/api/oidc/token'
|
||||||
|
jwks_uri: 'https://auth.{{ domain }}/jwks.json'
|
||||||
allow_existing_users: true
|
allow_existing_users: true
|
||||||
user_mapping_provider:
|
user_mapping_provider:
|
||||||
config:
|
config:
|
||||||
|
@ -121,7 +126,3 @@ oidc_providers:
|
||||||
localpart_template: "{% raw %}{{ user.preferred_username }}{% endraw %}"
|
localpart_template: "{% raw %}{{ user.preferred_username }}{% endraw %}"
|
||||||
display_name_template: "{% raw %}{{ user.name }}{% endraw %}"
|
display_name_template: "{% raw %}{{ user.name }}{% endraw %}"
|
||||||
email_template: "{% raw %}{{ user.email }}{% endraw %}"
|
email_template: "{% raw %}{{ user.email }}{% endraw %}"
|
||||||
backchannel_logout_enabled: true
|
|
||||||
|
|
||||||
password_config:
|
|
||||||
enabled: false
|
|
||||||
|
|
|
@ -1,24 +1,29 @@
|
||||||
- name: "Backup PostgreSQL vaultwarden database"
|
- name:
|
||||||
shell: >
|
|
||||||
docker exec postgres
|
|
||||||
pg_dump -c {{ role_name }} |
|
|
||||||
borg create
|
|
||||||
--compression lzma
|
|
||||||
"{{ borg_repodir }}::{{ role_name }}-{now:%Y-%m-%d_%H-%M-%S}"
|
|
||||||
-
|
|
||||||
--stdin-name dump_{{ role_name }}.sql
|
|
||||||
environment:
|
|
||||||
DOCKER_HOST: "{{ docker_host }}"
|
|
||||||
BORG_PASSCOMMAND: "cat {{ borg_passphrase_file }}"
|
|
||||||
become: true
|
become: true
|
||||||
|
block:
|
||||||
|
- name: Backup SQLite database
|
||||||
|
command:
|
||||||
|
cmd: |
|
||||||
|
sqlite3
|
||||||
|
"{{ volumes['vaultwarden_datadir'] }}/db.sqlite3"
|
||||||
|
".backup {{ volumes['vaultwarden_datadir'] }}/db-backup.sqlite3"
|
||||||
|
|
||||||
- name: Prune borg repository
|
- name: Create borg backup
|
||||||
command:
|
command:
|
||||||
cmd: |
|
cmd: |
|
||||||
borg prune
|
borg create
|
||||||
--glob-archives='{{ role_name }}-*'
|
--compression=lzma
|
||||||
{{ borg_prune_options }}
|
"{{ borg_repodir }}::{{ role_name }}-{now:%Y-%m-%d_%H-%M-%S}"
|
||||||
{{ borg_repodir }}
|
{{ volumes['vaultwarden_datadir'] }}/db-backup.sqlite3
|
||||||
environment:
|
environment:
|
||||||
BORG_PASSCOMMAND: "cat {{ borg_passphrase_file }}"
|
BORG_PASSCOMMAND: "cat {{ borg_passphrase_file }}"
|
||||||
become: true
|
|
||||||
|
- name: Prune borg repository
|
||||||
|
command:
|
||||||
|
cmd: |
|
||||||
|
borg prune
|
||||||
|
--glob-archives='{{ role_name }}-*'
|
||||||
|
{{ borg_prune_options }}
|
||||||
|
{{ borg_repodir }}
|
||||||
|
environment:
|
||||||
|
BORG_PASSCOMMAND: "cat {{ borg_passphrase_file }}"
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
file:
|
file:
|
||||||
path: "{{ volumes['vaultwarden_datadir'] }}"
|
path: "{{ volumes['vaultwarden_datadir'] }}"
|
||||||
state: directory
|
state: directory
|
||||||
recurse: true
|
|
||||||
owner: "{{ users['vaultwarden'] + uid_shift }}"
|
owner: "{{ users['vaultwarden'] + uid_shift }}"
|
||||||
group: "{{ users['vaultwarden'] + uid_shift }}"
|
group: "{{ users['vaultwarden'] + uid_shift }}"
|
||||||
mode: '770'
|
mode: '770'
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
ADMIN_TOKEN='{{ vaultwarden_secrets["admin_token_hash"] }}'
|
ADMIN_TOKEN='{{ vaultwarden_secrets["admin_token_hash"] }}'
|
||||||
DOMAIN=https://vw.{{ domain }}
|
DOMAIN=https://vw.{{ domain }}
|
||||||
SIGNUPS_ALLOWED=false
|
SIGNUPS_ALLOWED=false
|
||||||
|
|
||||||
DATABASE_URL=postgresql://{{ vaultwarden_secrets['postgres_user'] }}:{{ vaultwarden_secrets['postgres_password'] }}@postgres.{{ domain }}:{{ ports['postgres'] }}/vaultwarden
|
|
||||||
|
|
||||||
SMTP_HOST=mail.{{ domain }}
|
SMTP_HOST=mail.{{ domain }}
|
||||||
SMTP_FROM=vaultwarden@{{ domain }}
|
SMTP_FROM=vaultwarden@{{ domain }}
|
||||||
SMTP_PORT={{ ports['mailserver_smtps'] }}
|
SMTP_PORT={{ ports['mailserver_smtps'] }}
|
||||||
|
|
|
@ -8,17 +8,46 @@ cifs_credentials:
|
||||||
username:
|
username:
|
||||||
password:
|
password:
|
||||||
|
|
||||||
|
|
||||||
|
authelia_secrets:
|
||||||
|
# Encryption key for the database, must be saved
|
||||||
|
encryption_key:
|
||||||
|
|
||||||
|
# Generate random client id : docker run --rm authelia/authelia:4 authelia crypto rand --length 72 --charset rfc3986
|
||||||
|
# Generate random secret + hash : docker run --rm authelia/authelia:4 authelia crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986
|
||||||
|
hedgedoc_client_id:
|
||||||
|
hedgedoc_client_secret:
|
||||||
|
hedgedoc_client_secret_hash:
|
||||||
|
synapse_client_id:
|
||||||
|
synapse_client_secret:
|
||||||
|
synapse_client_secret_hash:
|
||||||
|
|
||||||
|
hmac_secret:
|
||||||
|
jwks_key: | # openssl genrsa 4096
|
||||||
|
jwt_secret:
|
||||||
|
|
||||||
|
# LDAP bind dn
|
||||||
|
ldap_user:
|
||||||
|
ldap_password:
|
||||||
|
|
||||||
|
postgres_user:
|
||||||
|
postgres_password:
|
||||||
|
|
||||||
|
smtp_user:
|
||||||
|
smtp_password:
|
||||||
|
|
||||||
|
|
||||||
coturn_secrets:
|
coturn_secrets:
|
||||||
static_auth_secret:
|
static_auth_secret:
|
||||||
|
|
||||||
hedgedoc_secrets:
|
hedgedoc_secrets:
|
||||||
client_id:
|
|
||||||
client_secret:
|
|
||||||
postgres_user:
|
postgres_user:
|
||||||
postgres_password:
|
postgres_password:
|
||||||
session_secret:
|
session_secret:
|
||||||
|
|
||||||
keycloak_secerts:
|
lldap_secrets:
|
||||||
|
jwt_secret:
|
||||||
|
key_seed:
|
||||||
postgres_user:
|
postgres_user:
|
||||||
postgres_password:
|
postgres_password:
|
||||||
|
|
||||||
|
@ -41,8 +70,5 @@ synapse_secrets:
|
||||||
vaultwarden_secrets:
|
vaultwarden_secrets:
|
||||||
# Generate with: docker exec --rm -ti docker.io/vaultwarden/server:alpine /vaultwarden hash
|
# Generate with: docker exec --rm -ti docker.io/vaultwarden/server:alpine /vaultwarden hash
|
||||||
admin_token_hash:
|
admin_token_hash:
|
||||||
# https://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding_reserved_characters
|
|
||||||
postgres_user:
|
|
||||||
postgres_password:
|
|
||||||
smtp_username:
|
smtp_username:
|
||||||
smtp_password:
|
smtp_password:
|
||||||
|
|
Loading…
Reference in a new issue