Make (most) containers start as non-root

This makes all containers (except mautrix-telegram and
mautrix-whatsapp), start as a non-root user.

We do this, because we don't trust some of the images.
In any case, we'd rather not trust ALL images and avoid giving
`root` access at all. We can't be sure they would drop privileges
or what they might do before they do it.

Because Postfix doesn't support running as non-root,
it had to be replaced by an Exim mail server.

The matrix-nginx-proxy nginx container image is patched up
(by replacing its main configuration) so that it can work as non-root.
It seems like there's no other good image that we can use and that is up-to-date
(https://hub.docker.com/r/nginxinc/nginx-unprivileged is outdated).

Likewise for riot-web (https://hub.docker.com/r/bubuntux/riot-web/),
we patch it up ourselves when starting (replacing the main nginx
configuration).
Ideally, it would be fixed upstream so we can simplify.
This commit is contained in:
Slavi Pantaleev 2019-01-27 20:25:13 +02:00
parent 56d501679d
commit 299a8c4c7c
24 changed files with 265 additions and 96 deletions

View File

@ -1,3 +1,29 @@
# 2019-01-xx
## Running container processes as non-root
To improve security, this playbook no longer starts container processes as the `root` user.
Usually, most containers were dropping privileges anyway, but by the time they do that, we were trusting them with `root` privileges.
Not anymore -- container processes now start as a non-root user (usually `matrix`) from the get-go.
The only images that we still start as `root` and trust to drop privileges are the optional bridge extensions (disabled by default):
- [tulir/mautrix-telegram](https://hub.docker.com/r/tulir/mautrix-telegram)
- [tulir/mautrix-whatsapp](https://hub.docker.com/r/tulir/mautrix-whatsapp)
## 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 # 2019-01-17
## (BC Break) Making the playbook's roles more independent of one another ## (BC Break) Making the playbook's roles more independent of one another

View File

@ -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) 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) - (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) - [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) - [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)

View File

@ -1,6 +1,6 @@
# Adjusting email-sending settings (optional) # 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. 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.) This may or may not work, depending on your domain configuration (SPF settings, etc.)
@ -28,8 +28,6 @@ matrix_mailer_relay_auth_username: "another.sender@example.com"
matrix_mailer_relay_auth_password: "some-password" 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 ## Troubleshooting

View File

@ -125,7 +125,7 @@ matrix_mxisd_dns_overwrite_homeserver_client_value: "http://{{ 'matrix-corporal:
# By default, we send mail through the `matrix-mailer` service. # 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_identity_from: "{{ matrix_mailer_sender_address }}"
matrix_mxisd_threepid_medium_email_connectors_smtp_host: "matrix-mailer" 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_threepid_medium_email_connectors_smtp_tls: 0
matrix_mxisd_systemd_wanted_services_list: | matrix_mxisd_systemd_wanted_services_list: |
@ -269,7 +269,7 @@ matrix_synapse_database_database: "{{ matrix_postgres_db_name }}"
matrix_synapse_email_enabled: "{{ matrix_mailer_enabled }}" matrix_synapse_email_enabled: "{{ matrix_mailer_enabled }}"
matrix_synapse_email_smtp_host: "matrix-mailer" 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_smtp_require_transport_security: false
matrix_synapse_email_notif_from: "Matrix <{{ matrix_mailer_sender_address }}>" matrix_synapse_email_notif_from: "Matrix <{{ matrix_mailer_sender_address }}>"
matrix_synapse_email_riot_base_url: "https://{{ hostname_riot }}" matrix_synapse_email_riot_base_url: "https://{{ hostname_riot }}"

View File

@ -2,7 +2,12 @@ matrix_mailer_enabled: true
matrix_mailer_base_path: "{{ matrix_base_data_path }}/mailer" 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_sender_address: "matrix@{{ hostname_identity }}"
matrix_mailer_relay_use: false matrix_mailer_relay_use: false

View File

@ -1,8 +1,7 @@
MAILNAME={{ hostname_matrix }}
{% if matrix_mailer_relay_use %} {% 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 %} {% endif %}
{% if matrix_mailer_relay_auth %} {% if matrix_mailer_relay_auth %}
RELAYHOST_AUTH=yes SMTP_USERNAME={{ matrix_mailer_relay_auth_username }}
RELAYHOST_PASSWORDMAP={{ matrix_mailer_relay_host_name }}:{{ matrix_mailer_relay_auth_username }}:{{ matrix_mailer_relay_auth_password }} SMTP_PASSWORD={{ matrix_mailer_relay_auth_password }}
{% endif %} {% endif %}

View File

@ -9,8 +9,10 @@ ExecStartPre=-/usr/bin/docker kill matrix-mailer
ExecStartPre=-/usr/bin/docker rm matrix-mailer ExecStartPre=-/usr/bin/docker rm matrix-mailer
ExecStart=/usr/bin/docker run --rm --name matrix-mailer \ ExecStart=/usr/bin/docker run --rm --name matrix-mailer \
--log-driver=none \ --log-driver=none \
--user={{ matrix_mailer_container_user_uid }}:{{ matrix_mailer_container_user_gid }} \
--network={{ matrix_docker_network }} \ --network={{ matrix_docker_network }} \
--env-file={{ matrix_mailer_base_path }}/env-mailer \ --env-file={{ matrix_mailer_base_path }}/env-mailer \
--hostname={{ hostname_matrix }} \
{{ matrix_mailer_docker_image }} {{ matrix_mailer_docker_image }}
ExecStop=-/usr/bin/docker kill matrix-mailer ExecStop=-/usr/bin/docker kill matrix-mailer
ExecStop=-/usr/bin/docker rm matrix-mailer ExecStop=-/usr/bin/docker rm matrix-mailer

View File

@ -1,5 +1,8 @@
matrix_nginx_proxy_enabled: true 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_docker_image: "nginx:1.15.8-alpine"
matrix_nginx_proxy_data_path: "{{ matrix_base_data_path }}/nginx-proxy" matrix_nginx_proxy_data_path: "{{ matrix_base_data_path }}/nginx-proxy"

View File

@ -21,23 +21,30 @@
- "{{ matrix_nginx_proxy_data_path }}" - "{{ matrix_nginx_proxy_data_path }}"
- "{{ matrix_nginx_proxy_confd_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) - name: Ensure Matrix nginx-proxy configured (generic)
template: 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" dest: "{{ matrix_nginx_proxy_confd_path }}/nginx-http.conf"
mode: 0644 mode: 0644
when: "matrix_nginx_proxy_enabled" when: "matrix_nginx_proxy_enabled"
- name: Ensure Matrix nginx-proxy configuration for matrix domain exists - name: Ensure Matrix nginx-proxy configuration for matrix domain exists
template: 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" dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-synapse.conf"
mode: 0644 mode: 0644
when: "matrix_nginx_proxy_proxy_matrix_enabled" when: "matrix_nginx_proxy_proxy_matrix_enabled"
- name: Ensure Matrix nginx-proxy configuration for riot domain exists - name: Ensure Matrix nginx-proxy configuration for riot domain exists
template: 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" dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-riot-web.conf"
mode: 0644 mode: 0644
when: "matrix_nginx_proxy_proxy_riot_enabled" when: "matrix_nginx_proxy_proxy_riot_enabled"
@ -104,3 +111,8 @@
state: absent state: absent
when: "not matrix_nginx_proxy_proxy_riot_enabled" 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"

View File

@ -15,6 +15,7 @@
mode: 0770 mode: 0770
owner: "{{ matrix_user_username }}" owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_username }}" group: "{{ matrix_user_username }}"
recurse: true
with_items: with_items:
- "{{ matrix_ssl_log_dir_path }}" - "{{ matrix_ssl_log_dir_path }}"
- "{{ matrix_ssl_config_dir_path }}" - "{{ matrix_ssl_config_dir_path }}"

