Matrix
Matrix is an open standard for
interoperable, decentralised, real-time communication over IP. It can be used
to power Instant Messaging, VoIP/WebRTC signalling, Internet of Things
communication - or anywhere you need a standard HTTP API for publishing and
subscribing to data whilst tracking the conversation history.
This chapter will show you how to set up your own, self-hosted Matrix
homeserver using the Synapse reference homeserver, and how to serve your own
copy of the Element web client. See the
Try
Matrix Now! overview page for links to Element Apps for Android and iOS,
desktop clients, as well as bridges to other networks and other projects
around Matrix.
Synapse Homeserver
Synapse is
the reference homeserver implementation of Matrix from the core development
team at matrix.org. The following configuration example will set up a
synapse server for the example.org domain, served from
the host myhostname.example.org. For more information,
please refer to the
installation instructions of Synapse .
{ pkgs, lib, config, ... }:
let
fqdn = "${config.networking.hostName}.${config.networking.domain}";
clientConfig = {
"m.homeserver".base_url = "https://${fqdn}";
"m.identity_server" = {};
};
serverConfig."m.server" = "${config.services.matrix-synapse.settings.server_name}:443";
mkWellKnown = data: ''
add_header Content-Type application/json;
add_header Access-Control-Allow-Origin *;
return 200 '${builtins.toJSON data}';
'';
in {
= "myhostname";
= "example.org";
= [ 80 443 ];
= true;
= pkgs.writeText "synapse-init.sql" ''
CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse';
CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse"
TEMPLATE template0
LC_COLLATE = "C"
LC_CTYPE = "C";
'';
services.nginx = {
enable = true;
recommendedTlsSettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedProxySettings = true;
virtualHosts = {
"${config.networking.domain}" = {
enableACME = true;
forceSSL = true;
locations."= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig;
locations."= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig;
};
"${fqdn}" = {
enableACME = true;
forceSSL = true;
locations."/".extraConfig = ''
return 404;
'';
locations."/_matrix".proxyPass = "http://[::1]:8008";
locations."/_synapse/client".proxyPass = "http://[::1]:8008";
};
};
};
services.matrix-synapse = {
enable = true;
settings.server_name = config.networking.domain;
settings.listeners = [
{ port = 8008;
bind_addresses = [ "::1" ];
type = "http";
tls = false;
x_forwarded = true;
resources = [ {
names = [ "client" "federation" ];
compress = true;
} ];
}
];
};
}
If the A and AAAA DNS records on
example.org do not point on the same host as the records
for myhostname.example.org, you can easily move the
/.well-known virtualHost section of the code to the host that
is serving example.org, while the rest stays on
myhostname.example.org with no other changes required.
This pattern also allows to seamlessly move the homeserver from
myhostname.example.org to
myotherhost.example.org by only changing the
/.well-known redirection target.
This section is not needed if the server_name
of matrix-synapse is equal to the domain (i.e.
example.org from @foo:example.org)
and the federation port is 8448.
Further reference can be found in the docs
about delegation.
This is usually needed for homeserver discovery (from e.g. other Matrix clients).
Further reference can be found in the upstream docs
It's also possible to do a redirect here or something else, this vhost is not
needed for Matrix. It's recommended though to not put element
here, see also the section about Element.
Forward all Matrix API calls to the synapse Matrix homeserver. A trailing slash
must not be used here.
Forward requests for e.g. SSO and password-resets.
Registering Matrix users
If you want to run a server with public registration by anybody, you can
then enable services.matrix-synapse.settings.enable_registration =
true;. Otherwise, or you can generate a registration secret with
pwgen -s 64 1 and set it with
.
To create a new user or admin, run the following after you have set the secret
and have rebuilt NixOS:
$ nix-shell -p matrix-synapse
$ register_new_matrix_user -k your-registration-shared-secret http://localhost:8008
New user localpart: your-usernamePassword:Confirm password:Make admin [no]:
Success!
In the example, this would create a user with the Matrix Identifier
@your-username:example.org.
When using , the secret
will end up in the world-readable store. Instead it's recommended to deploy the secret
in an additional file like this:
Create a file with the following contents:
registration_shared_secret: your-very-secret-secret
Deploy the file with a secret-manager such as
from nixops1
or sops-nix to
e.g. /run/secrets/matrix-shared-secret and ensure that it's readable
by matrix-synapse.
Include the file like this in your configuration:
{
= [
"/run/secrets/matrix-shared-secret"
];
}
It's also possible to user alternative authentication mechanism such as
LDAP (via matrix-synapse-ldap3)
or OpenID.
Element (formerly known as Riot) Web Client
Element Web is
the reference web client for Matrix and developed by the core team at
matrix.org. Element was formerly known as Riot.im, see the
Element introductory blog post
for more information. The following snippet can be optionally added to the code before
to complete the synapse installation with a web client served at
https://element.myhostname.example.org and
https://element.example.org. Alternatively, you can use the hosted
copy at https://app.element.io/,
or use other web clients or native client applications. Due to the
/.well-known urls set up done above, many clients should
fill in the required connection details automatically when you enter your
Matrix Identifier. See
Try
Matrix Now! for a list of existing clients and their supported
featureset.
{
services.nginx.virtualHosts."element.${fqdn}" = {
enableACME = true;
forceSSL = true;
serverAliases = [
"element.${config.networking.domain}"
];
root = pkgs.element-web.override {
conf = {
default_server_config = clientConfig; # see `clientConfig` from the snippet above.
};
};
};
}
The Element developers do not recommend running Element and your Matrix
homeserver on the same fully-qualified domain name for security reasons. In
the example, this means that you should not reuse the
myhostname.example.org virtualHost to also serve Element,
but instead serve it on a different subdomain, like
element.example.org in the example. See the
Element
Important Security Notes for more information on this subject.