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