Installazione di Matrix-Synapse su Debian 12 con Nginx e TLSv1.3

Introduzione

In un mondo dominato da WhatsApp, Telegram e Signal, Matrix rappresenta una rivoluzione: non è solo un’altra app di messaggistica, ma un protocollo aperto e federato che restituisce il controllo delle comunicazioni agli utenti. Con Synapse, l’implementazione server di riferimento di Matrix, potete creare la vostra infrastruttura di comunicazione sovrana, sicura e interoperabile.

Questa guida vi accompagnerà nell’installazione completa di Matrix-Synapse su Debian 12, configurando un server production-ready con database PostgreSQL, reverse proxy Nginx, certificati SSL/TLS 1.3 e tutte le ottimizzazioni necessarie per gestire centinaia di utenti.

Cos’è Matrix e Perché è Rivoluzionario

Il Protocollo Matrix

Matrix è un protocollo di comunicazione che offre:

  • Federazione: Come l’email, utenti su server diversi possono comunicare liberamente
  • Decentralizzazione: Nessun controllo centrale, ogni organizzazione gestisce il proprio server
  • Crittografia E2E: Messaggi, file e chiamate protetti con algoritmi state-of-the-art
  • Interoperabilità: Bridge verso Telegram, WhatsApp, Discord, Slack e molti altri
  • Storia persistente: Conversazioni sincronizzate su tutti i dispositivi
  • Standard aperto: Specifiche pubbliche, nessun vendor lock-in

Synapse: Il Server Matrix

Synapse è l’implementazione di riferimento del server Matrix, sviluppata in Python. Offre:

  • Supporto completo delle specifiche Matrix
  • Gestione di stanze (room) con migliaia di utenti
  • Voice/Video calling tramite WebRTC
  • API REST per integrazione con altri servizi
  • Modularità e estensibilità attraverso plugin

Architettura del Sistema

Prima di iniziare, comprendiamo l’architettura che andremo a implementare:

┌─────────────────┐
│   Client Web    │  (Element, FluffyChat, etc.)
└────────┬────────┘
         │ HTTPS/WSS
         ↓
┌─────────────────┐
│     Nginx       │  (Reverse Proxy + TLS 1.3)
│   Port 443/8448 │
└────────┬────────┘
         │ HTTP
         ↓
┌─────────────────┐
│    Synapse      │  (Matrix Server)
│   Port 8008     │
└────────┬────────┘
         │
         ↓
┌─────────────────┐
│   PostgreSQL    │  (Database)
│   Port 5432     │
└─────────────────┘

Requisiti di Sistema

Hardware Minimo

  • CPU: 2 core per piccole istanze, 4+ core consigliati
  • RAM: Minimo 2GB, 4GB per 50 utenti, 8GB+ per centinaia di utenti
  • Storage: 20GB base + 500MB per utente attivo (multimedia inclusi)
  • Bandwidth: 100Mbps simmetrici consigliati per federazione attiva

Requisiti DNS

Prima di iniziare, configurate questi record DNS:

# Record A per il server Matrix
matrix.esempio.com    A    [IP_SERVER]

# SRV record per la federazione (opzionale ma consigliato)
_matrix._tcp.esempio.com    SRV    10 0 8448 matrix.esempio.com

# Record per delegazione (se il server_name è diverso dal dominio host)
_matrix._tcp.esempio.com    SRV    10 0 8448 matrix.esempio.com

Preparazione del Sistema

Aggiornamento e Strumenti Base

# Aggiornamento sistema
apt update && apt upgrade -y

# Installazione strumenti essenziali
apt install -y \
  curl wget gnupg lsb-release \
  apt-transport-https ca-certificates \
  software-properties-common \
  python3 python3-pip python3-venv \
  build-essential libssl-dev libffi-dev \
  python3-dev libjpeg-dev zlib1g-dev \
  libwebp-dev libxml2-dev libxslt1-dev \
  git ufw fail2ban

