1# Matrix {#module-services-matrix} 2 3[Matrix](https://matrix.org/) is an open standard for 4interoperable, decentralised, real-time communication over IP. It can be used 5to power Instant Messaging, VoIP/WebRTC signalling, Internet of Things 6communication - or anywhere you need a standard HTTP API for publishing and 7subscribing to data whilst tracking the conversation history. 8 9This chapter will show you how to set up your own, self-hosted Matrix 10homeserver using the Synapse reference homeserver, and how to serve your own 11copy of the Element web client. See the 12[Try Matrix Now!](https://matrix.org/docs/projects/try-matrix-now.html) 13overview page for links to Element Apps for Android and iOS, 14desktop clients, as well as bridges to other networks and other projects 15around Matrix. 16 17## Synapse Homeserver {#module-services-matrix-synapse} 18 19[Synapse](https://github.com/matrix-org/synapse) is 20the reference homeserver implementation of Matrix from the core development 21team at matrix.org. The following configuration example will set up a 22synapse server for the `example.org` domain, served from 23the host `myhostname.example.org`. For more information, 24please refer to the 25[installation instructions of Synapse](https://matrix-org.github.io/synapse/latest/setup/installation.html) . 26``` 27{ pkgs, lib, config, ... }: 28let 29 fqdn = "${config.networking.hostName}.${config.networking.domain}"; 30 clientConfig."m.homeserver".base_url = "https://${fqdn}"; 31 serverConfig."m.server" = "${fqdn}:443"; 32 mkWellKnown = data: '' 33 add_header Content-Type application/json; 34 add_header Access-Control-Allow-Origin *; 35 return 200 '${builtins.toJSON data}'; 36 ''; 37in { 38 networking.hostName = "myhostname"; 39 networking.domain = "example.org"; 40 networking.firewall.allowedTCPPorts = [ 80 443 ]; 41 42 services.postgresql.enable = true; 43 services.postgresql.initialScript = pkgs.writeText "synapse-init.sql" '' 44 CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse'; 45 CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse" 46 TEMPLATE template0 47 LC_COLLATE = "C" 48 LC_CTYPE = "C"; 49 ''; 50 51 services.nginx = { 52 enable = true; 53 recommendedTlsSettings = true; 54 recommendedOptimisation = true; 55 recommendedGzipSettings = true; 56 recommendedProxySettings = true; 57 virtualHosts = { 58 # If the A and AAAA DNS records on example.org do not point on the same host as the 59 # records for myhostname.example.org, you can easily move the /.well-known 60 # virtualHost section of the code to the host that is serving example.org, while 61 # the rest stays on myhostname.example.org with no other changes required. 62 # This pattern also allows to seamlessly move the homeserver from 63 # myhostname.example.org to myotherhost.example.org by only changing the 64 # /.well-known redirection target. 65 "${config.networking.domain}" = { 66 enableACME = true; 67 forceSSL = true; 68 # This section is not needed if the server_name of matrix-synapse is equal to 69 # the domain (i.e. example.org from @foo:example.org) and the federation port 70 # is 8448. 71 # Further reference can be found in the docs about delegation under 72 # https://matrix-org.github.io/synapse/latest/delegate.html 73 locations."= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig; 74 # This is usually needed for homeserver discovery (from e.g. other Matrix clients). 75 # Further reference can be found in the upstream docs at 76 # https://spec.matrix.org/latest/client-server-api/#getwell-knownmatrixclient 77 locations."= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig; 78 }; 79 "${fqdn}" = { 80 enableACME = true; 81 forceSSL = true; 82 # It's also possible to do a redirect here or something else, this vhost is not 83 # needed for Matrix. It's recommended though to *not put* element 84 # here, see also the section about Element. 85 locations."/".extraConfig = '' 86 return 404; 87 ''; 88 # Forward all Matrix API calls to the synapse Matrix homeserver. A trailing slash 89 # *must not* be used here. 90 locations."/_matrix".proxyPass = "http://[::1]:8008"; 91 # Forward requests for e.g. SSO and password-resets. 92 locations."/_synapse/client".proxyPass = "http://[::1]:8008"; 93 }; 94 }; 95 }; 96 97 services.matrix-synapse = { 98 enable = true; 99 settings.server_name = config.networking.domain; 100 settings.listeners = [ 101 { port = 8008; 102 bind_addresses = [ "::1" ]; 103 type = "http"; 104 tls = false; 105 x_forwarded = true; 106 resources = [ { 107 names = [ "client" "federation" ]; 108 compress = true; 109 } ]; 110 } 111 ]; 112 }; 113} 114``` 115 116## Registering Matrix users {#module-services-matrix-register-users} 117 118If you want to run a server with public registration by anybody, you can 119then enable `services.matrix-synapse.settings.enable_registration = true;`. 120Otherwise, or you can generate a registration secret with 121{command}`pwgen -s 64 1` and set it with 122[](#opt-services.matrix-synapse.settings.registration_shared_secret). 123To create a new user or admin, run the following after you have set the secret 124and have rebuilt NixOS: 125```ShellSession 126$ nix-shell -p matrix-synapse 127$ register_new_matrix_user -k your-registration-shared-secret http://localhost:8008 128New user localpart: your-username 129Password: 130Confirm password: 131Make admin [no]: 132Success! 133``` 134In the example, this would create a user with the Matrix Identifier 135`@your-username:example.org`. 136 137::: {.warning} 138When using [](#opt-services.matrix-synapse.settings.registration_shared_secret), the secret 139will end up in the world-readable store. Instead it's recommended to deploy the secret 140in an additional file like this: 141 142 - Create a file with the following contents: 143 144 ``` 145 registration_shared_secret: your-very-secret-secret 146 ``` 147 - Deploy the file with a secret-manager such as 148 [{option}`deployment.keys`](https://nixops.readthedocs.io/en/latest/overview.html#managing-keys) 149 from {manpage}`nixops(1)` or [sops-nix](https://github.com/Mic92/sops-nix/) to 150 e.g. {file}`/run/secrets/matrix-shared-secret` and ensure that it's readable 151 by `matrix-synapse`. 152 - Include the file like this in your configuration: 153 154 ``` 155 { 156 services.matrix-synapse.extraConfigFiles = [ 157 "/run/secrets/matrix-shared-secret" 158 ]; 159 } 160 ``` 161::: 162 163::: {.note} 164It's also possible to user alternative authentication mechanism such as 165[LDAP (via `matrix-synapse-ldap3`)](https://github.com/matrix-org/matrix-synapse-ldap3) 166or [OpenID](https://matrix-org.github.io/synapse/latest/openid.html). 167::: 168 169## Element (formerly known as Riot) Web Client {#module-services-matrix-element-web} 170 171[Element Web](https://github.com/vector-im/riot-web/) is 172the reference web client for Matrix and developed by the core team at 173matrix.org. Element was formerly known as Riot.im, see the 174[Element introductory blog post](https://element.io/blog/welcome-to-element/) 175for more information. The following snippet can be optionally added to the code before 176to complete the synapse installation with a web client served at 177`https://element.myhostname.example.org` and 178`https://element.example.org`. Alternatively, you can use the hosted 179copy at <https://app.element.io/>, 180or use other web clients or native client applications. Due to the 181`/.well-known` urls set up done above, many clients should 182fill in the required connection details automatically when you enter your 183Matrix Identifier. See 184[Try Matrix Now!](https://matrix.org/docs/projects/try-matrix-now.html) 185for a list of existing clients and their supported featureset. 186``` 187{ 188 services.nginx.virtualHosts."element.${fqdn}" = { 189 enableACME = true; 190 forceSSL = true; 191 serverAliases = [ 192 "element.${config.networking.domain}" 193 ]; 194 195 root = pkgs.element-web.override { 196 conf = { 197 default_server_config = clientConfig; # see `clientConfig` from the snippet above. 198 }; 199 }; 200 }; 201} 202``` 203 204::: {.note} 205The Element developers do not recommend running Element and your Matrix 206homeserver on the same fully-qualified domain name for security reasons. In 207the example, this means that you should not reuse the 208`myhostname.example.org` virtualHost to also serve Element, 209but instead serve it on a different subdomain, like 210`element.example.org` in the example. See the 211[Element Important Security Notes](https://github.com/vector-im/element-web/tree/v1.10.0#important-security-notes) 212for more information on this subject. 213:::