Compare commits
9 commits
14b484dd37
...
1514031f1e
Author | SHA1 | Date | |
---|---|---|---|
1514031f1e | |||
e3c7c4f38a | |||
ce753e991c | |||
1292bc6f5c | |||
36bd236beb | |||
aca23d6af6 | |||
3852896273 | |||
1e26499932 | |||
b27a553dfb |
47 changed files with 732 additions and 446 deletions
21
env.yml
21
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,14 +39,16 @@ cifs_mounts:
|
||||||
|
|
||||||
|
|
||||||
projects:
|
projects:
|
||||||
|
- authelia
|
||||||
- coturn
|
- coturn
|
||||||
- element
|
- element
|
||||||
- etebase
|
- etebase
|
||||||
- hedgedoc
|
- hedgedoc
|
||||||
- homepage
|
- homepage
|
||||||
|
- lldap
|
||||||
- mailserver
|
- mailserver
|
||||||
|
- nginx
|
||||||
- postgres
|
- postgres
|
||||||
- reverse-proxy
|
|
||||||
- searxng
|
- searxng
|
||||||
- synapse
|
- synapse
|
||||||
- syncthing
|
- syncthing
|
||||||
|
@ -54,8 +57,10 @@ projects:
|
||||||
|
|
||||||
|
|
||||||
projects_to_backup:
|
projects_to_backup:
|
||||||
|
- authelia
|
||||||
- etebase
|
- etebase
|
||||||
- hedgedoc
|
- hedgedoc
|
||||||
|
- lldap
|
||||||
- mailserver
|
- mailserver
|
||||||
- postgres
|
- postgres
|
||||||
- synapse
|
- synapse
|
||||||
|
@ -76,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
|
||||||
|
@ -84,6 +90,7 @@ ports:
|
||||||
etebase: 3735
|
etebase: 3735
|
||||||
hedgedoc: 8086
|
hedgedoc: 8086
|
||||||
homepage: 8082
|
homepage: 8082
|
||||||
|
lldap: 17170
|
||||||
mailserver_smtp: 1025
|
mailserver_smtp: 1025
|
||||||
mailserver_smtps: 1465
|
mailserver_smtps: 1465
|
||||||
mailserver_imaps: 1993
|
mailserver_imaps: 1993
|
||||||
|
@ -103,17 +110,18 @@ ports:
|
||||||
|
|
||||||
# UID in containers
|
# UID in containers
|
||||||
users:
|
users:
|
||||||
|
authelia: 1008
|
||||||
coturn: 666
|
coturn: 666
|
||||||
etebase: 373
|
etebase: 373
|
||||||
hedgedoc: 1004
|
hedgedoc: 1004
|
||||||
hedgedoc_mysql: 1005
|
hedgedoc_mysql: 1005
|
||||||
homepage: 8686
|
homepage: 8686
|
||||||
|
lldap: 1007
|
||||||
mailserver: 8
|
mailserver: 8
|
||||||
postgres: 70
|
postgres: 70
|
||||||
searxng: 977
|
searxng: 977
|
||||||
searxng_redis: 999
|
searxng_redis: 999
|
||||||
synapse: 991
|
synapse: 991
|
||||||
synapse_postgres: 70
|
|
||||||
syncthing: 1001
|
syncthing: 1001
|
||||||
syncthing_discosrv: 1002
|
syncthing_discosrv: 1002
|
||||||
syncthing_relaysrv: 1003
|
syncthing_relaysrv: 1003
|
||||||
|
@ -127,24 +135,17 @@ volumes:
|
||||||
etebase_datadir: /mnt/etebasedata
|
etebase_datadir: /mnt/etebasedata
|
||||||
hedgedoc_mysql_datadir: /mnt/hedgedoc/mysql-data
|
hedgedoc_mysql_datadir: /mnt/hedgedoc/mysql-data
|
||||||
hedgedoc_configdir: /mnt/hedgedoc/config
|
hedgedoc_configdir: /mnt/hedgedoc/config
|
||||||
|
lldap_datadir: /mnt/lldapdata
|
||||||
mailserver_datadir: /mnt/mailserverdata
|
mailserver_datadir: /mnt/mailserverdata
|
||||||
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"
|
||||||
postgres_datadir: /mnt/postgresdata
|
postgres_datadir: /mnt/postgresdata
|
||||||
synapse_datadir: /mnt/synapsedata
|
synapse_datadir: /mnt/synapsedata
|
||||||
synapse_postgres_datadir: /mnt/synapsepgdata
|
|
||||||
syncthing_datadir: "{{ cifs_mounts['syncthing']['path'] }}"
|
syncthing_datadir: "{{ cifs_mounts['syncthing']['path'] }}"
|
||||||
uptime_kuma_datadir: /mnt/uptimekumadata
|
uptime_kuma_datadir: /mnt/uptimekumadata
|
||||||
vaultwarden_datadir: /mnt/vwdata
|
vaultwarden_datadir: /mnt/vwdata
|
||||||
|
|
||||||
|
|
||||||
# Service-specific variables
|
# Service-specific variables
|
||||||
reverse_proxy:
|
|
||||||
ssl_certificate_file: "/etc/letsencrypt/live/{{ domain }}/fullchain.pem"
|
|
||||||
ssl_certificate_key_file: "/etc/letsencrypt/live/{{ domain }}/privkey.pem"
|
|
||||||
ssl_trusted_certificate_file: "/etc/letsencrypt/live/{{ domain }}/chain.pem"
|
|
||||||
resolver: "185.12.64.12 [a01:4ff:ff00::add:2] [2a01:4ff:ff00::add:1]"
|
|
||||||
|
|
||||||
|
|
||||||
synapse:
|
synapse:
|
||||||
max_upload_size: 50M
|
max_upload_size: 50M
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
hosts: localhost
|
hosts: localhost
|
||||||
vars:
|
vars:
|
||||||
run_backup: false
|
run_backup: false
|
||||||
|
run_setup: true
|
||||||
run_update: true
|
run_update: true
|
||||||
vars_prompt:
|
vars_prompt:
|
||||||
- name: selected_projects
|
- name: selected_projects
|
||||||
|
|
24
psql-create-db-user.sh
Executable file
24
psql-create-db-user.sh
Executable file
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
read -rp "Database: " database
|
||||||
|
|
||||||
|
read -rp "User: " user
|
||||||
|
|
||||||
|
read -srp "Password: " password
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
read -rp "Create database $database & user $user? [Y/n]: " answer
|
||||||
|
|
||||||
|
if ! [[ $answer =~ ^(Y|y)?$ ]]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
stmts=(
|
||||||
|
"CREATE USER $user PASSWORD '$password'"
|
||||||
|
"CREATE DATABASE $database WITH OWNER = $user"
|
||||||
|
"GRANT ALL ON DATABASE $database TO $user"
|
||||||
|
)
|
||||||
|
|
||||||
|
for stmt in "${stmts[@]}"; do
|
||||||
|
docker exec postgres psql -c "$stmt"
|
||||||
|
done
|
24
roles/authelia/tasks/backup.yml
Normal file
24
roles/authelia/tasks/backup.yml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
- name: "Backup PostgreSQL authelia database"
|
||||||
|
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
|
||||||
|
|
||||||
|
- 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/authelia/tasks/main.yml
Normal file
14
roles/authelia/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
|
23
roles/authelia/tasks/setup.yml
Normal file
23
roles/authelia/tasks/setup.yml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
- name: "Create {{ project_dir }} project directory"
|
||||||
|
file:
|
||||||
|
path: "{{ project_dir }}"
|
||||||
|
state: 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
|
||||||
|
register: authelia_template_configuration_result
|
||||||
|
|
||||||
|
# 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
|
24
roles/authelia/tasks/update.yml
Normal file
24
roles/authelia/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: authelia_docker_compose_pull_result
|
||||||
|
|
||||||
|
- name: Display pulled image(s) name
|
||||||
|
set_fact:
|
||||||
|
authelia_pulled_images: "{{ authelia_pulled_images | default([]) + [item.pulled_image.name] }}"
|
||||||
|
loop: "{{ authelia_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 and authelia_pulled_images is defined
|
||||||
|
|
||||||
|
- name: Create/Restart project services
|
||||||
|
community.docker.docker_compose:
|
||||||
|
project_src: "{{ project_dir }}"
|
||||||
|
restarted: "{{ authelia_template_configuration_result['changed'] | default(false) | bool }}"
|
72
roles/authelia/templates/configuration.yml
Normal file
72
roles/authelia/templates/configuration.yml
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
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:
|
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
|
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
|
24
roles/lldap/tasks/setup.yml
Normal file
24
roles/lldap/tasks/setup.yml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
- name: "Create {{ project_dir }} project directory"
|
||||||
|
file:
|
||||||
|
path: "{{ project_dir }}"
|
||||||
|
state: 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
|
23
roles/lldap/tasks/update.yml
Normal file
23
roles/lldap/tasks/update.yml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
- 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 and lldap_pulled_images is defined
|
||||||
|
|
||||||
|
- name: Create/Restart project services
|
||||||
|
community.docker.docker_compose:
|
||||||
|
project_src: "{{ project_dir }}"
|
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'
|
20
roles/lldap/templates/docker-compose.yaml
Normal file
20
roles/lldap/templates/docker-compose.yaml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
services:
|
||||||
|
lldap:
|
||||||
|
container_name: lldap
|
||||||
|
image: docker.io/lldap/lldap:latest-alpine-rootless
|
||||||
|
restart: always
|
||||||
|
user: {{ users['lldap'] }}:{{ users['lldap'] }}
|
||||||
|
env_file: .env
|
||||||
|
networks:
|
||||||
|
- authelia
|
||||||
|
- mailserver
|
||||||
|
ports:
|
||||||
|
- {{ ports['lldap'] }}:17170
|
||||||
|
volumes:
|
||||||
|
- {{ volumes['lldap_datadir'] }}:/data
|
||||||
|
|
||||||
|
networks:
|
||||||
|
authelia:
|
||||||
|
name: authelia
|
||||||
|
mailserver:
|
||||||
|
name: mailserver
|
|
@ -1,6 +1,6 @@
|
||||||
services:
|
services:
|
||||||
mailserver:
|
mailserver:
|
||||||
image: docker.io/stalwartlabs/mail-server:latest
|
image: docker.io/stalwartlabs/mail-server:v0.6.0
|
||||||
container_name: mailserver
|
container_name: mailserver
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
|
|
60
roles/nginx/tasks/main.yml
Normal file
60
roles/nginx/tasks/main.yml
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
- name:
|
||||||
|
become: true
|
||||||
|
block:
|
||||||
|
- name: Install package nginx
|
||||||
|
apt:
|
||||||
|
name: nginx
|
||||||
|
|
||||||
|
- name: Delete directories in /etc/nginx/
|
||||||
|
file:
|
||||||
|
path: "/etc/nginx/{{ item }}"
|
||||||
|
state: absent
|
||||||
|
loop:
|
||||||
|
- sites-enabled
|
||||||
|
- snippets
|
||||||
|
|
||||||
|
- name: Create directories in /etc/nginx/
|
||||||
|
file:
|
||||||
|
path: "/etc/nginx/{{ item }}"
|
||||||
|
state: directory
|
||||||
|
loop:
|
||||||
|
- sites-enabled
|
||||||
|
- snippets
|
||||||
|
|
||||||
|
- name: Template configuration files to /etc/nginx/
|
||||||
|
template:
|
||||||
|
src: "{{ item.src }}"
|
||||||
|
dest: "/etc/nginx/{{ item.path }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '644'
|
||||||
|
with_filetree: ../templates/
|
||||||
|
when: item.state == 'file'
|
||||||
|
|
||||||
|
- name: Get state of file /etc/nginx/dhparam.txt
|
||||||
|
stat:
|
||||||
|
path: /etc/nginx/dhparam.txt
|
||||||
|
register: nginx_stat_dhparam_result
|
||||||
|
|
||||||
|
- name: Download dhparam file from Mozilla
|
||||||
|
get_url:
|
||||||
|
url: https://ssl-config.mozilla.org/ffdhe2048.txt
|
||||||
|
dest: /etc/nginx/dhparam.txt
|
||||||
|
when: not nginx_stat_dhparam_result.stat.exists
|
||||||
|
|
||||||
|
- name: Set correct permissions on certificate directories
|
||||||
|
file:
|
||||||
|
path: "/etc/letsencrypt/{{ item }}/{{ domain }}"
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '750'
|
||||||
|
loop:
|
||||||
|
- live
|
||||||
|
- archive
|
||||||
|
|
||||||
|
- name: Start/Reload NGINX service
|
||||||
|
service:
|
||||||
|
name: nginx
|
||||||
|
state: reloaded
|
||||||
|
enabled: yes
|
38
roles/nginx/templates/nginx.conf
Normal file
38
roles/nginx/templates/nginx.conf
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
user www-data;
|
||||||
|
worker_processes auto;
|
||||||
|
worker_rlimit_nofile 1024;
|
||||||
|
include /etc/nginx/modules-enabled/*.conf;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 512;
|
||||||
|
multi_accept off;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
sendfile on;
|
||||||
|
tcp_nopush on;
|
||||||
|
tcp_nodelay on;
|
||||||
|
|
||||||
|
gzip off;
|
||||||
|
server_tokens off;
|
||||||
|
keepalive_timeout 30;
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access.log;
|
||||||
|
error_log /var/log/nginx/error.log;
|
||||||
|
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
|
||||||
|
# Needed to support websocket connections
|
||||||
|
map $http_upgrade $connection_upgrade {
|
||||||
|
default upgrade;
|
||||||
|
'' "";
|
||||||
|
}
|
||||||
|
|
||||||
|
include /etc/nginx/conf.d/*.conf;
|
||||||
|
|
||||||
|
include /etc/nginx/snippets/proxy.conf;
|
||||||
|
include /etc/nginx/snippets/ssl.conf;
|
||||||
|
include /etc/nginx/snippets/ssl-headers.conf;
|
||||||
|
|
||||||
|
include /etc/nginx/sites-enabled/*;
|
||||||
|
}
|
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'] }};
|
||||||
|
}
|
||||||
|
}
|
15
roles/nginx/templates/sites-enabled/default.conf
Normal file
15
roles/nginx/templates/sites-enabled/default.conf
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Redirect HTTP to HTTPS
|
||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
listen [::]:80 default_server;
|
||||||
|
|
||||||
|
return 308 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Default HTTPS server
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2 default_server;
|
||||||
|
listen [::]:443 ssl http2 default_server;
|
||||||
|
|
||||||
|
return 404;
|
||||||
|
}
|
9
roles/nginx/templates/sites-enabled/downloads.conf
Normal file
9
roles/nginx/templates/sites-enabled/downloads.conf
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
|
||||||
|
server_name dl.{{ domain }};
|
||||||
|
|
||||||
|
root /var/www/html;
|
||||||
|
autoindex on;
|
||||||
|
}
|
16
roles/nginx/templates/sites-enabled/element.conf
Normal file
16
roles/nginx/templates/sites-enabled/element.conf
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
|
||||||
|
server_name element.{{ domain }};
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:{{ ports['element'] }};
|
||||||
|
|
||||||
|
include /etc/nginx/snippets/ssl-headers.conf;
|
||||||
|
add_header X-Frame-Options SAMEORIGIN;
|
||||||
|
add_header X-Content-Type-Options nosniff;
|
||||||
|
add_header X-XSS-Protection "1; mode=block";
|
||||||
|
add_header Content-Security-Policy "frame-ancestors 'none'";
|
||||||
|
}
|
||||||
|
}
|
10
roles/nginx/templates/sites-enabled/etebase.conf
Normal file
10
roles/nginx/templates/sites-enabled/etebase.conf
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
|
||||||
|
server_name etebase.{{ domain }};
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:{{ ports['etebase'] }};
|
||||||
|
}
|
||||||
|
}
|
16
roles/nginx/templates/sites-enabled/hedgedoc.conf
Normal file
16
roles/nginx/templates/sites-enabled/hedgedoc.conf
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
|
||||||
|
server_name hedgedoc.{{ domain }};
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:{{ ports['hedgedoc'] }};
|
||||||
|
}
|
||||||
|
|
||||||
|
location /socket.io/ {
|
||||||
|
proxy_pass http://127.0.0.1:{{ ports['hedgedoc'] }};
|
||||||
|
|
||||||
|
include /etc/nginx/snippets/websocket.conf;
|
||||||
|
}
|
||||||
|
}
|
25
roles/nginx/templates/sites-enabled/homepage.conf
Normal file
25
roles/nginx/templates/sites-enabled/homepage.conf
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
|
||||||
|
server_name {{ domain }};
|
||||||
|
|
||||||
|
location = /.well-known/matrix/server {
|
||||||
|
default_type application/json;
|
||||||
|
|
||||||
|
return 200 '{ "m.server": "matrix.{{ domain }}:443" }';
|
||||||
|
}
|
||||||
|
|
||||||
|
location = /.well-known/matrix/client {
|
||||||
|
default_type application/json;
|
||||||
|
|
||||||
|
include /etc/nginx/snippets/ssl-headers.conf;
|
||||||
|
add_header Access-Control-Allow-Origin '*';
|
||||||
|
|
||||||
|
return 200 '{ "m.homeserver": { "base_url": "https://matrix.{{ domain }}" } }';
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:{{ ports['homepage'] }};
|
||||||
|
}
|
||||||
|
}
|
12
roles/nginx/templates/sites-enabled/jmap.conf
Normal file
12
roles/nginx/templates/sites-enabled/jmap.conf
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
|
||||||
|
server_name jmap.{{ domain }};
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass https://127.0.0.1:{{ ports['mailserver_jmap'] }};
|
||||||
|
|
||||||
|
include /etc/nginx/snippets/websocket.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;
|
||||||
|
}
|
||||||
|
}
|
13
roles/nginx/templates/sites-enabled/searxng.conf
Normal file
13
roles/nginx/templates/sites-enabled/searxng.conf
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
|
||||||
|
server_name searx.{{ domain }};
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:{{ ports['searxng'] }};
|
||||||
|
|
||||||
|
include /etc/nginx/snippets/ssl-headers.conf;
|
||||||
|
add_header Content-Security-Policy "upgrade-insecure-requests; default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; form-action 'self' https://github.com/searxng/searxng/issues/new; font-src 'self'; frame-ancestors 'self'; base-uri 'self'; connect-src 'self' https://overpass-api.de; img-src 'self' data: https://*.tile.openstreetmap.org; frame-src https://www.youtube-nocookie.com https://player.vimeo.com https://www.dailymotion.com https://www.deezer.com https://www.mixcloud.com https://w.soundcloud.com https://embed.spotify.com";
|
||||||
|
}
|
||||||
|
}
|
12
roles/nginx/templates/sites-enabled/synapse.conf
Normal file
12
roles/nginx/templates/sites-enabled/synapse.conf
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
|
||||||
|
server_name matrix.{{ domain }};
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:{{ ports['synapse'] }};
|
||||||
|
|
||||||
|
client_max_body_size {{ synapse['max_upload_size'] }};
|
||||||
|
}
|
||||||
|
}
|
16
roles/nginx/templates/sites-enabled/syncthing-discovery.conf
Normal file
16
roles/nginx/templates/sites-enabled/syncthing-discovery.conf
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
|
||||||
|
server_name stdisco.{{ domain }};
|
||||||
|
|
||||||
|
ssl_verify_client optional_no_ca;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:{{ ports['syncthing_discosrv'] }};
|
||||||
|
|
||||||
|
proxy_set_header X-Client-Port $remote_port;
|
||||||
|
proxy_set_header X-SSL-Cert $ssl_client_cert;
|
||||||
|
include /etc/nginx/snippets/websocket.conf;
|
||||||
|
}
|
||||||
|
}
|
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;
|
||||||
|
}
|
||||||
|
}
|
12
roles/nginx/templates/sites-enabled/uptime-kuma.conf
Normal file
12
roles/nginx/templates/sites-enabled/uptime-kuma.conf
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
|
||||||
|
server_name status.{{ domain }};
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:{{ ports['uptime_kuma'] }};
|
||||||
|
|
||||||
|
include /etc/nginx/snippets/websocket.conf;
|
||||||
|
}
|
||||||
|
}
|
18
roles/nginx/templates/sites-enabled/vaultwarden.conf
Normal file
18
roles/nginx/templates/sites-enabled/vaultwarden.conf
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
upstream vaultwarden {
|
||||||
|
zone vaultwarden 64k;
|
||||||
|
server 127.0.0.1:{{ ports['vaultwarden'] }};
|
||||||
|
keepalive 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
|
||||||
|
server_name vw.{{ domain }};
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://vaultwarden;
|
||||||
|
|
||||||
|
include /etc/nginx/snippets/websocket.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;
|
||||||
|
}
|
10
roles/nginx/templates/snippets/proxy.conf
Normal file
10
roles/nginx/templates/snippets/proxy.conf
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $http_host;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header X-Forwarded-Scheme $scheme;
|
||||||
|
proxy_set_header X-Forwarded-URI $request_uri;
|
||||||
|
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
18
roles/nginx/templates/snippets/ssl.conf
Normal file
18
roles/nginx/templates/snippets/ssl.conf
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
ssl_certificate /etc/letsencrypt/live/{{ domain }}/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/{{ domain }}/privkey.pem;
|
||||||
|
ssl_trusted_certificate /etc/letsencrypt/live/{{ domain }}/chain.pem;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
|
||||||
|
|
||||||
|
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
|
||||||
|
ssl_dhparam /etc/nginx/dhparam.txt;
|
||||||
|
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
|
ssl_session_timeout 1d;
|
||||||
|
ssl_session_cache shared:MozSSL:10m;
|
||||||
|
ssl_session_tickets off;
|
||||||
|
|
||||||
|
ssl_stapling on;
|
||||||
|
ssl_stapling_verify on;
|
2
roles/nginx/templates/snippets/websocket.conf
Normal file
2
roles/nginx/templates/snippets/websocket.conf
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
|
@ -1,79 +0,0 @@
|
||||||
- name:
|
|
||||||
become: true
|
|
||||||
block:
|
|
||||||
- name: Install package nginx
|
|
||||||
apt:
|
|
||||||
name: nginx
|
|
||||||
|
|
||||||
- name: Template nginx.conf to /etc/nginx/nginx.conf
|
|
||||||
template:
|
|
||||||
src: nginx.conf
|
|
||||||
dest: /etc/nginx/nginx.conf
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '644'
|
|
||||||
register: nginx_template_nginx_conf_result
|
|
||||||
|
|
||||||
- name: Template reverse-proxy.conf to /etc/nginx/sites-available/reverse-proxy.conf
|
|
||||||
template:
|
|
||||||
src: reverse-proxy.conf
|
|
||||||
dest: /etc/nginx/sites-available/reverse-proxy.conf
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '644'
|
|
||||||
register: nginx_template_reverse_proxy_conf_result
|
|
||||||
|
|
||||||
- name: Copy ssl-headers.conf to /etc/nginx/conf.d/ssl-headers.conf
|
|
||||||
copy:
|
|
||||||
src: files/ssl-headers.conf
|
|
||||||
dest: /etc/nginx/conf.d/ssl-headers.conf
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '644'
|
|
||||||
register: nginx_copy_ssl_headers_conf_result
|
|
||||||
|
|
||||||
- name: Remove all enabled NGINX sites
|
|
||||||
file:
|
|
||||||
state: "{{ item }}"
|
|
||||||
path: "/etc/nginx/sites-enabled"
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '755'
|
|
||||||
loop:
|
|
||||||
- absent
|
|
||||||
- directory
|
|
||||||
|
|
||||||
- name: Enable reverse-proxy.conf site
|
|
||||||
file:
|
|
||||||
state: link
|
|
||||||
src: /etc/nginx/sites-available/reverse-proxy.conf
|
|
||||||
dest: /etc/nginx/sites-enabled/reverse-proxy.conf
|
|
||||||
|
|
||||||
- name: Get state of file /etc/nginx/dhparam.txt
|
|
||||||
stat:
|
|
||||||
path: /etc/nginx/dhparam.txt
|
|
||||||
register: nginx_stat_dhparam_result
|
|
||||||
|
|
||||||
- name: Download dhparam file from Mozilla
|
|
||||||
get_url:
|
|
||||||
url: https://ssl-config.mozilla.org/ffdhe2048.txt
|
|
||||||
dest: /etc/nginx/dhparam.txt
|
|
||||||
when: not nginx_stat_dhparam_result.stat.exists
|
|
||||||
|
|
||||||
- name: Set correct permissions on certificate directories
|
|
||||||
file:
|
|
||||||
path: "/etc/letsencrypt/{{ item }}/{{ domain }}"
|
|
||||||
state: directory
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: '750'
|
|
||||||
loop:
|
|
||||||
- live
|
|
||||||
- archive
|
|
||||||
|
|
||||||
- name: Start/Reload NGINX service
|
|
||||||
service:
|
|
||||||
name: nginx
|
|
||||||
# Reload if conf changed, if not make sure it is started
|
|
||||||
state: "{{ (nginx_template_nginx_conf_result['changed'] or nginx_template_reverse_proxy_conf_result['changed'] or nginx_copy_ssl_headers_conf_result['changed']) | ternary('reloaded', 'started') }}"
|
|
||||||
enabled: yes
|
|
|
@ -1,84 +0,0 @@
|
||||||
user www-data;
|
|
||||||
worker_processes auto;
|
|
||||||
worker_rlimit_nofile 1024;
|
|
||||||
include /etc/nginx/modules-enabled/*.conf;
|
|
||||||
|
|
||||||
events {
|
|
||||||
worker_connections 512;
|
|
||||||
multi_accept off;
|
|
||||||
}
|
|
||||||
|
|
||||||
http {
|
|
||||||
|
|
||||||
##
|
|
||||||
# Basic Settings
|
|
||||||
##
|
|
||||||
|
|
||||||
sendfile on;
|
|
||||||
tcp_nopush on;
|
|
||||||
tcp_nodelay on;
|
|
||||||
|
|
||||||
gzip off;
|
|
||||||
server_tokens off;
|
|
||||||
keepalive_timeout 30;
|
|
||||||
|
|
||||||
include /etc/nginx/mime.types;
|
|
||||||
|
|
||||||
##
|
|
||||||
# SSL Settings
|
|
||||||
##
|
|
||||||
|
|
||||||
ssl_certificate {{ reverse_proxy['ssl_certificate_file'] }};
|
|
||||||
ssl_certificate_key {{ reverse_proxy['ssl_certificate_key_file'] }};
|
|
||||||
ssl_trusted_certificate {{ reverse_proxy['ssl_trusted_certificate_file'] }};
|
|
||||||
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
|
||||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
|
|
||||||
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
|
|
||||||
ssl_dhparam /etc/nginx/dhparam.txt;
|
|
||||||
|
|
||||||
ssl_prefer_server_ciphers on;
|
|
||||||
|
|
||||||
ssl_session_timeout 1d;
|
|
||||||
ssl_session_cache shared:MozSSL:10m;
|
|
||||||
ssl_session_tickets off;
|
|
||||||
|
|
||||||
ssl_stapling on;
|
|
||||||
ssl_stapling_verify on;
|
|
||||||
|
|
||||||
##
|
|
||||||
# Logging Settings
|
|
||||||
##
|
|
||||||
|
|
||||||
access_log /var/log/nginx/access.log;
|
|
||||||
error_log /var/log/nginx/error.log;
|
|
||||||
|
|
||||||
##
|
|
||||||
# Headers
|
|
||||||
##
|
|
||||||
|
|
||||||
resolver {{ reverse_proxy['resolver'] }};
|
|
||||||
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-Port $server_port;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_set_header X-Forwarded-Scheme $scheme;
|
|
||||||
|
|
||||||
# Needed to support websocket connections
|
|
||||||
# See: https://nginx.org/en/docs/http/websocket.html
|
|
||||||
# Instead of "close" as stated in the above link we send an empty value.
|
|
||||||
# Else all keepalive connections will not work.
|
|
||||||
map $http_upgrade $connection_upgrade {
|
|
||||||
default upgrade;
|
|
||||||
'' "";
|
|
||||||
}
|
|
||||||
|
|
||||||
##
|
|
||||||
# Virtual Host Configs
|
|
||||||
##
|
|
||||||
|
|
||||||
include /etc/nginx/conf.d/*.conf;
|
|
||||||
include /etc/nginx/sites-enabled/*;
|
|
||||||
}
|
|
|
@ -1,228 +0,0 @@
|
||||||
# Redirect HTTP to HTTPS
|
|
||||||
server {
|
|
||||||
listen 80 default_server;
|
|
||||||
listen [::]:80 default_server;
|
|
||||||
|
|
||||||
server_name _;
|
|
||||||
|
|
||||||
return 308 https://$host$request_uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Default HTTPS server
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2 default_server;
|
|
||||||
listen [::]:443 ssl http2 default_server;
|
|
||||||
|
|
||||||
server_name _;
|
|
||||||
server_name_in_redirect off;
|
|
||||||
|
|
||||||
return 404;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Homepage
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
|
|
||||||
server_name {{ domain }};
|
|
||||||
|
|
||||||
location = /.well-known/matrix/server {
|
|
||||||
default_type application/json;
|
|
||||||
|
|
||||||
return 200 '{ "m.server": "matrix.{{ domain }}:443" }';
|
|
||||||
}
|
|
||||||
|
|
||||||
location = /.well-known/matrix/client {
|
|
||||||
default_type application/json;
|
|
||||||
|
|
||||||
include /etc/nginx/conf.d/ssl-headers.conf;
|
|
||||||
add_header Access-Control-Allow-Origin '*';
|
|
||||||
|
|
||||||
return 200 '{ "m.homeserver": { "base_url": "https://matrix.{{ domain }}" } }';
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:{{ ports['homepage'] }};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Downloads
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
|
|
||||||
server_name dl.{{ domain }};
|
|
||||||
|
|
||||||
root /var/www/html;
|
|
||||||
autoindex on;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Element
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
|
|
||||||
server_name element.{{ domain }};
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:{{ ports['element'] }};
|
|
||||||
|
|
||||||
include /etc/nginx/conf.d/ssl-headers.conf;
|
|
||||||
add_header X-Frame-Options SAMEORIGIN;
|
|
||||||
add_header X-Content-Type-Options nosniff;
|
|
||||||
add_header X-XSS-Protection "1; mode=block";
|
|
||||||
add_header Content-Security-Policy "frame-ancestors 'none'";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Etebase
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
|
|
||||||
server_name etebase.{{ domain }};
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:{{ ports['etebase'] }};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Hedgedoc
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
|
|
||||||
server_name hedgedoc.{{ domain }};
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:{{ ports['hedgedoc'] }};
|
|
||||||
}
|
|
||||||
|
|
||||||
location /socket.io/ {
|
|
||||||
proxy_pass http://127.0.0.1:{{ ports['hedgedoc'] }};
|
|
||||||
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $http_connection;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# JMAP
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
|
|
||||||
server_name mail.{{ domain }};
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass https://127.0.0.1:{{ ports['mailserver_jmap'] }};
|
|
||||||
|
|
||||||
# Websocket
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# SearXNG
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
|
|
||||||
server_name searx.{{ domain }};
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:{{ ports['searxng'] }};
|
|
||||||
|
|
||||||
include /etc/nginx/conf.d/ssl-headers.conf;
|
|
||||||
add_header Content-Security-Policy "upgrade-insecure-requests; default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; form-action 'self' https://github.com/searxng/searxng/issues/new; font-src 'self'; frame-ancestors 'self'; base-uri 'self'; connect-src 'self' https://overpass-api.de; img-src 'self' data: https://*.tile.openstreetmap.org; frame-src https://www.youtube-nocookie.com https://player.vimeo.com https://www.dailymotion.com https://www.deezer.com https://www.mixcloud.com https://w.soundcloud.com https://embed.spotify.com";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Synapse
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
|
|
||||||
server_name matrix.{{ domain }};
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:{{ ports['synapse'] }};
|
|
||||||
|
|
||||||
# Nginx by default only allows file uploads up to 1M in size
|
|
||||||
# Increase client_max_body_size to match max_upload_size defined in homeserver.yaml
|
|
||||||
client_max_body_size {{ synapse['max_upload_size'] }};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Syncthing Discovery
|
|
||||||
upstream stdisco.{{ domain }} {
|
|
||||||
# Local IP address:port for discovery server
|
|
||||||
server 127.0.0.1:{{ ports['syncthing_discosrv'] }};
|
|
||||||
}
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
|
|
||||||
server_name stdisco.{{ domain }};
|
|
||||||
|
|
||||||
ssl_verify_client optional_no_ca;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://stdisco.{{ domain }};
|
|
||||||
|
|
||||||
proxy_set_header X-Client-Port $remote_port;
|
|
||||||
proxy_set_header X-SSL-Cert $ssl_client_cert;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $http_connection;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Uptime Kuma
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
|
|
||||||
server_name status.{{ domain }};
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:{{ ports['uptime_kuma'] }};
|
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Vaultwarden
|
|
||||||
upstream vaultwarden-default {
|
|
||||||
zone vaultwarden-default 64k;
|
|
||||||
server 127.0.0.1:{{ ports['vaultwarden'] }};
|
|
||||||
keepalive 2;
|
|
||||||
}
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
|
|
||||||
server_name vw.{{ domain }};
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://vaultwarden-default;
|
|
||||||
|
|
||||||
# Websocket
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +1,15 @@
|
||||||
- name: Backup PostgreSQL database
|
- name: "Backup PostgreSQL synapse database & {{ volumes['synapse_datadir'] }} directory"
|
||||||
community.docker.docker_container_exec:
|
shell: >
|
||||||
container: synapse-postgres
|
docker exec postgres
|
||||||
docker_host: "{{ docker_host }}"
|
pg_dump -c {{ role_name }} |
|
||||||
command: |
|
borg create
|
||||||
pg_dump -c
|
--compression lzma
|
||||||
-d synapse
|
"{{ borg_repodir }}::{{ role_name }}-{now:%Y-%m-%d_%H-%M-%S}"
|
||||||
-U synapse
|
"{{ volumes['synapse_datadir'] }}"
|
||||||
-f /var/lib/postgresql/data/synapse-dump.sql
|
-
|
||||||
|
--stdin-name dump_{{ role_name }}.sql
|
||||||
- name: Create borg backup
|
|
||||||
command:
|
|
||||||
cmd: |
|
|
||||||
borg create
|
|
||||||
--compression=lzma
|
|
||||||
"{{ borg_repodir }}::{{ role_name }}-{now:%Y-%m-%d_%H-%M-%S}"
|
|
||||||
{{ volumes['synapse_datadir'] }}/media_store
|
|
||||||
{{ volumes['synapse_postgres_datadir'] }}/synapse-dump.sql
|
|
||||||
environment:
|
environment:
|
||||||
|
DOCKER_HOST: "{{ docker_host }}"
|
||||||
BORG_PASSCOMMAND: "cat {{ borg_passphrase_file }}"
|
BORG_PASSCOMMAND: "cat {{ borg_passphrase_file }}"
|
||||||
become: true
|
become: true
|
||||||
|
|
||||||
|
|
|
@ -36,15 +36,6 @@
|
||||||
mode: '770'
|
mode: '770'
|
||||||
become: true
|
become: true
|
||||||
|
|
||||||
- name: "Create directory {{ volumes['synapse_postgres_datadir'] }} with correct permissions"
|
|
||||||
file:
|
|
||||||
path: "{{ volumes['synapse_postgres_datadir'] }}"
|
|
||||||
state: directory
|
|
||||||
owner: "{{ users['synapse_postgres'] + uid_shift }}"
|
|
||||||
group: "{{ users['synapse_postgres'] + uid_shift }}"
|
|
||||||
mode: '700'
|
|
||||||
become: true
|
|
||||||
|
|
||||||
- name: Pull project services
|
- name: Pull project services
|
||||||
community.docker.docker_compose:
|
community.docker.docker_compose:
|
||||||
project_src: "{{ project_dir }}"
|
project_src: "{{ project_dir }}"
|
||||||
|
|
|
@ -1,17 +1,4 @@
|
||||||
services:
|
services:
|
||||||
postgres:
|
|
||||||
container_name: synapse-postgres
|
|
||||||
image: docker.io/library/postgres:alpine
|
|
||||||
restart: always
|
|
||||||
user: {{ users['synapse_postgres'] }}:{{ users['synapse_postgres'] }}
|
|
||||||
environment:
|
|
||||||
LANG: C
|
|
||||||
POSTGRES_INITDB_ARGS: "--locale=C --encoding=UTF8"
|
|
||||||
POSTGRES_USER: synapse
|
|
||||||
POSTGRES_PASSWORD: {{ synapse_secrets['postgres_password'] }}
|
|
||||||
volumes:
|
|
||||||
- {{ volumes['synapse_postgres_datadir'] }}:/var/lib/postgresql/data
|
|
||||||
|
|
||||||
synapse:
|
synapse:
|
||||||
container_name: synapse
|
container_name: synapse
|
||||||
image: docker.io/matrixdotorg/synapse:latest
|
image: docker.io/matrixdotorg/synapse:latest
|
||||||
|
|
|
@ -33,10 +33,10 @@ max_avatar_size: 2M
|
||||||
database:
|
database:
|
||||||
name: psycopg2
|
name: psycopg2
|
||||||
args:
|
args:
|
||||||
user: synapse
|
user: '{{ synapse_secrets["postgres_user"] }}'
|
||||||
password: {{ synapse_secrets['postgres_password'] }}
|
password: '{{ synapse_secrets["postgres_password"] }}'
|
||||||
dbname: synapse
|
dbname: synapse
|
||||||
host: synapse-postgres
|
host: 'postgres.{{ domain }}'
|
||||||
cp_min: 5
|
cp_min: 5
|
||||||
cp_max: 10
|
cp_max: 10
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
# To generate random secret: openssl rand -base64 <length>
|
||||||
|
|
||||||
ansible_become_password:
|
ansible_become_password:
|
||||||
|
|
||||||
borg_passphrase:
|
borg_passphrase:
|
||||||
|
@ -6,19 +8,38 @@ cifs_credentials:
|
||||||
username:
|
username:
|
||||||
password:
|
password:
|
||||||
|
|
||||||
# To generate random secret: openssl rand -base64 50
|
|
||||||
|
authelia_secrets:
|
||||||
|
# Encryption key for the database, must be saved
|
||||||
|
encryption_key:
|
||||||
|
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:
|
||||||
mysql_root_password:
|
mysql_root_password:
|
||||||
|
|
||||||
|
lldap_secrets:
|
||||||
|
jwt_secret:
|
||||||
|
key_seed:
|
||||||
|
postgres_user:
|
||||||
|
postgres_password:
|
||||||
|
|
||||||
searxng_secrets:
|
searxng_secrets:
|
||||||
searxng_secret:
|
searxng_secret:
|
||||||
|
|
||||||
synapse_secrets:
|
synapse_secrets:
|
||||||
smtp_user:
|
smtp_user:
|
||||||
smtp_pass:
|
smtp_pass:
|
||||||
|
postgres_user:
|
||||||
postgres_password:
|
postgres_password:
|
||||||
turn_shared_secret: "{{ coturn_secrets['static_auth_secret'] }}"
|
turn_shared_secret: "{{ coturn_secrets['static_auth_secret'] }}"
|
||||||
macaroon_secret_key:
|
macaroon_secret_key:
|
||||||
|
|
Loading…
Reference in a new issue