Configurazione Firewall

# Configurazione UFW
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp    # SSH
ufw allow 80/tcp    # HTTP
ufw allow 443/tcp   # HTTPS Client API
ufw allow 8448/tcp  # Federation API
ufw enable

Installazione PostgreSQL

PostgreSQL è il database consigliato per Synapse in produzione, offrendo performance superiori rispetto a SQLite:

# Installazione PostgreSQL
apt install -y postgresql postgresql-contrib

# Avvio e abilitazione
systemctl start postgresql
systemctl enable postgresql

# Creazione utente e database per Synapse
sudo -u postgres psql << EOF
CREATE USER synapse WITH PASSWORD 'password-sicura-qui';
CREATE DATABASE synapse ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' TEMPLATE=template0 OWNER synapse;
GRANT ALL PRIVILEGES ON DATABASE synapse TO synapse;
EOF

# Test connessione
sudo -u postgres psql -d synapse -c "SELECT version();"

Aggiunta Repository Ufficiale

# Download chiave GPG
wget -qO /usr/share/keyrings/matrix-org-archive-keyring.gpg \
  https://packages.matrix.org/debian/matrix-org-archive-keyring.gpg

# Aggiunta repository
echo "deb [signed-by=/usr/share/keyrings/matrix-org-archive-keyring.gpg] https://packages.matrix.org/debian/ $(lsb_release -cs) main" \
  > /etc/apt/sources.list.d/matrix-org.list

# Aggiornamento repository
apt update

Installazione Synapse

# Installazione Matrix Synapse
apt install -y matrix-synapse-py3

# Durante l'installazione vi verrà chiesto:
# - Server name: esempio.com (NON matrix.esempio.com)
# - Report anonymous statistics: No (per privacy)

Configurazione Principale

Il file di configurazione principale si trova in /etc/matrix-synapse/homeserver.yaml:

# Backup configurazione originale
cp /etc/matrix-synapse/homeserver.yaml /etc/matrix-synapse/homeserver.yaml.backup

# Modifica configurazione
nano /etc/matrix-synapse/homeserver.yaml

Parametri essenziali da configurare:

# Nome del server (IMPORTANTE: non può essere cambiato dopo!)
server_name: "esempio.com"

# URL pubblico del server
public_baseurl: "https://matrix.esempio.com/"

# Listener configuration
listeners:
  # Client API
  - port: 8008
    tls: false
    type: http
    x_forwarded: true
    bind_addresses: ['127.0.0.1']
    resources:
      - names: [client, federation]
        compress: true

# Database PostgreSQL
database:
  name: psycopg2
  args:
    user: synapse
    password: "password-sicura-qui"
    database: synapse
    host: localhost
    port: 5432
    cp_min: 5
    cp_max: 10

# Media store
media_store_path: "/var/lib/matrix-synapse/media"
max_upload_size: "50M"
max_image_pixels: "32M"
url_preview_enabled: true

# Registrazione utenti
enable_registration: false  # Cambiare in true per permettere registrazioni
registration_shared_secret: "GENERA-UN-SECRET-SICURO-QUI"
allow_guest_access: false

# Rate limiting
rc_message:
  per_second: 0.2
  burst_count: 10
rc_registration:
  per_second: 0.17
  burst_count: 3
rc_login:
  address:
    per_second: 0.17
    burst_count: 3
  account:
    per_second: 0.17
    burst_count: 3

# Retention policy (opzionale)
retention:
  enabled: true
  default_policy:
    min_lifetime: 1d
    max_lifetime: 365d
  allowed_lifetime_min: 1d
  allowed_lifetime_max: 365d

# Logging
log_config: "/etc/matrix-synapse/log.yaml"

# Trusted key servers
trusted_key_servers:
  - server_name: "matrix.org"

Generazione Secret Keys

# Generazione registration shared secret
echo "registration_shared_secret: \"$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)\"" 

