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:::