Dominio, HTTPS e proxy inversi
Pubblica Antimatter su un nome di dominio con HTTPS, utilizzando il profilo Caddy del file compose o un proxy inverso di tua scelta, e configura correttamente l'URL del sito e gli indirizzi dei client.
L'URL del sito
L'URL del sito (ServiceSettings.SiteURL) è l'indirizzo che gli utenti utilizzano per raggiungere Antimatter, ad esempio https://chat.example.com. Il server lo utilizza nei link delle e-mail e delle notifiche, nei reindirizzamenti di accesso (OAuth, OpenID Connect, SAML), per le app mobile e desktop e per verificare da dove provengono le richieste. Impostalo esattamente come l'indirizzo nella barra degli indirizzi del browser: schema, dominio e porta (se non è quella predefinita), senza barra finale.
- Con il file compose del sito:
SITE_URLin.env. - Altrove:
AM_SERVICESETTINGS_SITEURL, oppure Console di Sistema › Ambiente › Server Web › URL del sito.
Se l'URL del sito è errato, l'accesso con un provider di identità fallisce, i link nelle e-mail puntano al posto sbagliato e le app potrebbero non connettersi. Dopo aver cambiato dominio, aggiornalo qui e negli URL di reindirizzamento di ogni provider di identità.
HTTPS con il profilo Caddy incluso
Il file compose.yaml del sito include un servizio Caddy nel profilo https. Ottiene un certificato da Let's Encrypt, lo rinnova automaticamente, reindirizza HTTP a HTTPS e inoltra tutto, inclusi i websocket, ad Antimatter.
- Punta un record DNS (A, e AAAA per IPv6) del tuo dominio al server.
- Apri le porte 80/tcp, 443/tcp e 443/udp (HTTP/3) nel firewall. Let's Encrypt deve poter raggiungere la porta 80 o 443 da Internet.
- Aggiungi il dominio a
.enve imposta l'URL del sito:echo "DOMAIN=chat.example.com" >> .env sed -i 's|^SITE_URL=.*|SITE_URL=https://chat.example.com|' .env - Avvia con il profilo:
docker compose --profile https up -d
Aggiungi --profile https a ogni successivo docker compose up, oppure inserisci COMPOSE_PROFILES=https in .env in modo che un semplice docker compose up -d lo includa. Caddy conserva i suoi certificati nel volume https.
La porta di Antimatter resta pubblicata sull'host (HTTP_PORT, 8065 di default). Con Caddy davanti, lasciala disponibile solo per il server stesso:
echo "HTTP_PORT=127.0.0.1:8065" >> .env
docker compose --profile https up -d
Caddy raggiunge Antimatter tramite la rete interna edge, non attraverso quella porta, quindi questo non cambia nulla per i tuoi utenti.
Con un tuo proxy inverso (nginx)
Se il server esegue già nginx o un altro proxy, disabilita il profilo https e punta il proxy alla porta 8065 di Antimatter. Il proxy deve:
- consentire l'upgrade a websocket (l'app web e le app mobili mantengono aperto un websocket su
/api/v4/websocket, e alcune app ne aprono di propri); - accettare corpi di richiesta almeno grandi quanto il caricamento più grande (Dimensione massima file, 100 MB di default);
- mantenere aperte le connessioni a lunga durata (websockets, caricamenti e scaricamenti di grandi dimensioni);
- trasmettere l'intestazione
Hoste l'indirizzo del client.
Un blocco server completo, adattato dal modello di produzione in antimatter-docker. Sostituisci il dominio e i percorsi dei certificati:
upstream antimatter {
server 127.0.0.1:8065;
keepalive 64;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' '';
}
proxy_cache_path /var/cache/nginx/antimatter levels=1:2 keys_zone=antimatter_cache:10m
max_size=3g inactive=120m use_temp_path=off;
server {
listen 80;
listen [::]:80;
server_name chat.example.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name chat.example.com;
ssl_certificate /etc/ssl/chat.example.com/fullchain.pem;
ssl_certificate_key /etc/ssl/chat.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_timeout 1d;
ssl_session_cache shared:AntimatterSSL:10m;
ssl_session_tickets off;
add_header Strict-Transport-Security "max-age=31536000" always;
# At least FileSettings.MaxFileSize (100 MB by default).
client_max_body_size 100M;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffers 256 16k;
proxy_buffer_size 16k;
location ~ ^/api/v[0-9]+/(users/)?websocket$ {
client_body_timeout 60s;
send_timeout 300s;
lingering_timeout 5s;
proxy_connect_timeout 90s;
proxy_send_timeout 300s;
proxy_read_timeout 90s;
proxy_pass http://antimatter;
}
location / {
proxy_read_timeout 600s;
proxy_cache antimatter_cache;
proxy_cache_revalidate on;
proxy_cache_min_uses 2;
proxy_cache_use_stale timeout;
proxy_cache_lock on;
proxy_pass http://antimatter;
}
}
Verifica il file con nginx -t e applicalo con systemctl reload nginx. Il server invia autonomamente X-Content-Type-Options, Referrer-Policy, Permissions-Policy e X-Frame-Options; solo HSTS è a carico del proxy. Aumenta il suo max-age una volta che HTTPS funziona, e aggiungi includeSubDomains solo se tutti i sottodomini utilizzano HTTPS.
Con Docker Compose e nginx sull'host, l'upstream sopra punta alla porta pubblicata 8065. Pubblicala solo su 127.0.0.1 (HTTP_PORT=127.0.0.1:8065), in modo che nessuno possa aggirare il proxy.
Il repository antimatter-docker contiene una configurazione completa con nginx in un container e Let's Encrypt tramite certbot, in deploy/compose.
Altri proxy
Qualsiasi proxy funziona se soddisfa i quattro punti sopra. Le chiamate audio e video non passano mai attraverso il proxy: utilizzano la propria porta, vedi Chiamate e voce.
Indirizzi client dietro un proxy
Dietro un proxy, ogni richiesta sembra provenire dal proxy. Per registrare l'indirizzo reale del client, applicare limiti di frequenza per client e utilizzare il filtraggio IP, indica al server quale intestazione contiene l'indirizzo e quali proxy possono essere considerati affidabili. Nessuna di queste impostazioni ha un campo nella Console di Sistema: impostale in config.json o con variabili.
| Chiave e variabile | Predefinito | Funzione |
|---|---|---|
ServiceSettings.TrustedProxyIPHeader, AM_SERVICESETTINGS_TRUSTEDPROXYIPHEADER | vuoto: il server utilizza l'indirizzo della connessione | Le intestazioni che contengono l'indirizzo del client, ad esempio X-Forwarded-For. Viene utilizzata la prima presente nella richiesta. |
ServiceSettings.TrustedProxyIPs, AM_SERVICESETTINGS_TRUSTEDPROXYIPS | vuoto | Gli indirizzi o gli intervalli CIDR dei tuoi proxy, ad esempio 172.29.71.0/28. Le intestazioni contano solo per le richieste che provengono da uno di questi. |
In una variabile, separa più valori con spazi: AM_SERVICESETTINGS_TRUSTEDPROXYIPHEADER="X-Forwarded-For X-Real-IP". Il server rifiuta una configurazione in cui un elemento di TrustedProxyIPs non è né un indirizzo IP né un intervallo CIDR.
Come il server individua l'indirizzo del client
Ogni proxy aggiunge a destra di X-Forwarded-For l'indirizzo da cui ha ricevuto la richiesta. Ciò che il client ha inviato nell'intestazione stessa resta a sinistra. Il server legge quindi l'intestazione da destra, ignora gli indirizzi dei proxy di fiducia e prende il primo indirizzo diverso come quello del client. Un client non può scegliere il proprio indirizzo inviando la propria intestazione.
- Dietro un solo proxy,
TrustedProxyIPHeaderda solo fornisce l'indirizzo corretto: il server prende l'indirizzo più a destra dell'intestazione. Al momento dell'avvio registra un avviso finché non imposti ancheTrustedProxyIPs. Senza di esso, chiunque raggiunga direttamente la porta 8065 può impostare l'intestazione, quindi pubblica quella porta solo su127.0.0.1o su una rete privata. - Dietro più proxy, ad esempio un CDN o un bilanciatore di carico davanti al tuo proxy, elenca tutti in
TrustedProxyIPs. Altrimenti il server prende l'indirizzo del proxy esterno come quello del client. - Il proxy può sostituire l'intestazione con l'indirizzo che vede, come fa l'esempio nginx sopra (
X-Forwarded-For $remote_addr), oppure aggiungerla (con$proxy_add_x_forwarded_fordi nginx). Entrambi i metodi funzionano.
Quali indirizzi elencare
Elenca l'indirizzo da cui provengono le richieste del proxy, così come lo vede Antimatter.
- Con il file compose del sito e Caddy, questo è già fatto: Caddy raggiunge Antimatter attraverso la rete
edge, e il file compose impostaTrustedProxyIPHeadersuX-Forwarded-ForeTrustedProxyIPssull'intervallo di quella rete,EDGE_SUBNET(172.29.71.0/28a meno che non lo modifichi in.env). ModificaEDGE_SUBNETse sovrappone una delle tue reti. - La configurazione di produzione in antimatter-docker fa lo stesso per il suo container nginx, con
FRONTEND_SUBNET. - Con nginx sull'host e Antimatter in Docker, le richieste raggiungono Antimatter attraverso la porta pubblicata, di solito dall'indirizzo gateway della rete del progetto compose (visibile con
docker network inspect). ImpostaAM_SERVICESETTINGS_TRUSTEDPROXYIPSsu quell'indirizzo incompose.override.yaml. - Senza Docker, con nginx sullo stesso host, è
127.0.0.1(e::1se nginx si connette tramite IPv6).
TLS senza proxy
Il server può anche gestire direttamente HTTPS, in Console di Sistema › Ambiente › Server Web: Sicurezza connessione impostata su TLS (ServiceSettings.ConnectionSecurity), con File del certificato TLS e File della chiave TLS (ServiceSettings.TLSCertFile, ServiceSettings.TLSKeyFile), oppure Utilizza Let's Encrypt (ServiceSettings.UseLetsEncrypt). In questo caso, il server deve ascoltare sulla porta 443 (Indirizzo di ascolto, ServiceSettings.ListenAddress, :8065 di default) e ServiceSettings.Forward80To443 reindirizza la porta 80. Un reverse proxy è più semplice da gestire e aggiornare, ed è ciò che questa guida presuppone.
Timeout del server e dimensione delle richieste
Impostazioni del server web del server, in Console di Sistema › Ambiente › Server Web:
| Impostazione | Chiave | Predefinito |
|---|---|---|
| Indirizzo di ascolto | ServiceSettings.ListenAddress | :8065 |
| Timeout lettura | ServiceSettings.ReadTimeout | 300 secondi |
| Timeout scrittura | ServiceSettings.WriteTimeout | 300 secondi |
| Timeout di inattività (nessun campo nella Console di Sistema) | ServiceSettings.IdleTimeout | 60 secondi |
| Dimensione massima payload (byte) | ServiceSettings.MaximumPayloadSizeBytes | vedi Sicurezza |
Mantieni i timeout del proxy almeno pari a questi per le richieste normali, e la dimensione del body almeno pari a Dimensione Massima File.