Óscar García Amor

Ingeniero de Sistemas Exóticos

Monta tu propio homeserver de Matrix

Actualmente existen cientos de soluciones de comunicación en Internet. De hecho es un elemento tan importante que hasta las aplicaciones que no están creadas para tal fin incorporan una sección de chat para que sus usuarios se comuniquen entre si. Todas estas aplicaciones tienen dos desventajas.

  1. Son islas, no se comunican entre sí. Si tu tienes tu cuenta en, por poner un ejemplo, Telegram y quieres charlar con alguien que tenga Signal simplemente no podrás a no ser que uno de los dos cree una cuenta en la red contraria.
  2. No tienes el control. Tus datos no son tuyos, si un día por la razón que sea el servicio deja de funcionar te quedas sin nada.

En algunos casos incluso podemos tener la tercera desventaja de la privacidad, es decir, que quien maneja el servidor podría estar leyendo tus conversaciones. Aunque para ser justos esto no sucede en todas la redes ya que muchas de ellas o bien establecen comunicaciones de punto a punto o bien almacenan el contenido cifrado con una contraseña que solo los clientes conocen y, por tanto, solo los clientes pueden descifrar.

Es por estas razones que existen otro tipo de soluciones mas amigables con todos estos conceptos como son las redes federadas.

Las redes federadas

Una red federada se compone básicamente de un conjunto de protocolos estandarizados los cuales permiten que sus servidores (llamados comúnmente instancias) intercambien información sin importar que implementación de software esté ejecutando cada instancia. Esto supone una ventaja enorme frente a las redes centralizadas por varias razones.

  1. Al tratarse de un estándar cualquiera puede desarrollar su propia implementación del protocolo (ya sea a nivel de servidor como a nivel de cliente).
  2. Permite que cada usuario o conjunto de usuarios monte el servicio como mejor le convenga.
  3. No hay un centro, los usuarios se comunican entre si de igual a igual.
  4. Si una instancia se cae o desaparece la red sigue operativa.

Matrix

Matrix es un estándar de red federada que permite la comunicación entre los usuarios de sus instancias (llamadas homeservers) por diferentes vías, ya sea la por principal, el chat, cómo también el audio y vídeo.

Si quieres simplemente entrar a la red y charlar con los usuarios de la misma no necesitas montar tu propio homeserver, simplemente eliges un software cliente, creas una cuenta en un servidor ya existente y a disfrutar, pero esto no aprovecha realmente la ventaja de la red federada, me explico.

Si todos los clientes de una red federada utilizan el mismo servidor para alojar su cuenta, volvemos al modelo centralizado. Da lo mismo que la red sea federada ya que, si cae ese servidor, caen con él todas las cuentas. Es por eso que, siempre que sea posible, tengamos nuestra propia instancia controlada por nosotros. Con esto no quiero decir que cada usuario deba tener su instancia propia (sería un desperdicio brutal de recursos), sino que al menos nuestra instancia local. Ya sea una instancia montada para nuestra familia, grupo de amigos o comunidad.

Existen varias implementaciones que permiten montar tu propio homeserver, cada una de ellas con sus pros y sus contras. La implementación base con la que se inició la red de Matrix en matrix.org es Synapse aunque actualmente se esta trabajando en una nueva implementación llamada Dendrite que recoge el testigo de la primera que estaba programada en Python y mejora su rendimiento al estar programada en Go. Estas dos implementaciones están ideadas para servidores especialmente grandes que soportan cientos de miles de cuentas, por lo que nosotros utilizaremos algo mas comedido y que funciona exactamente igual de bien, Conduit.

Conduit

Conduit es una de las implementaciones de Matrix para montar un homeserver, esta escrita en Rust por lo que tiene una serie de ventajas interesantes.

  1. Es ligera. Puede ejecutarse sin problemas en una Raspberry Pi 2 o superior sin consumir apenas recursos.
  2. Es rápida y potente. Puede soportar un número bastante importante de usuarios.
  3. Es completa. Implementa todo el estándar del protocolo a excepción de ciertas funciones beta o en pruebas que no son necesarias para trabajar.
  4. No tiene dependencias. Es un binario que se ejecuta, no es necesario tener un servicio de base de datos en ejecución o cientos de librerías instaladas.

