diff --git a/CHANGELOG.md b/CHANGELOG.md index d96635b6..29bded25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,31 @@ +# 2019-01-29 + +## Running container processes as non-root, without capabilities and read-only + +To improve security, this playbook no longer starts container processes as the `root` user. +Most containers were dropping privileges anyway, but we were trusting them with `root` privileges until they would do that. +Not anymore -- container processes now start as a non-root user (usually `matrix`) from the get-go. + +For additional security, various capabilities are also dropped (see [why it's important](https://github.com/projectatomic/atomic-site/issues/203)) for all containers. + +Additionally, most containers now use a read-only filesystem (see [why it's important](https://www.projectatomic.io/blog/2015/12/making-docker-images-write-only-in-production/)). +Containers are given write access only to the directories they need to write to. + +A minor breaking change is the `matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size` variable having being renamed to `matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb` (note the `_mb` suffix). The new variable expects a number value (e.g. `25M` -> `25`). +If you weren't customizing this variable, this wouldn't affect you. + + +## matrix-mailer is now based on Exim, not Postfix + +While we would have preferred to stay with [Postfix](http://www.postfix.org/), we found out that it cannot run as a non-root user. +We've had to replace it with [Exim](https://www.exim.org/) (via the [devture/exim-relay](https://hub.docker.com/r/devture/exim-relay) container image). + +The internal `matrix-mailer` service (running in a container) now listens on port `8025` (used to be `587` before). +The playbook will update your Synapse and mxisd email settings to match (`matrix-mailer:587` -> `matrix-mailer:8025`). + +Using the [devture/exim-relay](https://hub.docker.com/r/devture/exim-relay) container image instead of [panubo/postfix](https://hub.docker.com/r/panubo/postfix/) also gives us a nice disk usage reduction (~200MB -> 8MB). + + # 2019-01-17 ## (BC Break) Making the playbook's roles more independent of one another diff --git a/README.md b/README.md index 2b18df77..b43ba590 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Using this playbook, you can get the following services configured on your serve - (optional, default) an [mxisd](https://github.com/kamax-io/mxisd) Matrix Identity server -- (optional, default) a [Postfix](http://www.postfix.org/) mail server, through which all Matrix services send outgoing email (can be configured to relay through another SMTP server) +- (optional, default) an [Exim](https://www.exim.org/) mail server, through which all Matrix services send outgoing email (can be configured to relay through another SMTP server) - (optional, default) an [nginx](http://nginx.org/) web server, listening on ports 80 and 443 - standing in front of all the other services. Using your own webserver [is possible](docs/configuring-playbook-own-webserver.md) @@ -98,7 +98,7 @@ This playbook sets up your server using the following Docker images: - [ewoutp/goofys](https://hub.docker.com/r/ewoutp/goofys/) - the [Goofys](https://github.com/kahing/goofys) Amazon [S3](https://aws.amazon.com/s3/) file-system-mounting program (optional) -- [panubo/postfix](https://hub.docker.com/r/panubo/postfix/) - the [Postfix](http://www.postfix.org/) email server (optional) +- [devture/exim-relay](https://hub.docker.com/r/devture/exim-relay/) - the [Exim](https://www.exim.org/) email server (optional) - [devture/matrix-corporal](https://hub.docker.com/r/devture/matrix-corporal/) - [Matrix Corporal](https://github.com/devture/matrix-corporal): reconciliator and gateway for a managed Matrix server (optional) diff --git a/docs/configuring-playbook-email.md b/docs/configuring-playbook-email.md index 7fb35eed..59e080f3 100644 --- a/docs/configuring-playbook-email.md +++ b/docs/configuring-playbook-email.md @@ -1,6 +1,6 @@ # Adjusting email-sending settings (optional) -By default, this playbook sets up a [postfix](http://www.postfix.org/) email server through which all Matrix services send emails. +By default, this playbook sets up an [Exim](https://www.exim.org/) email server through which all Matrix services send emails. The email server would attempt to deliver emails directly to their final destination. This may or may not work, depending on your domain configuration (SPF settings, etc.) @@ -28,9 +28,7 @@ matrix_mailer_relay_auth_username: "another.sender@example.com" matrix_mailer_relay_auth_password: "some-password" ``` -Keep in mind that postfix will look up the MX record of your relay host (`matrix_mailer_relay_host_name`) and, if available, will actually use that instead of what you've defined. This behavior is [documented here](http://www.postfix.org/postconf.5.html#relayhost). If you'd like to suppress this and use the relay host value as is, wrap it in square brackets (e.g. `matrix_mailer_relay_host_name: "[mail.example.com]"`). - ## Troubleshooting -If you're having trouble with email not being delivered, it may be useful to inspect the mailer logs: `journalctl -f -u matrix-mailer`. \ No newline at end of file +If you're having trouble with email not being delivered, it may be useful to inspect the mailer logs: `journalctl -f -u matrix-mailer`. diff --git a/group_vars/matrix-servers b/group_vars/matrix-servers index 3167c612..7d4becce 100644 --- a/group_vars/matrix-servers +++ b/group_vars/matrix-servers @@ -125,7 +125,7 @@ matrix_mxisd_dns_overwrite_homeserver_client_value: "http://{{ 'matrix-corporal: # By default, we send mail through the `matrix-mailer` service. matrix_mxisd_threepid_medium_email_identity_from: "{{ matrix_mailer_sender_address }}" matrix_mxisd_threepid_medium_email_connectors_smtp_host: "matrix-mailer" -matrix_mxisd_threepid_medium_email_connectors_smtp_port: 587 +matrix_mxisd_threepid_medium_email_connectors_smtp_port: 8025 matrix_mxisd_threepid_medium_email_connectors_smtp_tls: 0 matrix_mxisd_systemd_wanted_services_list: | @@ -158,7 +158,7 @@ matrix_nginx_proxy_enabled: true matrix_nginx_proxy_proxy_matrix_client_api_addr_with_container: "{{ 'matrix-corporal:41080' if matrix_corporal_enabled else 'matrix-synapse:8008' }}" matrix_nginx_proxy_proxy_matrix_client_api_addr_sans_container: "{{ 'localhost:41080' if matrix_corporal_enabled else 'localhost:8008' }}" -matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size: "{{ matrix_synapse_max_upload_size_mb }}M" +matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb: "{{ matrix_synapse_max_upload_size_mb }}" matrix_nginx_proxy_proxy_matrix_enabled: true matrix_nginx_proxy_proxy_riot_enabled: "{{ matrix_riot_web_enabled }}" @@ -269,7 +269,7 @@ matrix_synapse_database_database: "{{ matrix_postgres_db_name }}" matrix_synapse_email_enabled: "{{ matrix_mailer_enabled }}" matrix_synapse_email_smtp_host: "matrix-mailer" -matrix_synapse_email_smtp_port: 587 +matrix_synapse_email_smtp_port: 8025 matrix_synapse_email_smtp_require_transport_security: false matrix_synapse_email_notif_from: "Matrix <{{ matrix_mailer_sender_address }}>" matrix_synapse_email_riot_base_url: "https://{{ hostname_riot }}" diff --git a/roles/matrix-corporal/templates/systemd/matrix-corporal.service.j2 b/roles/matrix-corporal/templates/systemd/matrix-corporal.service.j2 index eb11890d..4035aa65 100644 --- a/roles/matrix-corporal/templates/systemd/matrix-corporal.service.j2 +++ b/roles/matrix-corporal/templates/systemd/matrix-corporal.service.j2 @@ -12,6 +12,8 @@ ExecStartPre=-/usr/bin/docker rm matrix-corporal ExecStart=/usr/bin/docker run --rm --name matrix-corporal \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --read-only \ --network={{ matrix_docker_network }} \ {% if matrix_corporal_container_expose_ports %} -p 127.0.0.1:41080:41080 \ diff --git a/roles/matrix-coturn/templates/systemd/matrix-coturn.service.j2 b/roles/matrix-coturn/templates/systemd/matrix-coturn.service.j2 index 69bd5eb8..980ca984 100644 --- a/roles/matrix-coturn/templates/systemd/matrix-coturn.service.j2 +++ b/roles/matrix-coturn/templates/systemd/matrix-coturn.service.j2 @@ -12,6 +12,9 @@ ExecStartPre=-/usr/bin/docker rm matrix-coturn ExecStart=/usr/bin/docker run --rm --name matrix-coturn \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --read-only \ + --tmpfs=/var/tmp:rw,noexec,nosuid,size=100m \ -p 3478:3478 \ -p 3478:3478/udp \ -p {{ matrix_coturn_turn_udp_min_port }}-{{ matrix_coturn_turn_udp_max_port }}:{{ matrix_coturn_turn_udp_min_port }}-{{ matrix_coturn_turn_udp_max_port }}/udp \ diff --git a/roles/matrix-mailer/defaults/main.yml b/roles/matrix-mailer/defaults/main.yml index a820f087..3b652799 100644 --- a/roles/matrix-mailer/defaults/main.yml +++ b/roles/matrix-mailer/defaults/main.yml @@ -2,7 +2,12 @@ matrix_mailer_enabled: true matrix_mailer_base_path: "{{ matrix_base_data_path }}/mailer" -matrix_mailer_docker_image: "panubo/postfix:latest" +matrix_mailer_docker_image: "devture/exim-relay:4.91-r1-0" + +# The user/group that the container runs with. +# These match the `exim` user/group within the container image. +matrix_mailer_container_user_uid: 100 +matrix_mailer_container_user_gid: 101 matrix_mailer_sender_address: "matrix@{{ hostname_identity }}" matrix_mailer_relay_use: false @@ -10,4 +15,4 @@ matrix_mailer_relay_host_name: "mail.example.com" matrix_mailer_relay_host_port: 587 matrix_mailer_relay_auth: false matrix_mailer_relay_auth_username: "" -matrix_mailer_relay_auth_password: "" \ No newline at end of file +matrix_mailer_relay_auth_password: "" diff --git a/roles/matrix-mailer/templates/env-mailer.j2 b/roles/matrix-mailer/templates/env-mailer.j2 index 9cacf789..7765b8f9 100644 --- a/roles/matrix-mailer/templates/env-mailer.j2 +++ b/roles/matrix-mailer/templates/env-mailer.j2 @@ -1,8 +1,7 @@ -MAILNAME={{ hostname_matrix }} {% if matrix_mailer_relay_use %} -RELAYHOST={{ matrix_mailer_relay_host_name }}:{{ matrix_mailer_relay_host_port }} +SMARTHOST={{ matrix_mailer_relay_host_name }}::{{ matrix_mailer_relay_host_port }} {% endif %} {% if matrix_mailer_relay_auth %} -RELAYHOST_AUTH=yes -RELAYHOST_PASSWORDMAP={{ matrix_mailer_relay_host_name }}:{{ matrix_mailer_relay_auth_username }}:{{ matrix_mailer_relay_auth_password }} -{% endif %} \ No newline at end of file +SMTP_USERNAME={{ matrix_mailer_relay_auth_username }} +SMTP_PASSWORD={{ matrix_mailer_relay_auth_password }} +{% endif %} diff --git a/roles/matrix-mailer/templates/systemd/matrix-mailer.service.j2 b/roles/matrix-mailer/templates/systemd/matrix-mailer.service.j2 index f0adaa7c..54beb215 100644 --- a/roles/matrix-mailer/templates/systemd/matrix-mailer.service.j2 +++ b/roles/matrix-mailer/templates/systemd/matrix-mailer.service.j2 @@ -9,8 +9,13 @@ ExecStartPre=-/usr/bin/docker kill matrix-mailer ExecStartPre=-/usr/bin/docker rm matrix-mailer ExecStart=/usr/bin/docker run --rm --name matrix-mailer \ --log-driver=none \ + --user={{ matrix_mailer_container_user_uid }}:{{ matrix_mailer_container_user_gid }} \ + --cap-drop=ALL \ + --read-only \ + --tmpfs=/var/spool/exim:rw,noexec,nosuid,size=100m \ --network={{ matrix_docker_network }} \ --env-file={{ matrix_mailer_base_path }}/env-mailer \ + --hostname={{ hostname_matrix }} \ {{ matrix_mailer_docker_image }} ExecStop=-/usr/bin/docker kill matrix-mailer ExecStop=-/usr/bin/docker rm matrix-mailer diff --git a/roles/matrix-mxisd/templates/systemd/matrix-mxisd.service.j2 b/roles/matrix-mxisd/templates/systemd/matrix-mxisd.service.j2 index 978a85c1..de0c0681 100644 --- a/roles/matrix-mxisd/templates/systemd/matrix-mxisd.service.j2 +++ b/roles/matrix-mxisd/templates/systemd/matrix-mxisd.service.j2 @@ -12,16 +12,23 @@ Wants={{ service }} Type=simple ExecStartPre=-/usr/bin/docker kill matrix-mxisd ExecStartPre=-/usr/bin/docker rm matrix-mxisd + +# mxisd writes an SQLite shared library (libsqlitejdbc.so) to /tmp and executes it from there, +# so /tmp needs to be mounted with an exec option. ExecStart=/usr/bin/docker run --rm --name matrix-mxisd \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --read-only \ + --tmpfs=/tmp:rw,exec,nosuid,size=10m \ --network={{ matrix_docker_network }} \ {% if matrix_mxisd_container_expose_port %} -p 127.0.0.1:8090:8090 \ {% endif %} -v {{ matrix_mxisd_config_path }}:/etc/mxisd:ro \ - -v {{ matrix_mxisd_data_path }}:/var/mxisd \ + -v {{ matrix_mxisd_data_path }}:/var/mxisd:rw \ {{ matrix_mxisd_docker_image }} + ExecStop=-/usr/bin/docker kill matrix-mxisd ExecStop=-/usr/bin/docker rm matrix-mxisd Restart=always diff --git a/roles/matrix-nginx-proxy/defaults/main.yml b/roles/matrix-nginx-proxy/defaults/main.yml index ccc51ac8..94a86adc 100644 --- a/roles/matrix-nginx-proxy/defaults/main.yml +++ b/roles/matrix-nginx-proxy/defaults/main.yml @@ -1,5 +1,8 @@ matrix_nginx_proxy_enabled: true +# We use an official nginx image, which we fix-up to run unprivileged. +# An alternative would be an `nginxinc/nginx-unprivileged` image, but +# those as more frequently out of date. matrix_nginx_proxy_docker_image: "nginx:1.15.8-alpine" matrix_nginx_proxy_data_path: "{{ matrix_base_data_path }}/nginx-proxy" @@ -41,7 +44,10 @@ matrix_nginx_proxy_proxy_matrix_identity_api_addr_sans_container: "localhost:809 matrix_nginx_proxy_proxy_matrix_client_api_addr_with_container: "matrix-synapse:8008" matrix_nginx_proxy_proxy_matrix_client_api_addr_sans_container: "localhost:8008" # This needs to be equal or higher than the maximum upload size accepted by Synapse. -matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size: "25M" +matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb: 25 + +# The tmpfs at /tmp needs to be large enough to handle multiple concurrent file uploads. +matrix_nginx_proxy_tmp_directory_size_mb: "{{ matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb * 50 }}" # A list of strings containing additional configuration blocks to add to the matrix domain's server configuration. matrix_nginx_proxy_proxy_matrix_additional_server_configuration_blocks: [] @@ -82,4 +88,4 @@ matrix_ssl_lets_encrypt_support_email: "{{ host_specific_matrix_ssl_lets_encrypt matrix_ssl_base_path: "{{ matrix_base_data_path }}/ssl" matrix_ssl_config_dir_path: "{{ matrix_ssl_base_path }}/config" -matrix_ssl_log_dir_path: "{{ matrix_ssl_base_path }}/log" \ No newline at end of file +matrix_ssl_log_dir_path: "{{ matrix_ssl_base_path }}/log" diff --git a/roles/matrix-nginx-proxy/tasks/setup_nginx_proxy.yml b/roles/matrix-nginx-proxy/tasks/setup_nginx_proxy.yml index 59c3fe15..434cfad8 100644 --- a/roles/matrix-nginx-proxy/tasks/setup_nginx_proxy.yml +++ b/roles/matrix-nginx-proxy/tasks/setup_nginx_proxy.yml @@ -21,23 +21,30 @@ - "{{ matrix_nginx_proxy_data_path }}" - "{{ matrix_nginx_proxy_confd_path }}" +- name: Ensure Matrix nginx-proxy configured (main config override) + template: + src: "{{ role_path }}/templates/nginx/nginx.conf.j2" + dest: "{{ matrix_nginx_proxy_data_path }}/nginx.conf" + mode: 0644 + when: "matrix_nginx_proxy_enabled" + - name: Ensure Matrix nginx-proxy configured (generic) template: - src: "{{ role_path }}/templates/nginx-conf.d/nginx-http.conf.j2" + src: "{{ role_path }}/templates/nginx/conf.d/nginx-http.conf.j2" dest: "{{ matrix_nginx_proxy_confd_path }}/nginx-http.conf" mode: 0644 when: "matrix_nginx_proxy_enabled" - name: Ensure Matrix nginx-proxy configuration for matrix domain exists template: - src: "{{ role_path }}/templates/nginx-conf.d/matrix-synapse.conf.j2" + src: "{{ role_path }}/templates/nginx/conf.d/matrix-synapse.conf.j2" dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-synapse.conf" mode: 0644 when: "matrix_nginx_proxy_proxy_matrix_enabled" - name: Ensure Matrix nginx-proxy configuration for riot domain exists template: - src: "{{ role_path }}/templates/nginx-conf.d/matrix-riot-web.conf.j2" + src: "{{ role_path }}/templates/nginx/conf.d/matrix-riot-web.conf.j2" dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-riot-web.conf" mode: 0644 when: "matrix_nginx_proxy_proxy_riot_enabled" @@ -104,3 +111,8 @@ state: absent when: "not matrix_nginx_proxy_proxy_riot_enabled" +- name: Ensure Matrix nginx-proxy configuration for main config override deleted + file: + path: "{{ matrix_nginx_proxy_data_path }}/nginx.conf" + state: absent + when: "not matrix_nginx_proxy_enabled" diff --git a/roles/matrix-nginx-proxy/tasks/ssl/main.yml b/roles/matrix-nginx-proxy/tasks/ssl/main.yml index c78b4f35..2681164d 100644 --- a/roles/matrix-nginx-proxy/tasks/ssl/main.yml +++ b/roles/matrix-nginx-proxy/tasks/ssl/main.yml @@ -15,6 +15,7 @@ mode: 0770 owner: "{{ matrix_user_username }}" group: "{{ matrix_user_username }}" + recurse: true with_items: - "{{ matrix_ssl_log_dir_path }}" - "{{ matrix_ssl_config_dir_path }}" diff --git a/roles/matrix-nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt_obtain_for_domain.yml b/roles/matrix-nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt_obtain_for_domain.yml index cf97444f..8adc1e60 100644 --- a/roles/matrix-nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt_obtain_for_domain.yml +++ b/roles/matrix-nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt_obtain_for_domain.yml @@ -19,12 +19,16 @@ /usr/bin/docker run --rm --name=matrix-certbot - --net=host + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + -p 80:8080 -v {{ matrix_ssl_config_dir_path }}:/etc/letsencrypt -v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt {{ matrix_ssl_lets_encrypt_certbot_docker_image }} certonly --non-interactive + --work-dir=/tmp + --http-01-port 8080 {% if matrix_ssl_lets_encrypt_staging %}--staging{% endif %} --standalone --preferred-challenges http @@ -42,13 +46,17 @@ /usr/bin/docker run --rm --name=matrix-certbot - -p 127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}:80 + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + -p 127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}:8080 --network={{ matrix_docker_network }} -v {{ matrix_ssl_config_dir_path }}:/etc/letsencrypt -v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt {{ matrix_ssl_lets_encrypt_certbot_docker_image }} certonly --non-interactive + --work-dir=/tmp + --http-01-port 8080 {% if matrix_ssl_lets_encrypt_staging %}--staging{% endif %} --standalone --preferred-challenges http diff --git a/roles/matrix-nginx-proxy/templates/nginx-conf.d/matrix-riot-web.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-riot-web.conf.j2 similarity index 85% rename from roles/matrix-nginx-proxy/templates/nginx-conf.d/matrix-riot-web.conf.j2 rename to roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-riot-web.conf.j2 index 99172147..578a7e0c 100644 --- a/roles/matrix-nginx-proxy/templates/nginx-conf.d/matrix-riot-web.conf.j2 +++ b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-riot-web.conf.j2 @@ -1,5 +1,5 @@ server { - listen 80; + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; server_name {{ matrix_nginx_proxy_proxy_riot_hostname }}; server_tokens off; @@ -8,7 +8,7 @@ server { {% if matrix_nginx_proxy_enabled %} {# Use the embedded DNS resolver in Docker containers to discover the service #} resolver 127.0.0.11 valid=5s; - set $backend "matrix-certbot:80"; + set $backend "matrix-certbot:8080"; proxy_pass http://$backend; {% else %} {# Generic configuration for use outside of our container setup #} @@ -22,8 +22,8 @@ server { } server { - listen 443 ssl http2; - listen [::]:443 ssl http2; + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; server_name {{ matrix_nginx_proxy_proxy_riot_hostname }}; @@ -43,7 +43,7 @@ server { {% if matrix_nginx_proxy_enabled %} {# Use the embedded DNS resolver in Docker containers to discover the service #} resolver 127.0.0.11 valid=5s; - set $backend "matrix-riot-web:80"; + set $backend "matrix-riot-web:8080"; proxy_pass http://$backend; {% else %} {# Generic configuration for use outside of our container setup #} diff --git a/roles/matrix-nginx-proxy/templates/nginx-conf.d/matrix-synapse.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-synapse.conf.j2 similarity index 93% rename from roles/matrix-nginx-proxy/templates/nginx-conf.d/matrix-synapse.conf.j2 rename to roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-synapse.conf.j2 index 1a2d166b..016b9414 100644 --- a/roles/matrix-nginx-proxy/templates/nginx-conf.d/matrix-synapse.conf.j2 +++ b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-synapse.conf.j2 @@ -1,5 +1,5 @@ server { - listen 80; + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; server_name {{ matrix_nginx_proxy_proxy_matrix_hostname }}; server_tokens off; @@ -8,7 +8,7 @@ server { {% if matrix_nginx_proxy_enabled %} {# Use the embedded DNS resolver in Docker containers to discover the service #} resolver 127.0.0.11 valid=5s; - set $backend "matrix-certbot:80"; + set $backend "matrix-certbot:8080"; proxy_pass http://$backend; {% else %} {# Generic configuration for use outside of our container setup #} @@ -22,8 +22,8 @@ server { } server { - listen 443 ssl http2; - listen [::]:443 ssl http2; + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; server_name {{ matrix_nginx_proxy_proxy_matrix_hostname }}; @@ -116,7 +116,7 @@ server { proxy_set_header X-Forwarded-For $remote_addr; client_body_buffer_size 25M; - client_max_body_size {{ matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size }}; + client_max_body_size {{ matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb }}M; proxy_max_temp_file_size 0; } diff --git a/roles/matrix-nginx-proxy/templates/nginx-conf.d/nginx-http.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/conf.d/nginx-http.conf.j2 similarity index 100% rename from roles/matrix-nginx-proxy/templates/nginx-conf.d/nginx-http.conf.j2 rename to roles/matrix-nginx-proxy/templates/nginx/conf.d/nginx-http.conf.j2 diff --git a/roles/matrix-nginx-proxy/templates/nginx/nginx.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/nginx.conf.j2 new file mode 100644 index 00000000..3382d6c6 --- /dev/null +++ b/roles/matrix-nginx-proxy/templates/nginx/nginx.conf.j2 @@ -0,0 +1,45 @@ +# This is a custom nginx configuration file that we use in the container (instead of the default one), +# because it allows us to run nginx with a non-root user. +# +# For this to work, the default vhost file (`/etc/nginx/conf.d/default.conf`) also needs to be removed. +# +# The following changes have been done compared to a default nginx configuration file: +# - various temp paths are changed to `/tmp`, so that a non-root user can write to them +# - the `user` directive was removed, as we don't want nginx to switch users + +worker_processes 1; + +error_log /var/log/nginx/error.log warn; +pid /tmp/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + proxy_temp_path /tmp/proxy_temp; + client_body_temp_path /tmp/client_temp; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + include /etc/nginx/conf.d/*.conf; +} diff --git a/roles/matrix-nginx-proxy/templates/systemd/matrix-nginx-proxy.service.j2 b/roles/matrix-nginx-proxy/templates/systemd/matrix-nginx-proxy.service.j2 index 62700157..410d6a01 100644 --- a/roles/matrix-nginx-proxy/templates/systemd/matrix-nginx-proxy.service.j2 +++ b/roles/matrix-nginx-proxy/templates/systemd/matrix-nginx-proxy.service.j2 @@ -12,15 +12,22 @@ Wants={{ service }} Type=simple ExecStartPre=-/usr/bin/docker kill matrix-nginx-proxy ExecStartPre=-/usr/bin/docker rm matrix-nginx-proxy + ExecStart=/usr/bin/docker run --rm --name matrix-nginx-proxy \ --log-driver=none \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --read-only \ + --tmpfs=/tmp:rw,noexec,nosuid,size={{ matrix_nginx_proxy_tmp_directory_size_mb }}m \ --network={{ matrix_docker_network }} \ - -p 80:80 \ - -p 443:443 \ + -p 80:8080 \ + -p 443:8443 \ + -v {{ matrix_nginx_proxy_data_path }}/nginx.conf:/etc/nginx/nginx.conf:ro \ -v {{ matrix_nginx_proxy_confd_path }}:/etc/nginx/conf.d:ro \ -v {{ matrix_ssl_config_dir_path }}:{{ matrix_ssl_config_dir_path }}:ro \ -v {{ matrix_static_files_base_path }}:{{ matrix_static_files_base_path }}:ro \ {{ matrix_nginx_proxy_docker_image }} + ExecStop=-/usr/bin/docker kill matrix-nginx-proxy ExecStop=-/usr/bin/docker rm matrix-nginx-proxy ExecReload=/usr/bin/docker exec matrix-nginx-proxy /usr/sbin/nginx -s reload diff --git a/roles/matrix-nginx-proxy/templates/usr-local-bin/matrix-ssl-lets-encrypt-certificates-renew.j2 b/roles/matrix-nginx-proxy/templates/usr-local-bin/matrix-ssl-lets-encrypt-certificates-renew.j2 index 12504d1f..1b36acaf 100644 --- a/roles/matrix-nginx-proxy/templates/usr-local-bin/matrix-ssl-lets-encrypt-certificates-renew.j2 +++ b/roles/matrix-nginx-proxy/templates/usr-local-bin/matrix-ssl-lets-encrypt-certificates-renew.j2 @@ -3,19 +3,23 @@ # For renewal to work, matrix-nginx-proxy (or another webserver, if matrix-nginx-proxy is disabled) # need to forward requests for `/.well-known/acme-challenge` to the certbot container. # -# This can happen inside the container network by proxying to `http://matrix-certbot:80` +# This can happen inside the container network by proxying to `http://matrix-certbot:8080` # or outside (on the host) by proxying to `http://localhost:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}`. docker run \ --rm \ --name=matrix-certbot \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ --network="{{ matrix_docker_network }}" \ - -p 127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}:80 \ + -p 127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}:8080 \ -v {{ matrix_ssl_config_dir_path }}:/etc/letsencrypt \ -v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt \ {{ matrix_ssl_lets_encrypt_certbot_docker_image }} \ renew \ --non-interactive \ + --work-dir=/tmp \ + --http-01-port 8080 {% if matrix_ssl_lets_encrypt_staging %} --staging \ {% endif %} diff --git a/roles/matrix-postgres/tasks/import_postgres.yml b/roles/matrix-postgres/tasks/import_postgres.yml index 66b20a64..67d7f86c 100644 --- a/roles/matrix-postgres/tasks/import_postgres.yml +++ b/roles/matrix-postgres/tasks/import_postgres.yml @@ -60,18 +60,20 @@ set_fact: matrix_postgres_import_command: >- /usr/bin/docker run --rm --name matrix-postgres-import + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} + --cap-drop=ALL --network={{ matrix_docker_network }} --env-file={{ matrix_postgres_base_path }}/env-postgres-psql - -v {{ server_path_postgres_dump }}:{{ server_path_postgres_dump }}:ro + -v {{ server_path_postgres_dump }}:/{{ server_path_postgres_dump|basename }}:ro --entrypoint=/bin/sh {{ matrix_postgres_docker_image_latest }} - -c 'cat {{ server_path_postgres_dump }} | + -c 'cat /{{ server_path_postgres_dump|basename }} | {{ 'gunzip |' if server_path_postgres_dump.endswith('.gz') else '' }} psql -v ON_ERROR_STOP=1 -h matrix-postgres' - name: Note about Postgres importing alternative debug: - msg: > + msg: >- Importing Postgres database using the following command: `{{ matrix_postgres_import_command }}`. If this crashes, you can stop Postgres (`systemctl stop matrix-postgres`), delete its existing data (`rm -rf {{ matrix_postgres_data_path }}/*`), start it again (`systemctl start matrix-postgres`) diff --git a/roles/matrix-postgres/tasks/import_sqlite_db.yml b/roles/matrix-postgres/tasks/import_sqlite_db.yml index b3cf75be..c989dca9 100644 --- a/roles/matrix-postgres/tasks/import_sqlite_db.yml +++ b/roles/matrix-postgres/tasks/import_sqlite_db.yml @@ -79,11 +79,12 @@ detach: no cleanup: yes entrypoint: /usr/local/bin/python - command: "/usr/local/bin/synapse_port_db --sqlite-database {{ server_path_homeserver_db }} --postgres-config /data/homeserver.yaml" + command: "/usr/local/bin/synapse_port_db --sqlite-database /{{ server_path_homeserver_db|basename }} --postgres-config /data/homeserver.yaml" user: "{{ matrix_user_uid }}:{{ matrix_user_gid }}" + cap_drop: ['all'] volumes: - "{{ matrix_synapse_config_dir_path }}:/data" - "{{ matrix_synapse_run_path }}:/matrix-run" - - "{{ server_path_homeserver_db }}:/{{ server_path_homeserver_db }}:ro" + - "{{ server_path_homeserver_db }}:/{{ server_path_homeserver_db|basename }}:ro" networks: - name: "{{ matrix_docker_network }}" diff --git a/roles/matrix-postgres/tasks/upgrade_postgres.yml b/roles/matrix-postgres/tasks/upgrade_postgres.yml index 3e67dfc5..c32634b9 100644 --- a/roles/matrix-postgres/tasks/upgrade_postgres.yml +++ b/roles/matrix-postgres/tasks/upgrade_postgres.yml @@ -70,6 +70,7 @@ - name: Perform Postgres database dump command: | /usr/bin/docker run --rm --name matrix-postgres-dump \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --network={{ matrix_docker_network }} \ --env-file={{ matrix_postgres_base_path }}/env-postgres-psql \ -v {{ postgres_dump_dir }}:/out \ @@ -104,6 +105,8 @@ - name: Perform Postgres database import command: | /usr/bin/docker run --rm --name matrix-postgres-import \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ --network={{ matrix_docker_network }} \ --env-file={{ matrix_postgres_base_path }}/env-postgres-psql \ -v {{ postgres_dump_dir }}:/in:ro \ diff --git a/roles/matrix-postgres/templates/systemd/matrix-postgres.service.j2 b/roles/matrix-postgres/templates/systemd/matrix-postgres.service.j2 index 40509e8c..0d2b9fcf 100644 --- a/roles/matrix-postgres/templates/systemd/matrix-postgres.service.j2 +++ b/roles/matrix-postgres/templates/systemd/matrix-postgres.service.j2 @@ -10,9 +10,13 @@ ExecStartPre=-/usr/bin/docker rm matrix-postgres ExecStart=/usr/bin/docker run --rm --name matrix-postgres \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --read-only \ + --tmpfs=/tmp:rw,noexec,nosuid,size=100m \ + --tmpfs=/run/postgresql:rw,noexec,nosuid,size=100m \ --network={{ matrix_docker_network }} \ --env-file={{ matrix_postgres_base_path }}/env-postgres-server \ - -v {{ matrix_postgres_data_path }}:/var/lib/postgresql/data \ + -v {{ matrix_postgres_data_path }}:/var/lib/postgresql/data:rw \ -v /etc/passwd:/etc/passwd:ro \ {{ matrix_postgres_docker_image_to_use }} ExecStop=-/usr/bin/docker stop matrix-postgres diff --git a/roles/matrix-postgres/templates/usr-local-bin/matrix-make-user-admin.j2 b/roles/matrix-postgres/templates/usr-local-bin/matrix-make-user-admin.j2 index 7b8fba37..5f474453 100644 --- a/roles/matrix-postgres/templates/usr-local-bin/matrix-make-user-admin.j2 +++ b/roles/matrix-postgres/templates/usr-local-bin/matrix-make-user-admin.j2 @@ -8,6 +8,8 @@ fi docker run \ -it \ --rm \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ --env-file={{ matrix_postgres_base_path }}/env-postgres-psql \ --network {{ matrix_docker_network }} \ {{ matrix_postgres_docker_image_to_use }} \ diff --git a/roles/matrix-postgres/templates/usr-local-bin/matrix-postgres-cli.j2 b/roles/matrix-postgres/templates/usr-local-bin/matrix-postgres-cli.j2 index 07e1f43b..34836629 100644 --- a/roles/matrix-postgres/templates/usr-local-bin/matrix-postgres-cli.j2 +++ b/roles/matrix-postgres/templates/usr-local-bin/matrix-postgres-cli.j2 @@ -3,6 +3,8 @@ docker run \ -it \ --rm \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ --env-file={{ matrix_postgres_base_path }}/env-postgres-psql \ --network {{ matrix_docker_network }} \ {{ matrix_postgres_docker_image_to_use }} \ diff --git a/roles/matrix-riot-web/tasks/setup_riot_web.yml b/roles/matrix-riot-web/tasks/setup_riot_web.yml index 1eadf933..c9a84f91 100644 --- a/roles/matrix-riot-web/tasks/setup_riot_web.yml +++ b/roles/matrix-riot-web/tasks/setup_riot_web.yml @@ -27,6 +27,7 @@ group: "{{ matrix_user_username }}" with_items: - {src: "{{ role_path }}/templates/config.json.j2", name: "config.json"} + - {src: "{{ role_path }}/templates/nginx.conf.j2", name: "nginx.conf"} - {src: "{{ matrix_riot_web_homepage_template }}", name: "home.html"} when: matrix_riot_web_enabled diff --git a/roles/matrix-riot-web/templates/nginx.conf.j2 b/roles/matrix-riot-web/templates/nginx.conf.j2 new file mode 100644 index 00000000..a7707cd9 --- /dev/null +++ b/roles/matrix-riot-web/templates/nginx.conf.j2 @@ -0,0 +1,60 @@ +# This is a custom nginx configuration file that we use in the container (instead of the default one), +# because it allows us to run nginx with a non-root user. +# +# For this to work, the default vhost file (`/etc/nginx/conf.d/default.conf`) also needs to be removed. +# (mounting `/dev/null` over `/etc/nginx/conf.d/default.conf` works well) +# +# The following changes have been done compared to a default nginx configuration file: +# - default server port is changed (80 -> 8080), so that a non-root user can bind it +# - various temp paths are changed to `/tmp`, so that a non-root user can write to them +# - the `user` directive was removed, as we don't want nginx to switch users + +worker_processes 1; + +error_log /var/log/nginx/error.log warn; +pid /tmp/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + proxy_temp_path /tmp/proxy_temp; + client_body_temp_path /tmp/client_temp; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + server { + listen 8080; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + } +} diff --git a/roles/matrix-riot-web/templates/systemd/matrix-riot-web.service.j2 b/roles/matrix-riot-web/templates/systemd/matrix-riot-web.service.j2 index 6ef2ad17..5cd69774 100644 --- a/roles/matrix-riot-web/templates/systemd/matrix-riot-web.service.j2 +++ b/roles/matrix-riot-web/templates/systemd/matrix-riot-web.service.j2 @@ -11,11 +11,17 @@ ExecStartPre=-/usr/bin/docker kill matrix-riot-web ExecStartPre=-/usr/bin/docker rm matrix-riot-web ExecStart=/usr/bin/docker run --rm --name matrix-riot-web \ --log-driver=none \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --read-only \ + --tmpfs=/tmp:rw,noexec,nosuid,size=10m \ + -v {{ matrix_riot_web_data_path }}/nginx.conf:/etc/nginx/nginx.conf:ro \ + -v /dev/null:/etc/nginx/conf.d/default.conf:ro \ -v {{ matrix_riot_web_data_path }}/config.json:/etc/riot-web/config.json:ro \ -v {{ matrix_riot_web_data_path }}/home.html:/etc/riot-web/home.html:ro \ --network={{ matrix_docker_network }} \ {% if matrix_riot_web_container_expose_port %} - -p 127.0.0.1:8765:80 \ + -p 127.0.0.1:8765:8080 \ {% endif %} {{ matrix_riot_web_docker_image }} ExecStop=-/usr/bin/docker kill matrix-riot-web diff --git a/roles/matrix-synapse/defaults/main.yml b/roles/matrix-synapse/defaults/main.yml index a0c42b03..cc3eed17 100644 --- a/roles/matrix-synapse/defaults/main.yml +++ b/roles/matrix-synapse/defaults/main.yml @@ -39,6 +39,9 @@ matrix_synapse_max_upload_size_mb: 10 matrix_synapse_max_log_file_size_mb: 100 matrix_synapse_max_log_files_count: 10 +# The tmpfs at /tmp needs to be large enough to handle multiple concurrent file uploads. +matrix_synapse_tmp_directory_size_mb: "{{ matrix_synapse_max_upload_size_mb * 50 }}" + # Log levels # Possible options are defined here https://docs.python.org/3/library/logging.html#logging-levels # warning: setting log level to DEBUG will make synapse log sensitive information such @@ -187,4 +190,4 @@ matrix_mautrix_whatsapp_enabled: false matrix_mautrix_whatsapp_docker_image: "tulir/mautrix-whatsapp:latest" -matrix_mautrix_whatsapp_base_path: "{{ matrix_base_data_path }}/mautrix-whatsapp" \ No newline at end of file +matrix_mautrix_whatsapp_base_path: "{{ matrix_base_data_path }}/mautrix-whatsapp" diff --git a/roles/matrix-synapse/tasks/ext/mautrix-telegram/setup.yml b/roles/matrix-synapse/tasks/ext/mautrix-telegram/setup.yml index f85abb13..189c9356 100644 --- a/roles/matrix-synapse/tasks/ext/mautrix-telegram/setup.yml +++ b/roles/matrix-synapse/tasks/ext/mautrix-telegram/setup.yml @@ -14,8 +14,10 @@ group: "{{ matrix_user_username }}" when: "matrix_mautrix_telegram_enabled" -- stat: "path={{ matrix_mautrix_telegram_base_path }}/config.yaml" - register: mautrix_config_file +- name: Check if a mautrix-telegram configuration file exists + stat: + path: "{{ matrix_mautrix_telegram_base_path }}/config.yaml" + register: mautrix_telegram_config_file_stat - name: Ensure Matrix Mautrix telegram config installed template: @@ -24,7 +26,18 @@ mode: 0644 owner: "{{ matrix_user_username }}" group: "{{ matrix_user_username }}" - when: "matrix_mautrix_telegram_enabled and mautrix_config_file.stat.exists == False" + when: "matrix_mautrix_telegram_enabled and not mautrix_telegram_config_file_stat.stat.exists" + +- name: (Migration) Fix up old configuration + lineinfile: + path: "{{ matrix_mautrix_telegram_base_path }}/config.yaml" + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + backrefs: yes + with_items: + - {'regexp': '^(\s+)filename: \./mautrix-telegram.log', 'line': '\1filename: /data/mautrix-telegram.log'} + - {'regexp': '^(\s+)database:', 'line': '\1database: sqlite:////data/mautrix-telegram.db'} + when: "matrix_mautrix_telegram_enabled and mautrix_telegram_config_file_stat.stat.exists" - name: Ensure matrix-mautrix-telegram.service installed template: @@ -33,13 +46,23 @@ mode: 0644 when: "matrix_mautrix_telegram_enabled" -- stat: +- name: Check if a mautrix-telegram registration file exists + stat: path: "{{ matrix_mautrix_telegram_base_path }}/registration.yaml" - register: mautrix_telegram_registration_file + register: mautrix_telegram_registration_file_stat - name: Generate matrix-mautrix-telegram registration.yaml if it doesn't exist - shell: /usr/bin/docker run --rm --name matrix-mautrix-telegram-gen -v {{ matrix_mautrix_telegram_base_path }}:/data:z {{ matrix_mautrix_telegram_docker_image }} python3 -m mautrix_telegram -g -c /data/config.yaml -r /data/registration.yaml - when: "matrix_mautrix_telegram_enabled and mautrix_telegram_registration_file.stat.exists == False" + shell: + cmd: >- + /usr/bin/docker run + --rm + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} + --cap-drop=ALL + --name matrix-mautrix-telegram-gen + -v {{ matrix_mautrix_telegram_base_path }}:/data:z + {{ matrix_mautrix_telegram_docker_image }} + python3 -m mautrix_telegram -g -c /data/config.yaml -r /data/registration.yaml + when: "matrix_mautrix_telegram_enabled and not mautrix_telegram_registration_file_stat.stat.exists" - set_fact: matrix_synapse_app_service_config_file_mautrix_telegram: '/app-registration/mautrix-telegram.yml' diff --git a/roles/matrix-synapse/tasks/ext/mautrix-whatsapp/setup.yml b/roles/matrix-synapse/tasks/ext/mautrix-whatsapp/setup.yml index ee9b3358..3c22c62c 100644 --- a/roles/matrix-synapse/tasks/ext/mautrix-whatsapp/setup.yml +++ b/roles/matrix-synapse/tasks/ext/mautrix-whatsapp/setup.yml @@ -14,8 +14,10 @@ group: "{{ matrix_user_username }}" when: "matrix_mautrix_whatsapp_enabled" -- stat: "path={{ matrix_mautrix_whatsapp_base_path }}/config.yaml" - register: mautrix_config_file +- name: Check if a mautrix-whatsapp configuration file exists + stat: + path: "{{ matrix_mautrix_whatsapp_base_path }}/config.yaml" + register: mautrix_whatsapp_config_file_stat - name: Ensure Matrix Mautrix whatsapp config installed template: @@ -24,7 +26,7 @@ mode: 0644 owner: "{{ matrix_user_username }}" group: "{{ matrix_user_username }}" - when: "matrix_mautrix_whatsapp_enabled and mautrix_config_file.stat.exists == False" + when: "matrix_mautrix_whatsapp_enabled and not mautrix_whatsapp_config_file_stat.stat.exists" - name: Ensure matrix-mautrix-whatsapp.service installed template: @@ -33,13 +35,23 @@ mode: 0644 when: "matrix_mautrix_whatsapp_enabled" -- stat: +- name: Check if a mautrix-whatsapp registration file exists + stat: path: "{{ matrix_mautrix_whatsapp_base_path }}/registration.yaml" - register: mautrix_whatsapp_registration_file + register: mautrix_whatsapp_registration_file_stat - name: Generate matrix-mautrix-whatsapp registration.yaml if it doesn't exist - shell: /usr/bin/docker run --rm --name matrix-mautrix-whatsapp-gen -v {{ matrix_mautrix_whatsapp_base_path }}:/data:z {{ matrix_mautrix_whatsapp_docker_image }} /usr/bin/mautrix-whatsapp -g -c /data/config.yaml -r /data/registration.yaml - when: "matrix_mautrix_whatsapp_enabled and mautrix_whatsapp_registration_file.stat.exists == False" + shell: + cmd: >- + /usr/bin/docker run + --rm + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} + --cap-drop=ALL + --name matrix-mautrix-whatsapp-gen + -v {{ matrix_mautrix_whatsapp_base_path }}:/data:z + {{ matrix_mautrix_whatsapp_docker_image }} + /usr/bin/mautrix-whatsapp -g -c /data/config.yaml -r /data/registration.yaml + when: "matrix_mautrix_whatsapp_enabled and not mautrix_whatsapp_registration_file_stat.stat.exists" - set_fact: matrix_synapse_app_service_config_file_mautrix_whatsapp: '/app-registration/mautrix-whatsapp.yml' diff --git a/roles/matrix-synapse/tasks/setup_synapse_main.yml b/roles/matrix-synapse/tasks/setup_synapse_main.yml index 7d86428c..57a296bc 100644 --- a/roles/matrix-synapse/tasks/setup_synapse_main.yml +++ b/roles/matrix-synapse/tasks/setup_synapse_main.yml @@ -41,6 +41,7 @@ SYNAPSE_SERVER_NAME: "{{ hostname_matrix }}" SYNAPSE_REPORT_STATS: "no" user: "{{ matrix_user_uid }}:{{ matrix_user_gid }}" + cap_drop: ['all'] volumes: - "{{ matrix_synapse_config_dir_path }}:/data" when: "not matrix_synapse_config_stat.stat.exists" diff --git a/roles/matrix-synapse/templates/ext/mautrix-telegram/config.yaml.j2 b/roles/matrix-synapse/templates/ext/mautrix-telegram/config.yaml.j2 index c1858686..7e6174a1 100644 --- a/roles/matrix-synapse/templates/ext/mautrix-telegram/config.yaml.j2 +++ b/roles/matrix-synapse/templates/ext/mautrix-telegram/config.yaml.j2 @@ -26,7 +26,7 @@ appservice: # Format examples: # SQLite: sqlite:///filename.db # Postgres: postgres://username:password@hostname/dbname - database: sqlite:///mautrix-telegram.db + database: sqlite:////data/mautrix-telegram.db # Public part of web server for out-of-Matrix interaction with the bridge. # Used for things like login if the user wants to make sure the 2FA password isn't stored in @@ -253,7 +253,7 @@ logging: file: class: logging.handlers.RotatingFileHandler formatter: precise - filename: ./mautrix-telegram.log + filename: /data/mautrix-telegram.log maxBytes: 10485760 backupCount: 10 console: diff --git a/roles/matrix-synapse/templates/ext/mautrix-telegram/systemd/matrix-mautrix-telegram.service.j2 b/roles/matrix-synapse/templates/ext/mautrix-telegram/systemd/matrix-mautrix-telegram.service.j2 index 61f7e7f8..7e965804 100644 --- a/roles/matrix-synapse/templates/ext/mautrix-telegram/systemd/matrix-mautrix-telegram.service.j2 +++ b/roles/matrix-synapse/templates/ext/mautrix-telegram/systemd/matrix-mautrix-telegram.service.j2 @@ -9,12 +9,21 @@ After=matrix-synapse.service Type=simple ExecStartPre=-/usr/bin/docker kill matrix-mautrix-telegram ExecStartPre=-/usr/bin/docker rm matrix-mautrix-telegram +ExecStartPre=/usr/bin/docker run --rm --name matrix-mautrix-telegram-db \ + --log-driver=none \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + -v {{ matrix_mautrix_telegram_base_path }}:/data:z \ + {{ matrix_mautrix_telegram_docker_image }} \ + alembic -x config=/data/config.yaml upgrade head ExecStart=/usr/bin/docker run --rm --name matrix-mautrix-telegram \ --log-driver=none \ - -e "UID={{ matrix_user_uid }}" -e "GID={{ matrix_user_gid }}" \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ --network={{ matrix_docker_network }} \ -v {{ matrix_mautrix_telegram_base_path }}:/data:z \ - {{ matrix_mautrix_telegram_docker_image }} + {{ matrix_mautrix_telegram_docker_image }} \ + python3 -m mautrix_telegram -c /data/config.yaml ExecStop=-/usr/bin/docker kill matrix-mautrix-telegram ExecStop=-/usr/bin/docker rm matrix-mautrix-telegram Restart=always diff --git a/roles/matrix-synapse/templates/ext/mautrix-whatsapp/systemd/matrix-mautrix-whatsapp.service.j2 b/roles/matrix-synapse/templates/ext/mautrix-whatsapp/systemd/matrix-mautrix-whatsapp.service.j2 index e90b7a9e..bb4194aa 100644 --- a/roles/matrix-synapse/templates/ext/mautrix-whatsapp/systemd/matrix-mautrix-whatsapp.service.j2 +++ b/roles/matrix-synapse/templates/ext/mautrix-whatsapp/systemd/matrix-mautrix-whatsapp.service.j2 @@ -11,10 +11,13 @@ ExecStartPre=-/usr/bin/docker kill matrix-mautrix-whatsapp ExecStartPre=-/usr/bin/docker rm matrix-mautrix-whatsapp ExecStart=/usr/bin/docker run --rm --name matrix-mautrix-whatsapp \ --log-driver=none \ - -e "UID={{ matrix_user_uid }}" -e "GID={{ matrix_user_gid }}" \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ --network={{ matrix_docker_network }} \ -v {{ matrix_mautrix_whatsapp_base_path }}:/data:z \ - {{ matrix_mautrix_whatsapp_docker_image }} + --workdir=/data \ + {{ matrix_mautrix_whatsapp_docker_image }} \ + /usr/bin/mautrix-whatsapp ExecStop=-/usr/bin/docker kill matrix-mautrix-whatsapp ExecStop=-/usr/bin/docker rm matrix-mautrix-whatsapp Restart=always diff --git a/roles/matrix-synapse/templates/synapse/systemd/matrix-synapse.service.j2 b/roles/matrix-synapse/templates/synapse/systemd/matrix-synapse.service.j2 index dba102da..a369190d 100644 --- a/roles/matrix-synapse/templates/synapse/systemd/matrix-synapse.service.j2 +++ b/roles/matrix-synapse/templates/synapse/systemd/matrix-synapse.service.j2 @@ -18,26 +18,31 @@ ExecStartPre=-/usr/bin/docker rm matrix-synapse # we'd write files to the local filesystem and fusermount will complain. ExecStartPre=/bin/sleep 5 {% endif %} + ExecStart=/usr/bin/docker run --rm --name matrix-synapse \ --log-driver=none \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --entrypoint=python \ + --read-only \ + --tmpfs=/tmp:rw,noexec,nosuid,size={{ matrix_synapse_tmp_directory_size_mb }}m \ --network={{ matrix_docker_network }} \ - -e SYNAPSE_CONFIG_PATH=/data/homeserver.yaml \ -e SYNAPSE_CACHE_FACTOR={{ matrix_synapse_cache_factor }} \ - -e UID={{ matrix_user_uid }} \ - -e GID={{ matrix_user_gid }} \ {% if matrix_synapse_federation_enabled %} -p 8448:8448 \ {% endif %} {% if matrix_synapse_container_expose_client_server_api_port %} -p 127.0.0.1:8008:8008 \ {% endif %} - -v {{ matrix_synapse_config_dir_path }}:/data \ - -v {{ matrix_synapse_run_path }}:/matrix-run \ + -v {{ matrix_synapse_config_dir_path }}:/data:ro \ + -v {{ matrix_synapse_run_path }}:/matrix-run:rw \ -v {{ matrix_synapse_base_path }}/storage:/matrix-media-store-parent:slave \ {% for volume in matrix_synapse_container_additional_volumes %} -v {{ volume.src }}:{{ volume.dst }}:{{ volume.options }} \ {% endfor %} - {{ matrix_synapse_docker_image }} + {{ matrix_synapse_docker_image }} \ + -m synapse.app.homeserver -c /data/homeserver.yaml + ExecStop=-/usr/bin/docker kill matrix-synapse ExecStop=-/usr/bin/docker rm matrix-synapse Restart=always