# Generazione macaroon secret key
echo "macaroon_secret_key: \"$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)\""

# Generazione form secret
echo "form_secret: \"$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)\""

Configurazione Logging

# Creazione file di configurazione log
cat > /etc/matrix-synapse/log.yaml << 'EOF'
version: 1

formatters:
  precise:
    format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s'

handlers:
  file:
    class: logging.handlers.TimedRotatingFileHandler
    formatter: precise
    filename: /var/log/matrix-synapse/homeserver.log
    when: midnight
    backupCount: 7
    encoding: utf8
  console:
    class: logging.StreamHandler
    formatter: precise

loggers:
  synapse.storage.SQL:
    level: INFO

root:
  level: INFO
  handlers: [file, console]

disable_existing_loggers: false
EOF

Installazione Nginx

# Installazione Nginx
apt install -y nginx

# Rimozione configurazione default
rm /etc/nginx/sites-enabled/default

Configurazione Virtual Host

# Creazione configurazione Matrix
cat > /etc/nginx/sites-available/matrix << 'EOF'
# HTTP Redirect
server {
    listen 80;
    listen [::]:80;
    server_name matrix.esempio.com;
    return 301 https://$server_name$request_uri;
}

# HTTPS Server per Client API
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name matrix.esempio.com;

    # SSL Configuration
    ssl_certificate /etc/letsencrypt/live/matrix.esempio.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/matrix.esempio.com/privkey.pem;
    
    # Modern SSL configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
    ssl_prefer_server_ciphers off;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;

    # Security Headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options DENY;
    add_header X-XSS-Protection "1; mode=block";
    add_header Referrer-Policy "strict-origin-when-cross-origin";

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

    # Client API
    location ~* ^(\/_matrix|\/_synapse\/client) {
        proxy_pass http://127.0.0.1:8008;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;

        # Nginx by default only allows file uploads up to 1M in size
        client_max_body_size 50M;
        
        # Synapse responses may be chunked
        proxy_buffering off;
    }
    
    # Federation API
    location /.well-known/matrix/server {
        return 200 '{"m.server": "matrix.esempio.com:8448"}';
        add_header Content-Type application/json;
    }
    
    location /.well-known/matrix/client {
        return 200 '{"m.homeserver": {"base_url": "https://matrix.esempio.com"}}';
        add_header Content-Type application/json;
        add_header Access-Control-Allow-Origin *;
    }
}

# Federation Port (8448)
server {
    listen 8448 ssl http2 default_server;
    listen [::]:8448 ssl http2 default_server;
    server_name matrix.esempio.com;

    # SSL Configuration (same as above)
    ssl_certificate /etc/letsencrypt/live/matrix.esempio.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/matrix.esempio.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
    
    location / {
        proxy_pass http://127.0.0.1:8008;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
        proxy_buffering off;
    }
}
EOF

# Sostituite esempio.com con il vostro dominio
sed -i 's/esempio.com/IL-VOSTRO-DOMINIO/g' /etc/nginx/sites-available/matrix

# Abilitazione sito
ln -s /etc/nginx/sites-available/matrix /etc/nginx/sites-enabled/

# Test configurazione
nginx -t

# Installazione Certbot
apt install -y certbot python3-certbot-nginx

# Generazione certificato
certbot --nginx -d matrix.esempio.com \
  --non-interactive \
  --agree-tos \
  --email admin@esempio.com \
  --redirect

# Test rinnovo automatico
certbot renew --dry-run

# Configurazione rinnovo automatico
echo "0 0,12 * * * root certbot renew --quiet --post-hook 'systemctl reload nginx'" >> /etc/crontab

Avvio Servizi

# Riavvio e abilitazione servizi
systemctl restart matrix-synapse
systemctl enable matrix-synapse
systemctl restart nginx
systemctl enable nginx

# Verifica stato
systemctl status matrix-synapse
systemctl status nginx

Test Federazione

Verificate che la federazione funzioni correttamente:

