summary refs log tree commit diff
path: root/latest/print.html
diff options
context:
space:
mode:
authoranoadragon453 <anoadragon453@users.noreply.github.com>2022-01-18 11:46:24 +0000
committeranoadragon453 <anoadragon453@users.noreply.github.com>2022-01-18 11:46:24 +0000
commitcd28aadaff705c909f227c92f23b92c9639476f5 (patch)
tree2c754c90f9c37736229c162acc6da0c90c2f72a9 /latest/print.html
parentdeploy: cefd4b87a32a28fddc36a640a14ba3bdb50cb0c6 (diff)
downloadsynapse-cd28aadaff705c909f227c92f23b92c9639476f5.tar.xz
deploy: 4ec0a309cf8608df1d29746af76f91b8d35e5de3
Diffstat (limited to 'latest/print.html')
-rw-r--r--latest/print.html301
1 files changed, 268 insertions, 33 deletions
diff --git a/latest/print.html b/latest/print.html
index f63feb2351..755e8f79df 100644
--- a/latest/print.html
+++ b/latest/print.html
@@ -101,7 +101,7 @@
 
         <nav id="sidebar" class="sidebar" aria-label="Table of contents">
             <div class="sidebar-scrollbox">
-                <ol class="chapter"><li class="chapter-item expanded affix "><li class="part-title">Introduction</li><li class="chapter-item expanded "><a href="welcome_and_overview.html">Welcome and Overview</a></li><li class="chapter-item expanded affix "><li class="part-title">Setup</li><li class="chapter-item expanded "><a href="setup/installation.html">Installation</a></li><li class="chapter-item expanded "><a href="postgres.html">Using Postgres</a></li><li class="chapter-item expanded "><a href="reverse_proxy.html">Configuring a Reverse Proxy</a></li><li class="chapter-item expanded "><a href="setup/forward_proxy.html">Configuring a Forward/Outbound Proxy</a></li><li class="chapter-item expanded "><a href="turn-howto.html">Configuring a Turn Server</a></li><li class="chapter-item expanded "><a href="delegate.html">Delegation</a></li><li class="chapter-item expanded affix "><li class="part-title">Upgrading</li><li class="chapter-item expanded "><a href="upgrade.html">Upgrading between Synapse Versions</a></li><li class="chapter-item expanded "><a href="MSC1711_certificates_FAQ.html">Upgrading from pre-Synapse 1.0</a></li><li class="chapter-item expanded affix "><li class="part-title">Usage</li><li class="chapter-item expanded "><a href="federate.html">Federation</a></li><li class="chapter-item expanded "><a href="usage/configuration/index.html">Configuration</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/configuration/homeserver_sample_config.html">Homeserver Sample Config File</a></li><li class="chapter-item expanded "><a href="usage/configuration/logging_sample_config.html">Logging Sample Config File</a></li><li class="chapter-item expanded "><a href="structured_logging.html">Structured Logging</a></li><li class="chapter-item expanded "><a href="templates.html">Templates</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/index.html">User Authentication</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/single_sign_on/index.html">Single-Sign On</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="openid.html">OpenID Connect</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/single_sign_on/saml.html">SAML</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/single_sign_on/cas.html">CAS</a></li><li class="chapter-item expanded "><a href="sso_mapping_providers.html">SSO Mapping Providers</a></li></ol></li><li class="chapter-item expanded "><a href="password_auth_providers.html">Password Auth Providers</a></li><li class="chapter-item expanded "><a href="jwt.html">JSON Web Tokens</a></li></ol></li><li class="chapter-item expanded "><a href="CAPTCHA_SETUP.html">Registration Captcha</a></li><li class="chapter-item expanded "><a href="application_services.html">Application Services</a></li><li class="chapter-item expanded "><a href="server_notices.html">Server Notices</a></li><li class="chapter-item expanded "><a href="consent_tracking.html">Consent Tracking</a></li><li class="chapter-item expanded "><a href="development/url_previews.html">URL Previews</a></li><li class="chapter-item expanded "><a href="user_directory.html">User Directory</a></li><li class="chapter-item expanded "><a href="message_retention_policies.html">Message Retention Policies</a></li><li class="chapter-item expanded "><a href="modules/index.html">Pluggable Modules</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="modules/writing_a_module.html">Writing a module</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="modules/spam_checker_callbacks.html">Spam checker callbacks</a></li><li class="chapter-item expanded "><a href="modules/third_party_rules_callbacks.html">Third-party rules callbacks</a></li><li class="chapter-item expanded "><a href="modules/presence_router_callbacks.html">Presence router callbacks</a></li><li class="chapter-item expanded "><a href="modules/account_validity_callbacks.html">Account validity callbacks</a></li><li class="chapter-item expanded "><a href="modules/password_auth_provider_callbacks.html">Password auth provider callbacks</a></li><li class="chapter-item expanded "><a href="modules/background_update_controller_callbacks.html">Background update controller callbacks</a></li><li class="chapter-item expanded "><a href="modules/porting_legacy_module.html">Porting a legacy module to the new interface</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="workers.html">Workers</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="synctl_workers.html">Using synctl with Workers</a></li><li class="chapter-item expanded "><a href="systemd-with-workers/index.html">Systemd</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="usage/administration/index.html">Administration</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/administration/admin_api/index.html">Admin API</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="admin_api/account_validity.html">Account Validity</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_api/background_updates.html">Background Updates</a></li><li class="chapter-item expanded "><a href="admin_api/delete_group.html">Delete Group</a></li><li class="chapter-item expanded "><a href="admin_api/event_reports.html">Event Reports</a></li><li class="chapter-item expanded "><a href="admin_api/media_admin_api.html">Media</a></li><li class="chapter-item expanded "><a href="admin_api/purge_history_api.html">Purge History</a></li><li class="chapter-item expanded "><a href="admin_api/register_api.html">Register Users</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_api/registration_tokens.html">Registration Tokens</a></li><li class="chapter-item expanded "><a href="admin_api/room_membership.html">Manipulate Room Membership</a></li><li class="chapter-item expanded "><a href="admin_api/rooms.html">Rooms</a></li><li class="chapter-item expanded "><a href="admin_api/server_notices.html">Server Notices</a></li><li class="chapter-item expanded "><a href="admin_api/statistics.html">Statistics</a></li><li class="chapter-item expanded "><a href="admin_api/user_admin_api.html">Users</a></li><li class="chapter-item expanded "><a href="admin_api/version_api.html">Server Version</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_api/federation.html">Federation</a></li></ol></li><li class="chapter-item expanded "><a href="manhole.html">Manhole</a></li><li class="chapter-item expanded "><a href="metrics-howto.html">Monitoring</a></li><li class="chapter-item expanded "><a href="usage/administration/understanding_synapse_through_grafana_graphs.html">Understanding Synapse Through Grafana Graphs</a></li><li class="chapter-item expanded "><a href="usage/administration/useful_sql_for_admins.html">Useful SQL for Admins</a></li><li class="chapter-item expanded "><a href="usage/administration/database_maintenance_tools.html">Database Maintenance Tools</a></li><li class="chapter-item expanded "><a href="usage/administration/state_groups.html">State Groups</a></li><li class="chapter-item expanded "><a href="usage/administration/request_log.html">Request log format</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_faq.html">Admin FAQ</a></li><li class="chapter-item expanded "><div>Scripts</div></li></ol></li><li class="chapter-item expanded "><li class="part-title">Development</li><li class="chapter-item expanded "><a href="development/contributing_guide.html">Contributing Guide</a></li><li class="chapter-item expanded "><a href="code_style.html">Code Style</a></li><li class="chapter-item expanded "><a href="development/git.html">Git Usage</a></li><li class="chapter-item expanded "><div>Testing</div></li><li class="chapter-item expanded "><a href="opentracing.html">OpenTracing</a></li><li class="chapter-item expanded "><a href="development/database_schema.html">Database Schemas</a></li><li class="chapter-item expanded "><a href="development/experimental_features.html">Experimental features</a></li><li class="chapter-item expanded "><div>Synapse Architecture</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="log_contexts.html">Log Contexts</a></li><li class="chapter-item expanded "><a href="replication.html">Replication</a></li><li class="chapter-item expanded "><a href="tcp_replication.html">TCP Replication</a></li></ol></li><li class="chapter-item expanded "><a href="development/internal_documentation/index.html">Internal Documentation</a></li><li><ol class="section"><li class="chapter-item expanded "><div>Single Sign-On</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="development/saml.html">SAML</a></li><li class="chapter-item expanded "><a href="development/cas.html">CAS</a></li></ol></li><li class="chapter-item expanded "><a href="development/room-dag-concepts.html">Room DAG concepts</a></li><li class="chapter-item expanded "><div>State Resolution</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="auth_chain_difference_algorithm.html">The Auth Chain Difference Algorithm</a></li></ol></li><li class="chapter-item expanded "><a href="media_repository.html">Media Repository</a></li><li class="chapter-item expanded "><a href="room_and_user_statistics.html">Room and User Statistics</a></li></ol></li><li class="chapter-item expanded "><div>Scripts</div></li><li class="chapter-item expanded affix "><li class="part-title">Other</li><li class="chapter-item expanded "><a href="deprecation_policy.html">Dependency Deprecation Policy</a></li><li class="chapter-item expanded "><a href="other/running_synapse_on_single_board_computers.html">Running Synapse on a Single-Board Computer</a></li></ol>
+                <ol class="chapter"><li class="chapter-item expanded affix "><li class="part-title">Introduction</li><li class="chapter-item expanded "><a href="welcome_and_overview.html">Welcome and Overview</a></li><li class="chapter-item expanded affix "><li class="part-title">Setup</li><li class="chapter-item expanded "><a href="setup/installation.html">Installation</a></li><li class="chapter-item expanded "><a href="postgres.html">Using Postgres</a></li><li class="chapter-item expanded "><a href="reverse_proxy.html">Configuring a Reverse Proxy</a></li><li class="chapter-item expanded "><a href="setup/forward_proxy.html">Configuring a Forward/Outbound Proxy</a></li><li class="chapter-item expanded "><a href="turn-howto.html">Configuring a Turn Server</a></li><li class="chapter-item expanded "><a href="delegate.html">Delegation</a></li><li class="chapter-item expanded affix "><li class="part-title">Upgrading</li><li class="chapter-item expanded "><a href="upgrade.html">Upgrading between Synapse Versions</a></li><li class="chapter-item expanded "><a href="MSC1711_certificates_FAQ.html">Upgrading from pre-Synapse 1.0</a></li><li class="chapter-item expanded affix "><li class="part-title">Usage</li><li class="chapter-item expanded "><a href="federate.html">Federation</a></li><li class="chapter-item expanded "><a href="usage/configuration/index.html">Configuration</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/configuration/homeserver_sample_config.html">Homeserver Sample Config File</a></li><li class="chapter-item expanded "><a href="usage/configuration/logging_sample_config.html">Logging Sample Config File</a></li><li class="chapter-item expanded "><a href="structured_logging.html">Structured Logging</a></li><li class="chapter-item expanded "><a href="templates.html">Templates</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/index.html">User Authentication</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/single_sign_on/index.html">Single-Sign On</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="openid.html">OpenID Connect</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/single_sign_on/saml.html">SAML</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/single_sign_on/cas.html">CAS</a></li><li class="chapter-item expanded "><a href="sso_mapping_providers.html">SSO Mapping Providers</a></li></ol></li><li class="chapter-item expanded "><a href="password_auth_providers.html">Password Auth Providers</a></li><li class="chapter-item expanded "><a href="jwt.html">JSON Web Tokens</a></li><li class="chapter-item expanded "><a href="usage/configuration/user_authentication/refresh_tokens.html">Refresh Tokens</a></li></ol></li><li class="chapter-item expanded "><a href="CAPTCHA_SETUP.html">Registration Captcha</a></li><li class="chapter-item expanded "><a href="application_services.html">Application Services</a></li><li class="chapter-item expanded "><a href="server_notices.html">Server Notices</a></li><li class="chapter-item expanded "><a href="consent_tracking.html">Consent Tracking</a></li><li class="chapter-item expanded "><a href="development/url_previews.html">URL Previews</a></li><li class="chapter-item expanded "><a href="user_directory.html">User Directory</a></li><li class="chapter-item expanded "><a href="message_retention_policies.html">Message Retention Policies</a></li><li class="chapter-item expanded "><a href="modules/index.html">Pluggable Modules</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="modules/writing_a_module.html">Writing a module</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="modules/spam_checker_callbacks.html">Spam checker callbacks</a></li><li class="chapter-item expanded "><a href="modules/third_party_rules_callbacks.html">Third-party rules callbacks</a></li><li class="chapter-item expanded "><a href="modules/presence_router_callbacks.html">Presence router callbacks</a></li><li class="chapter-item expanded "><a href="modules/account_validity_callbacks.html">Account validity callbacks</a></li><li class="chapter-item expanded "><a href="modules/password_auth_provider_callbacks.html">Password auth provider callbacks</a></li><li class="chapter-item expanded "><a href="modules/background_update_controller_callbacks.html">Background update controller callbacks</a></li><li class="chapter-item expanded "><a href="modules/porting_legacy_module.html">Porting a legacy module to the new interface</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="workers.html">Workers</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="synctl_workers.html">Using synctl with Workers</a></li><li class="chapter-item expanded "><a href="systemd-with-workers/index.html">Systemd</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="usage/administration/index.html">Administration</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="usage/administration/admin_api/index.html">Admin API</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="admin_api/account_validity.html">Account Validity</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_api/background_updates.html">Background Updates</a></li><li class="chapter-item expanded "><a href="admin_api/delete_group.html">Delete Group</a></li><li class="chapter-item expanded "><a href="admin_api/event_reports.html">Event Reports</a></li><li class="chapter-item expanded "><a href="admin_api/media_admin_api.html">Media</a></li><li class="chapter-item expanded "><a href="admin_api/purge_history_api.html">Purge History</a></li><li class="chapter-item expanded "><a href="admin_api/register_api.html">Register Users</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_api/registration_tokens.html">Registration Tokens</a></li><li class="chapter-item expanded "><a href="admin_api/room_membership.html">Manipulate Room Membership</a></li><li class="chapter-item expanded "><a href="admin_api/rooms.html">Rooms</a></li><li class="chapter-item expanded "><a href="admin_api/server_notices.html">Server Notices</a></li><li class="chapter-item expanded "><a href="admin_api/statistics.html">Statistics</a></li><li class="chapter-item expanded "><a href="admin_api/user_admin_api.html">Users</a></li><li class="chapter-item expanded "><a href="admin_api/version_api.html">Server Version</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_api/federation.html">Federation</a></li></ol></li><li class="chapter-item expanded "><a href="manhole.html">Manhole</a></li><li class="chapter-item expanded "><a href="metrics-howto.html">Monitoring</a></li><li class="chapter-item expanded "><a href="usage/administration/understanding_synapse_through_grafana_graphs.html">Understanding Synapse Through Grafana Graphs</a></li><li class="chapter-item expanded "><a href="usage/administration/useful_sql_for_admins.html">Useful SQL for Admins</a></li><li class="chapter-item expanded "><a href="usage/administration/database_maintenance_tools.html">Database Maintenance Tools</a></li><li class="chapter-item expanded "><a href="usage/administration/state_groups.html">State Groups</a></li><li class="chapter-item expanded "><a href="usage/administration/request_log.html">Request log format</a></li><li class="chapter-item expanded "><a href="usage/administration/admin_faq.html">Admin FAQ</a></li><li class="chapter-item expanded "><div>Scripts</div></li></ol></li><li class="chapter-item expanded "><li class="part-title">Development</li><li class="chapter-item expanded "><a href="development/contributing_guide.html">Contributing Guide</a></li><li class="chapter-item expanded "><a href="code_style.html">Code Style</a></li><li class="chapter-item expanded "><a href="development/git.html">Git Usage</a></li><li class="chapter-item expanded "><div>Testing</div></li><li class="chapter-item expanded "><a href="opentracing.html">OpenTracing</a></li><li class="chapter-item expanded "><a href="development/database_schema.html">Database Schemas</a></li><li class="chapter-item expanded "><a href="development/experimental_features.html">Experimental features</a></li><li class="chapter-item expanded "><div>Synapse Architecture</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="log_contexts.html">Log Contexts</a></li><li class="chapter-item expanded "><a href="replication.html">Replication</a></li><li class="chapter-item expanded "><a href="tcp_replication.html">TCP Replication</a></li></ol></li><li class="chapter-item expanded "><a href="development/internal_documentation/index.html">Internal Documentation</a></li><li><ol class="section"><li class="chapter-item expanded "><div>Single Sign-On</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="development/saml.html">SAML</a></li><li class="chapter-item expanded "><a href="development/cas.html">CAS</a></li></ol></li><li class="chapter-item expanded "><a href="development/room-dag-concepts.html">Room DAG concepts</a></li><li class="chapter-item expanded "><div>State Resolution</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="auth_chain_difference_algorithm.html">The Auth Chain Difference Algorithm</a></li></ol></li><li class="chapter-item expanded "><a href="media_repository.html">Media Repository</a></li><li class="chapter-item expanded "><a href="room_and_user_statistics.html">Room and User Statistics</a></li></ol></li><li class="chapter-item expanded "><div>Scripts</div></li><li class="chapter-item expanded affix "><li class="part-title">Other</li><li class="chapter-item expanded "><a href="deprecation_policy.html">Dependency Deprecation Policy</a></li><li class="chapter-item expanded "><a href="other/running_synapse_on_single_board_computers.html">Running Synapse on a Single-Board Computer</a></li></ol>
             </div>
             <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
         </nav>
