Domain, HTTPS und Reverse Proxies

Bereitstellen von Antimatter auf einem Domainnamen mit HTTPS, unter Verwendung des Caddy-Profils der Compose-Datei oder eines eigenen Reverse-Proxy, und korrektes Einrichten der Site-URL und der Client-Adressen.

Die Site-URL

Die Site-URL (ServiceSettings.SiteURL) ist die Adresse, die Personen verwenden, um Antimatter zu erreichen, z. B. https://chat.example.com. Der Server verwendet sie in Links in E-Mails und Benachrichtigungen, bei Anmelde-Umleitungen (OAuth, OpenID Connect, SAML), für die mobilen und Desktop-Apps und um zu prüfen, von wo aus Anfragen kommen. Stellen Sie sie exakt auf die Adresse in der Adressleiste des Browsers ein: Schema, Domain und Port (falls nicht der Standard), ohne schließenden Schrägstrich.

  • Mit der Compose-Datei der Site: SITE_URL in .env.
  • An anderer Stelle: AM_SERVICESETTINGS_SITEURL oder Systemkonsole › Umgebung › Webserver › Seiten-URL.

Wenn die Site-URL falsch ist, schlägt die Anmeldung mit einem Identitätsanbieter fehl, Links in E-Mails zeigen an den falschen Ort und die Apps können sich möglicherweise nicht verbinden. Nach einer Änderung der Domain aktualisieren Sie sie hier und in den Umleitungs-URLs aller Identitätsanbieter.

HTTPS mit dem mitgelieferten Caddy-Profil

Die compose.yaml-Datei der Site enthält einen Caddy-Dienst im https-Profil. Er erhält ein Zertifikat von Let's Encrypt, erneuert es automatisch, leitet HTTP auf HTTPS um und leitet alles, einschließlich WebSockets, an Antimatter weiter.

  1. Richten Sie einen DNS-Eintrag (A, und AAAA für IPv6) Ihrer Domain auf den Server ein.
  2. Öffnen Sie die Ports 80/tcp, 443/tcp und 443/udp (HTTP/3) in der Firewall. Let's Encrypt muss von Internet aus auf Port 80 oder 443 zugreifen können.
  3. Fügen Sie die Domain zu .env hinzu und setzen Sie die Site-URL:
    echo "DOMAIN=chat.example.com" >> .env
    sed -i 's|^SITE_URL=.*|SITE_URL=https://chat.example.com|' .env
  4. Starten Sie mit dem Profil:
    docker compose --profile https up -d

Fügen Sie --profile https zu jedem späteren docker compose up hinzu, oder setzen Sie COMPOSE_PROFILES=https in .env, damit ein normales docker compose up -d es einschließt. Caddy speichert seine Zertifikate im https-Volume.

Der eigene Port von Antimatter bleibt auf dem Host veröffentlicht (HTTP_PORT, standardmäßig 8065). Wenn Caddy davor steht, halten Sie ihn nur für den Server selbst:

echo "HTTP_PORT=127.0.0.1:8065" >> .env
docker compose --profile https up -d

Caddy erreicht Antimatter über das interne edge-Netzwerk, nicht über diesen Port, daher ändert sich für Ihre Benutzer nichts.

Mit Ihrem eigenen Reverse-Proxy (nginx)

Falls der Server bereits nginx oder einen anderen Proxy ausführt, deaktivieren Sie das https-Profil und leiten Sie den Proxy an Port 8065 von Antimatter weiter. Der Proxy muss:

  • WebSocket-Upgrade-Anfragen weiterleiten (die Web-App und die mobilen Apps halten eine WebSocket-Verbindung auf /api/v4/websocket offen, und einige Apps öffnen eigene);
  • Anforderungskörper (Request Bodies) mindestens in der Größe des größten Uploads akzeptieren (Maximale Dateigröße, standardmäßig 100 MB);
  • langlebige Verbindungen offen halten (WebSockets, große Uploads und Downloads);
  • den Host-Header und die Adresse des Clients weiterleiten.

Ein vollständiger Server-Block, abgeleitet aus der Produktionsvorlage in antimatter-docker. Ersetzen Sie die Domain und die Zertifikatspfade:

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;
    }
}

Prüfen Sie die Datei mit nginx -t und wenden Sie sie mit systemctl reload nginx an. Der Server sendet X-Content-Type-Options, Referrer-Policy, Permissions-Policy und X-Frame-Options selbst; nur HSTS liegt in der Verantwortung des Proxys. Erhöhen Sie dessen max-age, sobald HTTPS funktioniert, und fügen Sie includeSubDomains nur hinzu, wenn alle Subdomains HTTPS verwenden.

Bei Docker Compose und nginx auf dem Host zeigt der oben genannte upstream auf den veröffentlichten Port 8065. Veröffentlichen Sie ihn nur auf 127.0.0.1 (HTTP_PORT=127.0.0.1:8065), damit niemand den Proxy umgeht.

Das antimatter-docker-Repository enthält eine vollständige Einrichtung mit nginx in einem Container und Let's Encrypt über certbot, unter deploy/compose.

Andere Proxys

Jeder Proxy funktioniert, wenn er die vier oben genannten Punkte erfüllt. Audio- und Videoanrufe gehen nie durch den Proxy: Sie verwenden ihren eigenen Port, siehe Anrufe und Sprache.

Client-Adressen hinter einem Proxy

Hinter einem Proxy scheint jede Anfrage vom Proxy zu kommen. Um die tatsächliche Client-Adresse zu protokollieren, Ratenlimits pro Client anzuwenden und IP-Filter zu verwenden, müssen Sie dem Server mitteilen, welcher Header die Adresse enthält und welchen Proxys er vertrauen kann. Für beide Einstellungen gibt es kein Feld in der Systemkonsole: Richten Sie sie in config.json oder mit Variablen ein.

