Installing Synapse, The Matrix homeserver

Element is becoming a very popular messaging application with a host of interesting privacy features. Even more impressive is Matrix, the open source standard that Element and other clients run on. What convinced me to try Matrix was that it is federated. You can even self-host your own “homeserver” called Synapse. Check it out and see if it meets your privacy needs. I installed Synapse in mid-2020 and have used it almost daily to communicate with family (messaging, voice calls, and video) without a single problem. This article is mostly an installation guide with a little bit of opinion mixed in.

Step 1: Server prerequisites

The Synapse installation guides on matrix.org describe several methods for setting up the server. My guide is written specifically for Debian-based servers running Apache 2 and assumes you have a working web server, whether self-hosted or VPS. I’m also assuming you are comfortable with a command line. The level of difficulty to this installation is intermediate… at least it was for me.

Step 2: Configure SRV DNS record

I set up an SRV record for Synapse since it is a communication service on a unique port. The ‘service’ (SRV) DNS record specifies a host and port for services like voice over IP (VoIP) and instant messaging. Most DNS records specify a single IP address, but SRV records include a port as well. Some Internet protocols require the use of SRV records in order to function. I’m not sure if Synapse requires it… but it won’t hurt, right?

Below is the structure of the SRV record according to wikipedia.org:

_service._proto.name. TTL class SRV priority weight port target.
  • service: the symbolic name of the desired service.
  • proto: the transport protocol of the desired service; this is usually either TCP or UDP.
  • name: the domain name for which this record is valid, ending in a dot.
  • TTL: standard DNS time to live field.
  • class: standard DNS class field (this is always IN).
  • SRV: Type of Record (this is always SRV).
  • priority: the priority of the target host, lower value means more preferred.
  • weight: A relative weight for records with the same priority, higher value means higher chance of getting picked.
  • port: the TCP or UDP port on which the service is to be found.
  • target: the canonical hostname of the machine providing the service, ending in a dot.

In my case, I am creating a SRV record at https://freedns.afraid.org/ (which I highly recommend). The format there is slightly different:

Subdomain: _service._protocol.subdomain
Domain: yourdomain.com
Destination: [priority] [weight] [port] [target]

After a few attempts, my SRV record looks like this:

Type: SRV
Subdomain: _matrix._tcp.matrix.pret
Domain: ext.io
Destination: 10 5 8448 matrix.pret.ext.io

Step 3: Configure the firewall

Assuming you’re behind a firewall, you’ll need to open specific ports for Synapse to work. Open port 8448 for matrix federation and port 443 for matrix clients to listen.

Step 4: Install the Matrix-Synapse server

References:

Now, add the matrix.org repository to your /etc/apt/sources.list.d/ directory. Then install the software.

$ sudo apt install -y lsb-release wget apt-transport-https
$ sudo wget -O /usr/share/keyrings/matrix-org-archive-keyring.gpg https://packages.matrix.org/debian/matrix-org-archive-keyring.gpg
$ echo "deb [signed-by=/usr/share/keyrings/matrix-org-archive-keyring.gpg] https://packages.matrix.org/debian/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/matrix-org.list
$ sudo apt update
$ sudo apt install matrix-synapse-py3

Pay attention during the installation process. You’ll be asked a few questions:

Server name? pret.ext.io
share usage data? No

Step 5: Enable required Apache 2 modules

$ sudo a2enmod proxy
$ sudo a2enmod proxy_http
$ sudo a2enmod proxy_balancer
$ sudo a2enmod ssl
$ sudo a2enmod headers
$ sudo a2enmod lbmethod_byrequests

Step 6: Enable listening on required ports

Open /etc/apache2/ports.conf and add port information.

<IfModule ssl_module>
        Listen 443
        Listen 8448
</IfModule>

Step 7: Create the virtual host file

Modify the file /etc/apache2/sites-available/000-default.conf.

<IfModule mod_ssl.c>
<VirtualHost *:8448>
    ServerName matrix.pret.ext.io
    ServerAlias *.matrix.pret.ext.io
    DocumentRoot /var/www/html/matrix/

    # Configure the SSL Certificate
    SSLEngine On
    SSLCertificateFile /etc/letsencrypt/live/matrix.pret.ext.io/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/matrix.pret.ext.io/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf

    <Location />
    ProxyPass http://127.0.0.1:8008/ nocanon
    ProxyPassReverse http://127.0.0.1:8008/
    </Location>
