From ca3b158d94a72b27e7d370faf5282da504a4f062 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Fri, 6 Dec 2019 11:53:09 +0200 Subject: [PATCH] Add support to matrix-nginx-proxy to work in HTTP-only mode --- CHANGELOG.md | 12 ++ docs/configuring-playbook-own-webserver.md | 70 +++++++++- roles/matrix-nginx-proxy/defaults/main.yml | 37 ++++++ .../nginx/conf.d/matrix-dimension.conf.j2 | 86 +++++++------ .../nginx/conf.d/matrix-domain.conf.j2 | 79 +++++++----- .../nginx/conf.d/matrix-riot-web.conf.j2 | 87 +++++++------ .../nginx/conf.d/matrix-synapse.conf.j2 | 120 +++++++++++------- .../systemd/matrix-nginx-proxy.service.j2 | 12 +- 8 files changed, 335 insertions(+), 168 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6dedf384..34b2d8b76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# 2019-12-06 + +## Added support for an alternative method for using another webserver + +We have added support for making `matrix-nginx-proxy` not being so invasive, so that it would be easier to [use your own webserver](docs/configuring-playbook-own-webserver.md). + +The documentation has been updated with a **Method 2**, which might make "own webserver" setup easier in some cases (such as [reverse-proxying using Traefik](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/296)). + +**Existing users** are not affected by this and **don't need to change anything**. +The defaults are still the same (`matrix-nginx-proxy` obtaining SSL certificates and doing everything for you automatically). + + # 2019-11-10 ## Tightened security around room directory publishing diff --git a/docs/configuring-playbook-own-webserver.md b/docs/configuring-playbook-own-webserver.md index a543b1b3e..29b7625b8 100644 --- a/docs/configuring-playbook-own-webserver.md +++ b/docs/configuring-playbook-own-webserver.md @@ -6,8 +6,19 @@ If that's alright, you can skip this. If you don't want this playbook's nginx webserver to take over your server's 80/443 ports like that, and you'd like to use your own webserver (be it nginx, Apache, Varnish Cache, etc.), you can. +There are **2 ways you can go about it**, if you'd like to use your own webserver: -## Preparation +- [Method 1: Disabling the integrated nginx reverse-proxy webserver](#method-1-disabling-the-integrated-nginx-reverse-proxy-webserver) + +- [Method 2: Fronting the integrated nginx reverse-proxy webserver with another reverse-proxy](#method-2-fronting-the-integrated-nginx-reverse-proxy-webserver-with-another-reverse-proxy) + + +## Method 1: Disabling the integrated nginx reverse-proxy webserver + +This method is about completely disabling the integrated nginx reverse-proxy webserver and replicating its behavior using another webserver. +For an alternative, make sure to check Method #2 as well. + +### Preparation No matter which external webserver you decide to go with, you'll need to: @@ -28,7 +39,7 @@ matrix_ssl_retrieval_method: none **Note**: During [installation](installing.md), unless you've disabled SSL certificate management (`matrix_ssl_retrieval_method: none`), the playbook would need 80 to be available, in order to retrieve SSL certificates. **Please manually stop your other webserver while installing**. You can start it back up afterwards. -## Using your own external nginx webserver +### Using your own external nginx webserver Once you've followed the [Preparation](#preparation) guide above, it's time to set up your external nginx server. @@ -45,17 +56,64 @@ matrix_nginx_proxy_ssl_protocols: "TLSv1.1 TLSv1.2" ``` -## Using your own external Apache webserver +### Using your own external Apache webserver Once you've followed the [Preparation](#preparation) guide above, you can take a look at the [examples/apache](../examples/apache) directory for a sample configuration. -## Using your own external caddy webserver +### Using your own external caddy webserver After following the [Preparation](#preparation) guide above, you can take a look at the [examples/caddy](../examples/caddy) directory for a sample configuration. -## Using your own HAproxy reverse proxy +### Using your own HAproxy reverse proxy After following the [Preparation](#preparation) guide above, you can take a look at the [examples/haproxy](../examples/haproxy) directory for a sample configuration. In this case HAproxy is used as a reverse proxy and a simple Nginx container is used to serve statically `.well-known` files. -## Using another external webserver +### Using another external webserver Feel free to look at the [examples/apache](../examples/apache) directory, or the [template files in the matrix-nginx-proxy role](../roles/matrix-nginx-proxy/templates/conf.d/). + + +## Method 2: Fronting the integrated nginx reverse-proxy webserver with another reverse-proxy + +This method is about leaving the integrated nginx reverse-proxy webserver be, but making it not get in the way (using up important ports, trying to retrieve SSL certificates, etc.). + +If you wish to use another webserver, the integrated nginx reverse-proxy webserver usually gets in the way because it attempts to fetch SSL certificates and binds to ports 80, 443 and 8448 (if Matrix Federation is enabled). + +You can disable such behavior and make the integrated nginx reverse-proxy webserver only serve traffic locally (or over a local network). + +You would need some configuration like this: + +```yaml +# Do not retrieve SSL certificates. This shall be managed by another webserver or other means. +matrix_ssl_retrieval_method: none + +# Do not try to serve HTTPS, since we have no SSL certificates. +# Disabling this also means services will be served on the HTTP port +# (`matrix_nginx_proxy_container_http_host_bind_port`). +matrix_nginx_proxy_https_enabled: false + +# Do not listen for HTTP on port 80 globally (default), listen on the loopback interface. +# If you'd like, you can make it use the local network as well and reverse-proxy from another local machine. +matrix_nginx_proxy_container_http_host_bind_port: '127.0.0.1:81' + +# Likewise, expose the Matrix Federation port on the loopback interface. +# Since `matrix_nginx_proxy_https_enabled` is set to `false`, this federation port will serve HTTP traffic. +# If you'd like, you can make it use the local network as well and reverse-proxy from another local machine. +# +# You'd most likely need to expose it publicly on port 8448 (8449 was chosen for the local port to prevent overlap). +matrix_nginx_proxy_container_federation_host_bind_port: '127.0.0.1:8449' + +# Coturn relies on SSL certificates that have already been obtained. +# Since we don't obtain any certificates (`matrix_ssl_retrieval_method: none` above), it won't work by default. +# An alternative is to tweak some of: `matrix_coturn_tls_enabled`, `matrix_coturn_tls_cert_path` and `matrix_coturn_tls_key_path`. +matrix_coturn_enabled: false +``` + +With this, nginx would still be in use, but it would not bother with anything SSL related or with taking up public ports. + +All services would be served locally on `127.0.0.1:81` and `127.0.0.1:8449` (as per the example configuration above). + +You can then set up another reverse-proxy server on ports 80/443/8448 for all of the expected domains and make traffic go to these local ports. +The expected domains vary depending on the services you have enabled (`matrix.DOMAIN` for sure; `riot.DOMAIN` and `dimension.DOMAIN` are optional). + +We don't have sample webserver configuration for this use-case yet, but hope to expand on this documentation entry in the future. +For [Traefik](https://traefik.io/), you can [see some work in progress examples here](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/296). diff --git a/roles/matrix-nginx-proxy/defaults/main.yml b/roles/matrix-nginx-proxy/defaults/main.yml index 0fc1d9a41..b62c45294 100644 --- a/roles/matrix-nginx-proxy/defaults/main.yml +++ b/roles/matrix-nginx-proxy/defaults/main.yml @@ -25,6 +25,41 @@ matrix_nginx_proxy_container_additional_volumes: [] # A list of extra arguments to pass to the container matrix_nginx_proxy_container_extra_arguments: [] +# Controls whether matrix-nginx-proxy serves its vhosts over HTTPS or HTTP. +# +# If enabled: +# - SSL certificates would be expected to be available (see `matrix_ssl_retrieval_method`) +# - the HTTP vhost would be made a redirect to the HTTPS vhost +# +# If not enabled: +# - you don't need any SSL certificates (you can set `matrix_ssl_retrieval_method: none`) +# - naturally, there's no HTTPS vhost +# - services are served directly from the HTTP vhost +matrix_nginx_proxy_https_enabled: true + +# Controls whether the matrix-nginx-proxy container exposes its HTTP port (tcp/8080 in the container). +# +# Takes an ":" or "" value (e.g. "127.0.0.1:80"), or empty string to not expose. +matrix_nginx_proxy_container_http_host_bind_port: '80' + +# Controls whether the matrix-nginx-proxy container exposes its HTTPS port (tcp/8443 in the container). +# +# Takes an ":" or "" value (e.g. "127.0.0.1:443"), or empty string to not expose. +# +# This only makes sense and applies if `matrix_nginx_proxy_https_enabled` is set to `true`. +# Otherwise, there are no HTTPS vhosts to expose. +matrix_nginx_proxy_container_https_host_bind_port: '443' + +# Controls whether the matrix-nginx-proxy container exposes the Matrix Federation port (tcp/8448 in the container). +# +# Takes an ":" or "" value (e.g. "127.0.0.1:8448"), or empty string to not expose. +# +# This only makes sense and applies if `matrix_nginx_proxy_proxy_matrix_federation_api_enabled` is set to `true`. +# Otherwise, there is no Matrix Federation port to expose. +# +# This port can take HTTP or HTTPS traffic, depending on `matrix_nginx_proxy_https_enabled`. +# When HTTPS is disabled, you'd likely want to only expose the port locally, and front it with another HTTPS-enabled reverse-proxy. +matrix_nginx_proxy_container_federation_host_bind_port: '8448' # Controls whether matrix-nginx-proxy should serve the base domain. # @@ -149,6 +184,8 @@ matrix_nginx_proxy_self_check_validate_certificates: true # The "none" type (`matrix_ssl_retrieval_method: none`), simply means that no certificate retrieval will happen. # It's useful for when you've disabled the nginx proxy (`matrix_nginx_proxy_enabled: false`) # and you'll be using another reverse-proxy server (like Apache) with your own certificates, managed by yourself. +# It's also useful if you're using `matrix_nginx_proxy_https_enabled: false` to make this nginx proxy serve +# plain HTTP traffic only (usually, on the loopback interface only) and you'd be terminating SSL using another reverse-proxy. matrix_ssl_retrieval_method: "lets-encrypt" # The list of domains that this role will obtain certificates for. diff --git a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-dimension.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-dimension.conf.j2 index dbfe96ce7..babcb98c0 100644 --- a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-dimension.conf.j2 +++ b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-dimension.conf.j2 @@ -1,45 +1,9 @@ #jinja2: lstrip_blocks: "True" -server { - listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; - server_name {{ matrix_nginx_proxy_proxy_dimension_hostname }}; - - server_tokens off; - - location /.well-known/acme-challenge { - {% 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:8080"; - proxy_pass http://$backend; - {% else %} - {# Generic configuration for use outside of our container setup #} - proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; - {% endif %} - } - - location / { - return 301 https://$http_host$request_uri; - } -} - -server { - 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_dimension_hostname }}; - - server_tokens off; - root /dev/null; +{% macro render_vhost_directives() %} gzip on; gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; - ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_dimension_hostname }}/fullchain.pem; - ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_dimension_hostname }}/privkey.pem; - ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; - ssl_prefer_server_ciphers on; - ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; - location / { {% if matrix_nginx_proxy_enabled %} {# Use the embedded DNS resolver in Docker containers to discover the service #} @@ -54,4 +18,52 @@ server { proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + server_name {{ matrix_nginx_proxy_proxy_dimension_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% 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:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} } + +{% if matrix_nginx_proxy_https_enabled %} +server { + 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_dimension_hostname }}; + + server_tokens off; + root /dev/null; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_dimension_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_dimension_hostname }}/privkey.pem; + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + ssl_prefer_server_ciphers on; + ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; + + {{ render_vhost_directives() }} +} +{% endif %} diff --git a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-domain.conf.j2 b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-domain.conf.j2 index 0d2348272..1ad8b9266 100644 --- a/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-domain.conf.j2 +++ b/roles/matrix-nginx-proxy/templates/nginx/conf.d/matrix-domain.conf.j2 @@ -1,45 +1,11 @@ #jinja2: lstrip_blocks: "True" -server { - listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; - server_name {{ matrix_nginx_proxy_base_domain_hostname }}; - server_tokens off; - - location /.well-known/acme-challenge { - {% 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:8080"; - proxy_pass http://$backend; - {% else %} - {# Generic configuration for use outside of our container setup #} - proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; - {% endif %} - } - - location / { - return 301 https://$http_host$request_uri; - } -} - -server { - 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_base_domain_hostname }}; - - server_tokens off; +{% macro render_vhost_directives() %} root /nginx-data/matrix-domain; gzip on; gzip_types text/plain application/json; - ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_base_domain_hostname }}/fullchain.pem; - ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_base_domain_hostname }}/privkey.pem; - ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; - ssl_prefer_server_ciphers on; - ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; - location /.well-known/matrix { root {{ matrix_static_files_base_path }}; {# @@ -50,4 +16,47 @@ server { default_type application/json; add_header Access-Control-Allow-Origin *; } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + + server_name {{ matrix_nginx_proxy_base_domain_hostname }}; + server_tokens off; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% 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:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} } + +{% if matrix_nginx_proxy_https_enabled %} +server { + 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_base_domain_hostname }}; + server_tokens off; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_base_domain_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_base_domain_hostname }}/privkey.pem; + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + ssl_prefer_server_ciphers on; + ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; +} +{% endif %} 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 index 4a97ebfaf..a81035c73 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,45 +1,9 @@ #jinja2: lstrip_blocks: "True" -server { - listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; - server_name {{ matrix_nginx_proxy_proxy_riot_hostname }}; - - server_tokens off; - - location /.well-known/acme-challenge { - {% 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:8080"; - proxy_pass http://$backend; - {% else %} - {# Generic configuration for use outside of our container setup #} - proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; - {% endif %} - } - - location / { - return 301 https://$http_host$request_uri; - } -} - -server { - 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 }}; - - server_tokens off; - root /dev/null; +{% macro render_vhost_directives() %} gzip on; gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; - ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_riot_hostname }}/fullchain.pem; - ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_riot_hostname }}/privkey.pem; - ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; - ssl_prefer_server_ciphers on; - ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; - location / { {% if matrix_nginx_proxy_enabled %} {# Use the embedded DNS resolver in Docker containers to discover the service #} @@ -54,4 +18,53 @@ server { proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + + server_name {{ matrix_nginx_proxy_proxy_riot_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% 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:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} } + +{% if matrix_nginx_proxy_https_enabled %} +server { + 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 }}; + + server_tokens off; + root /dev/null; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_riot_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_riot_hostname }}/privkey.pem; + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + ssl_prefer_server_ciphers on; + ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; + + {{ render_vhost_directives() }} +} +{% endif %} 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 index b3efd7009..996625156 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 @@ -12,51 +12,11 @@ } {% endmacro %} -server { - listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; - server_name {{ matrix_nginx_proxy_proxy_matrix_hostname }}; - - server_tokens off; - - location /.well-known/acme-challenge { - {% 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:8080"; - proxy_pass http://$backend; - {% else %} - {# Generic configuration for use outside of our container setup #} - proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; - {% endif %} - } - - {% if matrix_nginx_proxy_proxy_matrix_nginx_status_enabled %} - {{ render_nginx_status_location_block(matrix_nginx_proxy_proxy_matrix_nginx_status_allowed_addresses) }} - {% endif %} - - location / { - return 301 https://$http_host$request_uri; - } -} - -server { - 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 }}; - - server_tokens off; - root /dev/null; +{% macro render_vhost_directives() %} gzip on; gzip_types text/plain application/json; - ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_matrix_hostname }}/fullchain.pem; - ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_matrix_hostname }}/privkey.pem; - ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; - ssl_prefer_server_ciphers on; - ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; - location /.well-known/matrix { root {{ matrix_static_files_base_path }}; {# @@ -212,27 +172,89 @@ server { location / { rewrite ^/$ /_matrix/static/ last; } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + server_name {{ matrix_nginx_proxy_proxy_matrix_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% 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:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + {% if matrix_nginx_proxy_proxy_matrix_nginx_status_enabled %} + {{ render_nginx_status_location_block(matrix_nginx_proxy_proxy_matrix_nginx_status_allowed_addresses) }} + {% endif %} + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} } -{% if matrix_nginx_proxy_proxy_matrix_federation_api_enabled %} +{% if matrix_nginx_proxy_https_enabled %} server { - listen 8448 ssl http2; - listen [::]:8448 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 }}; server_tokens off; root /dev/null; - gzip on; - gzip_types text/plain application/json; - - ssl_certificate {{ matrix_nginx_proxy_proxy_matrix_federation_api_ssl_certificate }}; - ssl_certificate_key {{ matrix_nginx_proxy_proxy_matrix_federation_api_ssl_certificate_key }}; + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_matrix_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_matrix_hostname }}/privkey.pem; ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; + {{ render_vhost_directives() }} +} +{% endif %} + +{% if matrix_nginx_proxy_proxy_matrix_federation_api_enabled %} +{# + This federation vhost is a little special. + It serves federation over HTTP or HTTPS, depending on `matrix_nginx_proxy_https_enabled`. +#} +server { + {% if matrix_nginx_proxy_https_enabled %} + listen 8448 ssl http2; + listen [::]:8448 ssl http2; + {% else %} + listen 8448; + {% endif %} + + server_name {{ matrix_nginx_proxy_proxy_matrix_hostname }}; + server_tokens off; + + root /dev/null; + + gzip on; + gzip_types text/plain application/json; + + {% if matrix_nginx_proxy_https_enabled %} + ssl_certificate {{ matrix_nginx_proxy_proxy_matrix_federation_api_ssl_certificate }}; + ssl_certificate_key {{ matrix_nginx_proxy_proxy_matrix_federation_api_ssl_certificate_key }}; + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + ssl_prefer_server_ciphers on; + ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; + {% endif %} + location / { {% if matrix_nginx_proxy_enabled %} {# Use the embedded DNS resolver in Docker containers to discover the service #} 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 6d30322a5..5b4dfb2af 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 @@ -21,10 +21,14 @@ ExecStart=/usr/bin/docker run --rm --name matrix-nginx-proxy \ --read-only \ --tmpfs=/tmp:rw,noexec,nosuid,size={{ matrix_nginx_proxy_tmp_directory_size_mb }}m \ --network={{ matrix_docker_network }} \ - -p 80:8080 \ - -p 443:8443 \ - {% if matrix_nginx_proxy_proxy_matrix_federation_api_enabled %} - -p 8448:8448 \ + {% if matrix_nginx_proxy_container_http_host_bind_port %} + -p {{ matrix_nginx_proxy_container_http_host_bind_port }}:8080 \ + {% endif %} + {% if matrix_nginx_proxy_https_enabled and matrix_nginx_proxy_container_https_host_bind_port %} + -p {{ matrix_nginx_proxy_container_https_host_bind_port }}:8443 \ + {% endif %} + {% if matrix_nginx_proxy_proxy_matrix_federation_api_enabled and matrix_nginx_proxy_container_federation_host_bind_port %} + -p {{ matrix_nginx_proxy_container_federation_host_bind_port }}:8448 \ {% endif %} -v {{ matrix_nginx_proxy_base_path }}/nginx.conf:/etc/nginx/nginx.conf:ro \ -v {{ matrix_nginx_proxy_data_path }}:/nginx-data:ro \