Dominio, HTTPS y proxies inversos
Coloque Antimatter en un nombre de dominio con HTTPS, usando el perfil de Caddy del archivo de composición o un proxy inverso propio, y configure correctamente la URL del sitio y las direcciones del cliente.
La URL del sitio
La URL del sitio (ServiceSettings.SiteURL) es la dirección que las personas usan para acceder a Antimatter, por ejemplo https://chat.example.com. El servidor la utiliza en los enlaces de correos electrónicos y notificaciones, en las redirecciones de inicio de sesión (OAuth, OpenID Connect, SAML), para las aplicaciones móviles y de escritorio, y para verificar de dónde provienen las solicitudes. Establezca exactamente la dirección que aparece en la barra de direcciones del navegador: esquema, dominio y puerto (si no es el predeterminado), sin barra diagonal final.
- Con el archivo de composición del sitio:
SITE_URLen.env. - En cualquier otro lugar:
AM_SERVICESETTINGS_SITEURL, o Consola de sistema › Entorno › Servidor web › URL del sitio.
Si la URL del sitio es incorrecta, el inicio de sesión con un proveedor de identidad fallará, los enlaces en los correos electrónicos apuntarán al lugar equivocado y las aplicaciones podrían no conectarse. Después de cambiar el dominio, actualícelo aquí y en las URL de redirección de cada proveedor de identidad.
HTTPS con el perfil de Caddy incluido
El archivo compose.yaml del sitio incluye un servicio de Caddy en el perfil https. Obtiene un certificado de Let's Encrypt, lo renueva automáticamente, redirige HTTP a HTTPS y reenvía todo, incluidos los websockets, a Antimatter.
- Apunte un registro DNS (A, y AAAA para IPv6) de su dominio al servidor.
- Abra los puertos 80/tcp, 443/tcp y 443/udp (HTTP/3) en el cortafuegos. Let's Encrypt debe poder acceder al puerto 80 o 443 desde Internet.
- Agregue el dominio a
.envy establezca la URL del sitio:echo "DOMAIN=chat.example.com" >> .env sed -i 's|^SITE_URL=.*|SITE_URL=https://chat.example.com|' .env - Inicie con el perfil:
docker compose --profile https up -d
Agregue --profile https a cada comando posterior de docker compose up, o coloque COMPOSE_PROFILES=https en .env para que un simple docker compose up -d lo incluya. Caddy guarda sus certificados en el volumen https.
El propio puerto de Antimatter sigue publicado en el host (HTTP_PORT, 8065 por defecto). Con Caddy al frente, consérvelo solo para el propio servidor:
echo "HTTP_PORT=127.0.0.1:8065" >> .env
docker compose --profile https up -d
Caddy se comunica con Antimatter a través de la red interna edge, no a través de ese puerto, por lo que esto no cambia nada para sus usuarios.
Con su propio proxy inverso (nginx)
Si el servidor ya ejecuta nginx u otro proxy, desactiva el perfil https y apunta el proxy al puerto 8065 de Antimatter. El proxy debe:
- transmitir las actualizaciones de websocket (la aplicación web y las aplicaciones móviles mantienen un websocket abierto en
/api/v4/websocket, y algunas aplicaciones abren los suyos propios); - aceptar cuerpos de solicitud al menos tan grandes como la mayor carga (Tamaño máximo de los Archivos, 100 MB por defecto);
- mantener abiertas las conexiones de larga duración (websockets, cargas y descargas grandes);
- transmitir la cabecera
Hosty la dirección del cliente.
Un bloque de servidor completo, adaptado de la plantilla de producción en antimatter-docker. Sustituye el dominio y las rutas de los certificados:
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;
}
}
Comprueba el archivo con nginx -t y aplícalo con systemctl reload nginx. El servidor envía por sí mismo X-Content-Type-Options, Referrer-Policy, Permissions-Policy y X-Frame-Options; solo HSTS depende del proxy. Aumenta su max-age una vez que HTTPS funcione, y añade includeSubDomains solo si todos los subdominios usan HTTPS.
Con Docker Compose y nginx en el host, el upstream anterior apunta al puerto publicado 8065. Publícalo solo en 127.0.0.1 (HTTP_PORT=127.0.0.1:8065), para que nadie eluda el proxy.
El repositorio antimatter-docker incluye una configuración completa con nginx en un contenedor y Let's Encrypt a través de certbot, en deploy/compose.
Otros proxies
Cualquier proxy funciona si cumple los cuatro puntos anteriores. El audio y el vídeo de las llamadas nunca pasan por el proxy: usan su propio puerto, ver Llamadas y voz.
Direcciones de cliente detrás de un proxy
Detrás de un proxy, todas las solicitudes parecen provenir del proxy. Para registrar la dirección real del cliente, aplicar límites de tasa por cliente y usar filtrado por IP, indica al servidor qué cabecera contiene la dirección y qué proxies puede confiar. Ninguna de estas configuraciones tiene un campo en la Consola de sistema: configúralas en config.json o con variables.
| Clave y variable | Predeterminado | Qué hace |
|---|---|---|
ServiceSettings.TrustedProxyIPHeader, AM_SERVICESETTINGS_TRUSTEDPROXYIPHEADER | vacío: el servidor usa la dirección de la conexión | Las cabeceras que contienen la dirección del cliente, por ejemplo X-Forwarded-For. Se usa la primera presente en la solicitud. |
ServiceSettings.TrustedProxyIPs, AM_SERVICESETTINGS_TRUSTEDPROXYIPS | vacío | Las direcciones o rangos CIDR de tus proxies, por ejemplo 172.29.71.0/28. Las cabeceras solo cuentan para las solicitudes que provienen de una de ellas. |
En una variable, separa varios valores con espacios: AM_SERVICESETTINGS_TRUSTEDPROXYIPHEADER="X-Forwarded-For X-Real-IP". El servidor rechaza una configuración que contenga en TrustedProxyIPs una entrada que no sea una dirección IP ni un rango CIDR.
Cómo el servidor encuentra la dirección del cliente
Cada proxy añade la dirección desde la que recibió la solicitud a la derecha de X-Forwarded-For. Lo que el cliente envió en el propio encabezado permanece a la izquierda. Así, el servidor lee el encabezado desde la derecha, omite las direcciones de tus proxies de confianza y toma la primera dirección restante como la del cliente. Un cliente no puede elegir su dirección enviando su propio encabezado.
- Detrás de un solo proxy,
TrustedProxyIPHeaderpor sí solo proporciona la dirección correcta: el servidor toma la dirección más a la derecha del encabezado. Registra una advertencia al inicio hasta que también configuresTrustedProxyIPs. Sin esta configuración, cualquiera que acceda directamente al puerto 8065 puede establecer el encabezado, por lo que publica ese puerto solo en127.0.0.1o en una red privada. - Detrás de varios proxies, por ejemplo un CDN o un equilibrador de carga delante de tu propio proxy, enumera todos ellos en
TrustedProxyIPs. De lo contrario, el servidor tomará la dirección del proxy externo como la del cliente. - El proxy puede reemplazar el encabezado con la dirección que ve, como hace el ejemplo de nginx anterior (
X-Forwarded-For $remote_addr), o añadir a él (el$proxy_add_x_forwarded_forde nginx). Ambas opciones funcionan.
Qué direcciones enumerar
Enumera la dirección desde la que llegan las solicitudes del proxy, tal como la ve Antimatter.
- Con el archivo compose del sitio y Caddy, esto ya está hecho: Caddy se comunica con Antimatter a través de la red
edge, y el archivo compose estableceTrustedProxyIPHeaderenX-Forwarded-ForyTrustedProxyIPsen el rango de esa red,EDGE_SUBNET(172.29.71.0/28a menos que lo cambies en.env). CambiaEDGE_SUBNETsi se superpone con una de tus redes. - La configuración de producción en antimatter-docker hace lo mismo para su contenedor nginx, con
FRONTEND_SUBNET. - Con nginx en el host y Antimatter en Docker, las solicitudes llegan a Antimatter a través del puerto publicado, generalmente desde la dirección de la puerta de enlace de la red del proyecto compose (se muestra con
docker network inspect). EstableceAM_SERVICESETTINGS_TRUSTEDPROXYIPSen esa dirección encompose.override.yaml. - Sin Docker, con nginx en el mismo host, es
127.0.0.1(y::1si nginx se conecta a través de IPv6).
TLS sin un proxy
El servidor también puede servir HTTPS por sí mismo, en Consola de sistema › Entorno › Servidor Web: Seguridad de Conexión configurado en TLS (ServiceSettings.ConnectionSecurity), con Archivo de Certificado TLS y Archivo llave TLS (ServiceSettings.TLSCertFile, ServiceSettings.TLSKeyFile), o Utilizar Let's Encrypt (ServiceSettings.UseLetsEncrypt). El servidor debe entonces escuchar en el puerto 443 (Dirección de escucha, ServiceSettings.ListenAddress, :8065 por defecto), y ServiceSettings.Forward80To443 redirige el puerto 80. Un proxy inverso es más fácil de ejecutar y renovar, y es lo que asume esta guía.
Tiempo de espera del servidor y tamaño de la solicitud
Configuraciones del propio servidor web del servidor, en Consola de sistema › Entorno › Servidor web:
| Ajuste | Clave | Predeterminado |
|---|---|---|
| Dirección de escucha | ServiceSettings.ListenAddress | :8065 |
| Tiempo de espera de lectura | ServiceSettings.ReadTimeout | 300 segundos |
| Tiempo de espera de escritura | ServiceSettings.WriteTimeout | 300 segundos |
| Tiempo de espera inactivo (sin campo en la Consola de sistema) | ServiceSettings.IdleTimeout | 60 segundos |
| Tamaño máximo de la carga (bytes) | ServiceSettings.MaximumPayloadSizeBytes | ver Seguridad |
Mantenga los propios tiempos de espera del proxy al menos tan largos como estos para las solicitudes normales, y su tamaño de cuerpo al menos Tamaño máximo de los Archivos.