Domain, HTTPS, dan reverse proxy

Pasang Antimatter di nama domain dengan HTTPS, menggunakan profil Caddy dari file compose atau reverse proxy Anda sendiri, dan pastikan alamat situs serta alamat klien diatur dengan benar.

Alamat situs

Alamat situs (ServiceSettings.SiteURL) adalah alamat yang digunakan orang untuk mengakses Antimatter, seperti https://chat.example.com. Server menggunakannya dalam tautan di email dan notifikasi, dalam pengalihan masuk (OAuth, OpenID Connect, SAML), untuk aplikasi seluler dan desktop, serta untuk memeriksa asal permintaan. Atur persis seperti alamat di bilah alamat browser: skema, domain, dan port jika bukan port bawaan, tanpa garis miring di akhir.

  • Dengan file compose situs: SITE_URL di .env.
  • Di tempat lain: AM_SERVICESETTINGS_SITEURL, atau Konsol Sistem › Lingkungan › Server Web › URL Situs.

Jika alamat situs salah, masuk dengan penyedia identitas akan gagal, tautan di email mengarah ke tempat yang salah, dan aplikasi mungkin tidak dapat terhubung. Setelah mengubah domain, perbarui di sini dan di URL pengalihan setiap penyedia identitas.

HTTPS dengan profil Caddy bawaan

File compose.yaml situs menyertakan layanan Caddy dalam profil https. Caddy mendapatkan sertifikat dari Let's Encrypt, memperbaruinya secara otomatis, mengalihkan HTTP ke HTTPS, dan meneruskan semuanya, termasuk websocket, ke Antimatter.

  1. Arahkan catatan DNS (A, dan AAAA untuk IPv6) domain Anda ke server.
  2. Buka port 80/tcp, 443/tcp, dan 443/udp (HTTP/3) di firewall. Let's Encrypt harus dapat mengakses port 80 atau 443 dari Internet.
  3. Tambahkan domain ke .env dan atur alamat situs:
    echo "DOMAIN=chat.example.com" >> .env
    sed -i 's|^SITE_URL=.*|SITE_URL=https://chat.example.com|' .env
  4. Mulai dengan profil:
    docker compose --profile https up -d

Tambahkan --profile https ke setiap docker compose up berikutnya, atau letakkan COMPOSE_PROFILES=https di .env agar docker compose up -d biasa menyertakannya. Caddy menyimpan sertifikatnya di volume https.

Port Antimatter sendiri tetap dipublikasikan di host (HTTP_PORT, 8065 secara bawaan). Dengan Caddy di depan, biarkan port ini hanya untuk server itu sendiri:

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

Caddy mengakses Antimatter melalui jaringan internal edge, bukan melalui port tersebut, sehingga ini tidak mengubah apa pun bagi pengguna Anda.

Dengan reverse proxy Anda sendiri (nginx)

Jika server sudah menjalankan nginx atau proxy lain, nonaktifkan profil https dan arahkan proxy ke port 8065 Antimatter. Proxy harus:

  • melewati peningkatan websocket (aplikasi web dan aplikasi seluler mempertahankan koneksi websocket yang terbuka di /api/v4/websocket, dan beberapa aplikasi membuka koneksinya sendiri);
  • menerima isi permintaan (request body) setidaknya sebesar unggahan terbesar (Ukuran File Maksimum, 100 MB secara bawaan);
  • mempertahankan koneksi jangka panjang (websocket, unggahan dan unduhan besar);
  • melewati header Host dan alamat klien.

Blok server lengkap, diadaptasi dari template produksi di antimatter-docker. Ganti domain dan jalur sertifikat:

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

Periksa file dengan nginx -t dan terapkan dengan systemctl reload nginx. Server mengirim X-Content-Type-Options, Referrer-Policy, Permissions-Policy, dan X-Frame-Options sendiri; hanya HSTS yang menjadi tanggung jawab proxy. Naikkan max-age setelah HTTPS berfungsi, dan tambahkan includeSubDomains hanya jika semua subdomain menggunakan HTTPS.

Dengan Docker Compose dan nginx di host, upstream di atas menunjuk ke port 8065 yang dipublikasikan. Publikasikan hanya di 127.0.0.1 (HTTP_PORT=127.0.0.1:8065), sehingga tidak ada yang dapat melewati proxy.

Repositori antimatter-docker memiliki pengaturan lengkap dengan nginx dalam kontainer dan Let's Encrypt melalui certbot, di deploy/compose.

Proxy lainnya

Proxy apa pun dapat digunakan jika memenuhi empat poin di atas. Audio dan video panggilan tidak pernah melewati proxy: mereka menggunakan port mereka sendiri, lihat Panggilan dan suara.

Alamat klien di belakang proxy

Di belakang proxy, setiap permintaan tampaknya berasal dari proxy. Untuk mencatat alamat klien yang sebenarnya, terapkan batas laju per klien dan gunakan penyaringan IP, beri tahu server header mana yang membawa alamat, dan proxy mana yang dapat dipercaya. Tidak ada pengaturan Konsol Sistem untuk keduanya: atur di config.json atau dengan variabel.

