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