Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Improved delegation doc (adding .well-known info) #4781

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 118 additions & 38 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -220,32 +220,117 @@ Federation is the process by which users on different servers can participate
in the same room. For this to work, those other servers must be able to contact
yours to send messages.

The ``server_name`` in your ``homeserver.yaml`` file determines the way that
other servers will reach yours. By default, they will treat it as a hostname
and try to connect to port 8448. This is easy to set up and will work with the
default configuration, provided you set the ``server_name`` to match your
machine's public DNS hostname, and give Synapse a TLS certificate which is
valid for your ``server_name``.

For a more flexible configuration, you can set up a DNS SRV record. This allows
you to run your server on a machine that might not have the same name as your
domain name. For example, you might want to run your server at
``synapse.example.com``, but have your Matrix user-ids look like
``@user:example.com``. (A SRV record also allows you to change the port from
the default 8448).

To use a SRV record, first create your SRV record and publish it in DNS. This
should have the format ``_matrix._tcp.<yourdomain.com> <ttl> IN SRV 10 0 <port>
<synapse.server.name>``. The DNS record should then look something like::
The ``server_name`` configured in synapse configuration file (often
``homeserver.yaml``) defines how resources (users, rooms,...) will be
identified (ie: ``@user:example.com``, ``#room:example.com``). By
default, it is also the default domain that other servers will use to
try to reach your server, and they'll try to connect on
port 8448. This is easy to set up and will work provided you set the
``server_name`` to match your machine's public DNS hostname, and give
Synapse a TLS certificate which is valid for your ``server_name``.

For a more flexible configuration, you can have ``server_name``
resources (ie: ``@user:example.com``) served by a different host and
port (ie: ``synapse.example.com:443``). There are 2 ways to do that:

- adding a ``/.well-known/matrix/server`` URL served on ``https://example.com``

- adding a DNS ``SRV`` record in DNS zone of domain
``èxample.com``. Beware that this method has some limitation as it
will still require your delegated server to use a SSL certification
identifying him as the original ``server_name`` domain name. Meaning
that the provided ``synapse.example.com`` delegate domain name will
only be used to get a possibly different IP/port, but won't be used
for SSL domain name verification.

For both method let's say you want to run your server at
``synapse.example.com`` on port ``443`` (instead of ``8448``), but you
want to have your Matrix user-ids look like ``@user:example.com``.

Without any of these delegation method, the matrix federation will
expect to find your resources through ``example.com:8448``. These
following method allows you to provide a different server and port for
``*:example.com`` resources.

If all goes well, you should be able to `connect to your server with a client`__,
and then join a room via federation. (Try ``#matrix-dev:matrix.org`` as a first
step. "Matrix HQ"'s sheer size and activity level tends to make even the
largest boxes pause for thought.)

.. __: `Connecting to Synapse from a client`_

DNS SRV delegation method
-------------------------

To use this method, you need to have write access to your
``server_name`` 's domain zone DNS records (in our example it would be
``example.com`` DNS zone).

This method additionally requires your delegate server to provide a
valid SSL certificate identifying him on the original ``server_name``
domain zone. So with this method the delegate domain name is only
used to resolve a possible different IP/Port combination to find your
server. You must use the other delegation method is this isn't what
you want. (here are `the rationale about this behavior <https://github.com/matrix-org/matrix-doc/blob/master/proposals/1711-x509-for-federation.md#interaction-with-srv-records>`_)

You need to add a SRV record in your ``server_name`` 's DNS zone with
this format::

_matrix._tcp.<yourdomain.com> <ttl> IN SRV 10 0 <port> <synapse.server.name>

In our example, we would need to add this SRV record in the
``example.com`` DNS zone::

_matrix._tcp.example.com. 3600 IN SRV 10 0 443 synapse.example.com.


Once done and set up, you can check the DNS record with ``dig -t srv
_matrix._tcp.<server_name>``, in our example, we would expect this::

