From ef41b5c2bf5acf349493279ce19851de7542d04e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 22 Aug 2018 12:48:37 -0600 Subject: [PATCH 1/7] Server ACLs Implements the proposal for https://github.com/matrix-org/matrix-doc/issues/1383 --- event-schemas/examples/m.room.server_acl | 14 +++++ event-schemas/schema/m.room.server_acl | 69 ++++++++++++++++++++++++ specification/modules/server_acls.rst | 66 +++++++++++++++++++++++ specification/server_server_api.rst | 26 +++++++++ specification/targets.yaml | 1 + 5 files changed, 176 insertions(+) create mode 100644 event-schemas/examples/m.room.server_acl create mode 100644 event-schemas/schema/m.room.server_acl create mode 100644 specification/modules/server_acls.rst diff --git a/event-schemas/examples/m.room.server_acl b/event-schemas/examples/m.room.server_acl new file mode 100644 index 00000000..86da2093 --- /dev/null +++ b/event-schemas/examples/m.room.server_acl @@ -0,0 +1,14 @@ +{ + "age": 242352, + "content": { + "allow_ip_literals": false, + "allow": ["*"], + "deny": ["*.evil.com", "evil.com"] + }, + "state_key": "", + "origin_server_ts": 1431961217939, + "event_id": "$WLGTSEFSEF:localhost", + "type": "m.room.server_acl", + "room_id": "!Cuyf34gef24t:localhost", + "sender": "@example:localhost" +} diff --git a/event-schemas/schema/m.room.server_acl b/event-schemas/schema/m.room.server_acl new file mode 100644 index 00000000..ed64038c --- /dev/null +++ b/event-schemas/schema/m.room.server_acl @@ -0,0 +1,69 @@ +--- +title: Server ACL +description: |- + An event to indicate which servers are permitted to participate in the + room. Server ACLs may allow or deny groups of hosts. All servers participating + in the room, including those that are denied, are expected to uphold the + server ACL. Servers that do not uphold the ACLs are recommended to be + added to the denied hosts list. + + The ``allow`` and ``deny`` lists are lists of globs supporting ``?`` and ``*`` + as wildcards. When comparing against the server ACLs, the suspect server's port + number must not be considered. Therefore ``evil.com``, ``evil.com:8448``, and + ``evil.com:1234`` would all match rules that apply to ``evil.com``, for example. + + The ACLs are applied to servers when they make requests, and are applied in + the following order: + + 1. If there is no ``m.room.server_acl`` event in the room state, allow. + #. If the server name is an IP address (v4 or v6) literal, and ``allow_ip_literals`` + is present and ``false``, deny. + #. If the server name matches an entry in the ``deny`` list, deny. + #. If the server name matches an entry in the ``allow`` list, allow. + #. Otherwise, deny. + + .. WARNING:: + Failing to provide an ``allow`` rule of some kind will prevent **all** + servers from participating in the room, including the sender. This renders + the room unusable. A common allow rule is ``[ "*" ]`` which would still + permit the use of the ``deny`` list without losing the room. +allOf: + - $ref: core-event-schema/state_event.yaml +type: object +properties: + content: + properties: + allow_ip_literals: + type: boolean + description: |- + True to allow server names that are IP address literals. False to + deny. Defaults to true if missing or otherwise not a boolean. + allow: + type: array + description: |- + The server names to allow in the room, excluding any port information. + Wildcards may be used to cover a wider range of hosts, where ``*`` + matches zero or more characters and ``?`` matches one or more characters. + + **This defaults to an empty list when not provided, effectively disallowing + every server.** + items: + type: string + deny: + type: array + description: |- + The server names to disallow in the room, excluding any port information. + Wildcards may be used to cover a wider range of hosts, where ``*`` + matches zero or more characters and ``?`` matches one or more characters. + + This defaults to an empty list when not provided. + items: + type: string + type: object + state_key: + description: A zero-length string. + pattern: '^$' + type: string + type: + enum: ['m.room.server_acl'] + type: enum diff --git a/specification/modules/server_acls.rst b/specification/modules/server_acls.rst new file mode 100644 index 00000000..72892fce --- /dev/null +++ b/specification/modules/server_acls.rst @@ -0,0 +1,66 @@ +.. Copyright 2018 New Vector Ltd +.. +.. Licensed under the Apache License, Version 2.0 (the "License"); +.. you may not use this file except in compliance with the License. +.. You may obtain a copy of the License at +.. +.. http://www.apache.org/licenses/LICENSE-2.0 +.. +.. Unless required by applicable law or agreed to in writing, software +.. distributed under the License is distributed on an "AS IS" BASIS, +.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +.. See the License for the specific language governing permissions and +.. limitations under the License. + +Server Access Control Lists (ACLs) for rooms +============================================ + +.. _module:server-acls: + +In some scenarios room operators may wish to prevent a malicous or untrusted +server from participating in their room. Sending an `m.room.server_acl`_ state +event into a room is an effective way to prevent the server from participating +in the room at the federation level. + +Server ACLs can also be used to make rooms only federate with a limited set of +servers, or retroactively make the room no longer federate with any other server, +similar to setting the ``m.federate`` value on the `m.room.create`_ event. + +{{m_room_server_acl_event}} + +.. Note:: + Port numbers are not supported because it is unclear to parsers whether a + port number should be matched or an IP address literal. + +.. Note:: + CIDR notation is not supported for IP addresses because Matrix does not + encourage the use of IPs for identifying servers. Instead, a blanket + ``allow_ip_literals`` is provided to cover banning them. + +Client behaviour +---------------- +Clients are not expected to perform any additional duties beyond sending the +event. Clients should describe changes to the server ACLs to the user in the +user interface, such as in the timeline. + +Clients may wish to kick affected users from the room prior to denying a server +access to the room to help prevent those servers from participating. + +Server behaviour +---------------- +Servers MUST prevent blacklisted servers from sending events or participating +in the room when an `m.room.server_acl`_ event is present in the room state. +Which APIs are specifically affected are described in the Server-Server API +specification. + +Servers should still send events to denied servers if they are still residents +of the room. + + +Security considerations +----------------------- +Server ACLs are only effective if every server in the room honours them. Servers +that do not honour the ACLs may still permit events sent by denied servers into +the room, leaking them to other servers in the room. To effectively enforce an +ACL in a room, the servers that do not honour the ACLs should be denied in the +room as well. \ No newline at end of file diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index dbde8b10..439b35f9 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -929,6 +929,32 @@ described in the `Client-Server API`_, being sure to use the ``allow_remote`` parameter (set to ``false``). +Server Access Control Lists (ACLs) +---------------------------------- + +Server ACLs and their purpose are described in the `Server ACLs`_ section of the +Client-Server API. + +When a remote server makes a request, it MUST be verified to be allowed by the +server ACLs. If the server is denied access to a room, the receiving server +MUST reply with a 403 HTTP status code and an ``errcode`` of ``M_FORBIDDEN``. + +The following endpoint prefixes MUST be protected: + +* ``/_matrix/federation/v1/send`` (on a per-PDU basis) +* ``/_matrix/federation/v1/make_join`` +* ``/_matrix/federation/v1/make_leave`` +* ``/_matrix/federation/v1/send_join`` +* ``/_matrix/federation/v1/send_leave`` +* ``/_matrix/federation/v1/invite`` +* ``/_matrix/federation/v1/state`` +* ``/_matrix/federation/v1/state_ids`` +* ``/_matrix/federation/v1/backfill`` +* ``/_matrix/federation/v1/event_auth`` +* ``/_matrix/federation/v1/query_auth`` +* ``/_matrix/federation/v1/get_missing_events`` + + Signing Events -------------- diff --git a/specification/targets.yaml b/specification/targets.yaml index 5480bbc5..acf4b6ac 100644 --- a/specification/targets.yaml +++ b/specification/targets.yaml @@ -67,6 +67,7 @@ groups: # reusable blobs of files when prefixed with 'group:' - modules/report_content.rst - modules/third_party_networks.rst - modules/openid.rst + - modules/server_acls.rst title_styles: ["=", "-", "~", "+", "^", "`", "@", ":"] From a95d7092eb3bf4e02cbd1aabc31548462d6376c2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 22 Aug 2018 15:27:48 -0600 Subject: [PATCH 2/7] Changelog --- changelogs/client_server/newsfragments/1550.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/1550.feature diff --git a/changelogs/client_server/newsfragments/1550.feature b/changelogs/client_server/newsfragments/1550.feature new file mode 100644 index 00000000..f04fa9ae --- /dev/null +++ b/changelogs/client_server/newsfragments/1550.feature @@ -0,0 +1 @@ +Add server ACLs as an option for controlling federation in a room. From be2e0fc9d416348b411c21a8fc394387a1194ebc Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 Aug 2018 16:12:42 -0600 Subject: [PATCH 3/7] Clarify that ACLs are required to manually deny unsupported hosts --- event-schemas/schema/m.room.server_acl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/event-schemas/schema/m.room.server_acl b/event-schemas/schema/m.room.server_acl index ed64038c..29a91f4b 100644 --- a/event-schemas/schema/m.room.server_acl +++ b/event-schemas/schema/m.room.server_acl @@ -4,8 +4,8 @@ description: |- An event to indicate which servers are permitted to participate in the room. Server ACLs may allow or deny groups of hosts. All servers participating in the room, including those that are denied, are expected to uphold the - server ACL. Servers that do not uphold the ACLs are recommended to be - added to the denied hosts list. + server ACL. Servers that do not uphold the ACLs MUST be added to the denied hosts + list in order for the ACLs to remain effective. The ``allow`` and ``deny`` lists are lists of globs supporting ``?`` and ``*`` as wildcards. When comparing against the server ACLs, the suspect server's port @@ -27,6 +27,14 @@ description: |- servers from participating in the room, including the sender. This renders the room unusable. A common allow rule is ``[ "*" ]`` which would still permit the use of the ``deny`` list without losing the room. + + .. WARNING:: + Servers that do not uphold the ACLs MUST be manually appended to the denied hosts + list. To accomplish this, events should have their ``prev_events`` inspected for + denied hosts, therefore detecting servers which are not upholding the ACLs. Server + versions can also be used to detect hosts that will not uphold the ACLs, although + this is less effective. Server ACLs were added in Synapse v0.32.0 although other + server implementations and versions exist in the world. allOf: - $ref: core-event-schema/state_event.yaml type: object From 82be6077ffc941bfce0a26fb4f631618046ea8de Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 Aug 2018 16:13:42 -0600 Subject: [PATCH 4/7] Add a note that ACLs don't operate at the auth level; Fix glob definition --- event-schemas/schema/m.room.server_acl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/event-schemas/schema/m.room.server_acl b/event-schemas/schema/m.room.server_acl index 29a91f4b..9e7ccc3b 100644 --- a/event-schemas/schema/m.room.server_acl +++ b/event-schemas/schema/m.room.server_acl @@ -22,6 +22,11 @@ description: |- #. If the server name matches an entry in the ``allow`` list, allow. #. Otherwise, deny. + .. Note:: + Server ACLs do not restrict the events relative to the room DAG via authorisation + rules, but instead act purely at the network layer to determine which servers are + allowed to connect and interact with a given room. + .. WARNING:: Failing to provide an ``allow`` rule of some kind will prevent **all** servers from participating in the room, including the sender. This renders @@ -51,7 +56,7 @@ properties: description: |- The server names to allow in the room, excluding any port information. Wildcards may be used to cover a wider range of hosts, where ``*`` - matches zero or more characters and ``?`` matches one or more characters. + matches zero or more characters and ``?`` matches exactly one character. **This defaults to an empty list when not provided, effectively disallowing every server.** @@ -62,7 +67,7 @@ properties: description: |- The server names to disallow in the room, excluding any port information. Wildcards may be used to cover a wider range of hosts, where ``*`` - matches zero or more characters and ``?`` matches one or more characters. + matches zero or more characters and ``?`` matches exactly one character. This defaults to an empty list when not provided. items: From 76afef79f8f09809b8dafecc37b7804f52d610e7 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 Aug 2018 16:14:37 -0600 Subject: [PATCH 5/7] Clarify the rationale and motive for blanket IP banning and port exclusion --- event-schemas/schema/m.room.server_acl | 4 ++++ specification/modules/server_acls.rst | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/event-schemas/schema/m.room.server_acl b/event-schemas/schema/m.room.server_acl index 9e7ccc3b..317031cd 100644 --- a/event-schemas/schema/m.room.server_acl +++ b/event-schemas/schema/m.room.server_acl @@ -51,6 +51,10 @@ properties: description: |- True to allow server names that are IP address literals. False to deny. Defaults to true if missing or otherwise not a boolean. + + This is strongly recommended to be set to ``false`` as servers running + with IP literal names are strongly discouraged in order to require + legitimate homeservers to be backed by a valid registered domain name. allow: type: array description: |- diff --git a/specification/modules/server_acls.rst b/specification/modules/server_acls.rst index 72892fce..f26b8c6b 100644 --- a/specification/modules/server_acls.rst +++ b/specification/modules/server_acls.rst @@ -17,7 +17,7 @@ Server Access Control Lists (ACLs) for rooms .. _module:server-acls: -In some scenarios room operators may wish to prevent a malicous or untrusted +In some scenarios room operators may wish to prevent a malicious or untrusted server from participating in their room. Sending an `m.room.server_acl`_ state event into a room is an effective way to prevent the server from participating in the room at the federation level. @@ -30,7 +30,10 @@ similar to setting the ``m.federate`` value on the `m.room.create`_ event. .. Note:: Port numbers are not supported because it is unclear to parsers whether a - port number should be matched or an IP address literal. + port number should be matched or an IP address literal. Additionally, it + is unlikely that one would trust a server running on a particular domain's + port but not a different port, especially considering the server host can + easily change ports. .. Note:: CIDR notation is not supported for IP addresses because Matrix does not From d7397ccd563fb886c48944c1f3869e0d617aadc8 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 27 Aug 2018 16:21:10 -0600 Subject: [PATCH 6/7] Provide additional rationale for kicking users when they are ACLd --- specification/modules/server_acls.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/specification/modules/server_acls.rst b/specification/modules/server_acls.rst index f26b8c6b..2b2d8f35 100644 --- a/specification/modules/server_acls.rst +++ b/specification/modules/server_acls.rst @@ -47,7 +47,8 @@ event. Clients should describe changes to the server ACLs to the user in the user interface, such as in the timeline. Clients may wish to kick affected users from the room prior to denying a server -access to the room to help prevent those servers from participating. +access to the room to help prevent those servers from participating and to +provide feedback to the users that they have been excluded from the room. Server behaviour ---------------- From 313e6de48bb99afefa8adb18d6dd097a4d88a849 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 27 Aug 2018 23:36:48 +0100 Subject: [PATCH 7/7] tweak wording to spell out that handling legacy/noncompliant servers. --- event-schemas/schema/m.room.server_acl | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/event-schemas/schema/m.room.server_acl b/event-schemas/schema/m.room.server_acl index 317031cd..c6adaf05 100644 --- a/event-schemas/schema/m.room.server_acl +++ b/event-schemas/schema/m.room.server_acl @@ -34,12 +34,14 @@ description: |- permit the use of the ``deny`` list without losing the room. .. WARNING:: - Servers that do not uphold the ACLs MUST be manually appended to the denied hosts - list. To accomplish this, events should have their ``prev_events`` inspected for - denied hosts, therefore detecting servers which are not upholding the ACLs. Server - versions can also be used to detect hosts that will not uphold the ACLs, although - this is less effective. Server ACLs were added in Synapse v0.32.0 although other - server implementations and versions exist in the world. + All compliant servers must implement server ACLs. However, legacy or noncompliant + servers exist which do not uphold ACLs, and these MUST be manually appended to + the denied hosts list when setting an ACL to prevent them from leaking events from + banned servers into a room. Currently, the only way to determine noncompliant hosts is + to check the ``prev_events`` of leaked events, therefore detecting servers which + are not upholding the ACLs. Server versions can also be used to try to detect hosts that + will not uphold the ACLs, although this is not comprehensive. Server ACLs were added + in Synapse v0.32.0, although other server implementations and versions exist in the world. allOf: - $ref: core-event-schema/state_event.yaml type: object