Install a Matrix Server with Synapse on Arch Linux
Matrix is a new(ish) open source communications protocol. Modern features like encryption, voip, etc. are a part of it which makes it very interesting. A popular client is Riot, another open source protocol that reminds me a lot about the popular but closed discord platform.
This article explains the installation of a self hosted matrix server with LDAP support on top of Arch Linux. As a database backend I chose an existing PostgreSQL server. Of course the database backend is up to you. Change the installation procedure as needed.
LDAP support is provided by the Synapse LDAP Auth provider package.
Arch Linux provides a ready to use matrix-synapse
package. This is skipped in favor of a manual installation however as the LDAP extension is currently out of date.
Preparing Arch Linux
The following line installs the required compilers, python 3 and various python extensions.
pacman -S base-devel python python-pip python-setuptools python-virtualenv postgresql-libs
Next, create a service user. At this point I assume that the installation will live in /opt/synapse
.
useradd -r -U -d /opt/synapse -s /bin/nologin synapse
Prepating PostgreSQL Database
Login to your PostgeSQL server to create a new database and a new user for it:
CREATE USER synapse WITH ENCRYPTED PASSWORD 'your_super_secret_password';
CREATE DATABASE synapse ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' template=template0 OWNER synapse;
GRANT ALL PRIVILEGES ON DATABASE synapse TO synapse;
If you're using a remote host remember to set an entry in your pg_hba.conf
file.
Installing synapse
Creating the destination directory and switching to the synapse
user.
mkdir -p /opt/synapse
chown -R synapse:synapse /opt/synapse
sudo -u synapse /bin/bash
Continue as synapse
user!
Preapre the Python Virtual Environment to hold the required packages for synapse including all it's Python dependencies.
python3 -m venv /opt/synapse/env
source /opt/synapse/env/bin/activate
pip install --upgrade pip
pip install --upgrade setuptools
Continue with the installation of synapse and additional packages.
pip install matrix-synapse psycopg2-binary matrix-synapse-ldap3
Next, generate the initial config.
IMPORTANT: Change the domain name to the domain you would like to use.
python -m synapse.app.homeserver \
--server-name my.domain.name \
--config-path homeserver.yaml \
--generate-config \
--report-stats=[yes|no]
Three new files, a ky, a logging config and the main server conifg homeserver.yaml
should have been created. Edit homeserver.yaml
as needed. Take some time to read through the various config options to see if they're for you.
Set your bind_addresses
array to contain your server's IP otherwise it will only be accessible through localhost. Ecxample:
...
bind_addresses: ['::1', '127.0.0.1', '133.144.155.166']
...
In the database
section remove the sqlite config and replace it with something like this:
database:
name: psycopg2
args:
user: synapse
password: PASSWORD_GOES_HERE
database: synapse
host: localhost
cp_min: 5
cp_max: 10
An example LDAP configuration has been created as well. Change as needed:
password_providers:
- module: "ldap_auth_provider.LdapAuthProvider"
config:
enabled: true
uri: "ldap://ldap.example.com:389"
start_tls: true
base: "ou=users,dc=example,dc=com"
attributes:
uid: "cn"
mail: "mail"
name: "givenName"
#bind_dn:
#bind_password:
#filter: "(objectClass=posixAccount)"
Check the matrix-synapse-ldap3 repository for additional documentation.
This should be it. Run synctl start
. After the command ran, check if port 8008
(or whatever port you set) shows up when you run ss -tulpn
.
Troubleshooting
LDAP user DN start ist uid instead of cn
If you use something else then cn
as the first property of a user's dn, change the uid
attribute in the LDAP configuration.
Only admin users can create communities
Setting an admin user is done setting the admin
flag of an entry in the database's user
entry to 1
. Example:
UPDATE users SET admin=1 WHERE name=’@roman:romangeber.com’
Not very elegant but it works.
Integration manager cannot be reached
I solved this issue by enabling tls on my matrix backend. Encryption was already enabled though the reverse proxy, however the internal communication was established through plain old http.
Set up a TLS listener (preferrably on port 8448) and integrate a cert and a key file.
More on that topic can be found in this github issue
URL previews don't work
Set url_preview_enabled
to true
and enable the mandatory url_preview_ip_range_blacklist
.