Por todas estas razones esta implementación es la candidata ideal para montar nuestro homeserver para nosotros, nuestra familia, amigos o incluso nuestra comunidad o grupo de usuarios local.

Desplegando nuestro homeserver

Ya conocemos las opciones que existen. Evidentemente el despliegue de cada opción es diferente y aunque aquí nos vamos a centrar en Conduit existen puntos comunes a todas las implementaciones de servidor, como los prerrequisitos o la configuración para la federación.

Prerrequisitos

Para poder montar nuestro propio homeserver necesitamos tener un dominio propio. Si no tienes uno no puedes montar el servidor y no te aconsejo utilizar un dominio que no controles como un DynDNS o similar.

También necesitamos una máquina que este funcionando 24/7, no te estreses, no pasa nada si la maquina deja de responder unas horas por alguna razón, lo que no puede suceder es que la máquina pase la mitad del día apagada.

Por último en la máquina que escojamos necesitamos tener instalado nginx para que actúe como proxy inverso entre Internet y Conduit.

Y ya, no necesitamos nada mas. En mis ejemplos utilizare como dominio example.com, por lo que deberás sustituir ese dominio por el que tengas tú.

Además el método de instalación que vamos a emplear es el de poner el servicio en su propio subdominio. Esto quiere decir que aunque nuestras cuentas serán @usuario:example.com el servicio estará en ejecución en el subdominio matrix.example.com. Esto tiene la ventaja de que así podremos tener, si nos interesa, el dominio principal alojado en una máquina y el servicio de Matrix en otra distinta.

Finalmente comentar que tanto el dominio example.com como el subdominio matrix.example.com deberán tener sus certificados SSL válidos y reconocidos (no valen autofirmados) ya que toda la comunicación entre servidores se hace por https. Puedes utilizar Let's Encrypt para generar tus certificados.

Instalar Conduit

Como he comentado anteriormente Conduit es un simple binario ejecutable, por lo que simplemente descargamos de aqui la ultima versión de desarrollo que tengamos disponible para nuestra plataforma y copiamos el binario descargado como /usr/bin/conduit (o en /usr/local/bin/ lo que mas nos guste) y le daremos permisos de ejecución con un chmod 755.

Con esto ya lo tendríamos instalado, no necesitamos hacer nada mas en este sentido.

Configurar Conduit

La configuración de Conduit es bastante sencilla. Primero creamos un fichero /etc/systemd/system/conduit.service para poder arrancar el servicio con systemd.

[Unit]
Description=A simple, fast and reliable chat server powered by Matrix
Documentation=https://gitlab.com/famedly/conduit/-/blob/master/README.md
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
DynamicUser=yes
StateDirectory=conduit
Environment="CONDUIT_CONFIG=/etc/conduit.conf"
ExecStart=/usr/bin/conduit

[Install]
WantedBy=multi-user.target

A continuación crearemos la propia configuración de Conduit en /etc/conduit.conf, se podría alojar en otro sitio, lo importante es definir la ruta del fichero de configuración en la unit de systemd.

[global]

# este es el nombre del servidor, tendremos que cambiarla a nuestro dominio
# propio
server_name = "example.com"

# Directorio donde Conduit almacena su base de datos, se crea desde systemd
# gracias al StateDirectory
database_path = "/var/lib/conduit/"
database_backend = "rocksdb"

port = 6167

# Tamaño máximo de los archivos que se suben al servidor
max_request_size = 20_000_000 # en bytes

# Si permite que los usuarios anónimos se puedan registrar
# La primera cuenta que se registre será el administrador, una vez
# registradas todas las cuentas necesarias podemos poner el valor a false
allow_registration = true

allow_encryption = true
allow_federation = true

trusted_servers = ["matrix.org"]

