Skip to content

Commit 0347e87

Browse files
committed
Specify .well-known s2s discovery and X.509 validation
Original proposals: * #1708 (note: the JSON requirements were softened by #1824) * #1711 Implementation proofs: * matrix-org/synapse#4489 * No explicit PRs for MSC1711 could be found, however Synapse is known to implement it. There are no intentional changes which differ from the proposals in this commit, however the author has relied upon various historical conversations outside of the proposals to gain the required context. Inaccuracies introduced by the author are purely accidental.
1 parent 72a2871 commit 0347e87

File tree

4 files changed

+155
-50
lines changed

4 files changed

+155
-50
lines changed

api/server-server/definitions/keys.yaml

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ properties:
2525
verify_keys:
2626
type: object
2727
description: |-
28-
Public keys of the homeserver for verifying digital signatures.
29-
30-
The object's key is the algorithm and version combined (``ed25519`` being the
28+
Public keys of the homeserver for verifying digital signatures.
29+
30+
The object's key is the algorithm and version combined (``ed25519`` being the
3131
algorithm and ``abc123`` being the version in the example below). Together,
3232
this forms the Key ID. The version must have characters matching the regular
3333
expression ``[a-zA-Z0-9_]``.
@@ -49,9 +49,9 @@ properties:
4949
old_verify_keys:
5050
type: object
5151
description: |-
52-
The public keys that the server used to use and when it stopped using them.
53-
54-
The object's key is the algorithm and version combined (``ed25519`` being the
52+
The public keys that the server used to use and when it stopped using them.
53+
54+
The object's key is the algorithm and version combined (``ed25519`` being the
5555
algorithm and ``0ldK3y`` being the version in the example below). Together,
5656
this forms the Key ID. The version must have characters matching the regular
5757
expression ``[a-zA-Z0-9_]``.
@@ -90,17 +90,6 @@ properties:
9090
additionalProperties:
9191
type: string
9292
name: Encoded Signature Verification Key
93-
tls_fingerprints:
94-
type: array
95-
description: Hashes of X.509 TLS certificates used by this server.
96-
items:
97-
type: object
98-
title: TLS Fingerprint
99-
properties:
100-
sha256:
101-
type: string
102-
description: The `Unpadded Base64`_ encoded fingerprint.
103-
example: "VGhpcyBpcyBoYXNoIHdoaWNoIHNob3VsZCBiZSBieXRlcw"
10493
valid_until_ts:
10594
type: integer
10695
format: int64

api/server-server/examples/server_key.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,5 @@
1616
"ed25519:auto2": "VGhpcyBzaG91bGQgYWN0dWFsbHkgYmUgYSBzaWduYXR1cmU"
1717
}
1818
},
19-
"tls_fingerprints": [{
20-
"sha256": "VGhpcyBpcyBoYXNoIHdoaWNoIHNob3VsZCBiZSBieXRlcw"
21-
}],
2219
"valid_until_ts": 1652262000000
23-
}
20+
}

api/server-server/wellknown.yaml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Copyright 2019 New Vector Ltd
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
swagger: '2.0'
15+
info:
16+
title: "Matrix Federation Server Discovery API"
17+
version: "1.0.0"
18+
host: localhost:443
19+
schemes:
20+
- https
21+
basePath: /.well-known
22+
produces:
23+
- application/json
24+
paths:
25+
"/matrix/server":
26+
get:
27+
summary: Gets information about the delegated server for server-server communication.
28+
description: |-
29+
Gets information about the delegated server for server-server communication
30+
between Matrix homeservers. Servers should follow 30x redirects, carefully
31+
avoiding redirect loops, and use normal X.509 certificate validation.
32+
responses:
33+
200:
34+
description:
35+
The delegated server information. The ``Content-Type`` for this response SHOULD
36+
be ``application/json``, however servers parsing the response should assume that
37+
the body is JSON regardless of type. Failures parsing the JSON or invalid data
38+
provided in the resulting parsed JSON must result in server discovery failure (no
39+
attempts should be made to continue finding an IP address/port number to connect
40+
to).
41+
examples:
42+
application/json: {
43+
"m.server": "delegated.example.com:1234"
44+
}
45+
schema:
46+
type: object
47+
properties:
48+
"m.server":
49+
type: string
50+
description: |-
51+
The server name to delegate server-server communciations to, with optional
52+
port. The delegated server name uses the same grammar as
53+
`server names in the appendices <../appendices.html#server-name>`_.

