From e1014938892bc452d4ca9d7fb0bfd7dd6b00c6c8 Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Tue, 25 Jun 2024 09:45:53 +0200 Subject: [PATCH] Add synapse role For all the hipster kids. --- roles/synapse/handlers/main.yml | 11 ++++ roles/synapse/tasks/main.yml | 64 ++++++++++++++++++++++ roles/synapse/templates/homeserver.yaml.j2 | 60 ++++++++++++++++++++ roles/synapse/templates/log.config.j2 | 37 +++++++++++++ roles/synapse/templates/nginx.conf.j2 | 20 +++++++ setup.yml | 9 +++ 6 files changed, 201 insertions(+) create mode 100644 roles/synapse/handlers/main.yml create mode 100644 roles/synapse/tasks/main.yml create mode 100644 roles/synapse/templates/homeserver.yaml.j2 create mode 100644 roles/synapse/templates/log.config.j2 create mode 100644 roles/synapse/templates/nginx.conf.j2 diff --git a/roles/synapse/handlers/main.yml b/roles/synapse/handlers/main.yml new file mode 100644 index 0000000..e37d3f7 --- /dev/null +++ b/roles/synapse/handlers/main.yml @@ -0,0 +1,11 @@ +- name: restart synapse + service: + name: synapse + state: restarted + when: "'handler' not in ansible_skip_tags" + +- name: reload nginx + service: + name: nginx + state: reloaded + when: "'handler' not in ansible_skip_tags" diff --git a/roles/synapse/tasks/main.yml b/roles/synapse/tasks/main.yml new file mode 100644 index 0000000..bda2a97 --- /dev/null +++ b/roles/synapse/tasks/main.yml @@ -0,0 +1,64 @@ +- set_fact: + password: '{{ lookup("passwordstore", "vm/"~inventory_hostname, returnall=true) | from_yaml }}' + +- name: Install packages + package: + name: synapse + +- name: Get existing config + slurp: + path: '/etc/synapse/{{ password.server_name }}.yaml' + register: config + failed_when: false + +- name: Parse config + set_fact: + config: '{{ config.content | b64decode | from_yaml }}' + when: '"content" in config' + +- name: Configure homeserver + template: + dest: '/etc/synapse/{{ password.server_name }}.yaml' + src: homeserver.yaml.j2 + notify: restart synapse + +- name: Configure logging + template: + dest: '/etc/synapse/{{ password.server_name }}.log.config' + src: log.config.j2 + notify: restart synapse + +- name: Generate keys + become: yes + become_user: synapse + command: + cmd: | + python3 -m synapse.app.homeserver --generate-keys --config-path /etc/synapse/{{ password.server_name }}.yaml + creates: '/etc/synapse/{{ password.server_name }}.signing.key' + notify: restart synapse + +- name: Secure keys + file: + path: '/etc/synapse/{{ password.server_name }}.signing.key' + mode: 0600 + +- name: Set config path + lineinfile: + path: /etc/conf.d/synapse + regexp: '^config=' + line: 'config="/etc/synapse/{{ password.server_name }}.yaml"' + notify: restart synapse + +- name: Create socket directory + file: + path: /var/lib/synapse/socket + state: directory + mode: 0750 + owner: synapse + group: nginx + +- name: Set up nginx site + template: + dest: '/etc/nginx/http.d/synapse.conf' + src: 'nginx.conf.j2' + notify: reload nginx diff --git a/roles/synapse/templates/homeserver.yaml.j2 b/roles/synapse/templates/homeserver.yaml.j2 new file mode 100644 index 0000000..bacf1b2 --- /dev/null +++ b/roles/synapse/templates/homeserver.yaml.j2 @@ -0,0 +1,60 @@ +server_name: "{{ password.server_name }}" +public_baseurl: "https://{{ dns_name }}" +report_stats: false + +log_config: "/etc/synapse/{{ password.server_name }}.log.config" +signing_key_path: "/etc/synapse/{{ password.server_name }}.signing.key" +media_store_path: /var/lib/synapse/media_store +pid_file: /var/lib/synapse/homeserver.pid + +listeners: + - path: /var/lib/synapse/socket/main.sock + type: http + x_forwarded: true + resources: + - names: [client, federation] + compress: false + +database: + name: psycopg2 + args: + #user: + #password: + #dbname: + host: localhost + cp_min: 5 + cp_max: 10 + +presence: + enabled: false + +#trusted_key_servers: +# - server_name: "matrix.org" + +oidc_providers: + - idp_id: microsoft + idp_name: {{ password.oidc_name }} + issuer: "{{ password.oidc_url }}/v2.0" + client_id: "{{ password.oidc_client_id }}" + client_secret: "{{ password.oidc_client_secret }}" + scopes: ["openid", "profile"] + authorization_endpoint: "{{ password.oidc_url }}/oauth2/v2.0/authorize" + token_endpoint: "{{ password.oidc_url }}/oauth2/v2.0/token" + userinfo_endpoint: "{{ password.oidc_userinfo_endpoint }}" + + user_mapping_provider: + config: +{% raw %} + localpart_template: "{{ user.preferred_username.split('@')[0] }}" + display_name_template: "{{ user.name }}" +{% endraw %} + +{% for secret in ["form_secret", "macaroon_secret_key", "registration_shared_secret"] %} +{{ secret }}: " +{%- if secret in config -%} +{{ config[secret] }} +{%- else -%} +{{ lookup("password", "/dev/null", length=64, chars=["ascii_letters", "digits"]) }} +{%- endif -%} +" +{% endfor %} diff --git a/roles/synapse/templates/log.config.j2 b/roles/synapse/templates/log.config.j2 new file mode 100644 index 0000000..5ffe71c --- /dev/null +++ b/roles/synapse/templates/log.config.j2 @@ -0,0 +1,37 @@ +# [2]: https://matrix-org.github.io/synapse/latest/structured_logging.html + +version: 1 +formatters: + precise: + format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s' + +handlers: + file: + class: logging.handlers.TimedRotatingFileHandler + formatter: precise + filename: /var/lib/synapse/{{ password.server_name }}.log + when: midnight + backupCount: 3 # Does not include the current log file. + encoding: utf8 + + buffer: + class: synapse.logging.handlers.PeriodicallyFlushingMemoryHandler + target: file + + capacity: 10 + flushLevel: 30 # Flush immediately for WARNING logs and higher + period: 5 + + console: + class: logging.StreamHandler + formatter: precise + +loggers: + synapse.storage.SQL: + level: INFO + +root: + level: INFO + handlers: [buffer] + +disable_existing_loggers: false diff --git a/roles/synapse/templates/nginx.conf.j2 b/roles/synapse/templates/nginx.conf.j2 new file mode 100644 index 0000000..841f223 --- /dev/null +++ b/roles/synapse/templates/nginx.conf.j2 @@ -0,0 +1,20 @@ +server { + server_name {{ dns_name }}; + + listen [::]:443 ssl ipv6only=off; + ssl_certificate /etc/letsencrypt/live/{{ dns_name }}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/{{ dns_name }}/privkey.pem; + + location ~ ^(/_matrix|/_synapse/client) { + proxy_pass http://unix:/var/lib/synapse/socket/main.sock; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $host; + + # match max_upload_size defined in homeserver.yaml + client_max_body_size 50M; + + # Synapse responses may be chunked, which is an HTTP/1.1 feature. + proxy_http_version 1.1; + } +} diff --git a/setup.yml b/setup.yml index c250bf7..94bdd8d 100644 --- a/setup.yml +++ b/setup.yml @@ -41,3 +41,12 @@ - alpine - nginx - forgejo + +- hosts: matrix + roles: + - alpine + - postgres + - nginx + - synapse + vars: + user: synapse