$ dig -t srv _matrix._tcp.example.com
_matrix._tcp.example.com. 3600 IN SRV 10 0 8448 synapse.example.com.
_matrix._tcp.example.com. 3600 IN SRV 10 0 443 synapse.example.com.

Note that the server hostname cannot be an alias (CNAME record): it has to point
Note that the server host name cannot be an alias (CNAME record): it has to point
directly to the server hosting the synapse instance.


.well-known delegation method
-----------------------------

To use this method, you need to be able to alter the
``server_name`` 's https server to make him serve the
``/.well-known/matrix/server`` URL. Having an active server (with
correct ``SSL`` certificate) serving your ``server_name`` domain is
out of the scope of this documentation.

The URL ``https://<server_name>/.well-known/matrix/server`` should
return a JSON structure containing the key ``m.server`` as this::

{
"m.server": "<synapse.server.name>:<yourport>"
}

In our example, this would mean that URL ``https://example.com/.well-known/matrix/server``
should return this::

{
"m.server": "synapse.example.com:443"
}

This delegation method allow a full delegation contrary to the DNS SRV
method: federation servers will contact the given hostname's IP and
will check for a valid SSL on the same delegated hostname (in our
example: ``synapse.example.com``).


Setting your server_name
------------------------

Note that you can NOT change the ``server_name`` after the database
was first created. So choose your ``server_name`` with care.

You can then configure your homeserver to use ``<yourdomain.com>`` as the domain in
its user-ids, by setting ``server_name``::
its user-ids, by setting ``server_name`` on the command line::

python -m synapse.app.homeserver \
--server-name <yourdomain.com> \
Expand All @@ -254,41 +339,36 @@ its user-ids, by setting ``server_name``::
python -m synapse.app.homeserver --config-path homeserver.yaml

If you've already generated the config file, you need to edit the ``server_name``
in your ``homeserver.yaml`` file. If you've already started Synapse and a
in your configuration file (often ``homeserver.yaml`` file). If you've already started Synapse and a
database has been created, you will have to recreate the database.

If all goes well, you should be able to `connect to your server with a client`__,
and then join a room via federation. (Try ``#matrix-dev:matrix.org`` as a first
step. "Matrix HQ"'s sheer size and activity level tends to make even the
largest boxes pause for thought.)

.. __: `Connecting to Synapse from a client`_

Troubleshooting
---------------

You can use the `federation tester <https://matrix.org/federationtester>`_ to
check if your homeserver is all set.
You can use the `federation tester
<https://matrix.org/federationtester>`_ to check if your homeserver is
all set. Or the `raw API url used by the federation tester
<https://matrix.org/federationtester/api/report?server_name=DOMAIN>`_
, note that you'll have to modify this URL to replace ``DOMAIN`` with your
``server_name``. The last URL will serve raw JSON that is often more
difficult to interpret but also way more complete.

The `complete server to server spec about this mecanism
<https://matrix.org/docs/spec/server_server/r0.1.1.html#resolving-server-names>`_
is available here if you want more details.

The typical failure mode with federation is that when you try to join a room,
it is rejected with "401: Unauthorized". Generally this means that other
servers in the room couldn't access yours. (Joining a room over federation is a
complicated dance which requires connections in both directions).

So, things to check are:

* If you are not using a SRV record, check that your ``server_name`` (the part
of your user-id after the ``:``) matches your hostname, and that port 8448 on
that hostname is reachable from outside your network.
* If you *are* using a SRV record, check that it matches your ``server_name``
(it should be ``_matrix._tcp.<server_name>``), and that the port and hostname
it specifies are reachable from outside your network.

Another common problem is that people on other servers can't join rooms that
you invite them to. This can be caused by an incorrectly-configured reverse
proxy: see `<docs/reverse_proxy.rst>`_ for instructions on how to correctly
configure a reverse proxy.


Running a Demo Federation of Synapses
richvdh marked this conversation as resolved.
Show resolved Hide resolved
-------------------------------------

Expand Down