@@ -376,7 +376,7 @@ xbps-install -S synapse
 <p>Synapse can be installed via FreeBSD Ports or Packages contributed by Brendan Molloy from:</p>
 <ul>
 <li>Ports: <code>cd /usr/ports/net-im/py-matrix-synapse &amp;&amp; make install clean</code></li>
-<li>Packages: <code>pkg install py37-matrix-synapse</code></li>
+<li>Packages: <code>pkg install py38-matrix-synapse</code></li>
 </ul>
 <h4 id="openbsd"><a class="header" href="#openbsd">OpenBSD</a></h4>
 <p>As of OpenBSD 6.7 Synapse is available as a pre-compiled binary. The filesystem
@@ -669,7 +669,7 @@ failing, e.g.:</p>
 <p>If you have any other problems, feel free to ask in
 <a href="https://matrix.to/#/#synapse:matrix.org">#synapse:matrix.org</a>.</p>
 <div id="chapter_begin" style="break-before: page; page-break-before: always;"></div><h1 id="using-postgres"><a class="header" href="#using-postgres">Using Postgres</a></h1>
-<p>Synapse supports PostgreSQL versions 9.6 or later.</p>
+<p>Synapse supports PostgreSQL versions 10 or later.</p>
 <h2 id="install-postgres-client-libraries"><a class="header" href="#install-postgres-client-libraries">Install postgres client libraries</a></h2>
 <p>Synapse will require the python postgres client library in order to
 connect to a postgres database.</p>