</VirtualHost>
</IfModule>

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName matrix.pret.ext.io
    ServerAlias *.matrix.pret.ext.io
    DocumentRoot /var/www/html/matrix/

    ProxyRequests off
    ProxyPreserveHost On
    ProxyVia full

    ProxyPass /_matrix/identity http://127.0.0.1:8090/_matrix/identity

    <Location />
    ProxyPass http://127.0.0.1:8008/ nocanon
    ProxyPassReverse http://127.0.0.1:8008/
    </Location>

    RequestHeader set X-Forwarded-Proto "https"

    # Configure the SSL Certificate
    SSLEngine On
    SSLCertificateFile /etc/letsencrypt/live/matrix.pret.ext.io/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/matrix.pret.ext.io/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

Step 8: Enable the site file and restart Apache

$ sudo a2ensite /etc/apache2/sites-available/000-default.conf
$ sudo systemctl reload apache2.service

Step 9: Modify the Matrix-Synapse configuration file

Now it’s time to modify the configuration file located at /etc/matrix-synapse/homeserver.yaml. The structure of a yaml file requires conventional block format for hyphens and spaces at the beginning of each line. I recommend reading a tutorial before continuing.

$ sudo nano /etc/matrix-synapse/homeserver.yaml

Set the public_baseurl:

public_baseurl: https://matrix.pret.ext.io/

Set the identity server:

default_identity_server: https://matrix.org

Ensure the default listener is set up:

- port: 8008
   tls: false
   type: http
   x_forwarded: true
   bind_addresses: ['::1', '127.0.0.1']

   resources:
   - names: [client, federation]
      compress: false

Ensure registration is not enabled (unless you want anyone on your server):

enable_registration: false

Set matrix.org as trusted key server and suppress warning:

trusted_key_servers:
  - server_name: "matrix.org"

suppress_key_server_warning: true

Enable password login:

password_config:
   enabled: true

   policy:
      enabled: true
      minimum_length: 8

Set up email capability:

email:
   smtp_host: mobile.charter.net
   smtp_port: 25
   require_transport_security: true
   notif_from: "Your Friendly %(app)s homeserver <admin@pret.ext.io>"

Step 10: Set up the well.known file

Create an ‘index.html’ file in the directory /.well-known/matrix/server with the following content:

$ cd /var/www/html/matrix/.well-known/matrix/server
$ sudo nano index.html

{
    "m.server": matrix.pret.ext.io:8448
}

Step 11: Start the Matrix-Synapse server

$ sudo systemctl start matrix-synapse.service
$ sudo systemctl enable matrix-synapse

Step 12: Test the server

Check port status for python listening on 8008 and Apache 2 on 8448

$ sudo ss -plntu

Go to Federation Tester and verify the server responds correctly:
https://federationtester.matrix.org/

Point the browser to your FQDN. Mine is https://matrix.pret.ext.io
If configured correctly, you’ll see a webpage that looks like the image below:

Step 13: Register a user

This step was the most confusing of all. I can’t tell you how many guides I searched to find an example of how to create an account. If you temporarily turn online registration on, others can register using the web interface. For my account I entered the command:

$ sudo register_new_matrix_user -c /etc/matrix-synapse/homeserver.yaml https://127.0.0.1:8008

Step 14: Install a chat client

I chose the element client because it’s the default client created by the Matrix team and there is an Android open-source version for phones. I’ve used the Linux desktop client for a long time and really enjoy it. Go to https://element.io/get-started. Following the directions from their website, enter the following commands:

$ sudo apt install -y wget apt-transport-https
$ sudo wget -O /usr/share/keyrings/riot-im-archive-keyring.gpg https://packages.riot.im/debian/riot-im-archive-keyring.gpg
$ echo "deb [signed-by=/usr/share/keyrings/riot-im-archive-keyring.gpg] https://packages.riot.im/debian/ default main" | sudo tee /etc/apt/sources.list.d/riot-im.list
$ sudo apt update
$ sudo apt install element-desktop

Troubleshooting your server installation

If you have any issues (I had several getting started), try these commands. Keep in mind the server is installed at /opt/venvs/matrix-synapse/

$ sudo systemctl status matrix-synapse.service
$ sudo journalctl -xe

Also, check /var/log/syslog:

$ sudo less /var/log/syslog
$ sudo less /var/log/matrix-synapse/homeserver.log

Summary

Wow! That was a lengthy installation process. If you made it all the way through, tell me how things went in the comments, or better yet contact me on Matrix.

Leave a Comment

Your email address will not be published. Required fields are marked *