diff --git a/CHANGELOG.md b/CHANGELOG.md index d96635b6d..29bded250 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 2b18df773..b43ba5907 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 7fb35eedf..59e080f32 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 3167c6121..7d4beccea 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 eb11890d0..4035aa651 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 69bd5eb81..980ca9840 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 a820f0870..3b6527992 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 9cacf7893..7765b8f92 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 f0adaa7c2..54beb215c 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 978a85c10..de0c06814 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 ccc51ac86..94a86adc4 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 59c3fe151..434cfad81 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 c78b4f351..2681164d8 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 cf97444f1..8adc1e60d 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 99172147b..578a7e0c3 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 1a2d166b3..016b94145 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 000000000..3382d6c65 --- /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 627001570..410d6a01b 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 12504d1f5..1b36acaf7 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 66b20a64a..67d7f86c5 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 b3cf75be1..c989dca9e 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 3e67dfc5d..c32634b90 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 40509e8cd..0d2b9fcf0 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 7b8fba379..5f474453d 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 07e1f43ba..348366299 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 1eadf9338..c9a84f916 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 000000000..a7707cd9c --- /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 6ef2ad17a..5cd697746 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 a0c42b038..cc3eed178 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 f85abb13b..189c9356a 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 ee9b3358c..3c22c62c0 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 7d86428c9..57a296bc1 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 c1858686b..7e6174a11 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 61f7e7f84..7e965804c 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 e90b7a9ed..bb4194aaa 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 dba102da9..a369190d0 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