Domínio, HTTPS e proxies reversos
Coloque o Antimatter em um nome de domínio com HTTPS, usando o perfil Caddy do arquivo 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 usam para acessar o Antimatter, como https://chat.example.com. O servidor a usa em links de e-mails e notificações, em redirecionamentos de login (OAuth, OpenID Connect, SAML), para os aplicativos móveis e de desktop, e para verificar de onde vêm as solicitações. Defina-a exatamente como o endereço na barra de endereços do navegador: esquema, domínio e porta (se não for a padrão), sem barra no final.
- Com o arquivo compose do site:
SITE_URLem.env. - Em qualquer outro lugar:
AM_SERVICESETTINGS_SITEURL, ou Console do Sistema › Ambiente › Servidor Web › Site URL.
Se a URL do site estiver incorreta, o login com um provedor de identidade falhará, os links nos e-mails apontarão para o lugar errado e os aplicativos podem não se conectar. Após alterar o domínio, atualize-a aqui e nas URLs de redirecionamento de todos os provedores de identidade.
HTTPS com o perfil Caddy incluído
O arquivo compose.yaml do site inclui um serviço Caddy no perfil https. Ele obtém um certificado da Let's Encrypt, renova-o automaticamente, redireciona HTTP para HTTPS e encaminha tudo, incluindo websockets, para o Antimatter.
- Aponte um registro 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 acessar a 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 cada docker compose up subsequente, ou coloque COMPOSE_PROFILES=https em .env para que um simples docker compose up -d o inclua. O Caddy mantém seus certificados no volume https.
A própria porta do Antimatter continua publicada no host (HTTP_PORT, 8065 por padrão). Com o Caddy na 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 acessa o Antimatter pela rede interna edge, não por essa porta, então isso não muda nada para seus usuários.
Com seu próprio proxy reverso (nginx)
Se o servidor já executa 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 (o aplicativo web e os aplicativos móveis mantêm um websocket aberto em
/api/v4/websocket, e alguns aplicativos abrem os seus próprios); - aceitar corpos de solicitação pelo menos do tamanho do maior upload (Tamanho Máximo do Arquivo, 100 MB por padrão);
- manter conexões de longa duração abertas (websockets, uploads e downloads 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 arquivo 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 conta própria; apenas o HSTS fica a cargo do proxy. Aumente o max-age quando o HTTPS estiver funcionando e adicione includeSubDomains apenas se todos os subdomínios usarem HTTPS.
Com Docker Compose e nginx no host, 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 em um contêiner e Let's Encrypt através do certbot, em deploy/compose.
Outros proxies
Qualquer proxy funciona se atender aos quatro pontos acima. As chamadas de áudio e vídeo nunca passam pelo proxy: elas usam a própria porta, veja Chamadas e voz.
Endereços de clientes atrás de um proxy
Atrás de um proxy, todas as solicitações parecem vir do proxy. Para registrar o endereço real do cliente, aplicar limites de taxa por cliente e usar filtragem de IP, informe ao servidor qual cabeçalho carrega o endereço e quais proxies ele pode confiar. Nenhuma dessas configurações tem um campo no Console do Sistema: defina-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 conexão | Os cabeçalhos que carregam o endereço do cliente, por exemplo X-Forwarded-For. O primeiro presente em uma solicitação é usado. |
ServiceSettings.TrustedProxyIPs, AM_SERVICESETTINGS_TRUSTEDPROXYIPS | vazio | Os endereços ou faixas CIDR dos seus proxies, por exemplo 172.29.71.0/28. Os cabeçalhos só valem para solicitações que vêm de um deles. |
Em uma 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 uma faixa CIDR.
Como o servidor encontra o endereço do cliente
Cada proxy adiciona o endereço de onde recebeu a solicitação à direita de X-Forwarded-For. O que o cliente enviou no próprio cabeçalho permanece à esquerda. Assim, o servidor lê o cabeçalho da direita para a esquerda, ignora os endereços dos seus proxies confiáveis e usa o primeiro outro endereço como o do cliente. Um cliente não pode escolher seu endereço enviando seu próprio cabeçalho.
- Atrás de um proxy,
TrustedProxyIPHeadersozinho fornece o endereço correto: o servidor usa o endereço mais à direita do cabeçalho. Ele registra um aviso na inicialização até que você também configureTrustedProxyIPs. Sem isso, qualquer pessoa que acesse a porta 8065 diretamente pode definir o cabeçalho, então publique essa porta apenas em127.0.0.1ou em uma 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 usará o endereço do proxy externo como o do cliente. - O proxy pode substituir o cabeçalho com o endereço que vê, como no exemplo do nginx acima (
X-Forwarded-For $remote_addr), ou adicioná-lo ao existente (o$proxy_add_x_forwarded_fordo nginx). Ambos funcionam.
Quais endereços listar
Liste o endereço de onde as solicitações do proxy vêm, conforme visto pelo Antimatter.
- Com o arquivo compose do site e o Caddy, isso já está feito: o Caddy acessa o Antimatter pela rede
edge, e o arquivo compose defineTrustedProxyIPHeadercomoX-Forwarded-ForeTrustedProxyIPscomo a faixa dessa rede,EDGE_SUBNET(172.29.71.0/28, a menos que você a altere no.env). AltereEDGE_SUBNETse ela sobrepor uma das suas redes. - A configuração de produção no antimatter-docker faz o mesmo para seu contêiner nginx, com
FRONTEND_SUBNET. - Com nginx no host e Antimatter no Docker, as solicitações chegam ao Antimatter através da porta publicada, geralmente a partir do endereço do gateway da rede do projeto compose (visível com
docker network inspect). DefinaAM_SERVICESETTINGS_TRUSTEDPROXYIPScom esse endereço nocompose.override.yaml. - Sem Docker, com nginx no mesmo host, é
127.0.0.1(e::1se o nginx se conectar via IPv6).
TLS sem proxy
O servidor também pode fornecer HTTPS por conta própria, em Console do Sistema › Ambiente › Servidor Web: Segurança da Conexão definido como TLS (ServiceSettings.ConnectionSecurity), com Arquivo de Certificado TLS e Arquivo da Chave TLS (ServiceSettings.TLSCertFile, ServiceSettings.TLSKeyFile), ou Usar Let's Encrypt (ServiceSettings.UseLetsEncrypt). O servidor deve então escutar na porta 443 (Endereço à Escutar, ServiceSettings.ListenAddress, :8065 por padrã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 da solicitação
Configurações do próprio servidor web do servidor, em Console do Sistema › Ambiente › Servidor Web:
| Configuração | Chave | Padrão |
|---|---|---|
| Endereço à Escutar | ServiceSettings.ListenAddress | :8065 |
| Tempo limite de escrita | ServiceSettings.ReadTimeout | 300 segundos |
| Tempo limite de gravação | ServiceSettings.WriteTimeout | 300 segundos |
| Tempo limite de ociosidade (sem campo no Console do Sistema) | ServiceSettings.IdleTimeout | 60 segundos |
| Tamanho máximo de payload (bytes) | ServiceSettings.MaximumPayloadSizeBytes | veja Segurança |
Mantenha os tempos limite do próprio proxy pelo menos tão longos quanto estes para solicitações normais, e o tamanho do corpo pelo menos Tamanho Máximo do Arquivo.