Schlüssel und VariableStandardFunktion
ServiceSettings.TrustedProxyIPHeader, AM_SERVICESETTINGS_TRUSTEDPROXYIPHEADERleer: Der Server verwendet die Adresse der VerbindungDie Header, die die Client-Adresse enthalten, zum Beispiel X-Forwarded-For. Der erste in einer Anfrage vorhandene wird verwendet.
ServiceSettings.TrustedProxyIPs, AM_SERVICESETTINGS_TRUSTEDPROXYIPSleerDie Adressen oder CIDR-Bereiche Ihrer Proxys, zum Beispiel 172.29.71.0/28. Die Header gelten nur für Anfragen, die von einem dieser Proxys stammen.

In einer Variablen trennen Sie mehrere Werte durch Leerzeichen: AM_SERVICESETTINGS_TRUSTEDPROXYIPHEADER="X-Forwarded-For X-Real-IP". Der Server lehnt eine Konfiguration ab, bei der TrustedProxyIPs einen Eintrag enthält, der weder eine IP-Adresse noch ein CIDR-Bereich ist.

Wie der Server die Adresse des Clients ermittelt

Jeder Proxy fügt die Adresse, von der er die Anfrage erhalten hat, rechts an X-Forwarded-For an. Was der Client selbst im Header gesendet hat, bleibt links. Der Server liest den Header daher von rechts, überspringt die Adressen Ihrer vertrauenswürdigen Proxys und nimmt die erste andere Adresse als die des Clients. Ein Client kann seine Adresse nicht festlegen, indem er einen eigenen Header sendet.

  • Hinter einem einzelnen Proxy liefert TrustedProxyIPHeader allein die richtige Adresse: Der Server nimmt die äußerste rechte Adresse des Headers. Bis Sie auch TrustedProxyIPs festgelegt haben, protokolliert der Server beim Start eine Warnung. Ohne diese Einstellung kann jeder, der direkt auf Port 8065 zugreift, den Header setzen. Veröffentlichen Sie diesen Port daher nur auf 127.0.0.1 oder in einem privaten Netzwerk.
  • Hinter mehreren Proxys, beispielsweise einem CDN oder einem Lastverteiler vor Ihrem eigenen Proxy, listen Sie alle in TrustedProxyIPs auf. Andernfalls nimmt der Server die Adresse des äußeren Proxys für die des Clients.
  • Der Proxy kann den Header durch die Adresse ersetzen, die er sieht, wie im nginx-Beispiel oben (X-Forwarded-For $remote_addr), oder sie anhängen (nginxs $proxy_add_x_forwarded_for). Beides funktioniert.

Welche Adressen Sie eintragen

Tragen Sie die Adresse ein, von der die Anfragen des Proxys kommen, so wie Antimatter sie sieht.

  • Mit der Compose-Datei der Website und Caddy ist dies bereits erledigt: Caddy erreicht Antimatter über das edge-Netzwerk, und die Compose-Datei setzt TrustedProxyIPHeader auf X-Forwarded-For und TrustedProxyIPs auf den Bereich dieses Netzwerks, EDGE_SUBNET (standardmäßig 172.29.71.0/28, sofern Sie es nicht in .env ändern). Ändern Sie EDGE_SUBNET, wenn es mit einem Ihrer Netzwerke überlappt.
  • Das Produktions-Setup in antimatter-docker macht dasselbe für seinen nginx-Container, mit FRONTEND_SUBNET.
  • Bei nginx auf dem Host und Antimatter in Docker erreichen die Anfragen Antimatter über den veröffentlichten Port, in der Regel von der Gateway-Adresse des Netzwerks des Compose-Projekts (docker network inspect zeigt sie an). Setzen Sie AM_SERVICESETTINGS_TRUSTEDPROXYIPS in compose.override.yaml auf diese Adresse.
  • Ohne Docker, aber mit nginx auf demselben Host, ist es 127.0.0.1 (bzw. ::1, wenn nginx über IPv6 verbunden ist).

TLS ohne Proxy

Der Server kann HTTPS auch selbst bereitstellen, in Systemkonsole › Umgebung › Webserver: Verbindungssicherheit auf TLS setzen (ServiceSettings.ConnectionSecurity), mit TLS-Zertifikatsdatei und TLS-Schlüsseldatei (ServiceSettings.TLSCertFile, ServiceSettings.TLSKeyFile), oder Let's Encrypt verwenden (ServiceSettings.UseLetsEncrypt). Der Server muss dann auf Port 443 lauschen (Empfangs-Adresse, ServiceSettings.ListenAddress, standardmäßig :8065), und ServiceSettings.Forward80To443 leitet Port 80 weiter. Ein Reverse Proxy ist einfacher zu betreiben und zu erneuern und wird in diesem Leitfaden vorausgesetzt.

Server-Timeouts und Anfragegröße

Einstellungen des eigenen Webservers des Servers, in Systemkonsole › Umgebung › Webserver:

EinstellungSchlüsselStandard
Empfangs-AdresseServiceSettings.ListenAddress:8065
Lese-ZeitüberschreitungServiceSettings.ReadTimeout300 Sekunden
Schreibe-ZeitüberschreitungServiceSettings.WriteTimeout300 Sekunden
Idle-Timeout (kein Feld in der Systemkonsole)ServiceSettings.IdleTimeout60 Sekunden
Maximale Größe der Nutzlast (Bytes)ServiceSettings.MaximumPayloadSizeBytessiehe Sicherheit

Halten Sie die eigenen Zeitüberschreitungen des Proxys für normale Anfragen mindestens so lang wie diese und die Größe des Anforderungskörpers mindestens auf dem Wert der Maximalen Dateigröße.