---
gitea: none
include_toc: true
---

# Installation and configuration of Synapse

Mind you: this an installation on Debian Linux (at least for now).

Start by installing the latest Synapse server, see the [upstream
documentation](https://element-hq.github.io/synapse/latest/setup/installation.html).

```
apt install -y lsb-release wget apt-transport-https build-essential python3-dev libffi-dev \
               python3-pip python3-setuptools sqlite3 \
               libssl-dev virtualenv libjpeg-dev libxslt1-dev libicu-dev

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" |
    tee /etc/apt/sources.list.d/matrix-org.list

apt update
apt install matrix-synapse-py3
```

This leaves a very basic configuration in `/etc/matrix-synapse/homeserver.yaml`
and  two settings under `/etc/conf.d`. All other configuration items will also
be configured with yaml-files in this directory.

Configure the domain you with to use in `/etc/matrix-synapse/conf.d/server_name.yaml`.
What you configure here will also be the global part of your Matrix handles
(the part after the colon). Also add the URL clients should connect to:

```
server_name: example.com
public_baseurl: https://matrix.example.com/
```

The `public_baseurl` will probably be different than the `server_name`, see
also [Delegation and DNS](#Delegation).

You now have a standard Matrix server that uses sqlite. You really don't want
to use this in production, so probably want to replace this with PostgreSQL.

There are two different ways to configure Synapse, documented here:

* [Monolithic](monolithic)
* [Workers](workers)

We'll use Synapse, using the workers architecture to make it scalable, flexible and reusable.


# Listeners

A fresh installation configures one listener, for both client and federation
traffic. This listens on port 8008 on localhost (IPv4 and IPv6) and does not
do TLS:

```
listeners:
  - port: 8008
    tls: false
    type: http
    x_forwarded: true
    bind_addresses: ['::1', '127.0.0.1']
    resources:
      - names: [client, federation]
        compress: false
```

# Database

The default installation leaves you with an sqlite3 database. Nice for experimenting, but
unsuitable for a production environment.

[Here's how you setup PostgreSQL](../postgresql).

Once you've created a database and user in PostgreSQL, you configure Synapse
to use it.

First delete (or comment out) the SQLITE datbase in `homeserver.yaml`:

```
#database:
#  name: sqlite3
#  args:
#    database: /var/lib/matrix-synapse/homeserver.db
```

Then create the database configuration for PostgreSQL in
`conf.d/database.yaml`:

```
database:
  name: psycopg2
  args:
    user: synapse
    password: <password>
    dbname: synapse
    host: /var/run/postgresql
    cp_min: 5
    cp_max: 10
```

Note: you configure the directory where the UNIX socket file lives, not the
actual file.

Of course, if you use localhost, you should configure it like this:

```
    host: localhost
    port: 5432
```

After changing the database, restart Synapse and check whether it can connect
and create the tables it needs.


# Create admin

Synapse doesn't create an admin account at install time, so you'll have to do
that yourself.

You need to set a `registration_shared_secret` for this, set that in
`conf.d/keys.yaml` like this:

```
registration_shared_secret: xxxx
```

You can create such a key by running `pwgen -csn 52 1`. Restart Synapse after
setting this key.

Now create an admin user. Login and issue this command:

```
register_new_matrix_user -u admin -a -c /etc/matrix-synapse/conf.d/keys.yaml
```

This will ask for a password, choose a safe one.


# Logging

Logging is configured in `log.yaml`. Some logging should go to systemd, the
more specific logging to Synapse's own logfile(s).

This part is yet to be completed.

# Delegation and DNS {#Delegation}

If you run your server under a different FQDN than just the domain name you
want to use, you need to delegate: point from your domain to the server.

Example. You want to use example.com for your domain, but your server is
called matrix.example.com. To make that work, you need to serve 2 bits of
JSON-code on example.com to point clients and servers to the correct
machine: matrix.example.com.

Pointing servers to the correct server is done by publishing this bit of
JSON-code under `https://example.com/.well-known/matrix/server`:

```
{
  "m.homeserver": {"base_url": "https://matrix.example.com"},
  "org.matrix.msc3575.proxy": {"url": "https://matrix.example.com"}
}
```

Pointing clients to the correct server needs this at
`https://example.com/.well-known/matrix/client`:

```
{
  "m.server": "matrix.example.com"
}
```

Very important: both names (example.com and matrix.example.com) must be A
and/or AAAA records in DNS, not CNAME.

See [nginx](../nginx) for details about how to publish this data.


# E-mail {#Email}

Synapse should probably be able to send out e-mails; notifications for those
who want that, and password reset for those who need one.

You configure this under the section `email` (yes, really). 

First of all, you need an SMTP-server that is configured to send e-mail for
your domain. Configuring that is out of scope, we'll assume we can use the
server `smtp.example.com`.

Configure this in `conf.d/email.yaml`:

```
email:
  smtp_host: smtp.example.com
  smtp_port: 465
  smtp_user: matrix@example.com
  smtp_pass: SuperSecretPassword
  force_tls: true
  notif_from: "Your Matrix server <matrix@example.com>"
```

This configures an SMTP-connection with SSL (port 465, `force_tls`). See Matrix'
[email documentation](https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html?highlight=require_transport_security#email)
for more information.


# Media store {#mediastore}

Files and avatars need to be stored somewhere, we configure these options in
`conf.d/mediastore.yaml`:

```
media_store_path: /var/lib/matrix-synapse/media
enable_authenticated_media: true
max_upload_size: 50M
url_preview_enabled: true
url_preview_ip_range_blacklist:
  - '127.0.0.0/8'
  - '10.0.0.0/8'
  - '172.16.0.0/12'
  - '192.168.0.0/16'
  - '100.64.0.0/10'
  - '192.0.0.0/24'
  - '169.254.0.0/16'
  - '192.88.99.0/24'
  - '198.18.0.0/15'
  - '192.0.2.0/24'
  - '198.51.100.0/24'
  - '203.0.113.0/24'
  - '224.0.0.0/4'
  - '::1/128'
  - 'fe80::/10'
  - 'fc00::/7'
  - '2001:db8::/32'
  - 'ff00::/8'
  - 'fec0::/10'
```

These are a few sane (?) defaults, check [Matrix' documentation](https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html?highlight=media_store_path#media-store)
for many more options.


# Homeserver blocking {#blocking}

This is a series of options that can be used to block and/or limit users. The
whole list of options can be found in [Matrix' documentation](https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html?highlight=mau_stats_only%3A#homeserver-blocking),
we're going to pick out a few useful ones.

Let's configure these options in `conf.d/homeserver_blocking.yaml`.

```
admin_contact: matrixadmin@example.com
mau_stats_only: true
max_avatar_size: 2M
allowed_avatar_mimetypes:
  - "image/png"
  - "image/jpeg"
  - "image/gif"
forgotten_room_retention_period: 7d
```


# Authentication {#authentication}

Logging in can be done in basically two ways: an internal or external
database. Let's start with the first: users and their passwords are stored in
Synapse's database.

We use `conf.d/authentication.yaml` to configure this stuff.

```
password_config:
  policy:
    enabled: true
    localdb_enabled: true
    pepper: CxDC6jU5FAxAcvD
    minimum_length: 8
    require_digit: true
    require_symbol: true
    require_lowercase: true
    require_uppercase: true
```

With this bit, we configure Synapse to let users pick and change their own
passwords, as long as they meet the configured conditions. Mind you: `pepper` is
a secret random string that should *NEVER* be changed after initial setup. 

But in a bigger environment you'll probably want to use some authentication
backend, such as LDAP. LDAP is configured by means of a module (see
[Synapse LDAP auth Provider](https://github.com/matrix-org/matrix-synapse-ldap3/)
on Github).

Configuring Synapse to use LDAP, would be something like this:

```
password_config:
  policy:
    enabled: only_for_reauth
    localdb_enabled: false

password_providers:
  - module: "ldap_auth_provider.LdapAuthProvider"
    config:
      enabled: true
      uri: "ldap://ldap.example.com:389"
      start_tls: true
      base: "ou=users,o=Example,dc=example,dc=com"
      attributes:
         uid: "uid"
         mail: "mail"
         name: "cn"
      filter: "(&(objectClass=posixAccount)(accountStatus=active))"

      mode: "search"
      bind_dn: "cn=matrix,ou=service,o=Example,dc=example,dc=com"
      bind_password: "<very secure password>"
```

This would connect to ldap.example.com over TLS, and authenticate users that
live under `ou=users,o=Example,dc=example,dc=com` and that are active Posix
accounts. Users will not be able to change their passwords via Matrix, they
have to do that in LDAP.

The bottom 3 lines enable search mode, necessary to find users' displayname
and e-mail address. These values are in LDAP under the attributes "mail" and
"cn" (completely dependent on your LDAP DIT of course, this setup is common
for OpenLDAP). The bind_dn and bind_password are for the account Synapse can
use to connect and search, necessary if anonymous access is prohibited.


# Server configuration {#serverconfig}

See [Define your homeserver name and other base options](https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html?highlight=require_auth_for_profile_requests#server)
in the Synapse documentation.

It would be logical to put the next options under `conf.d/server.yaml`, but
Debian insists on `conf.d/server_name.yaml` existing and containing the name
of the domain. So we'll use that file for the next options as well. Add these
options:

```
presence:
  enabled: true
  include_offline_users_on_sync: false

require_auth_for_profile_requests: true
allow_public_rooms_over_federation: true

ip_range_blacklist:
  - '127.0.0.0/8'
  - '10.0.0.0/8'
  - '172.16.0.0/12'
  - '192.168.0.0/16'
  - '100.64.0.0/10'
  - '192.0.0.0/24'
  - '169.254.0.0/16'
  - '192.88.99.0/24'
  - '198.18.0.0/15'
  - '192.0.2.0/24'
  - '198.51.100.0/24'
  - '203.0.113.0/24'
  - '224.0.0.0/4'
  - '::1/128'
  - 'fe80::/10'
  - 'fc00::/7'
  - '2001:db8::/32'
  - 'ff00::/8'
  - 'fec0::/10'

filter_timeline_limit: 500
delete_stale_devices_after: 1y
```

These should be reasonable defaults, but do check the [Server block](https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#server)
in Synapse's documentation for more options and information.


# Registration {#Registration}

Registration of new users is configured under `conf.d/registration.yaml`:

```
enable_registration: false
enable_registration_without_verification: false
registrations_require_3pid: email
registration_shared_secret: <long random string>
allow_guest_access: false

enable_set_displayname: false
enable_3pid_changes: false
```

The last two lines prohibit users to change their displayname and 3pid-data
(i.e. e-mail address and phone number). In many cases you'd want them to be
able to set these, of course. But when you use LDAP, which provides these
values, you don't want users to change those.

See for more options [Synapse's documentation](https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#registration).


# TURN

Check for more information about [how to configure the TURN
server](../coturn). Once you've set up your TURN server, configure it in
Synapse, in `conf.d/turn.yaml`:

```
turn_shared_secret: "<long random string>"
turn_uris:
  - "turn:turn.matrixdev.example.com?transport=udp"
  - "turn:turn.matrixdev.example.com?transport=tcp"
turn_user_lifetime: 86400000
turn_allow_guests: true
```

Restart Synapse to activate this bit.