# Test well-known
curl https://matrix.esempio.com/.well-known/matrix/server
curl https://matrix.esempio.com/.well-known/matrix/client

# Test federazione online
# Visitate: https://federationtester.matrix.org
# Inserite il vostro dominio e verificate i risultati

Registrazione Utente Admin

# Creazione utente admin via CLI
register_new_matrix_user -c /etc/matrix-synapse/homeserver.yaml

# Seguire i prompt:
# - Username: admin
# - Password: [password-sicura]
# - Make admin: yes

Gestione Utenti

# Lista utenti (richiede accesso al database)
sudo -u postgres psql -d synapse -c "SELECT name, admin FROM users;"

# Promuovere utente ad admin
sudo -u postgres psql -d synapse -c "UPDATE users SET admin = 1 WHERE name = '@username:esempio.com';"

# Reset password utente (tramite hash)
# Prima generare hash password con Python
python3 -c 'import bcrypt; print(bcrypt.hashpw(b"nuova-password", bcrypt.gensalt(rounds=12)).decode("ascii"))'

# Poi aggiornare nel database
sudo -u postgres psql -d synapse -c "UPDATE users SET password_hash = 'HASH-GENERATO' WHERE name = '@username:esempio.com';"

Web Client Element

Per fornire un client web ai vostri utenti, potete installare Element:

# Download Element
cd /var/www
wget https://github.com/vector-im/element-web/releases/latest/download/element-latest.tar.gz
tar -xzf element-latest.tar.gz
mv element-* element
chown -R www-data:www-data element

# Configurazione Element
cp element/config.sample.json element/config.json
nano element/config.json

# Modificare:
{
    "default_server_config": {
        "m.homeserver": {
            "base_url": "https://matrix.esempio.com",
            "server_name": "esempio.com"
        }
    },
    "brand": "Il Vostro Server Matrix",
    "default_country_code": "IT",
    "show_labs_settings": true
}

Configurazione Nginx per Element

# Aggiungere in /etc/nginx/sites-available/matrix

location /element {
    alias /var/www/element;
    index index.html;
    try_files $uri $uri/ /index.html;
}

# Reload Nginx
systemctl reload nginx

Tuning PostgreSQL

# Modifica /etc/postgresql/*/main/postgresql.conf

# Per 4GB RAM
shared_buffers = 1GB
effective_cache_size = 3GB
maintenance_work_mem = 256MB
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
random_page_cost = 1.1
work_mem = 10MB
max_connections = 200

# Restart PostgreSQL
systemctl restart postgresql

Worker di Synapse

Per server con alto carico, configurare worker separati:

# In /etc/matrix-synapse/homeserver.yaml
worker_app: synapse.app.generic_worker
worker_name: worker1
worker_replication_host: 127.0.0.1
worker_replication_http_port: 9093

worker_listeners:
  - type: http
    port: 8009
    resources:
      - names: [client, federation]

Cache Redis

# Installazione Redis
apt install -y redis-server

# Configurazione in homeserver.yaml
redis:
  enabled: true
  host: localhost
  port: 6379

Script di Backup

#!/bin/bash
# /opt/backup-matrix.sh

BACKUP_DIR="/backup/matrix"
DATE=$(date +%Y%m%d-%H%M%S)

# Creazione directory
mkdir -p $BACKUP_DIR

# Backup database
sudo -u postgres pg_dump synapse | gzip > $BACKUP_DIR/synapse-db-$DATE.sql.gz

# Backup media files
tar -czf $BACKUP_DIR/synapse-media-$DATE.tar.gz /var/lib/matrix-synapse/media

# Backup configurazione
tar -czf $BACKUP_DIR/synapse-config-$DATE.tar.gz /etc/matrix-synapse

# Pulizia backup vecchi (mantieni ultimi 7 giorni)
find $BACKUP_DIR -name "synapse-*" -mtime +7 -delete

echo "Backup completato: $DATE"