specification/server_server_api.rst

Lines changed: 95 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -90,35 +90,94 @@ Server discovery
9090
Resolving server names
9191
~~~~~~~~~~~~~~~~~~~~~~
9292

93-
Each matrix homeserver is identified by a server name consisting of a hostname
93+
Each Matrix homeserver is identified by a server name consisting of a hostname
9494
and an optional port, as described by the `grammar
95-
<../appendices.html#server-name>`_. Server names should be resolved to an IP
96-
address and port using the following process:
97-
98-
* If the hostname is an IP literal, then that IP address should be used,
99-
together with the given port number, or 8448 if no port is given.
100-
101-
* Otherwise, if the port is present, then an IP address is discovered by
102-
looking up an AAAA or A record for the hostname, and the specified port is
103-
used.
104-
105-
* If the hostname is not an IP literal and no port is given, the server is
106-
discovered by first looking up a ``_matrix._tcp`` SRV record for the
107-
hostname, which may give a hostname (to be looked up using AAAA or A queries)
108-
and port. If the SRV record does not exist, then the server is discovered by
109-
looking up an AAAA or A record on the hostname and taking the default
110-
fallback port number of 8448.
111-
112-
Homeservers may use SRV records to load balance requests between multiple TLS
113-
endpoints or to failover to another endpoint if an endpoint fails.
114-
115-
When making requests to servers, use the hostname of the target server in the
116-
``Host`` header, regardless of any hostname given in the SRV record. For
117-
example, if the server name is ``example.org``, and the SRV record resolves to
118-
``matrix.example.org``, the ``Host`` header in the request should be
119-
``example.org``. If an explicit port was given in the server name, it should be
120-
included in the ``Host`` header; otherwise, no port number should be given in
121-
the ``Host`` header.
95+
<../appendices.html#server-name>`_. Where applicable, a delegated server name
96+
uses the same grammar.
97+
98+
Server names are resolved to an IP address and port to connect to, and have
99+
various conditions affecting which certificates and ``Host`` headers to send.
100+
The process overall is as follows:
101+
102+
.. Note from the author: The repetitive "use this Host header and this cert"
103+
comments are intentional. The process is overall quite complicated, and
104+
explaining explicitly what requests look like at each step helps ease the
105+
understanding and ensure everyone is on the same page. Implementations
106+
are of course welcome to realize where the process can be optimized, and
107+
do so - just ensure that the result is the same!
108+
109+
1. If the hostname is an IP literal, then that IP address should be used,
110+
together with the given port number, or 8448 if no port is given. A
111+
valid TLS certificate must be provided by the target server for the
112+
IP address on all requests. Requests must be made with a ``Host``
113+
header containing the IP address, without port.
114+
115+
2. If the hostname is not an IP literal, a server is found by resolving
116+
an SRV record for ``_matrix._tcp.<hostname>``. This may result in
117+
a hostname (to be resolved using AAAA or A records) and port. Requests
118+
are made to the resolved IP address and port, using 8448 as a default
119+
port, with a ``Host`` header of ``<hostname>``. A valid TLS certificate
120+
for ``<hostname>`` must be provided by the target server on all requests.
121+
122+
3. If the SRV record yielded no results, a ``/.well-known`` request is
123+
made to the hostname (using port 443 exclusively, ignoring the port
124+
provided in the server name). The target must present a valid TLS
125+
certificate for the hostname, and a ``Host`` header containing the
126+
hostname is used to make the request. The schema of the ``/.well-known``
127+
request is later in this section. Assuming the response is valid,
128+
the ``m.server`` property is parsed as ``<delegated_server_name>[:<delegated_port>]``
129+
and processed as follows:
130+
131+
* If ``<delegated_server_name>`` is an IP literal, then that IP address
132+
should be used together with the ``<delegated_port>`` or 8448 if no
133+
port is provided. A valid TLS certificate must be provided by the
134+
target server for that IP address. Requests must be made with a
135+
``Host`` header containing the IP address, without port.
136+
137+
* If ``<delegated_server_name>`` is not an IP literal, and ``<delegated_port>``
138+
is present, an IP address is disovered by looking up an AAAA or A
139+
record for ``<delegated_server_name>``. The resulting IP address is
140+
used, alongside the ``<delegated_port>``, to make requests with a
141+
``Host`` header of ``<delegated_server_name>``. A valid TLS certificate
142+
must be provided by the target server for ``<delegated_server_name>``.
143+
144+
* If ``<delegated_server_name>`` is not an IP literal and no
145+
``<delegated_port>`` is present, an SRV record is looked up for
146+
``_matrix._tcp.<delegated_server_name>``. This may result in another
147+
hostname (to be resolved using AAAA or A records) and port. Requests
148+
should be made to the resolved IP address and port with a ``Host``
149+
header containing the ``<delegated_server_name>``. Additionally, a
150+
valid TLS certificate must be provided by the target server for the
151+
``<delegated_server_name>``.
152+
153+
* If no SRV record is found, an IP address is resolved using AAAA
154+
or A records. Requests are then made to the resolve IP address
155+
and a port of 8448, using a ``Host`` header of ``<delegated_server_name>``.
156+
A valid TLS certificate for ``<delegated_server_name>`` must be
157+
provided by the target server.
158+
159+
4. If the `/.well-known` request was invalid or returned an error response,
160+
and the SRV record was not found, an IP address is resolved using AAAA
161+
and A records. Requests are made to the resolved IP address using port
162+
8448 and a ``Host`` header containing the ``<hostname>``. A valid TLS
163+
certificate for ``<hostname>`` must be provided by the target server
164+
on all requests.
165+
166+
167+
The TLS certificate provided by the target server must be present on all
168+
requests made to the server. The TLS certificate must be signed by a known
169+
Certificate Authority. Servers are ultimately responsible for determining
170+
the trusted Certificate Authorities, however are strongly encouraged to
171+
rely on the operating system's judgement. Servers can offer administrators
172+
a means to override the trusted authorities list. Servers can additionally
173+
skip the certificate validation for a given whitelist of domains or netmasks
174+
for the purposes of testing or in networks where verification is done
175+
elsewhere, such as with ``.onion`` addresses.
176+
177+
Servers are encouraged to make use of the
178+
`Certificate Transparency <https://www.certificate-transparency.org/>`_ project.
179+
180+
{{wellknown_ss_http_api}}
122181