View File

@ -19,12 +19,15 @@
/usr/bin/docker run /usr/bin/docker run
--rm --rm
--name=matrix-certbot --name=matrix-certbot
--net=host --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
-p 80:8080
-v {{ matrix_ssl_config_dir_path }}:/etc/letsencrypt -v {{ matrix_ssl_config_dir_path }}:/etc/letsencrypt
-v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt -v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt
{{ matrix_ssl_lets_encrypt_certbot_docker_image }} {{ matrix_ssl_lets_encrypt_certbot_docker_image }}
certonly certonly
--non-interactive --non-interactive
--work-dir=/tmp
--http-01-port 8080
{% if matrix_ssl_lets_encrypt_staging %}--staging{% endif %} {% if matrix_ssl_lets_encrypt_staging %}--staging{% endif %}
--standalone --standalone
--preferred-challenges http --preferred-challenges http
@ -42,13 +45,16 @@
/usr/bin/docker run /usr/bin/docker run
--rm --rm
--name=matrix-certbot --name=matrix-certbot
-p 127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}:80 --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
-p 127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}:8080
--network={{ matrix_docker_network }} --network={{ matrix_docker_network }}
-v {{ matrix_ssl_config_dir_path }}:/etc/letsencrypt -v {{ matrix_ssl_config_dir_path }}:/etc/letsencrypt
-v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt -v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt
{{ matrix_ssl_lets_encrypt_certbot_docker_image }} {{ matrix_ssl_lets_encrypt_certbot_docker_image }}
certonly certonly
--non-interactive --non-interactive
--work-dir=/tmp
--http-01-port 8080
{% if matrix_ssl_lets_encrypt_staging %}--staging{% endif %} {% if matrix_ssl_lets_encrypt_staging %}--staging{% endif %}
--standalone --standalone
--preferred-challenges http --preferred-challenges http

