This is an updated and improved version of an article published in February 2021.
Yesterday I played a bit with Synapse, the reference implementation of a Matrix homeserver. Matrix is a federated chat protocol that features end-to-end encryption and does not require a phone number. As the system is federated, everyone can run their own server but can still talk to users registered to other servers. So the situation is quite comparable to email.
Why I’m writing this article? Well, I believe that Matrix should be preferred over Signal or comparable applications due to its decentralized nature, as it does not expose your valuable phone number, and other reasons. Unfortunately, the biggest hurdle of installing a homeserver is finding a complete documentation, which the following one is - more or less.
Step 0: DNS
You need a domain that points to your vserver, Raspberry Pi, etc. Let’s call it domain.tld
. In your DNS settings, also create a CNAME record called matrix.domain.tld
. After completing the setup procedure, your Matrix IDs will have the following format: @name:domain.tld
, not @name:matrix.domain.tld
.
Step 1: Creating the Initial Configuration
Create a directory for you configuration mkdir -p /docker/matrix
and cd /docker/matrix
into it.
Here, run the following command:
docker run -it --rm \
-v $(pwd)/data:/data \
-e SYNAPSE_SERVER_NAME=domain.tld \
-e SYNAPSE_REPORT_STATS=no \
matrixdotorg/synapse:latest generate
After this is complete, you’ll find some configuration files, keying material, and a TinySQL database in /docker/matrix/data
. For me, the configuration file was okay and I didn’t need to change anything.
Step 2: docker-compose
The initial run
command from above only created some config stuff. No Synapse process is running yet.
Create following docker-compose.yml
file in /docker/matrix/
…
version: '3'
services:
synapse:
container_name: synapse
image: matrixdotorg/synapse:latest
restart: always
volumes:
- ./data:/data
ports:
- 8008:8008
… and run the beast with docker-compose up -d
.
Step 3: Create Users
Execute docker exec -it synapse /bin/bash
to spawn a shell in the running container. In the container execute register_new_matrix_user -c /data/homeserver.yaml http://127.0.0.1:8008
. Follow the instructions on the screen and enter a new user and password, and confirm the password. Repeat for other users.
Step 4: Reverse Proxy and SSL with NGINX
Now we reached the maybe most tricky bit: the proxy configuration.
I have setup my domain and server in a way that I can have a wildcard certificate for domain.tld
, i.e., the certificate I have for domain.tld
will also be valid for matrix.domain.tld
. As setting up this feature depends a bit on your machine and your registrar, I cannot explain the necessary steps here.
The first nginx configuration file you have to create is the following:
server {
server_name matrix.domain.tld;
root /var/www/html/domain.tld;
listen 443 ssl http2;
listen [::]:443 ssl http2;
listen 8448 ssl http2 default_server;
listen [::]:8448 ssl http2 default_server;
location ~* ^(\/_matrix|\/_synapse\/client) {
proxy_pass http://localhost:8008;
proxy_set_header X-Forwarded-For $remote_addr;
client_max_body_size 50M;
}
ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
server {
server_name matrix.domain.tld;
listen 80;
return 404;
if ($host = matrix.domain.tld) {
return 301 https://$host$request_uri;
}
}
I assume you already have a configuration file for domain.tld
. To this file, add the following location
:
...
location /.well-known/matrix/client {
return 200 '{"m.homeserver": {"base_url": "https://matrix.domain.tld"}}';
default_type application/json;
add_header Access-Control-Allow-Origin *;
}
...
This statement creates some kind of redirect for Element (or other Matrix clients). You can now just enter domain.tld
as your homeserver, and the client will automagically find out that matrix.domain.tld
is your actual server.
Step 5: Testing
If everything worked according to plan, you should be able to do the following things:
- Open https://federationtester.matrix.org and enter
domain.tld
. The tool should print out “success”, which means your server can talk to other servers. Nice. - Install Element on your local machine. Enter your homeserver’s URL
domain.tld
and the credentials. Element should connect, and you should be able to chat with other users.
Congratulations, you have set up a brand new federated and secure messaging server. Now good luck with convincing others to use this system as well :D