Domínio, HTTPS e proxies reversos
Coloque o Antimatter num nome de domínio com HTTPS, utilizando o perfil Caddy do ficheiro compose ou um proxy reverso próprio, e configure corretamente a URL do site e os endereços dos clientes.
A URL do site
A URL do site (ServiceSettings.SiteURL) é o endereço que as pessoas utilizam para aceder ao Antimatter, como https://chat.example.com. O servidor utiliza-a nos links dos e-mails e notificações, nos redirecionamentos de início de sessão (OAuth, OpenID Connect, SAML), para as aplicações móveis e de desktop, e para verificar a origem das pedidos. Defina-a exatamente como o endereço na barra de endereços do navegador: esquema, domínio e porta (se não for a predefinida), sem barra final.
- Com o ficheiro compose do site:
SITE_URLno.env. - Em qualquer outro lugar:
AM_SERVICESETTINGS_SITEURL, ou Consola do sistema › Ambiente › Servidor web › URL do site.
Se a URL do site estiver incorreta, o início de sessão com um provedor de identidade falhará, os links nos e-mails apontarão para o local errado e as aplicações podem não conseguir ligar. Após alterar o domínio, atualize-a aqui e nos URLs de redirecionamento de todos os provedores de identidade.
HTTPS com o perfil Caddy incluído
O ficheiro compose.yaml do site inclui um serviço Caddy no perfil https. Este obtém um certificado da Let's Encrypt, renova-o automaticamente, redireciona o HTTP para HTTPS e encaminha tudo, incluindo websockets, para o Antimatter.
- Aponte um registo DNS (A, e AAAA para IPv6) do seu domínio para o servidor.
- Abra as portas 80/tcp, 443/tcp e 443/udp (HTTP/3) no firewall. A Let's Encrypt deve conseguir aceder à porta 80 ou 443 a partir da Internet.
- Adicione o domínio ao
.enve defina a URL do site:echo "DOMAIN=chat.example.com" >> .env sed -i 's|^SITE_URL=.*|SITE_URL=https://chat.example.com|' .env - Inicie com o perfil:
docker compose --profile https up -d
Adicione --profile https a todos os docker compose up subsequentes, ou coloque COMPOSE_PROFILES=https no .env para que um docker compose up -d simples o inclua. O Caddy guarda os seus certificados no volume https.
A própria porta do Antimatter continua a ser publicada no host (HTTP_PORT, 8065 por predefinição). Com o Caddy à frente, mantenha-a apenas para o próprio servidor:
echo "HTTP_PORT=127.0.0.1:8065" >> .env
docker compose --profile https up -d
O Caddy acede ao Antimatter através da rede interna edge, não através dessa porta, pelo que isto não altera nada para os seus utilizadores.
Com o seu próprio proxy reverso (nginx)
Se o servidor já executar o nginx ou outro proxy, desative o perfil https e aponte o proxy para a porta 8065 do Antimatter. O proxy deve:
- transmitir as atualizações de websocket (a aplicação web e as aplicações móveis mantêm um websocket aberto em
/api/v4/websocket, e algumas aplicações abrem os seus próprios); - aceitar corpos de pedido pelo menos do tamanho do maior carregamento (Tamanho máximo do ficheiro, 100 MB por omissão);
- manter as ligações de longa duração abertas (websockets, carregamentos e descargas grandes);
- transmitir o cabeçalho
Hoste o endereço do cliente.
Um bloco de servidor completo, adaptado do modelo de produção em antimatter-docker. Substitua o domínio e os caminhos dos 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;
}
}
Verifique o ficheiro com nginx -t e aplique-o com systemctl reload nginx. O servidor envia X-Content-Type-Options, Referrer-Policy, Permissions-Policy e X-Frame-Options por si mesmo; apenas o HSTS fica a cargo do proxy. Aumente o seu max-age quando o HTTPS estiver a funcionar e adicione includeSubDomains apenas se todos os subdomínios usarem HTTPS.
Com Docker Compose e nginx no anfitrião, o upstream acima aponta para a porta 8065 publicada. Publique-a apenas em 127.0.0.1 (HTTP_PORT=127.0.0.1:8065), para que ninguém contorne o proxy.
O repositório antimatter-docker tem uma configuração completa com nginx num contentor e Let's Encrypt através do certbot, em deploy/compose.
Outros proxies
Qualquer proxy funciona se cumprir os quatro pontos acima. As chamadas de áudio e vídeo nunca passam pelo proxy: usam a sua própria porta, veja Chamadas e voz.
Endereços de clientes atrás de um proxy
Atrás de um proxy, todos os pedidos parecem vir do proxy. Para registar o endereço real do cliente, aplicar limites de taxa por cliente e usar filtragem de IP, indique ao servidor qual o cabeçalho que transporta o endereço e quais os proxies em que pode confiar. Nenhuma destas definições tem um campo na Consola do sistema: configure-as em config.json ou com variáveis.
| Chave e variável | Padrão | O que faz |
|---|---|---|
ServiceSettings.TrustedProxyIPHeader, AM_SERVICESETTINGS_TRUSTEDPROXYIPHEADER | vazio: o servidor usa o endereço da ligação | Os cabeçalhos que transportam o endereço do cliente, por exemplo X-Forwarded-For. O primeiro presente num pedido é utilizado. |
ServiceSettings.TrustedProxyIPs, AM_SERVICESETTINGS_TRUSTEDPROXYIPS | vazio | Os endereços ou intervalos CIDR dos seus proxies, por exemplo 172.29.71.0/28. Os cabeçalhos só contam para pedidos que venham de um deles. |
Numa variável, separe vários valores com espaços: AM_SERVICESETTINGS_TRUSTEDPROXYIPHEADER="X-Forwarded-For X-Real-IP". O servidor rejeita uma configuração com uma entrada em TrustedProxyIPs que não seja um endereço IP nem um intervalo CIDR.
Como o servidor encontra o endereço do cliente
Cada proxy adiciona o endereço de onde recebeu o pedido à direita de X-Forwarded-For. O que o cliente enviou no próprio cabeçalho permanece à esquerda. Assim, o servidor lê o cabeçalho a partir da direita, ignora os endereços dos seus proxies de confiança e toma o primeiro outro endereço como o do cliente. Um cliente não pode escolher o seu endereço enviando o seu próprio cabeçalho.
- Atrás de um proxy, apenas
TrustedProxyIPHeaderfornece o endereço correto: o servidor toma o endereço mais à direita do cabeçalho. Regista um aviso no arranque até também definirTrustedProxyIPs. Sem ele, qualquer pessoa que aceda diretamente à porta 8065 pode definir o cabeçalho, pelo que publique essa porta apenas em127.0.0.1ou numa rede privada. - Atrás de vários proxies, por exemplo um CDN ou um balanceador de carga à frente do seu próprio proxy, liste todos eles em
TrustedProxyIPs. Caso contrário, o servidor toma o endereço do proxy externo como o do cliente. - O proxy pode substituir o cabeçalho pelo endereço que vê, como faz o exemplo nginx acima (
X-Forwarded-For $remote_addr), ou acrescentar-lhe (o$proxy_add_x_forwarded_fordo nginx). Ambos funcionam.
Que endereços listar
Liste o endereço de onde vêm os pedidos do proxy, tal como o Antimatter o vê.
- Com o ficheiro compose do site e o Caddy, isto já está feito: o Caddy acede ao Antimatter através da rede
edge, e o ficheiro compose defineTrustedProxyIPHeadercomoX-Forwarded-ForeTrustedProxyIPscomo o intervalo dessa rede,EDGE_SUBNET(172.29.71.0/28, a menos que o altere em.env). AltereEDGE_SUBNETse este se sobrepor a uma das suas redes. - A configuração de produção em antimatter-docker faz o mesmo para o seu contentor nginx, com
FRONTEND_SUBNET. - Com nginx no host e Antimatter no Docker, os pedidos chegam ao Antimatter através da porta publicada, normalmente a partir do endereço do gateway da rede do projeto compose (
docker network inspectmostra-o). DefinaAM_SERVICESETTINGS_TRUSTEDPROXYIPSpara esse endereço emcompose.override.yaml. - Sem Docker, com nginx no mesmo host, é
127.0.0.1(e::1se o nginx se ligar através de IPv6).
TLS sem proxy
O servidor também pode servir HTTPS diretamente, em Consola do sistema › Ambiente › Servidor web: Segurança da ligação definido como TLS (ServiceSettings.ConnectionSecurity), com Ficheiro de certificado TLS e Ficheiro de chave privada TLS (ServiceSettings.TLSCertFile, ServiceSettings.TLSKeyFile), ou Utilizar Let’s Encrypt (ServiceSettings.UseLetsEncrypt). O servidor deve, nesse caso, escutar na porta 443 (Endereço de escuta, ServiceSettings.ListenAddress, :8065 por omissão), e ServiceSettings.Forward80To443 redireciona a porta 80. Um proxy reverso é mais fácil de executar e renovar, e é o que este guia pressupõe.
Tempos limite do servidor e tamanho das pedidos
Definições do próprio servidor web do servidor, em Consola do sistema › Ambiente › Servidor web:
| Definição | Chave | Padrão |
|---|---|---|
| Endereço de escuta | ServiceSettings.ListenAddress | :8065 |
| Tempo limite de leitura | ServiceSettings.ReadTimeout | 300 segundos |
| Tempo limite de escrita | ServiceSettings.WriteTimeout | 300 segundos |
| Tempo limite de inatividade (sem campo na Consola do sistema) | ServiceSettings.IdleTimeout | 60 segundos |
| Tamanho máximo da carga (bytes) | ServiceSettings.MaximumPayloadSizeBytes | ver Segurança |
Mantenha os tempos limite do próprio proxy pelo menos tão longos como estes para pedidos normais, e o tamanho do corpo pelo menos Tamanho máximo do ficheiro.