@@ -918,7 +918,7 @@ to proxied traffic.)</p>
 
     server_name matrix.example.com;
 
-    location ~* ^(\/_matrix|\/_synapse\/client) {
+    location ~ ^(/_matrix|/_synapse/client) {
         # note: do not add a path (even a single /) after the port in `proxy_pass`,
         # otherwise nginx will canonicalise the URI and cause signature verification
         # errors.
@@ -1180,8 +1180,8 @@ TURN server.</p>
 <p>The following sections describe how to install <a href="https://github.com/coturn/coturn">coturn</a> (which implements the TURN REST API) and integrate it with synapse.</p>
 <h2 id="requirements"><a class="header" href="#requirements">Requirements</a></h2>
 <p>For TURN relaying with <code>coturn</code> to work, it must be hosted on a server/endpoint with a public IP.</p>
-<p>Hosting TURN behind a NAT (even with appropriate port forwarding) is known to cause issues
-and to often not work.</p>
+<p>Hosting TURN behind NAT requires port forwaring and for the NAT gateway to have a public IP.
+However, even with appropriate configuration, NAT is known to cause issues and to often not work.</p>
 <h2 id="coturn-setup"><a class="header" href="#coturn-setup"><code>coturn</code> setup</a></h2>
 <h3 id="initial-installation"><a class="header" href="#initial-installation">Initial installation</a></h3>
 <p>The TURN daemon <code>coturn</code> is available from a variety of sources such as native package managers, or installation from source.</p>
@@ -1250,7 +1250,23 @@ denied-peer-ip=10.0.0.0-10.255.255.255
 denied-peer-ip=192.168.0.0-192.168.255.255
 denied-peer-ip=172.16.0.0-172.31.255.255
 
+# recommended additional local peers to block, to mitigate external access to internal services.
+# https://www.rtcsec.com/article/slack-webrtc-turn-compromise-and-bug-bounty/#how-to-fix-an-open-turn-relay-to-address-this-vulnerability
+no-multicast-peers
+denied-peer-ip=0.0.0.0-0.255.255.255
+denied-peer-ip=100.64.0.0-100.127.255.255
+denied-peer-ip=127.0.0.0-127.255.255.255
+denied-peer-ip=169.254.0.0-169.254.255.255
+denied-peer-ip=192.0.0.0-192.0.0.255
+denied-peer-ip=192.0.2.0-192.0.2.255
+denied-peer-ip=192.88.99.0-192.88.99.255
+denied-peer-ip=198.18.0.0-198.19.255.255
+denied-peer-ip=198.51.100.0-198.51.100.255
+denied-peer-ip=203.0.113.0-203.0.113.255
+denied-peer-ip=240.0.0.0-255.255.255.255
+
 # special case the turn server itself so that client-&gt;TURN-&gt;TURN-&gt;client flows work
+# this should be one of the turn server's listening IPs
 allowed-peer-ip=10.0.0.1
 
 # consider whether you want to limit the quota of relayed streams per user (or total) to avoid risk of DoS.
@@ -1268,7 +1284,7 @@ cert=/path/to/fullchain.pem
 # TLS private key file
 pkey=/path/to/privkey.pem
 </code></pre>
-<p>In this case, replace the <code>turn:</code> schemes in the <code>turn_uri</code> settings below
+<p>In this case, replace the <code>turn:</code> schemes in the <code>turn_uris</code> settings below
 with <code>turns:</code>.</p>
 <p>We recommend that you only try to set up TLS/DTLS once you have set up a
 basic installation and got it working.</p>
@@ -1280,16 +1296,24 @@ traffic (remember to allow both TCP and UDP traffic), and ports 49152-65535
 for the UDP relay.)</p>
 </li>
 <li>
-<p>We do not recommend running a TURN server behind NAT, and are not aware of
-anyone doing so successfully.</p>
-<p>If you want to try it anyway, you will at least need to tell coturn its
-external IP address:</p>
-<pre><code>external-ip=192.88.99.1
+<p>If your TURN server is behind NAT, the NAT gateway must have an external,
+publicly-reachable IP address. You must configure coturn to advertise that
+address to connecting clients:</p>
+<pre><code>external-ip=EXTERNAL_NAT_IPv4_ADDRESS
+</code></pre>
+<p>You may optionally limit the TURN server to listen only on the local
+address that is mapped by NAT to the external address:</p>
+<pre><code>listening-ip=INTERNAL_TURNSERVER_IPv4_ADDRESS
 </code></pre>
-<p>... and your NAT gateway must forward all of the relayed ports directly
-(eg, port 56789 on the external IP must be always be forwarded to port
-56789 on the internal IP).</p>
-<p>If you get this working, let us know!</p>
+<p>If your NAT gateway is reachable over both IPv4 and IPv6, you may
+configure coturn to advertise each available address:</p>
+<pre><code>external-ip=EXTERNAL_NAT_IPv4_ADDRESS
+external-ip=EXTERNAL_NAT_IPv6_ADDRESS
+</code></pre>
+<p>When advertising an external IPv6 address, ensure that the firewall and
+network settings of the system running your TURN server are configured to
+accept IPv6 traffic, and that the TURN server is listening on the local
+IPv6 address that is mapped by NAT to the external IPv6 address.</p>
 </li>
 <li>
 <p>(Re)start the turn server:</p>
@@ -1357,10 +1381,6 @@ connecting&quot;. Unfortunately, troubleshooting this can be tricky.</p>
 <p>Here are a few things to try:</p>
 <ul>
 <li>
-<p>Check that your TURN server is not behind NAT. As above, we're not aware of
-anyone who has successfully set this up.</p>
-</li>
-<li>
 <p>Check that you have opened your firewall to allow TCP and UDP traffic to the
 TURN ports (normally 3478 and 5349).</p>
 </li>
@@ -1378,6 +1398,23 @@ defined by
 reachable over IPv4.</p>
 </li>
 <li>
+<p>If your TURN server is behind NAT:</p>
+<ul>
+<li>
+<p>double-check that your NAT gateway is correctly forwarding all TURN
+ports (normally 3478 &amp; 5349 for TCP &amp; UDP TURN traffic, and 49152-65535 for the UDP
+relay) to the NAT-internal address of your TURN server. If advertising
+both IPv4 and IPv6 external addresses via the <code>external-ip</code> option, ensure
+that the NAT is forwarding both IPv4 and IPv6 traffic to the IPv4 and IPv6
+internal addresses of your TURN server. When in doubt, remove AAAA records
+for your TURN server and specify only an IPv4 address as your <code>external-ip</code>.</p>
+</li>
+<li>
+<p>ensure that your TURN server uses the NAT gateway as its default route.</p>
+</li>
+</ul>
+</li>
+<li>
 <p>Enable more verbose logging in coturn via the <code>verbose</code> setting:</p>
 <pre><code>verbose
 </code></pre>
@@ -1585,6 +1622,12 @@ dpkg -i matrix-synapse-py3_1.3.0+stretch1_amd64.deb
 </code></pre>
 </li>
 </ul>
+<h1 id="upgrading-to-v1500"><a class="header" href="#upgrading-to-v1500">Upgrading to v1.50.0</a></h1>
+<h2 id="dropping-support-for-old-python-and-postgres-versions"><a class="header" href="#dropping-support-for-old-python-and-postgres-versions">Dropping support for old Python and Postgres versions</a></h2>
+<p>In line with our <a href="deprecation_policy.html">deprecation policy</a>,
+we've dropped support for Python 3.6 and PostgreSQL 9.6, as they are no
+longer supported upstream.</p>
+<p>This release of Synapse requires Python 3.7+ and PostgreSQL 10+.</p>
 <h1 id="upgrading-to-v1470"><a class="header" href="#upgrading-to-v1470">Upgrading to v1.47.0</a></h1>
 <h2 id="removal-of-old-room-admin-api"><a class="header" href="#removal-of-old-room-admin-api">Removal of old Room Admin API</a></h2>
 <p>The following admin APIs were deprecated in <a href="https://github.com/matrix-org/synapse/blob/v1.34.0/CHANGES.md#deprecations-and-removals">Synapse 1.34</a>
@@ -3108,7 +3151,7 @@ a fresh config using Synapse by following the instructions in
 
 # Server admins can expand Synapse's functionality with external modules.
 #
-# See https://matrix-org.github.io/synapse/latest/modules.html for more
+# See https://matrix-org.github.io/synapse/latest/modules/index.html for more
 # documentation on how to configure or create custom modules for Synapse.
 #
 modules:
@@ -4559,6 +4602,7 @@ room_prejoin_state:
    # - m.room.encryption
    # - m.room.name
    # - m.room.create
+   # - m.room.topic
    #
    # Uncomment the following to disable these defaults (so that only the event
    # types listed in 'additional_event_types' are shared). Defaults to 'false'.
@@ -6847,7 +6891,7 @@ comment these options out and use those specified by the module instead.</p>
 <h3 id="building-a-custom-openid-mapping-provider"><a class="header" href="#building-a-custom-openid-mapping-provider">Building a Custom OpenID Mapping Provider</a></h3>
 <p>A custom mapping provider must specify the following methods:</p>
 <ul>
-<li><code>__init__(self, parsed_config)</code>
+<li><code>def __init__(self, parsed_config)</code>
 <ul>
 <li>Arguments:
 <ul>
@@ -6858,7 +6902,7 @@ the module here.</li>
 </li>
 </ul>
 </li>
-<li><code>parse_config(config)</code>
+<li><code>def parse_config(config)</code>
 <ul>
 <li>This method should have the <code>@staticmethod</code> decoration.</li>
 <li>Arguments:
@@ -6873,7 +6917,7 @@ any option values they need here.</li>
 <code>__init__</code> method during construction.</li>
 </ul>
 </li>
-<li><code>get_remote_user_id(self, userinfo)</code>
+<li><code>def get_remote_user_id(self, userinfo)</code>
 <ul>
 <li>Arguments:
 <ul>
@@ -6885,7 +6929,7 @@ information from.</li>
 for the user. Commonly the <code>sub</code> claim of the response.</li>
 </ul>
 </li>
-<li><code>map_user_attributes(self, userinfo, token, failures)</code>
+<li><code>async def map_user_attributes(self, userinfo, token, failures)</code>
 <ul>
 <li>This method must be async.</li>
 <li>Arguments:
@@ -6916,7 +6960,7 @@ remote user ID (see <code>get_remote_user_id</code>) it cannot be updated.</li>
 </li>
 </ul>
 </li>
-<li><code>get_extra_attributes(self, userinfo, token)</code>
+<li><code>async def get_extra_attributes(self, userinfo, token)</code>
 <ul>
 <li>
 <p>This method must be async.</p>
@@ -6954,7 +6998,7 @@ comment these options out and use those specified by the module instead.</p>
 <h3 id="building-a-custom-saml-mapping-provider"><a class="header" href="#building-a-custom-saml-mapping-provider">Building a Custom SAML Mapping Provider</a></h3>
 <p>A custom mapping provider must specify the following methods:</p>
 <ul>
-<li><code>__init__(self, parsed_config, module_api)</code>
+<li><code>def __init__(self, parsed_config, module_api)</code>
 <ul>
 <li>Arguments:
 <ul>
@@ -6967,9 +7011,9 @@ stable API available for extension modules.</li>
 </li>
 </ul>
 </li>
-<li><code>parse_config(config)</code>
+<li><code>def parse_config(config)</code>
 <ul>
-<li>This method should have the <code>@staticmethod</code> decoration.</li>
+<li><strong>This method should have the <code>@staticmethod</code> decoration.</strong></li>
 <li>Arguments:
 <ul>
 <li><code>config</code> - A <code>dict</code> representing the parsed content of the
@@ -6982,9 +7026,9 @@ any option values they need here.</li>
 <code>__init__</code> method during construction.</li>
 </ul>
 </li>
-<li><code>get_saml_attributes(config)</code>
+<li><code>def get_saml_attributes(config)</code>
 <ul>
-<li>This method should have the <code>@staticmethod</code> decoration.</li>
+<li><strong>This method should have the <code>@staticmethod</code> decoration.</strong></li>
 <li>Arguments:
 <ul>
 <li><code>config</code> - A object resulting from a call to <code>parse_config</code>.</li>
@@ -6996,7 +7040,7 @@ the second set consists of those attributes which can be used if available,
 but are not necessary.</li>
 </ul>
 </li>
-<li><code>get_remote_user_id(self, saml_response, client_redirect_url)</code>
+<li><code>def get_remote_user_id(self, saml_response, client_redirect_url)</code>
 <ul>
 <li>Arguments:
 <ul>
@@ -7010,7 +7054,7 @@ redirected to.</li>
 for the user. Commonly the <code>uid</code> claim of the response.</li>
 </ul>
 </li>
-<li><code>saml_response_to_user_attributes(self, saml_response, failures, client_redirect_url)</code>
+<li><code>def saml_response_to_user_attributes(self, saml_response, failures, client_redirect_url)</code>
 <ul>
 <li>
 <p>Arguments:</p>
@@ -7261,6 +7305,128 @@ eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0LXVzZXIifQ.Ag71GT8v01UO3w80
 </li>
 </ol>
 <p>You should now be able to use the returned access token to query the client API.</p>
+<div id="chapter_begin" style="break-before: page; page-break-before: always;"></div><h1 id="refresh-tokens"><a class="header" href="#refresh-tokens">Refresh Tokens</a></h1>
+<p>Synapse supports refresh tokens since version 1.49 (some earlier versions had support for an earlier, experimental draft of <a href="https://github.com/matrix-org/matrix-doc/blob/main/proposals/2918-refreshtokens.md#msc2918-refresh-tokens">MSC2918</a> which is not compatible).</p>
+<h2 id="background-and-motivation"><a class="header" href="#background-and-motivation">Background and motivation</a></h2>
+<p>Synapse users' sessions are identified by <strong>access tokens</strong>; access tokens are
+issued to users on login. Each session gets a unique access token which identifies
+it; the access token must be kept secret as it grants access to the user's account.</p>
+<p>Traditionally, these access tokens were eternally valid (at least until the user
+explicitly chose to log out).</p>
+<p>In some cases, it may be desirable for these access tokens to expire so that the
+potential damage caused by leaking an access token is reduced.
+On the other hand, forcing a user to re-authenticate (log in again) often might
+be too much of an inconvenience.</p>
+<p><strong>Refresh tokens</strong> are a mechanism to avoid some of this inconvenience whilst
+still getting most of the benefits of short access token lifetimes.
+Refresh tokens are also a concept present in OAuth 2 — further reading is available
+<a href="https://datatracker.ietf.org/doc/html/rfc6749#section-1.5">here</a>.</p>
+<p>When refresh tokens are in use, both an access token and a refresh token will be
+issued to users on login. The access token will expire after a predetermined amount
+of time, but otherwise works in the same way as before. When the access token is
+close to expiring (or has expired), the user's client should present the homeserver
+(Synapse) with the refresh token.</p>
+<p>The homeserver will then generate a new access token and refresh token for the user
+and return them. The old refresh token is invalidated and can not be used again*.</p>
+<p>Finally, refresh tokens also make it possible for sessions to be logged out if they
+are inactive for too long, before the session naturally ends; see the configuration
+guide below.</p>
+<p>*To prevent issues if clients lose connection half-way through refreshing a token,
+the refresh token is only invalidated once the new access token has been used at
+least once. For all intents and purposes, the above simplification is sufficient.</p>
+<h2 id="caveats"><a class="header" href="#caveats">Caveats</a></h2>
+<p>There are some caveats:</p>
+<ul>
+<li>If a third party gets both your access token and refresh token, they will be able to
+continue to enjoy access to your session.
+<ul>
+<li>This is still an improvement because you (the user) will notice when <em>your</em>
+session expires and you're not able to use your refresh token.
+That would be a giveaway that someone else has compromised your session.
+You would be able to log in again and terminate that session.
+Previously (with long-lived access tokens), a third party that has your access
+token could go undetected for a very long time.</li>
+</ul>
+</li>
+<li>Clients need to implement support for refresh tokens in order for them to be a
+useful mechanism.
+<ul>
+<li>It is up to homeserver administrators if they want to issue long-lived access
+tokens to clients not implementing refresh tokens.
+<ul>
+<li>For compatibility, it is likely that they should, at least until client support
+is widespread.
+<ul>
+<li>Users with clients that support refresh tokens will still benefit from the
+added security; it's not possible to downgrade a session to using long-lived
+access tokens so this effectively gives users the choice.</li>
+</ul>
+</li>
+<li>In a closed environment where all users use known clients, this may not be
+an issue as the homeserver administrator can know if the clients have refresh
+token support. In that case, the non-refreshable access token lifetime
+may be set to a short duration so that a similar level of security is provided.</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+<h2 id="configuration-guide"><a class="header" href="#configuration-guide">Configuration Guide</a></h2>
+<p>The following configuration options, in the <code>registration</code> section, are related:</p>
+<ul>
+<li><code>session_lifetime</code>: maximum length of a session, even if it's refreshed.
+In other words, the client must log in again after this time period.
+In most cases, this can be unset (infinite) or set to a long time (years or months).</li>
+<li><code>refreshable_access_token_lifetime</code>: lifetime of access tokens that are created
+by clients supporting refresh tokens.
+This should be short; a good value might be 5 minutes (<code>5m</code>).</li>
+<li><code>nonrefreshable_access_token_lifetime</code>: lifetime of access tokens that are created
+by clients which don't support refresh tokens.
+Make this short if you want to effectively force use of refresh tokens.
+Make this long if you don't want to inconvenience users of clients which don't
+support refresh tokens (by forcing them to frequently re-authenticate using
+login credentials).</li>
+<li><code>refresh_token_lifetime</code>: lifetime of refresh tokens.
+In other words, the client must refresh within this time period to maintain its session.
+Unless you want to log inactive sessions out, it is often fine to use a long
+value here or even leave it unset (infinite).
+Beware that making it too short will inconvenience clients that do not connect
+very often, including mobile clients and clients of infrequent users (by making
+it more difficult for them to refresh in time, which may force them to need to
+re-authenticate using login credentials).</li>
+</ul>
+<p><strong>Note:</strong> All four options above only apply when tokens are created (by logging in or refreshing).
+Changes to these settings do not apply retroactively.</p>
+<h3 id="using-refresh-token-expiry-to-log-out-inactive-sessions"><a class="header" href="#using-refresh-token-expiry-to-log-out-inactive-sessions">Using refresh token expiry to log out inactive sessions</a></h3>
+<p>If you'd like to force sessions to be logged out upon inactivity, you can enable
+refreshable access token expiry and refresh token expiry.</p>
+<p>This works because a client must refresh at least once within a period of
+<code>refresh_token_lifetime</code> in order to maintain valid credentials to access the
+account.</p>
+<p>(It's suggested that <code>refresh_token_lifetime</code> should be longer than
+<code>refreshable_access_token_lifetime</code> and this section assumes that to be the case
+for simplicity.)</p>
+<p>Note: this will only affect sessions using refresh tokens. You may wish to
+set a short <code>nonrefreshable_access_token_lifetime</code> to prevent this being bypassed
+by clients that do not support refresh tokens.</p>
+<h4 id="choosing-values-that-guarantee-permitting-some-inactivity"><a class="header" href="#choosing-values-that-guarantee-permitting-some-inactivity">Choosing values that guarantee permitting some inactivity</a></h4>
+<p>It may be desirable to permit some short periods of inactivity, for example to
+accommodate brief outages in client connectivity.</p>
+<p>The following model aims to provide guidance for choosing <code>refresh_token_lifetime</code>
+and <code>refreshable_access_token_lifetime</code> to satisfy requirements of the form:</p>
+<ol>
+<li>inactivity longer than <code>L</code> <strong>MUST</strong> cause the session to be logged out; and</li>
+<li>inactivity shorter than <code>S</code> <strong>MUST NOT</strong> cause the session to be logged out.</li>
+</ol>
+<p>This model makes the weakest assumption that all active clients will refresh as
+needed to maintain an active access token, but no sooner.
+<em>In reality, clients may refresh more often than this model assumes, but the
+above requirements will still hold.</em></p>
+<p>To satisfy the above model,</p>
+<ul>
+<li><code>refresh_token_lifetime</code> should be set to <code>L</code>; and</li>
+<li><code>refreshable_access_token_lifetime</code> should be set to <code>L - S</code>.</li>
+</ul>
 <div id="chapter_begin" style="break-before: page; page-break-before: always;"></div><h1 id="overview-2"><a class="header" href="#overview-2">Overview</a></h1>
 <p>A captcha can be enabled on your homeserver to help prevent bots from registering
 accounts. Synapse currently uses Google's reCAPTCHA service which requires API keys
@@ -11388,6 +11554,75 @@ member are returned.</p>
 <li><code>joined_rooms</code> - An array of <code>room_id</code>.</li>
 <li><code>total</code> - Number of rooms.</li>
 </ul>
+<h2 id="account-data"><a class="header" href="#account-data">Account Data</a></h2>
+<p>Gets information about account data for a specific <code>user_id</code>.</p>
+<p>The API is:</p>
+<pre><code>GET /_synapse/admin/v1/users/&lt;user_id&gt;/accountdata
+</code></pre>
+<p>A response body like the following is returned:</p>
+<pre><code class="language-json">{
+    &quot;account_data&quot;: {
+        &quot;global&quot;: {
+            &quot;m.secret_storage.key.LmIGHTg5W&quot;: {
+                &quot;algorithm&quot;: &quot;m.secret_storage.v1.aes-hmac-sha2&quot;,
+                &quot;iv&quot;: &quot;fwjNZatxg==&quot;,
+                &quot;mac&quot;: &quot;eWh9kNnLWZUNOgnc=&quot;
+            },
+            &quot;im.vector.hide_profile&quot;: {
+                &quot;hide_profile&quot;: true
+            },
+            &quot;org.matrix.preview_urls&quot;: {
+                &quot;disable&quot;: false
+            },
+            &quot;im.vector.riot.breadcrumb_rooms&quot;: {
+                &quot;rooms&quot;: [
+                    &quot;!LxcBDAsDUVAfJDEo:matrix.org&quot;,
+                    &quot;!MAhRxqasbItjOqxu:matrix.org&quot;
+                ]
+            },
+            &quot;m.accepted_terms&quot;: {
+                &quot;accepted&quot;: [
+                    &quot;https://example.org/somewhere/privacy-1.2-en.html&quot;,
+                    &quot;https://example.org/somewhere/terms-2.0-en.html&quot;
+                ]
+            },
+            &quot;im.vector.setting.breadcrumbs&quot;: {
+                &quot;recent_rooms&quot;: [
+                    &quot;!MAhRxqasbItqxuEt:matrix.org&quot;,
+                    &quot;!ZtSaPCawyWtxiImy:matrix.org&quot;
+                ]
+            }
+        },
+        &quot;rooms&quot;: {
+            &quot;!GUdfZSHUJibpiVqHYd:matrix.org&quot;: {
+                &quot;m.fully_read&quot;: {
+                    &quot;event_id&quot;: &quot;$156334540fYIhZ:matrix.org&quot;
+                }
+            },
+            &quot;!tOZwOOiqwCYQkLhV:matrix.org&quot;: {
+                &quot;m.fully_read&quot;: {
+                    &quot;event_id&quot;: &quot;$xjsIyp4_NaVl2yPvIZs_k1Jl8tsC_Sp23wjqXPno&quot;
+                }
+            }
+        }
+    }
+}
+</code></pre>
+<p><strong>Parameters</strong></p>
+<p>The following parameters should be set in the URL:</p>
+<ul>
+<li><code>user_id</code> - fully qualified: for example, <code>@user:server.com</code>.</li>
+</ul>
+<p><strong>Response</strong></p>
+<p>The following fields are returned in the JSON response body:</p>
+<ul>
+<li><code>account_data</code> - A map containing the account data for the user
+<ul>
+<li><code>global</code> - A map containing the global account data for the user</li>
+<li><code>rooms</code> - A map containing the account data per room for the user</li>
+</ul>
+</li>
+</ul>
 <h2 id="user-media"><a class="header" href="#user-media">User media</a></h2>
 <h3 id="list-media-uploaded-by-a-user"><a class="header" href="#list-media-uploaded-by-a-user">List media uploaded by a user</a></h3>
 <p>Gets a list of all local media that a specific <code>user_id</code> has created.