123182
Server implementation
124183
~~~~~~~~~~~~~~~~~~~~~~
@@ -130,9 +189,16 @@ Retrieving server keys
130189

131190
.. NOTE::
132191
There was once a "version 1" of the key exchange. It has been removed from the
133-
specification due to lack of significance. It may be reviewed `here
192+
specification due to lack of significance. It may be reviewed `from the historical draft
134193
<https://github.com/matrix-org/matrix-doc/blob/51faf8ed2e4a63d4cfd6d23183698ed169956cc0/specification/server_server_api.rst#232version-1>`_.
135194

195+
.. NOTE::
196+
Older drafts of this specification made use of a different style of key verification,
197+
however for reasons discussed in `MSC1711 <https://github.com/matrix-org/matrix-doc/pull/1711>`_,
198+
the approach was removed from the initial version of the specification. The older
199+
draft may be reviewed `thanks to web.archive.org
200+
<https://web.archive.org/web/20181019044236/https://matrix.org/docs/spec/server_server/unstable.html>`_.
201+
136202
Each homeserver publishes its public keys under ``/_matrix/key/v2/server/{keyId}``.
137203
Homeservers query for keys by either getting ``/_matrix/key/v2/server/{keyId}``
138204
directly or by querying an intermediate notary server using a

0 commit comments

Comments
 (0)