# Escucha solo a localhost para que todas las conexiones pase a través de
# nginx
address = "127.0.0.1"

Ahora ya podemos iniciar el servicio.

systemctl start conduit
systemctl enable conduit

Y realizar la configuración de nginx.

server {
  listen 80;
  listen [::]:80;

  server_name matrix.example.com;

  access_log /var/log/nginx/matrix.access.log;
  error_log  /var/log/nginx/matrix.error.log;

  return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    listen 8448 ssl http2;
    listen [::]:8448 ssl http2;

    server_name matrix.example.com;

    access_log /var/log/nginx/matrix.access.log;
    error_log  /var/log/nginx/matrix.error.log;

    include                 /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_certificate         /etc/letsencrypt/live/matrix.example.com/fullchain.pem;
    ssl_certificate_key     /etc/letsencrypt/live/matrix.example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/matrix.example.com/chain.pem;

    # Nginx defaults to only allow 1MB uploads
    client_max_body_size 20M;

    location /_matrix/ {
        proxy_pass http://127.0.0.1:6167$request_uri;
        proxy_set_header Host $http_host;
        proxy_buffering off;
    }
}

Ten en cuenta que la configuración de nginx es un ejemplo, posiblemente tendrás que ajustarla a tu servidor y crear previamente los certificados de Let's Encrypt.

Si todo ha ido correctamente puedes comprobar que tu servidor funciona haciendo estos curls.

curl https://matrix.example.com/_matrix/client/versions
curl https://matrix.example.com:8448/_matrix/client/versions

Terminando la configuración

Ya tienes tu homeserver funcionando, pero seguramente si intentas registrarte con un cliente (inicialmente te recomiendo que utilices Element Web por ser lo mas sencillo y no requerir nada mas que un navegador), verás que no te da conectado al indicar que tu homeserver (o servidor base) está en example.com. Incluso si compruebas con el Matrix Federation Tester te dirá que ahí no hay nada. Esto es porque aunque tienes el servidor en ejecución, lo tienes funcionando en matrix.example.com.

Para que todo el sistema funcione hay que indicar en el dominio principal example.com que el servidor de Matrix se aloja en matrix.example.com. Para ello se utilizan los ficheros .well-known/matrix/server y .well-known/matrix/client. ¿Que significa esto? Que en donde tengas publicado tu dominio principal example.com tienes que publicar un par de ficheros estáticos en las rutas anteriormente citadas indicando cual es realmente la URL del servidor. Estos ficheros además tienen que tener un formato definido tal cual se detalla a continuación.

El fichero accesible a través de https://example.com/.well-known/matrix/server.

{"m.server":"matrix.example.com:8448"}

El fichero accesible a través de https://example.com/.well-known/matrix/client.

{"m.homeserver":{"base_url":"https://matrix.example.com"}}

Luego simplemente podemos comprobar con un curl.

curl https://example.com/.well-known/matrix/server
curl https://example.com/.well-known/matrix/client

De hecho si queremos ver un ejemplo podemos probar con matrix.org.

curl https://matrix.org/.well-known/matrix/server
curl https://matrix.org/.well-known/matrix/client

Una vez hecho esto, si volvemos a probar con el Matrix Federation Tester, ya debería indicarnos que todo es correcto y podríamos ya registrar nuestra primera cuenta @usuario:example.com.

Como comenté anteriormente este primer usuario que se registra será el administrador del servidor y podrá charlar con el bot @conduit:example.com para ejecutar comandos en el mismo. De hecho se podría deshabilitar en la configuración el registro de usuarios ya que gracias a este bot podemos crearlos charlando con él.

Notas finales

Aunque nuestro servidor ya esta listo, hay cosas que podemos hacer a mayores, como por ejemplo crear cuentas para nuestros familiares o amigos, instalar un servicio TURN/STURN para que funcionen las llamadas de audio y vídeo o echarle un vistazo a los Appservices. Pero eso ya lo dejo a vuestra propia elección.

Y ya sabéis, no dudéis en contactarme si tenéis alguna cuestión.