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:
- https://knowledge.decibite.com/how-to-install-and-set-up-a-matrix-synapse-server
- https://matrix.org/docs/spec/server_server/latest#resolving-server-names
- https://matrix.org/docs/guides/installing-synapse
- https://github.com/matrix-org/synapse
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.