Matrix - 1. Instalación y configuración
A partir de unos artículos de Lorenzo y de uGeek (podéis encontrar más información en la referencia), me picó la curiosidad sobre cómo sería tener mi propio servidor de mensajería y poderlo utilizar para enviar las notificaciones de mis servicios y así no depender tanto de Telegram.
De ahí viene este nuevo artículo, donde explicaré todo el proceso de instalación y uso de mi nuevo servidor Matrix en mi VPS y os aviso que no ha sido nada sencillo.
nota: Pero antes, tengo que tirarle un poco de las orejas a Lorenzo, porque la información que tiene puesta en su página web o en su repositorio de GitHub es muy floja con respecto a la instalación y configuración de todo lo que se necesita para su correcto uso, y eso me ha lastrado mucho a la hora de realizar toda la instalación y configuración. Porque cuando tienes algo por donde empezar, todo se hace más fácil y no como esta vez que ha sido como tirarte a la piscina sin saber nadar y sin flotador. Que sí, he aprendido mucho, pero no es lo más recomendable. Que conste que no es ninguna recriminación hacia Lorenzo, porque seguro que tendrá algún motivo para no haberlo subido a su repositorio, pero es que ha sido como un dolor de muelas todo el proceso. 😭
Después del tirón de orejas, viene lo bueno, la explicación de todo lo necesario para tener un servidor de Matrix en marcha y a pleno rendimiento, aunque aún le faltan algunas cosas que explicaré en próximos artículos.
Lo primero es decidir qué servidor de Matrix utilizar. Como he dicho, uGeek y Lorenzo usan 2 muy diferentes entre ellos, te recomiendo que leas los artículos que hablan de ello porque son muy interesantes, y estos servidores son:
En principio, el que recomienda Matrix es que se use Synapse, pero es un poco pesado de usar para las cosas que, en mi caso quiero hacer, que son básicamente:
- Un solo usuario 😁
- Solo enviará notificaciones de los servicios que tengo activos tanto en mi servidor doméstico como de mi VPS.
- El volumen de notificaciones que tendrá que enviar es muy bajo.
En este caso, para este tipo de uso, según lo que he podido leer, y atareao pone mucho énfasis en este punto, el mejor es Conduit por los pocos recursos que necesita así como los que consume.
Así que en primera instancia me fui a por la instalación de Conduit como servidor de Matrix y como he dicho, Lorenzo no lo ha puesto nada fácil, porque no había subido a su repositorio, como siempre hace, el docker-compose para la instalación, y ha sido una tarea ardua y nada sencilla.
Eso sí, lo cortés no quita lo valiente, y tengo que decir que Lorenzo sí que puso el docker-compose en este artículo, para instalar el servidor de Matrix y el cliente Cinny, pero no de la manera que nos tiene acostumbrados.
nota: Opinión personal: Con respecto a los artículos y más concretamente los vídeos de Lorenzo, antes sí explicaba todo el proceso de instalación, en plan rápido y explicaba un poco por encima lo que hace cada cosa, pero ya era algo por donde empezar, ahora en los nuevos vídeos esto no lo hace y se hace un poco más difícil ver y entender todo el conjunto. Que sí, de esta manera aprendes más, pero el inicio es más cuesta arriba.
Pues como iba diciendo, tenía un docker-compose.yml por el que empezar a trastear y en mi caso quedó de la siguiente manera:
cinny:
image: ajbura/cinny:latest
init: true
container_name: matrixCinny
networks:
- internal
volumes:
# Es el GitHub de Cinny, podéis encontrar un config.json para comenzar
- ${HOME}/config/matrix/cinny/config.json:/app/config.json
labels:
- traefik.enable=true
- traefik.http.services.cinny.loadbalancer.server.port=80
- traefik.http.routers.cinny-secure.entrypoints=websecure
- traefik.http.routers.cinny-secure.rule=Host(`${CINNY_SERVER}`)
- traefik.http.routers.cinny-secure.tls=true
# En este caso, encontré falta de información respecto a lo que hacen exactamente estos 2 middlewares.
# Más o menos ahora tengo claro qué hacen, pero...
- traefik.http.routers.cinny-secure.middlewares=traefik-real-ip@file,http2https@file
- traefik.http.routers.cinny-secure.tls.certresolver=letsencrypt
conduit:
image: matrixconduit/matrix-conduit:latest
container_name: matrixConduit
init: true
restart: unless-stopped
volumes:
- ${HOME}/config/matrix/db:/var/lib/matrix-conduit/
- ${HOME}/config/matrix/conduit.toml:/conduit.toml
environment:
CONDUIT_CONFIG: /conduit.toml
RUST_BACKTRACE: full
networks:
- internal
labels:
- traefik.enable=true
- traefik.http.services.conduit.loadbalancer.server.port=6167
- traefik.http.routers.conduit-secure.entrypoints=websecure
- traefik.http.routers.conduit-secure.rule=Host(`${MATRIX_SERVER}`)
- traefik.http.routers.conduit-secure.tls=true
- traefik.http.routers.conduit-secure.tls.certresolver=letsencrypt
- traefik.http.routers.conduit-secure.middlewares=cors-headers@docker
- traefik.http.middlewares.cors-headers.headers.accessControlAllowOriginList=*
- traefik.http.middlewares.cors-headers.headers.accessControlAllowHeaders=Origin, X-Requested-With, Content-Type, Accept, Authorization
- traefik.http.middlewares.cors-headers.headers.accessControlAllowMethods=GET, POST, PUT, DELETE, OPTIONS
well-known:
image: nginx:latest
container_name: matrixNginx
restart: unless-stopped
networks:
- internal
volumes:
- ${HOME}/config/matrix/nginx/matrix.conf:/etc/nginx/conf.d/matrix.conf # the config to serve the .well-known/matrix files
- ${HOME}/config/matrix/nginx/www:/var/www/ # location of the client and server .well-known-files
labels:
- traefik.enable=true
- traefik.http.routers.to-matrix-wellknown.rule=Host(`${MATRIX_SERVER}`) && PathPrefix(`/.well-known/matrix`)
- traefik.http.routers.to-matrix-wellknown.tls=true
- traefik.http.routers.to-matrix-wellknown.tls.certresolver=letsencrypt
- traefik.http.routers.to-matrix-wellknown.middlewares=cors-headers@docker
- traefik.http.middlewares.cors-headers.headers.accessControlAllowOriginList=*
- traefik.http.middlewares.cors-headers.headers.accessControlAllowHeaders=Origin, X-Requested-With, Content-Type, Accept, Authorization
- traefik.http.middlewares.cors-headers.headers.accessControlAllowMethods=GET, POST, PUT, DELETE, OPTIONS
Esto es el docker-compose.yml como ya he dicho, para Cinny, Conduit y WellKnown (Nginx), este último, por lo que he ido leyendo, entiendo que se usa más para todas las funcionalidades de cuando tu servidor de Matrix está federado con el resto de servidores, pero que en teoría, para un uso normal no haría falta, pero si lo usa Lorenzo seguramente algo se me escapa. Donde manda patrón, no manda marinero.
Así mismo, aparte del docker-compose.yml también se tienen que hacer unas modificaciones en el proxy que estés utilizando, que en mi caso es traefik. Las modificaciones que se tienen que hacer en el fichero traefik.yml son:
experimental:
plugins:
geoBlock:
moduleName: "github.com/PascalMinder/geoblock"
version: "v0.2.5"
traefik-real-ip:
modulename: github.com/soulbalz/traefik-real-ip
version: v1.0.3
A continuación la modificación que se tiene que hacer en dynamic.yml:
http:
middlewares:
http2https:
redirectScheme:
scheme: https
permanent: true
traefik-real-ip:
plugin:
traefik-real-ip:
excludednets:
- "1.1.1.1/24"
cors-headers:
headers:
accessControlAllowOriginList:
- "*"
accessControlAllowHeaders:
- "Origin"
- "X-Requested-With"
- "Content-Type"
- "Accept"
- "Authorization"
accessControlAllowMethods:
- "GET"
- "POST"
- "PUT"
- "DELETE"
- "OPTIONS"
routers:
conduit-secure:
rule: "Host(`${MATRIX_SERVER}`)"
entryPoints:
- "websecure"
# Servicio docker del Servidor de Matrix, en mi caso, Conduit
service: "conduit"
tls:
certResolver: "letsencrypt"
services:
conduit:
loadBalancer:
servers:
# URL del servicio de Conduit
- url: "http://conduit:6167"
Con esto, ya tendría que funcionar sin ningún problema nuestro servidor de Matrix. En principio es así, pero ahora es cuando te das de bruces con la realidad.
Lo primero es ver que si envías un mensaje desde la consola, este llegue correctamente a tu servidor y aquí es cuando empezaron mis problemas y eso que el script es fácil. Encontré miles de scripts. Pero la diferencia que había entre unos y otros, es que unos hacían uso de POST, que es la versión antigua para enviar los mensajes, y otros usaban el PUT que es la versión más actual y que todos los servidores de Matrix aceptan.
No os podéis imaginar la de problemas que tenía.
Llegué hasta un punto de eliminar el servidor de Conduit y probar con Synapse a ver si el problema radicaba en eso. También hice múltiples modificaciones a los ficheros de traefik (traefik.yml y dynamic.yml) y no conseguía que nada funcionase. El problema no estaba en el servidor que utilizase, sino más bien, en el script. Aquí fue donde sí que pedí ayuda a Lorenzo porque no sabía por dónde salir y fue cuando me pasó el script que lo solucionó todo y que pongo a continuación:
#! /bin/bash
MATRIX_SERVER="https://matrix.myserver.org"
TOKEN="TOKEN_MATRIX"
ROOM_ID="ROOM_ID:matrix.myserver.org"
curl -XPUT \
-H "Authorization: Bearer ${TOKEN}"\
-H "Content-Type: application/json"\
-d '{"msgtype":"m.text","body":"hello world"}' \
"https://${MATRIX_SERVER}/_matrix/client/v3/rooms/${ROOM_ID}:${MATRIX_SERVER}/send/m.room.message/$(date '+%s%3N')"
Con este simple script todo volvió a la vida y yo por fin podía ver la luz al final del camino.
No paré de enviar mensajes desde la consola al cliente, desde el cliente al móvil, desde el móvil al cliente y ahora sí, todo funcionaba correctamente.
Lo único que no me acababa de funcionar bien, era el tema de enviar imágenes, esto viene porque en una de las tareas que quiero usar, es necesario enviar imágenes, y no había manera de que en el cliente del portátil se pudieran ver las imágenes. En cambio en el móvil sí que las veía.
Para que veáis lo frustrante que es, llegué a probar todos los clientes habidos y por haber a través de web y en todos me pasaba lo mismo. Me pasé 3 días peleando contra esto y en todos me daba de bruces contra la pared. Hasta que se me ocurrió la brillante idea 💡, ¿por qué no lo hice antes?, de preguntar en el foro de Conduit. Lo que me respondieron era para darme de collejas hasta en el carnet de identidad. La pregunta era muy simple, ¿tienes el navegador en modo incógnito? 🤯
No me lo podía creer, no podía ser que por estar con esta configuración no se vieran las imágenes, pues ya os lo podéis imaginar. Sí, por esta tontería no se pueden ver las imágenes. Desactivé esa opción y las imágenes que enviaba las podía ver sin problemas en el cliente de mi portátil 🤬.
Llevaba 3 días intentando solucionar este problema y todo era por culpa del navegador Firefox que me estaba apuñalando por la espalda. Que es culpa mía porque podía haberlo preguntado antes, pero quién iba a pensar que por estar en modo incógnito se bloquearan las imágenes. Una cosa más que ya tenía solucionada.
Lo único que me faltaba era que los servicios pudieran enviar imágenes pero esto, ya os puedo decir que hasta donde yo sé, no es posible, porque por lo que he llegado a entender, y eso que he hecho miles de pruebas, y he leído mucho sobre este tema, es que primero se tiene que enviar la imagen al servidor de Matrix, para que te dé una especie de URL, más concretamente un MXC y luego con esta dirección tú ya puedes enviar un mensaje con esa imagen adjunta. Y no todos los servicios con los que se puede usar Matrix tienen ese tipo de funcionalidad implementada.
Aunque Matrix mismo podría cambiar esta manera de funcionar y funcionar de la misma manera que Telegram, Discord o Slack.
Pero bueno, ya podía hacer funcionar correctamente mi servidor de Matrix y podía enviar y recibir mensajes entre mis diferentes dispositivos.
Ahora solamente queda la opción de sacarle jugo al nuevo servicio. Pero esto ya lo explicaré en otro artículo que este me parece que ya se está haciendo muy largo. Porque también os tengo que decir que tuve que sudar sangre y lágrimas para conseguir lo que yo quería.