From 6e7b35a87f81bdf69a93f77feec3541cbbb93515 Mon Sep 17 00:00:00 2001 From: Enmanuel Date: Tue, 18 Nov 2025 23:50:42 +0000 Subject: [PATCH] primer intento authenticacion qr mas --- .gitignore | 8 ++++- docker-compose.yml | 34 ++++++++++++++++++ mas/README.md | 74 ++++++++++++++++++++++++++++++++++++++++ mas/config.example.yaml | 65 +++++++++++++++++++++++++++++++++++ mas/keys/.gitkeep | 0 mas/scripts/bootstrap.sh | 64 ++++++++++++++++++++++++++++++++++ mas/secrets/.gitkeep | 0 7 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 mas/README.md create mode 100644 mas/config.example.yaml create mode 100644 mas/keys/.gitkeep create mode 100755 mas/scripts/bootstrap.sh create mode 100644 mas/secrets/.gitkeep diff --git a/.gitignore b/.gitignore index 16b726e..b2fa436 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,11 @@ certs/ # Configuraciones sensibles generadas en tiempo de despliegue configs/livekit/livekit.yaml configs/well-known/matrix-client.json +mas/config.yaml +mas/secrets/* +!mas/secrets/.gitkeep +mas/keys/* +!mas/keys/.gitkeep # Archivos de media de Matrix (pueden ser muy grandes) */media_store/ @@ -43,4 +48,5 @@ configs/well-known/matrix-client.json # Archivos de estado de Docker .dockerignore -element-call \ No newline at end of file +element-call + diff --git a/docker-compose.yml b/docker-compose.yml index da6cb5d..2c31580 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,6 +14,19 @@ services: ports: - "5432:5432" + mas-postgres: + image: postgres:16 + restart: unless-stopped + networks: + default: + ipv4_address: 10.10.10.14 + volumes: + - mas_postgres_data:/var/lib/postgresql/data + environment: + - POSTGRES_DB=mas + - POSTGRES_USER=mas_user + - POSTGRES_PASSWORD=mas_password + element: image: vectorim/element-web:latest restart: unless-stopped @@ -51,6 +64,25 @@ services: depends_on: - synapse + mas: + image: ghcr.io/element-hq/matrix-authentication-service:latest + restart: unless-stopped + depends_on: + - mas-postgres + - synapse + networks: + default: + ipv4_address: 10.10.10.15 + volumes: + - ./mas/config.yaml:/etc/mas/config.yaml:ro + - ./mas/secrets:/run/mas/secrets:ro + - ./mas/keys:/run/mas/keys:ro + environment: + - MAS_CONFIG=/etc/mas/config.yaml + command: ["server", "--config", "/etc/mas/config.yaml"] + ports: + - "8083:8080" + wellknown: image: nginx:alpine restart: unless-stopped @@ -74,6 +106,8 @@ volumes: matrix_postgres_data: external: true name: matrix_postgres_data + mas_postgres_data: + driver: local networks: default: diff --git a/mas/README.md b/mas/README.md new file mode 100644 index 0000000..a0dc7bb --- /dev/null +++ b/mas/README.md @@ -0,0 +1,74 @@ +# Matrix Authentication Service setup + +Este directorio contiene la configuración base para desplegar +[Matrix Authentication Service (MAS)](https://github.com/element-hq/matrix-authentication-service) +junto al stack de Synapse/Element. MAS es el componente necesario para poder +delegar el inicio de sesión al flujo OIDC moderno y activar el acceso mediante +código QR (MSC4108) desde Element móvil. + +## Estructura + +``` +mas/ +├── config.example.yaml # Plantilla de configuración +├── config.yaml # (generado) Config en uso por el contenedor +├── keys/ # Claves de firma de OIDC (no se versionan) +├── scripts/bootstrap.sh # Script para generar secretos/clave y copiar la config +└── secrets/ # Secretos usados tanto por MAS como por Synapse +``` + +Los archivos dentro de `keys/` y `secrets/` están ignorados en git para evitar +exponer credenciales. El script `scripts/bootstrap.sh` genera la estructura +mínima necesaria y solo debe ejecutarse una vez (puedes volver a lanzarlo si +algún archivo falta). + +## Pasos rápidos + +1. Copia la plantilla de configuración y genera secretos/clave privada: + ```bash + cd mas + ./scripts/bootstrap.sh + ``` + Esto crea: + - `config.yaml` (copiado desde `config.example.yaml`). + - `secrets/encryption.key`: clave hex de 32 bytes para cifrado interno. + - `secrets/shared_secret.txt`: token compartido con Synapse (MAS API). + - `keys/mas_signing.key`: clave RSA 2048 bits para firmar tokens OIDC. + +2. Edita `config.yaml` y ajusta: + - `http.public_base`: dominio público donde expondrás MAS + (ej. `https://auth-af2f3d.organic-machine.com/`). + - `matrix.homeserver`: nombre del servidor Matrix si cambia. + - El string de conexión a Postgres si usas credenciales distintas. + +3. Copia el contenido de `secrets/shared_secret.txt` y pégalo en + `synapse_data/homeserver.yaml` dentro de + `matrix_authentication_service.secret` (agregado en este PR). + +4. Publica MAS detrás de tu reverse-proxy/Coolify redirigiendo + `/_matrix/client/*/(login|logout|refresh)` hacia el puerto del servicio. + +Consulta la guía en la raíz (`README.md`) para reiniciar los contenedores con +`docker compose`. Una vez que Synapse y MAS estén en marcha verás el flag +`org.matrix.msc4108: true` al consultar +`https://matrix-af2f3d.organic-machine.com/_matrix/client/versions` y Element +mostrará el inicio de sesión por QR. + +## Reverse proxy / Coolify + +- Publica MAS en un subdominio (p.ej. `auth-af2f3d.organic-machine.com`) que + apunte al puerto `8083` definido en `docker-compose.yml`. +- Copia las rutas de compatibilidad: + ``` + location ~ ^/_matrix/client/(.*)/(login|logout|refresh) { + proxy_pass http://10.10.10.7:8080; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $host; + } + ``` + Ajusta la IP/puerto si usas otra red interna o si el reverse proxy corre en + otro host. En Coolify puedes crear una regla HTTP adicional que apunte al + contenedor `mas`. +- Expón el endpoint de rendezvous en `https://auth.../_matrix/client/unstable/org.matrix.msc4108/rendezvous` + para que el valor coincida con `msc4108_delegation_endpoint` en + `synapse_data/homeserver.yaml`. diff --git a/mas/config.example.yaml b/mas/config.example.yaml new file mode 100644 index 0000000..7eebfe0 --- /dev/null +++ b/mas/config.example.yaml @@ -0,0 +1,65 @@ +# Configuration example for Matrix Authentication Service. +# Copia este archivo a `config.yaml` y ajusta los valores necesarios. + +http: + public_base: https://auth-af2f3d.organic-machine.com/ + listeners: + - name: web + resources: + - name: discovery + - name: human + - name: oauth + - name: compat + - name: graphql + - name: assets + binds: + - host: 0.0.0.0 + port: 8080 + proxy_protocol: false + + trusted_proxies: + - 192.168.0.0/16 + - 172.16.0.0/12 + - 10.0.0.0/10 + - 127.0.0.1/8 + - fd00::/8 + - ::1/128 + +database: + uri: postgresql://mas_user:mas_password@mas-postgres:5432/mas + max_connections: 5 + min_connections: 1 + connect_timeout: 30 + +email: + transport: blackhole + from: '"Matrix Authentication Service" ' + +matrix: + kind: synapse + homeserver: matrix-af2f3d.organic-machine.com + endpoint: http://synapse:8008 + secret_file: /run/mas/secrets/shared_secret.txt + +secrets: + encryption_file: /run/mas/secrets/encryption.key + keys: + - key_file: /run/mas/keys/mas_signing.key + +policy: + path: /usr/local/share/mas-cli/policy.wasm + +templates: + path: /usr/local/share/mas-cli/templates/ + assets_manifest: /usr/local/share/mas-cli/assets/manifest.json + translations_path: /usr/local/share/mas-cli/translations/ + +compat: + login: + enabled: true + logout: + enabled: true + refresh: + enabled: true + +clients: [] diff --git a/mas/keys/.gitkeep b/mas/keys/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/mas/scripts/bootstrap.sh b/mas/scripts/bootstrap.sh new file mode 100755 index 0000000..9ed7d2c --- /dev/null +++ b/mas/scripts/bootstrap.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +CONFIG_FILE="${ROOT_DIR}/config.yaml" +CONFIG_TEMPLATE="${ROOT_DIR}/config.example.yaml" +SECRETS_DIR="${ROOT_DIR}/secrets" +KEYS_DIR="${ROOT_DIR}/keys" +ENCRYPTION_FILE="${SECRETS_DIR}/encryption.key" +SHARED_SECRET_FILE="${SECRETS_DIR}/shared_secret.txt" +SIGNING_KEY_FILE="${KEYS_DIR}/mas_signing.key" + +command -v openssl >/dev/null 2>&1 || { + echo "openssl es requerido para generar los secretos." >&2 + exit 1 +} + +mkdir -p "${SECRETS_DIR}" "${KEYS_DIR}" + +if [ ! -f "${CONFIG_TEMPLATE}" ]; then + echo "No se encontró ${CONFIG_TEMPLATE}, abortando." >&2 + exit 1 +fi + +if [ ! -f "${CONFIG_FILE}" ]; then + cp "${CONFIG_TEMPLATE}" "${CONFIG_FILE}" + echo "Se creó ${CONFIG_FILE} a partir de la plantilla." +else + echo "Ya existe ${CONFIG_FILE}, se deja intacto." +fi + +if [ ! -f "${ENCRYPTION_FILE}" ]; then + openssl rand -hex 32 > "${ENCRYPTION_FILE}" + chmod 600 "${ENCRYPTION_FILE}" + echo "Generada clave de cifrado en ${ENCRYPTION_FILE}" +else + echo "Ya existe ${ENCRYPTION_FILE}" +fi + +if [ ! -f "${SHARED_SECRET_FILE}" ]; then + openssl rand -hex 48 > "${SHARED_SECRET_FILE}" + chmod 600 "${SHARED_SECRET_FILE}" + echo "Generado secreto compartido en ${SHARED_SECRET_FILE}" +else + echo "Ya existe ${SHARED_SECRET_FILE}" +fi + +if [ ! -f "${SIGNING_KEY_FILE}" ]; then + openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out "${SIGNING_KEY_FILE}" >/dev/null + chmod 600 "${SIGNING_KEY_FILE}" + echo "Generada clave RSA en ${SIGNING_KEY_FILE}" +else + echo "Ya existe ${SIGNING_KEY_FILE}" +fi + +cat <