# Rendere eseguibile e programmare
chmod +x /opt/backup-matrix.sh
echo "0 3 * * * root /opt/backup-matrix.sh" >> /etc/crontab

Monitoraggio

# Monitoraggio log in tempo reale
tail -f /var/log/matrix-synapse/homeserver.log

# Statistiche database
sudo -u postgres psql -d synapse -c "SELECT pg_database_size('synapse');"

# Utenti attivi
sudo -u postgres psql -d synapse -c "SELECT COUNT(*) FROM users WHERE deactivated = 0;"

# Stanze federate
sudo -u postgres psql -d synapse -c "SELECT COUNT(DISTINCT room_id) FROM current_state_events;"

Fail2ban per Matrix

# Creazione filtro
cat > /etc/fail2ban/filter.d/matrix-synapse.conf << 'EOF'
[Definition]
failregex = .*Failed password for .* from 
ignoreregex =
EOF

# Creazione jail
cat > /etc/fail2ban/jail.d/matrix-synapse.conf << 'EOF'
[matrix-synapse]
enabled = true
filter = matrix-synapse
logpath = /var/log/matrix-synapse/homeserver.log
maxretry = 5
findtime = 600
bantime = 3600
action = iptables-multiport[name=matrix, port="443,8448"]
EOF

# Restart fail2ban
systemctl restart fail2ban

Rate Limiting Nginx

# Aggiungere in /etc/nginx/nginx.conf nella sezione http
limit_req_zone $binary_remote_addr zone=matrix_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=matrix_conn:10m;

# Aggiungere nelle location di /etc/nginx/sites-available/matrix
limit_req zone=matrix_limit burst=20 nodelay;
limit_conn matrix_conn 10;

Problemi Comuni

Errore: "No more federation connections available"

# Aumentare in homeserver.yaml
federation_max_concurrent_requests: 1000

Errore: Database connection pool exhausted

# Aumentare in homeserver.yaml sotto database.args
cp_max: 20
cp_min: 10

Media non caricano

# Verificare permessi
chown -R matrix-synapse:nogroup /var/lib/matrix-synapse/media
chmod -R 755 /var/lib/matrix-synapse/media

Comandi Utili

# Verifica configurazione
matrix-synapse --config-path=/etc/matrix-synapse/homeserver.yaml --generate-config --check

# Pulizia media vecchi
synapse_auto_compressor -c /etc/matrix-synapse/homeserver.yaml -p /var/lib/matrix-synapse/media

# Statistiche stanze
sudo -u postgres psql -d synapse -c "SELECT room_id, COUNT(*) as members FROM room_memberships WHERE membership = 'join' GROUP BY room_id ORDER BY members DESC LIMIT 10;"

Matrix supporta bridge verso altre piattaforme. Esempio per Telegram:

# Installazione mautrix-telegram
pip3 install --upgrade mautrix-telegram

# Configurazione
mautrix-telegram --generate-config
nano config.yaml

# Configurare homeserver e app service
# Registrare con Synapse
matrix-synapse --config-path=/etc/matrix-synapse/homeserver.yaml --generate-keys -f telegram-registration.yaml

Avete ora un server Matrix completamente funzionale, sicuro e pronto per la produzione. Il vostro team o comunità può comunicare in modo sovrano, sicuro e federato, mantenendo il pieno controllo dei propri dati.

Prossimi passi consigliati:

  • Configurare backup automatici offsite
  • Implementare monitoring con Prometheus/Grafana
  • Esplorare i bridge per integrare altre piattaforme
  • Considerare l'implementazione di bot per automazione
  • Unirsi a stanze pubbliche per testare la federazione

Matrix rappresenta il futuro delle comunicazioni decentralizzate. Con questa installazione, siete parte di una rete globale che rispetta la privacy e l'autonomia degli utenti.

Per supporto, visitate matrix.org/docs o unitevi alla stanza #synapse:matrix.org.