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