Kunci dan variabelBawaanFungsinya
ServiceSettings.TrustedProxyIPHeader, AM_SERVICESETTINGS_TRUSTEDPROXYIPHEADERkosong: server menggunakan alamat koneksiHeader yang membawa alamat klien, misalnya X-Forwarded-For. Yang pertama hadir dalam permintaan akan digunakan.
ServiceSettings.TrustedProxyIPs, AM_SERVICESETTINGS_TRUSTEDPROXYIPSkosongAlamat atau rentang CIDR proxy Anda, misalnya 172.29.71.0/28. Header hanya dihitung untuk permintaan yang berasal dari salah satu dari mereka.

Di variabel, pisahkan beberapa nilai dengan spasi: AM_SERVICESETTINGS_TRUSTEDPROXYIPHEADER="X-Forwarded-For X-Real-IP". Server menolak konfigurasi yang memiliki entri di TrustedProxyIPs yang bukan alamat IP maupun rentang CIDR.

Cara server menemukan alamat klien

Setiap proxy menambahkan alamat tempatnya menerima permintaan ke sisi kanan X-Forwarded-For. Apa pun yang dikirim klien di header itu sendiri tetap berada di sisi kiri. Jadi, server membaca header dari kanan, melewati alamat proxy yang Anda percaya, dan mengambil alamat lain pertama sebagai alamat klien. Klien tidak dapat memilih alamatnya dengan mengirim header miliknya sendiri.

  • Di belakang satu proxy, TrustedProxyIPHeader saja sudah memberikan alamat yang benar: server mengambil alamat paling kanan dari header. Server mencatat peringatan saat startup sampai Anda juga mengatur TrustedProxyIPs. Tanpanya, siapa pun yang mencapai port 8065 secara langsung dapat mengatur header, jadi publikasikan port tersebut hanya di 127.0.0.1 atau di jaringan privat.
  • Di belakang beberapa proxy, misalnya CDN atau load balancer di depan proxy Anda sendiri, cantumkan semuanya di TrustedProxyIPs. Jika tidak, server akan mengambil alamat proxy terluar sebagai alamat klien.
  • Proxy dapat mengganti header dengan alamat yang dilihatnya, seperti contoh nginx di atas (X-Forwarded-For $remote_addr), atau menambahkannya (nginx's $proxy_add_x_forwarded_for). Keduanya berfungsi.

Alamat mana yang harus dicantumkan

Cantumkan alamat tempat permintaan proxy berasal, sebagaimana dilihat oleh Antimatter.

  • Dengan file compose situs dan Caddy, ini sudah dilakukan: Caddy mencapai Antimatter melalui jaringan edge, dan file compose mengatur TrustedProxyIPHeader ke X-Forwarded-For dan TrustedProxyIPs ke rentang jaringan tersebut, EDGE_SUBNET (172.29.71.0/28 kecuali Anda mengubahnya di .env). Ubah EDGE_SUBNET jika tumpang tindih dengan salah satu jaringan Anda.
  • Konfigurasi produksi di antimatter-docker melakukan hal yang sama untuk kontainer nginx-nya, dengan FRONTEND_SUBNET.
  • Dengan nginx di host dan Antimatter di Docker, permintaan mencapai Antimatter melalui port yang dipublikasikan, biasanya dari alamat gateway jaringan proyek compose (docker network inspect menampilkannya). Atur AM_SERVICESETTINGS_TRUSTEDPROXYIPS ke alamat tersebut di compose.override.yaml.
  • Tanpa Docker, dengan nginx di host yang sama, gunakan 127.0.0.1 (dan ::1 jika nginx terhubung melalui IPv6).

TLS tanpa proxy

Server juga dapat menyajikan HTTPS sendiri, di Konsol Sistem › Lingkungan › Server Web: Keamanan Koneksi diatur ke TLS (ServiceSettings.ConnectionSecurity), dengan Berkas Sertifikat TLS dan Berkas Kunci TLS (ServiceSettings.TLSCertFile, ServiceSettings.TLSKeyFile), atau Gunakan Let's Encrypt (ServiceSettings.UseLetsEncrypt). Server kemudian harus mendengarkan pada port 443 (Alamat Dengar, ServiceSettings.ListenAddress, :8065 secara bawaan), dan ServiceSettings.Forward80To443 mengalihkan port 80. Proxy terbalik lebih mudah dijalankan dan diperbarui, dan itulah yang diasumsikan oleh panduan ini.

Waktu habis (timeout) server dan ukuran permintaan

Pengaturan server web milik server itu sendiri, di Konsol Sistem › Lingkungan › Server Web:

PengaturanKunciBawaan
Alamat DengarServiceSettings.ListenAddress:8065
Batas Waktu BacaServiceSettings.ReadTimeout300 detik
Waktu Habis TulisServiceSettings.WriteTimeout300 detik
Waktu habis saat tidak aktif (tidak ada bidang di Konsol Sistem)ServiceSettings.IdleTimeout60 detik
Ukuran Muatan Maksimal (Bita)ServiceSettings.MaximumPayloadSizeByteslihat Keamanan

Jaga agar batas waktu proxy itu sendiri setidaknya sama panjang dengan nilai-nilai ini untuk permintaan normal, dan ukuran bodinya setidaknya Ukuran File Maksimum.