Fediversity/matrix/nginx
2024-12-02 15:40:44 +01:00
..
README.md Added headers for proxy to enable Element to accept the .well-known stuff. 2024-12-02 15:40:44 +01:00

Table of Contents

Reverse proxy with nginx

Clients connecting from the Internet to our Matrix environment will usually use SSL/TLS to encrypt whatever they want to send. This is one thing that nginx does better than Synapse.

Furthermore, granting or denying access to specific endpoints is much easier in nginx.

Synapse listens only on localhost, so nginx has to pass connections on from the wild west that is the Internet to our server listening on the inside.

Installing

Installing nginx and the Let's Encrypt plugin is easy:

apt install nginx python3-certbot-nginx

Get your certificate:

certbot certonly --nginx --agree-tos -m systeemmail@procolix.com --non-interactive -d matrixdev.procolix.com

Substitute the correct e-mailaddress and FQDN, or course.

Configuration

Almost all traffic should be encrypted, so a redirect from http to https seems like a good idea.

However, .well-known/matrix/client has to be available via http and https, so that should NOT be redirected to https. Some clients don't understand the redirect and will therefore not find the server if you redirect everything.

Under the server_name (the "domain name", the part after the username) you will need a configuration like this:

server {
    listen 80;
    listen [::]:80;
    listen 443 ssl;
    listen [::]:443 ssl;

    ssl_certificate /etc/letsencrypt/live/matrixdev.procolix.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/matrixdev.procolix.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/ssl/dhparams.pem;

    server_name matrixdev.procolix.com;

    location /.well-known/matrix/client {
       return 200 '{
          "m.homeserver": {"base_url": "https://vm02199.procolix.com"},
          "org.matrix.msc3575.proxy": {"url": "https://vm02199.procolix.com"}
       }';
       default_type application/json;

       add_header 'Access-Control-Allow-Origin' '*';
       add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
       add_header 'Access-Control-Allow-Headers' 'X-Requested-With, Content-Type, Authorization';
    }

    location /.well-known/matrix/server {
       return 200 '{"m.server": "vm02199.procolix.com"}';
       default_type application/json;
    }

    location / {
      if ($scheme = http) {
        return 301 https://$host$request_uri;
      }
    }

    access_log /var/log/nginx/matrixdev-access.log;
    error_log /var/log/nginx/matrixdev-error.log;

}

This defines a server that listens on both http and https. It hands out two .well-known entries over both http and https, and every other request over http is forwarded to https.

Be sure to substitute the correct values for server_name, base_url and the certificate files.

The three add_header lines are absolutely necessary, but probably need some tweaking. This is a TODO for this page.

For the actual proxy in front of Synapse, this is what you need:

server {
	listen 443 ssl;
	listen [::]:443 ssl;

	# For the federation port
	listen 8448 ssl default_server;
	listen [::]:8448 ssl default_server;

	ssl_certificate /etc/letsencrypt/live/vm02199.procolix.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/vm02199.procolix.com/privkey.pem;
	include /etc/letsencrypt/options-ssl-nginx.conf;
	ssl_dhparam /etc/ssl/dhparams.pem;

	server_name vm02199.procolix.com;

	location ~ ^(/_matrix|/_synapse/client) {
		proxy_pass http://localhost:8008;
		proxy_set_header X-Forwarded-For $remote_addr;
		proxy_set_header X-Forwarded-Proto $scheme;
		proxy_set_header Host $host;
		client_max_body_size 50M;
		proxy_http_version 1.1;
	}

}

Again, substitute the correct values. Don't forget to open the relevant ports in the firewall. Ports 80 and 443 may already be open, 8448 is probably not.

Firewall

For normal use, at least ports 80 and 443 must be openend, see Firewall.