Make (most) containers run with a read-only filesystem
This commit is contained in:
parent
b77b967171
commit
0be7b25c64
13
CHANGELOG.md
13
CHANGELOG.md
|
@ -1,13 +1,18 @@
|
||||||
# 2019-01-xx
|
# 2019-01-29
|
||||||
|
|
||||||
## Running container processes as non-root
|
## 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.
|
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.
|
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.
|
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](https://github.com/projectatomic/atomic-site/issues/203) for all containers.
|
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
|
## matrix-mailer is now based on Exim, not Postfix
|
||||||
|
|
|
@ -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_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_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_matrix_enabled: true
|
||||||
matrix_nginx_proxy_proxy_riot_enabled: "{{ matrix_riot_web_enabled }}"
|
matrix_nginx_proxy_proxy_riot_enabled: "{{ matrix_riot_web_enabled }}"
|
||||||
|
|
|
@ -13,6 +13,7 @@ ExecStart=/usr/bin/docker run --rm --name matrix-corporal \
|
||||||
--log-driver=none \
|
--log-driver=none \
|
||||||
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
|
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
|
||||||
--cap-drop=ALL \
|
--cap-drop=ALL \
|
||||||
|
--read-only \
|
||||||
--network={{ matrix_docker_network }} \
|
--network={{ matrix_docker_network }} \
|
||||||
{% if matrix_corporal_container_expose_ports %}
|
{% if matrix_corporal_container_expose_ports %}
|
||||||
-p 127.0.0.1:41080:41080 \
|
-p 127.0.0.1:41080:41080 \
|
||||||
|
|
|
@ -13,6 +13,8 @@ ExecStart=/usr/bin/docker run --rm --name matrix-coturn \
|
||||||
--log-driver=none \
|
--log-driver=none \
|
||||||
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
|
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
|
||||||
--cap-drop=ALL \
|
--cap-drop=ALL \
|
||||||
|
--read-only \
|
||||||
|
--tmpfs=/var/tmp:rw,noexec,nosuid,size=100m \
|
||||||
-p 3478:3478 \
|
-p 3478:3478 \
|
||||||
-p 3478:3478/udp \
|
-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 \
|
-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 \
|
||||||
|
|
|
@ -11,6 +11,8 @@ 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 }} \
|
--user={{ matrix_mailer_container_user_uid }}:{{ matrix_mailer_container_user_gid }} \
|
||||||
--cap-drop=ALL \
|
--cap-drop=ALL \
|
||||||
|
--read-only \
|
||||||
|
--tmpfs=/var/spool/exim:rw,noexec,nosuid,size=100m \
|
||||||
--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 }} \
|
--hostname={{ hostname_matrix }} \
|
||||||
|
|
|
@ -12,17 +12,23 @@ Wants={{ service }}
|
||||||
Type=simple
|
Type=simple
|
||||||
ExecStartPre=-/usr/bin/docker kill matrix-mxisd
|
ExecStartPre=-/usr/bin/docker kill matrix-mxisd
|
||||||
ExecStartPre=-/usr/bin/docker rm 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 \
|
ExecStart=/usr/bin/docker run --rm --name matrix-mxisd \
|
||||||
--log-driver=none \
|
--log-driver=none \
|
||||||
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
|
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
|
||||||
--cap-drop=ALL \
|
--cap-drop=ALL \
|
||||||
|
--read-only \
|
||||||
|
--tmpfs=/tmp:rw,exec,nosuid,size=10m \
|
||||||
--network={{ matrix_docker_network }} \
|
--network={{ matrix_docker_network }} \
|
||||||
{% if matrix_mxisd_container_expose_port %}
|
{% if matrix_mxisd_container_expose_port %}
|
||||||
-p 127.0.0.1:8090:8090 \
|
-p 127.0.0.1:8090:8090 \
|
||||||
{% endif %}
|
{% endif %}
|
||||||
-v {{ matrix_mxisd_config_path }}:/etc/mxisd:ro \
|
-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 }}
|
{{ matrix_mxisd_docker_image }}
|
||||||
|
|
||||||
ExecStop=-/usr/bin/docker kill matrix-mxisd
|
ExecStop=-/usr/bin/docker kill matrix-mxisd
|
||||||
ExecStop=-/usr/bin/docker rm matrix-mxisd
|
ExecStop=-/usr/bin/docker rm matrix-mxisd
|
||||||
Restart=always
|
Restart=always
|
||||||
|
|
|
@ -44,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_with_container: "matrix-synapse:8008"
|
||||||
matrix_nginx_proxy_proxy_matrix_client_api_addr_sans_container: "localhost: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.
|
# 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.
|
# 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: []
|
matrix_nginx_proxy_proxy_matrix_additional_server_configuration_blocks: []
|
||||||
|
|
|
@ -116,7 +116,7 @@ server {
|
||||||
proxy_set_header X-Forwarded-For $remote_addr;
|
proxy_set_header X-Forwarded-For $remote_addr;
|
||||||
|
|
||||||
client_body_buffer_size 25M;
|
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;
|
proxy_max_temp_file_size 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,10 +12,13 @@ Wants={{ service }}
|
||||||
Type=simple
|
Type=simple
|
||||||
ExecStartPre=-/usr/bin/docker kill matrix-nginx-proxy
|
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 }} \
|
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
|
||||||
--cap-drop=ALL \
|
--cap-drop=ALL \
|
||||||
|
--read-only \
|
||||||
|
--tmpfs=/tmp:rw,noexec,nosuid,size={{ matrix_nginx_proxy_tmp_directory_size_mb }}m \
|
||||||
--network={{ matrix_docker_network }} \
|
--network={{ matrix_docker_network }} \
|
||||||
-p 80:8080 \
|
-p 80:8080 \
|
||||||
-p 443:8443 \
|
-p 443:8443 \
|
||||||
|
@ -24,6 +27,7 @@ ExecStart=/usr/bin/docker run --rm --name matrix-nginx-proxy \
|
||||||
-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 \
|
||||||
{{ matrix_nginx_proxy_docker_image }}
|
{{ matrix_nginx_proxy_docker_image }}
|
||||||
|
|
||||||
ExecStop=-/usr/bin/docker kill matrix-nginx-proxy
|
ExecStop=-/usr/bin/docker kill matrix-nginx-proxy
|
||||||
ExecStop=-/usr/bin/docker rm matrix-nginx-proxy
|
ExecStop=-/usr/bin/docker rm matrix-nginx-proxy
|
||||||
ExecReload=/usr/bin/docker exec matrix-nginx-proxy /usr/sbin/nginx -s reload
|
ExecReload=/usr/bin/docker exec matrix-nginx-proxy /usr/sbin/nginx -s reload
|
||||||
|
|
|
@ -73,7 +73,7 @@
|
||||||
|
|
||||||
- name: Note about Postgres importing alternative
|
- name: Note about Postgres importing alternative
|
||||||
debug:
|
debug:
|
||||||
msg: >
|
msg: >-
|
||||||
Importing Postgres database using the following command: `{{ matrix_postgres_import_command }}`.
|
Importing Postgres database using the following command: `{{ matrix_postgres_import_command }}`.
|
||||||
If this crashes, you can stop Postgres (`systemctl stop matrix-postgres`),
|
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`)
|
delete its existing data (`rm -rf {{ matrix_postgres_data_path }}/*`), start it again (`systemctl start matrix-postgres`)
|
||||||
|
|
|
@ -11,9 +11,12 @@ ExecStart=/usr/bin/docker run --rm --name matrix-postgres \
|
||||||
--log-driver=none \
|
--log-driver=none \
|
||||||
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
|
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
|
||||||
--cap-drop=ALL \
|
--cap-drop=ALL \
|
||||||
|
--read-only \
|
||||||
|
--tmpfs=/tmp:rw,noexec,nosuid,size=100m \
|
||||||
|
--tmpfs=/run/postgresql:rw,noexec,nosuid,size=100m \
|
||||||
--network={{ matrix_docker_network }} \
|
--network={{ matrix_docker_network }} \
|
||||||
--env-file={{ matrix_postgres_base_path }}/env-postgres-server \
|
--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 \
|
-v /etc/passwd:/etc/passwd:ro \
|
||||||
{{ matrix_postgres_docker_image_to_use }}
|
{{ matrix_postgres_docker_image_to_use }}
|
||||||
ExecStop=-/usr/bin/docker stop matrix-postgres
|
ExecStop=-/usr/bin/docker stop matrix-postgres
|
||||||
|
|
|
@ -13,6 +13,8 @@ ExecStart=/usr/bin/docker run --rm --name matrix-riot-web \
|
||||||
--log-driver=none \
|
--log-driver=none \
|
||||||
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
|
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
|
||||||
--cap-drop=ALL \
|
--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 {{ matrix_riot_web_data_path }}/nginx.conf:/etc/nginx/nginx.conf:ro \
|
||||||
-v /dev/null:/etc/nginx/conf.d/default.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 \
|
||||||
|
|
|
@ -39,6 +39,9 @@ matrix_synapse_max_upload_size_mb: 10
|
||||||
matrix_synapse_max_log_file_size_mb: 100
|
matrix_synapse_max_log_file_size_mb: 100
|
||||||
matrix_synapse_max_log_files_count: 10
|
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
|
# Log levels
|
||||||
# Possible options are defined here https://docs.python.org/3/library/logging.html#logging-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
|
# warning: setting log level to DEBUG will make synapse log sensitive information such
|
||||||
|
|
|
@ -18,11 +18,14 @@ ExecStartPre=-/usr/bin/docker rm matrix-synapse
|
||||||
# we'd write files to the local filesystem and fusermount will complain.
|
# we'd write files to the local filesystem and fusermount will complain.
|
||||||
ExecStartPre=/bin/sleep 5
|
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 }} \
|
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
|
||||||
--cap-drop=ALL \
|
--cap-drop=ALL \
|
||||||
--entrypoint=python \
|
--entrypoint=python \
|
||||||
|
--read-only \
|
||||||
|
--tmpfs=/tmp:rw,noexec,nosuid,size={{ matrix_synapse_tmp_directory_size_mb }}m \
|
||||||
--network={{ matrix_docker_network }} \
|
--network={{ matrix_docker_network }} \
|
||||||
-e SYNAPSE_CACHE_FACTOR={{ matrix_synapse_cache_factor }} \
|
-e SYNAPSE_CACHE_FACTOR={{ matrix_synapse_cache_factor }} \
|
||||||
{% if matrix_synapse_federation_enabled %}
|
{% if matrix_synapse_federation_enabled %}
|
||||||
|
@ -31,14 +34,15 @@ ExecStart=/usr/bin/docker run --rm --name matrix-synapse \
|
||||||
{% if matrix_synapse_container_expose_client_server_api_port %}
|
{% if matrix_synapse_container_expose_client_server_api_port %}
|
||||||
-p 127.0.0.1:8008:8008 \
|
-p 127.0.0.1:8008:8008 \
|
||||||
{% endif %}
|
{% endif %}
|
||||||
-v {{ matrix_synapse_config_dir_path }}:/data \
|
-v {{ matrix_synapse_config_dir_path }}:/data:ro \
|
||||||
-v {{ matrix_synapse_run_path }}:/matrix-run \
|
-v {{ matrix_synapse_run_path }}:/matrix-run:rw \
|
||||||
-v {{ matrix_synapse_base_path }}/storage:/matrix-media-store-parent:slave \
|
-v {{ matrix_synapse_base_path }}/storage:/matrix-media-store-parent:slave \
|
||||||
{% 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
|
-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
|
||||||
|
|
Loading…
Reference in a new issue