View File

@ -1,5 +1,5 @@
server { server {
listen 80; listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }};
server_name {{ matrix_nginx_proxy_proxy_riot_hostname }}; server_name {{ matrix_nginx_proxy_proxy_riot_hostname }};
server_tokens off; server_tokens off;
@ -8,7 +8,7 @@ server {
{% if matrix_nginx_proxy_enabled %} {% if matrix_nginx_proxy_enabled %}
{# Use the embedded DNS resolver in Docker containers to discover the service #} {# Use the embedded DNS resolver in Docker containers to discover the service #}
resolver 127.0.0.11 valid=5s; resolver 127.0.0.11 valid=5s;
set $backend "matrix-certbot:80"; set $backend "matrix-certbot:8080";
proxy_pass http://$backend; proxy_pass http://$backend;
{% else %} {% else %}
{# Generic configuration for use outside of our container setup #} {# Generic configuration for use outside of our container setup #}
@ -22,8 +22,8 @@ server {
} }
server { server {
listen 443 ssl http2; listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2;
listen [::]:443 ssl http2; listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2;
server_name {{ matrix_nginx_proxy_proxy_riot_hostname }}; server_name {{ matrix_nginx_proxy_proxy_riot_hostname }};
@ -43,7 +43,7 @@ server {
{% if matrix_nginx_proxy_enabled %} {% if matrix_nginx_proxy_enabled %}
{# Use the embedded DNS resolver in Docker containers to discover the service #} {# Use the embedded DNS resolver in Docker containers to discover the service #}
resolver 127.0.0.11 valid=5s; resolver 127.0.0.11 valid=5s;
set $backend "matrix-riot-web:80"; set $backend "matrix-riot-web:8080";
proxy_pass http://$backend; proxy_pass http://$backend;
{% else %} {% else %}
{# Generic configuration for use outside of our container setup #} {# Generic configuration for use outside of our container setup #}

View File

@ -1,5 +1,5 @@
server { server {
listen 80; listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }};
server_name {{ matrix_nginx_proxy_proxy_matrix_hostname }}; server_name {{ matrix_nginx_proxy_proxy_matrix_hostname }};
server_tokens off; server_tokens off;
@ -8,7 +8,7 @@ server {
{% if matrix_nginx_proxy_enabled %} {% if matrix_nginx_proxy_enabled %}
{# Use the embedded DNS resolver in Docker containers to discover the service #} {# Use the embedded DNS resolver in Docker containers to discover the service #}
resolver 127.0.0.11 valid=5s; resolver 127.0.0.11 valid=5s;
set $backend "matrix-certbot:80"; set $backend "matrix-certbot:8080";
proxy_pass http://$backend; proxy_pass http://$backend;
{% else %} {% else %}
{# Generic configuration for use outside of our container setup #} {# Generic configuration for use outside of our container setup #}
@ -22,8 +22,8 @@ server {
} }
server { server {
listen 443 ssl http2; listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2;
listen [::]:443 ssl http2; listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2;
server_name {{ matrix_nginx_proxy_proxy_matrix_hostname }}; server_name {{ matrix_nginx_proxy_proxy_matrix_hostname }};

View File

@ -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;
}

View File

@ -14,9 +14,11 @@ ExecStartPre=-/usr/bin/docker kill matrix-nginx-proxy
ExecStartPre=-/usr/bin/docker rm matrix-nginx-proxy ExecStartPre=-/usr/bin/docker rm matrix-nginx-proxy
ExecStart=/usr/bin/docker run --rm --name matrix-nginx-proxy \ ExecStart=/usr/bin/docker run --rm --name matrix-nginx-proxy \
--log-driver=none \ --log-driver=none \
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
--network={{ matrix_docker_network }} \ --network={{ matrix_docker_network }} \
-p 80:80 \ -p 80:8080 \
-p 443:443 \ -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_nginx_proxy_confd_path }}:/etc/nginx/conf.d:ro \
-v {{ matrix_ssl_config_dir_path }}:{{ matrix_ssl_config_dir_path }}: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 \ -v {{ matrix_static_files_base_path }}:{{ matrix_static_files_base_path }}:ro \

View File

@ -3,19 +3,22 @@
# For renewal to work, matrix-nginx-proxy (or another webserver, if matrix-nginx-proxy is disabled) # 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. # 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 }}`. # or outside (on the host) by proxying to `http://localhost:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}`.
docker run \ docker run \
--rm \ --rm \
--name=matrix-certbot \ --name=matrix-certbot \
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
--network="{{ matrix_docker_network }}" \ --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_config_dir_path }}:/etc/letsencrypt \
-v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt \ -v {{ matrix_ssl_log_dir_path }}:/var/log/letsencrypt \
{{ matrix_ssl_lets_encrypt_certbot_docker_image }} \ {{ matrix_ssl_lets_encrypt_certbot_docker_image }} \
renew \ renew \
--non-interactive \ --non-interactive \
--work-dir=/tmp \
--http-01-port 8080
{% if matrix_ssl_lets_encrypt_staging %} {% if matrix_ssl_lets_encrypt_staging %}
--staging \ --staging \
{% endif %} {% endif %}

View File

@ -60,12 +60,13 @@
set_fact: set_fact:
matrix_postgres_import_command: >- matrix_postgres_import_command: >-
/usr/bin/docker run --rm --name matrix-postgres-import /usr/bin/docker run --rm --name matrix-postgres-import
--user={{ matrix_user_uid }}:{{ matrix_user_gid }}
--network={{ matrix_docker_network }} --network={{ matrix_docker_network }}
--env-file={{ matrix_postgres_base_path }}/env-postgres-psql --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 --entrypoint=/bin/sh
{{ matrix_postgres_docker_image_latest }} {{ 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 '' }} {{ 'gunzip |' if server_path_postgres_dump.endswith('.gz') else '' }}
psql -v ON_ERROR_STOP=1 -h matrix-postgres' psql -v ON_ERROR_STOP=1 -h matrix-postgres'

View File

@ -70,6 +70,7 @@
- name: Perform Postgres database dump - name: Perform Postgres database dump
command: | command: |
/usr/bin/docker run --rm --name matrix-postgres-dump \ /usr/bin/docker run --rm --name matrix-postgres-dump \
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
--network={{ matrix_docker_network }} \ --network={{ matrix_docker_network }} \
--env-file={{ matrix_postgres_base_path }}/env-postgres-psql \ --env-file={{ matrix_postgres_base_path }}/env-postgres-psql \
-v {{ postgres_dump_dir }}:/out \ -v {{ postgres_dump_dir }}:/out \
@ -104,6 +105,7 @@
- name: Perform Postgres database import - name: Perform Postgres database import
command: | command: |
/usr/bin/docker run --rm --name matrix-postgres-import \ /usr/bin/docker run --rm --name matrix-postgres-import \
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
--network={{ matrix_docker_network }} \ --network={{ matrix_docker_network }} \
--env-file={{ matrix_postgres_base_path }}/env-postgres-psql \ --env-file={{ matrix_postgres_base_path }}/env-postgres-psql \
-v {{ postgres_dump_dir }}:/in:ro \ -v {{ postgres_dump_dir }}:/in:ro \

View File

@ -27,6 +27,7 @@
group: "{{ matrix_user_username }}" group: "{{ matrix_user_username }}"
with_items: with_items:
- {src: "{{ role_path }}/templates/config.json.j2", name: "config.json"} - {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"} - {src: "{{ matrix_riot_web_homepage_template }}", name: "home.html"}
when: matrix_riot_web_enabled when: matrix_riot_web_enabled

View File

@ -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;
}
}
}

View File

@ -11,11 +11,14 @@ ExecStartPre=-/usr/bin/docker kill matrix-riot-web
ExecStartPre=-/usr/bin/docker rm matrix-riot-web ExecStartPre=-/usr/bin/docker rm matrix-riot-web
ExecStart=/usr/bin/docker run --rm --name matrix-riot-web \ ExecStart=/usr/bin/docker run --rm --name matrix-riot-web \
--log-driver=none \ --log-driver=none \
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
-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 }}/config.json:/etc/riot-web/config.json:ro \
-v {{ matrix_riot_web_data_path }}/home.html:/etc/riot-web/home.html:ro \ -v {{ matrix_riot_web_data_path }}/home.html:/etc/riot-web/home.html:ro \
--network={{ matrix_docker_network }} \ --network={{ matrix_docker_network }} \
{% if matrix_riot_web_container_expose_port %} {% if matrix_riot_web_container_expose_port %}
-p 127.0.0.1:8765:80 \ -p 127.0.0.1:8765:8080 \
{% endif %} {% endif %}
{{ matrix_riot_web_docker_image }} {{ matrix_riot_web_docker_image }}
ExecStop=-/usr/bin/docker kill matrix-riot-web ExecStop=-/usr/bin/docker kill matrix-riot-web

View File

@ -41,69 +41,69 @@
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 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" when: "matrix_mautrix_telegram_enabled and mautrix_telegram_registration_file.stat.exists == False"
- set_fact: # - set_fact:
matrix_synapse_app_service_config_file_mautrix_telegram: '/app-registration/mautrix-telegram.yml' # matrix_synapse_app_service_config_file_mautrix_telegram: '/app-registration/mautrix-telegram.yml'
- set_fact: # - set_fact:
matrix_synapse_container_additional_volumes: > # matrix_synapse_container_additional_volumes: >
{{ matrix_synapse_container_additional_volumes }} # {{ matrix_synapse_container_additional_volumes }}
+ # +
{{ [{'src': '{{ matrix_mautrix_telegram_base_path }}/registration.yaml', 'dst': '{{ matrix_synapse_app_service_config_file_mautrix_telegram }}', 'options': 'ro'}] }} # {{ [{'src': '{{ matrix_mautrix_telegram_base_path }}/registration.yaml', 'dst': '{{ matrix_synapse_app_service_config_file_mautrix_telegram }}', 'options': 'ro'}] }}
when: "matrix_mautrix_telegram_enabled" # when: "matrix_mautrix_telegram_enabled"
- set_fact: # - set_fact:
matrix_synapse_app_service_config_files: > # matrix_synapse_app_service_config_files: >
{{ matrix_synapse_app_service_config_files }} # {{ matrix_synapse_app_service_config_files }}
+ # +
{{ ["{{ matrix_synapse_app_service_config_file_mautrix_telegram }}"] | to_nice_json }} # {{ ["{{ matrix_synapse_app_service_config_file_mautrix_telegram }}"] | to_nice_json }}
when: "matrix_mautrix_telegram_enabled" # when: "matrix_mautrix_telegram_enabled"
- block: # - block:
- name: Fail if matrix-nginx-proxy role already executed # - name: Fail if matrix-nginx-proxy role already executed
fail: # fail:
msg: > # msg: >
Trying to append Mautrix Telegram's reverse-proxying configuration to matrix-nginx-proxy, # Trying to append Mautrix Telegram's reverse-proxying configuration to matrix-nginx-proxy,
but it's pointless since the matrix-nginx-proxy role had already executed. # but it's pointless since the matrix-nginx-proxy role had already executed.
To fix this, please change the order of roles in your plabook, # To fix this, please change the order of roles in your plabook,
so that the matrix-nginx-proxy role would run after the matrix-synapse role. # so that the matrix-nginx-proxy role would run after the matrix-synapse role.
when: "matrix_nginx_proxy_role_executed" # when: "matrix_nginx_proxy_role_executed"
- name: Generate Mautrix Telegram proxying configuration for matrix-nginx-proxy # - name: Generate Mautrix Telegram proxying configuration for matrix-nginx-proxy
set_fact: # set_fact:
matrix_mautrix_telegram_matrix_nginx_proxy_configuration: | # matrix_mautrix_telegram_matrix_nginx_proxy_configuration: |
location {{ matrix_mautrix_telegram_public_endpoint }} { # location {{ matrix_mautrix_telegram_public_endpoint }} {
{% if matrix_nginx_proxy_enabled %} # {% if matrix_nginx_proxy_enabled %}
{# Use the embedded DNS resolver in Docker containers to discover the service #} # {# Use the embedded DNS resolver in Docker containers to discover the service #}
resolver 127.0.0.11 valid=5s; # resolver 127.0.0.11 valid=5s;
set $backend "matrix-mautrix-telegram:8080"; # set $backend "matrix-mautrix-telegram:8080";
proxy_pass http://$backend; # proxy_pass http://$backend;
{% else %} # {% else %}
{# Generic configuration for use outside of our container setup #} # {# Generic configuration for use outside of our container setup #}
proxy_pass http://localhost:8080; # proxy_pass http://localhost:8080;
{% endif %} # {% endif %}
} # }
- name: Register Mautrix Telegram proxying configuration with matrix-nginx-proxy # - name: Register Mautrix Telegram proxying configuration with matrix-nginx-proxy
set_fact: # set_fact:
matrix_nginx_proxy_proxy_matrix_additional_server_configuration_blocks: | # matrix_nginx_proxy_proxy_matrix_additional_server_configuration_blocks: |
{{ # {{
matrix_nginx_proxy_proxy_matrix_additional_server_configuration_blocks # matrix_nginx_proxy_proxy_matrix_additional_server_configuration_blocks
+ # +
[matrix_mautrix_telegram_matrix_nginx_proxy_configuration] # [matrix_mautrix_telegram_matrix_nginx_proxy_configuration]
}} # }}
when: "matrix_mautrix_telegram_enabled and matrix_nginx_proxy_enabled|default(False)" # when: "matrix_mautrix_telegram_enabled and matrix_nginx_proxy_enabled|default(False)"
tags: # tags:
- always # - always
- name: Warn about reverse-proxying if matrix-nginx-proxy not used # - name: Warn about reverse-proxying if matrix-nginx-proxy not used
debug: # debug:
msg: > # msg: >
NOTE: You've enabled the Mautrix Telegram bridge but are not using the matrix-nginx-proxy # NOTE: You've enabled the Mautrix Telegram bridge but are not using the matrix-nginx-proxy
reverse proxy. # reverse proxy.
Please make sure that you're proxying the `{{ matrix_mautrix_telegram_public_endpoint }}` # Please make sure that you're proxying the `{{ matrix_mautrix_telegram_public_endpoint }}`
URL endpoint to the matrix-mautrix-telegram container. # URL endpoint to the matrix-mautrix-telegram container.
when: "matrix_mautrix_telegram_enabled and matrix_nginx_proxy_enabled is not defined" # when: "matrix_mautrix_telegram_enabled and matrix_nginx_proxy_enabled is not defined"
# #
# Tasks related to getting rid of matrix-mautrix-telegram (if it was previously enabled) # Tasks related to getting rid of matrix-mautrix-telegram (if it was previously enabled)

View File

@ -20,11 +20,10 @@ ExecStartPre=/bin/sleep 5
{% endif %} {% endif %}
ExecStart=/usr/bin/docker run --rm --name matrix-synapse \ ExecStart=/usr/bin/docker run --rm --name matrix-synapse \
--log-driver=none \ --log-driver=none \
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
--entrypoint=python \
--network={{ matrix_docker_network }} \ --network={{ matrix_docker_network }} \
-e SYNAPSE_CONFIG_PATH=/data/homeserver.yaml \
-e SYNAPSE_CACHE_FACTOR={{ matrix_synapse_cache_factor }} \ -e SYNAPSE_CACHE_FACTOR={{ matrix_synapse_cache_factor }} \
-e UID={{ matrix_user_uid }} \
-e GID={{ matrix_user_gid }} \
{% if matrix_synapse_federation_enabled %} {% if matrix_synapse_federation_enabled %}
-p 8448:8448 \ -p 8448:8448 \
{% endif %} {% endif %}
@ -37,7 +36,8 @@ ExecStart=/usr/bin/docker run --rm --name matrix-synapse \
{% for volume in matrix_synapse_container_additional_volumes %} {% for volume in matrix_synapse_container_additional_volumes %}
-v {{ volume.src }}:{{ volume.dst }}:{{ volume.options }} \ -v {{ volume.src }}:{{ volume.dst }}:{{ volume.options }} \
{% endfor %} {% 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 kill matrix-synapse
ExecStop=-/usr/bin/docker rm matrix-synapse ExecStop=-/usr/bin/docker rm matrix-synapse
Restart=always Restart=always