Własna domena (first-party)
Widżet, połączenie czatu i formularz offline z subdomeny Twojej strony – wymagania, konfiguracja, szablony dla nginx, Apache i Caddy, rozwiązywanie problemów.
Z własną domeną czat działa przez subdomenę Twojej strony, na przykład chat.twoja-domena.pl. Twój serwer przyjmuje żądania widżetu i jako reverse proxy przekazuje je do reactive.chat. Ta strona jest przeznaczona dla osoby, która prowadzi ten serwer.
Co daje własna domena
Przez Twoją subdomenę przechodzą:
- pliki widżetu (
loader.jsi doładowywany później rdzeń), - połączenie czatu (WebSocket), łącznie z załącznikami,
- formularz offline, który wkracza, gdy połączenie czatu nie dochodzi do skutku.
W efekcie:
- Brak żądań do cudzych domen. Na tych drogach przeglądarka odwiedzających rozmawia tylko z Twoją subdomeną, a nie z domeną reactive.chat.
- Blokery reklam. Listy filtrów, które blokują według nazwy domeny, nie rozpoznają już czatu po domenie reactive.chat.
- Jeden adres dla Content Security Policy. W
script-srciconnect-srcstoi Twoja subdomena zamiast adresów reactive.chat.connect-srcpotrzebuje jej dwa razy: zwss://dla połączenia czatu i zhttps://dla formularza offline, przesyłania plików i trybu awaryjnego HTTP (gdy proxy blokuje WebSocket). - Dociera prawdziwy adres odwiedzającego. Twoje proxy przekazuje nam adres odwiedzającego w osobnym nagłówku, zabezpieczonym tajnym kluczem. Ochrona przed nadużyciami (ograniczanie i blokady) liczy wtedy według odwiedzającego, a nie według proxy, a przy rozmowie widnieje adres odwiedzającego.
Czym nie jest
- To nie jest własny hosting. Twój serwer tylko przekazuje dalej. Rozmowy, załączniki i ustawienia nadal przetwarza i przechowuje reactive.chat, dokładnie tak jak bez własnej domeny.
- Żadnej deklaracji co do zgody. To, czy i na co potrzebujesz zgody odwiedzających, oceniasz niezależnie od tego. Własna domena nie zmienia tego, kto przetwarza dane. Sformułowania do polityki prywatności znajdziesz we fragmencie tekstu do polityki prywatności.
- Twój serwer widzi ruch. Połączenie TLS odwiedzającego kończy się na Twoim proxy. Wiadomości i załączniki są tam przez chwilę odszyfrowane, zanim proxy przekaże je nam ponownie zaszyfrowane. Nie zapisuj w logach proxy treści żądań.
Wymagania
- Własny serwer lub reverse proxy osiągalny z internetu przez HTTPS na porcie 443, który sam może nawiązywać wychodzące połączenia HTTPS. Szablony są dla nginx (z modułem ssl), Apache od 2.4.47 i Caddy 2.
- W Apache moduły mod_ssl, mod_proxy, mod_proxy_http, mod_proxy_wstunnel i mod_headers. Dopiero od 2.4.47 Apache zna
upgrade=websocket; dla starszych wersji na końcu szablonu jest rozwiązanie zastępcze z mod_rewrite. - Subdomena tylko dla czatu, na przykład
chat.twoja-domena.pl. Czat potrzebuje całego hosta; ścieżka w rodzajuwww.twoja-domena.pl/chat/nie zadziała. Wpisujesz tylko nazwę – bezhttps://, bez portu, bez ścieżki. Niedozwolone są adresy IP, wewnętrzne końcówki jak.local,.lanczy.internaloraz nazwy w domenie reactive.chat. - Ta sama domena co Twoja strona. Czat jest first-party tylko wtedy, gdy subdomena należy do domeny strony, na której jest osadzony. W przeciwnym razie i tak działa, a strona konta zwraca uwagę na różnicę.
- Rekord DNS (A i/lub AAAA) wskazujący na Twój serwer. Wszystkie adresy tej nazwy muszą być publiczne.
- Certyfikat TLS dla subdomeny. Szablony dla nginx i Apache zakładają ścieżki certbota (Let’s Encrypt); Caddy pobiera certyfikat sam.
- Uprawnienie do edycji projektu w Twoim koncie reactive.chat.
Za load balancerem lub CDN Twoje proxy widzi najpierw adres tego urządzenia zamiast adresu odwiedzającego. W takim przypadku skonfiguruj przejmowanie prawdziwego adresu odwiedzającego: w nginx moduł real_ip (set_real_ip_from, real_ip_header), w Apache mod_remoteip (RemoteIPHeader, RemoteIPTrustedProxy), w Caddy opcję trusted_proxies i placeholder {client_ip} zamiast {remote_host}. Nasz test nie wykryje tego przypadku: widzi tylko, że ustawiono prawidłowy adres, a nie jaki.
Konfiguracja krok po kroku
- Otwórz stronę. Otwórz projekt w swoim koncie. W sekcji „Osadzenie” znajdziesz link Skonfiguruj własną domenę.
- Wpisz host. W „1. Host” wpisz nazwę, na przykład
chat.twoja-domena.pl, i zapisz. - Utwórz klucz. W „2. Klucz proxy” kliknij Utwórz klucz. Klucz zaczyna się od
rcpx_i jest pokazywany dokładnie raz; przechowujemy tylko jego skrót. Skopiuj go od razu. Jest tajny i należy wyłącznie do konfiguracji Twojego proxy – nigdy do strony internetowej, skryptu w przeglądarce ani repozytorium. - Wstaw szablon. W „3. Konfiguracja serwera” są gotowe szablony dla nginx, Apache i Caddy. Zaraz po utworzeniu klucza już go zawierają; później widnieje w nich
__RC_PROXY_KEY__, który zastępujesz kluczem. W razie potrzeby dostosuj ścieżki certyfikatów, sprawdź konfigurację (nginx -tlubapachectl configtest) i przeładuj serwer. - Sprawdź. W „5. Sprawdź” kliknij Sprawdź teraz. Wywołujemy Twoją subdomenę z zewnątrz i sprawdzamy pięć dróg osobno (patrz niżej). Nie powstaje przy tym żadna wiadomość. Kolejny test jest możliwy najwcześniej po 10 sekundach.
- Wymień fragment kodu. Dopiero gdy wszystkie pięć kroków pokazuje „w porządku”, zastąp dotychczasowy fragment kodu na swojej stronie tym z „4. Fragment kodu”.
Nowy fragment wygląda tak – oba adresy wskazują na Twoją subdomenę:
<script src="https://chat.twoja-domena.pl/loader.js"
data-rc-site-key="SITE_KEY"
data-rc-ws-url="wss://chat.twoja-domena.pl/rc_wss/"
async></script>
Z src widżet bierze miejsce swoich plików, z data-rc-ws-url połączenie czatu – i na tej podstawie adres formularza offline. Pozostałe atrybuty, takie jak data-rc-locale, zostają bez zmian; opisuje je strona Osadzenie widgetu. Fragment na stronie konta zawiera dodatkowo kolor Twojej marki.
Pięć kroków testu
Każdy krok pokazuje „w porządku”, „błąd”, „uwaga” lub „nie sprawdzono”. Test jest zaliczony tylko wtedy, gdy wszystkie pięć pokazuje „w porządku”; uwaga nie liczy się jako zaliczenie. Sprawdzamy wyłącznie przez HTTPS na porcie 443, nie podążamy za przekierowaniami, każdy krok ma 5 sekund.
- Rozwiązywanie nazwy. Nazwa musi mieć rekord DNS, a wszystkie jej adresy muszą być publiczne. Błąd pojawia się, gdy nie ma ani rekordu A, ani AAAA, albo gdy co najmniej jeden adres jest prywatny, lokalny lub zarezerwowany – takich adresów nie sprawdzamy. Wszystkie kolejne kroki łączą się dokładnie z adresem sprawdzonym tutaj.
- loader.js przez Twoją domenę. Pobieramy
https://chat.twoja-domena.pl/loader.jsi porównujemy plik z naszym. Jeśli nie dojdzie do połączenia, nie przyjdzie odpowiedź albo brakuje ważnego certyfikatu, pozostałe kroki są pomijane („nie sprawdzono”). Jeśli proxy odpowiada przekierowaniem zamiast pliku, to błąd. Jeśli plik różni się od naszego, przyczyną jest zwykle pamięć podręczna w proxy albo zły cel dla/. - Klucz i adres odwiedzającego. Wywołujemy adres testowy pod
/rc_wss/. Nasz serwer odpowiada, czy otrzymał prawidłowy klucz i prawidłowy adres odwiedzającego oraz do którego projektu należy klucz. Możliwe błędy: brak nagłówkaX-RC-Proxy-Key; nieznany klucz (literówka, nieaktualny lub usunięty – zaraz po utworzeniu może to potrwać do 30 sekund); brak nagłówkaX-RC-Client-IPlub brak w nim prawidłowego adresu; klucz należy do innego projektu. Uwaga pojawia się, gdy klucz jest ważny, ale zarejestrowany dla innego hosta. - Połączenie czatu (WebSocket). Nawiązujemy połączenie WebSocket przez
wss://chat.twoja-domena.pl/rc_wss/i oczekujemy HTTP 101 z protokołemrc.v1. „Brak upgrade WebSocket” oznacza: proxy nie przekazuje nagłówkówUpgradeiConnection. - Formularz offline. Wywołujemy
https://chat.twoja-domena.pl/api/offline/SITE_KEYmetodą GET. Nasz punkt końcowy odpowiada HTTP 405, bo przyjmuje tylko POST – po tym poznajemy, że żądanie do nas dociera, a żadna wiadomość nie powstaje. Inne wyniki: odrzucone pochodzenie (uwaga, patrz rozwiązywanie problemów), projekt nieaktywny, cel wymaga uwierzytelnienia (HTTP 401).
Kroki 2–5 mogą też zgłosić HTTP 421 (nagłówek Host, patrz rozwiązywanie problemów). Jeśli krok 3 lub 5 zgłasza „Odpowiedź nie pochodzi od reactive.chat”, ta ścieżka w proxy wskazuje na zły cel.
Co proxy musi przekazywać
/rc_wss/do serwera czatu reactive.chat, z upgrade WebSocket i długim limitem czasu (szablony używają 3600 sekund). Tą samą ścieżką idzie przesyłanie plików; zależnie od taryfy do 32 MB na plik./api/offline/do tego samego serwera. Przez nią widżet wysyła formularz offline.- Wszystko inne do sieci dostarczania reactive.chat. Stamtąd pochodzą
loader.jsi pozostałe pliki widżetu.
Dla wszystkich trzech dróg:
- Nagłówek Host i SNI to nazwa celu, a nie Twoja subdomena. Nasz serwer odpowiada na obcy host kodem HTTP 421.
- Certyfikat celu jest weryfikowany.
- Bez ciasteczek i danych logowania. Nagłówki
CookieiAuthorizationprzeglądarki nie są przekazywane. - Bez przekierowań. Pamięć podręczna nie jest potrzebna. Jeśli ją dodasz, ustaw dla
loader.jskrótki czas – nazwa pliku nie zawiera numeru wersji.
Dla /rc_wss/ i /api/offline/ proxy dodatkowo ustawia przy każdym żądaniu dwa nagłówki:
X-RC-Proxy-Key– Twój klucz.X-RC-Client-IP– adres odwiedzającego, tak jak widzi go Twoje proxy.
„Ustawia” oznacza: to, co przeglądarka wyśle pod tymi nazwami, zostaje nadpisane i nigdy do nas nie dociera. Na drodze do sieci dostarczania oba nagłówki są czyszczone; klucz trafia tylko do serwera czatu.
Tryb awaryjny HTTP przez Twoją domenę
Jeśli sieć odwiedzającego nie przepuszcza WebSocket, widżet automatycznie przechodzi na tryb awaryjny HTTP. Korzysta on z tej samej ścieżki /rc_wss/ i nie wymaga dodatkowego wpisu w proxy. Potrzebne są dwie rzeczy:
- Przekazywanie bez buforowania. Proxy musi od razu przekazywać odpowiedzi na
/rc_wss/: w nginxproxy_buffering offiproxy_cache off, w Apacheflushpackets=on, w Caddyflush_interval -1. Szablony poniżej już to zawierają. - HTTPS w Content Security Policy.
connect-srcpotrzebuje Twojej subdomeny zwss://i zhttps://, na przykładconnect-src 'self' wss://chat.twoja-domena.pl https://chat.twoja-domena.pl.
Szablony
Poniższe szablony odpowiadają tym ze strony konta. Strona konta wstawia już Twój host, adresy docelowe właściwe dla Twojego konta oraz – zaraz po utworzeniu – Twój klucz. Dlatego najlepiej kopiuj szablon stamtąd; wersje tutaj służą do wglądu. Placeholdery to chat.twoja-domena.pl, SITE_KEY i __RC_PROXY_KEY__.
nginx
Należy do kontekstu http, na przykład jako /etc/nginx/conf.d/chat.twoja-domena.pl.conf. W RHEL i CentOS pakiet CA leży w /etc/pki/tls/certs/ca-bundle.crt zamiast /etc/ssl/certs/ca-certificates.crt.
# reactive.chat - own domain (first-party proxy) for site key SITE_KEY
# Host: chat.twoja-domena.pl
#
# Needs nginx >= 1.7 with the ssl module. Put this file into the http
# context (e.g. /etc/nginx/conf.d/chat.twoja-domena.pl.conf), adjust the certificate
# paths if you do not use certbot, then: nginx -t && systemctl reload nginx
#
# The proxy key is a secret: never put it into a web page or a repository.
# X-RC-Proxy-Key and X-RC-Client-IP are always SET here - whatever a browser
# sends under these names is overwritten.
server {
listen 80;
listen [::]:80;
server_name chat.twoja-domena.pl;
location /.well-known/acme-challenge/ { root /var/www/html; }
location / { return 301 https://$host$request_uri; }
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name chat.twoja-domena.pl;
ssl_certificate /etc/letsencrypt/live/chat.twoja-domena.pl/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/chat.twoja-domena.pl/privkey.pem;
# Chat connection (WebSocket). Host header and SNI must be the upstream
# name - reactive.chat answers 421 to any other host.
# HTTP fallback (Server-Sent Events / long polling): its requests carry a
# short-lived connection token in the query string - EventSource cannot
# send headers. Same settings as /rc_wss/ below, but kept out of the
# access log.
location /rc_wss/h/ {
access_log off;
proxy_pass https://ws.reactive.chat/rc_wss/h/;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host ws.reactive.chat;
proxy_ssl_server_name on;
proxy_ssl_name ws.reactive.chat;
proxy_ssl_verify on;
proxy_ssl_verify_depth 3;
proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
proxy_set_header X-RC-Proxy-Key "__RC_PROXY_KEY__";
proxy_set_header X-RC-Client-IP $remote_addr;
proxy_set_header Cookie "";
proxy_set_header Authorization "";
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
proxy_cache off;
}
location /rc_wss/ {
proxy_pass https://ws.reactive.chat/rc_wss/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host ws.reactive.chat;
proxy_ssl_server_name on;
proxy_ssl_name ws.reactive.chat;
proxy_ssl_verify on;
proxy_ssl_verify_depth 3;
proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
proxy_set_header X-RC-Proxy-Key "__RC_PROXY_KEY__";
proxy_set_header X-RC-Client-IP $remote_addr;
proxy_set_header Cookie "";
proxy_set_header Authorization "";
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
# Unbuffered: if a visitor's network blocks WebSockets, the widget
# falls back to Server-Sent Events / long polling on this path.
proxy_buffering off;
proxy_cache off;
# File attachments are uploaded through this path as well (PUT
# /rc_wss/upload/...). nginx allows 1 MB by default; reactive.chat
# accepts up to 32 MB per file depending on the plan.
client_max_body_size 32m;
proxy_request_buffering off;
}
# Offline form fallback (HTTP POST from the widget).
location /api/offline/ {
proxy_pass https://ws.reactive.chat/api/offline/;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host ws.reactive.chat;
proxy_ssl_server_name on;
proxy_ssl_name ws.reactive.chat;
proxy_ssl_verify on;
proxy_ssl_verify_depth 3;
proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
proxy_set_header X-RC-Proxy-Key "__RC_PROXY_KEY__";
proxy_set_header X-RC-Client-IP $remote_addr;
proxy_set_header Cookie "";
proxy_set_header Authorization "";
proxy_hide_header Set-Cookie;
client_max_body_size 32k;
proxy_read_timeout 30s;
}
# Smart Answer for site search (suche.js and the HTTP API). Same rules as
# the offline route: key and visitor address are set here.
location /api/suche/ {
proxy_pass https://ws.reactive.chat/api/suche/;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host ws.reactive.chat;
proxy_ssl_server_name on;
proxy_ssl_name ws.reactive.chat;
proxy_ssl_verify on;
proxy_ssl_verify_depth 3;
proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
proxy_set_header X-RC-Proxy-Key "__RC_PROXY_KEY__";
proxy_set_header X-RC-Client-IP $remote_addr;
proxy_set_header Cookie "";
proxy_set_header Authorization "";
proxy_hide_header Set-Cookie;
client_max_body_size 8k;
# The answer is a stream (Server-Sent Events): pass it on unbuffered.
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 120s;
}
# Widget files (loader.js, core.*.js ...). No caching required; if you
# add a cache, keep it short for loader.js (it is not versioned).
location / {
proxy_pass https://cdn.reactive.chat/;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host cdn.reactive.chat;
proxy_ssl_server_name on;
proxy_ssl_name cdn.reactive.chat;
proxy_ssl_verify on;
proxy_ssl_verify_depth 3;
proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
proxy_set_header X-RC-Proxy-Key "";
proxy_set_header X-RC-Client-IP "";
proxy_set_header Cookie "";
proxy_set_header Authorization "";
proxy_hide_header Set-Cookie;
}
}
# On RHEL/CentOS the CA bundle is /etc/pki/tls/certs/ca-bundle.crt.
# Behind a load balancer/CDN, $remote_addr is the balancer: configure the
# real_ip module so that it holds the visitor's address.
Apache
Szablon zawiera tylko VirtualHost dla portu 443. Przekierowanie z portu 80 i wystawienie certyfikatu skonfiguruj tak jak dla pozostałych hostów. SSLProxyVerifyDepth 5 jest konieczne: bez tej linii Apache sprawdza łańcuch certyfikatów celu tylko na jeden poziom w głąb, a połączenie kończy się błędem „Certificate Chain too long”.
# reactive.chat - own domain (first-party proxy) for site key SITE_KEY
# Host: chat.twoja-domena.pl
#
# Needs Apache >= 2.4.47 with mod_ssl, mod_proxy, mod_proxy_http,
# mod_proxy_wstunnel, mod_headers and mod_setenvif:
# a2enmod ssl proxy proxy_http proxy_wstunnel headers setenvif
# Adjust the certificate paths if you do not use certbot, then:
# apachectl configtest && systemctl reload apache2
#
# The proxy key is a secret: never put it into a web page or a repository.
<VirtualHost *:443>
ServerName chat.twoja-domena.pl
# HTTP fallback requests (/rc_wss/h/...) carry a short-lived connection
# token in the query string - keep them out of the access log.
SetEnvIf Request_URI "^/rc_wss/h/" rc_no_log
# ${APACHE_LOG_DIR} is set on Debian/Ubuntu; elsewhere e.g. /var/log/httpd.
CustomLog ${APACHE_LOG_DIR}/chat.twoja-domena.pl_access.log combined env=!rc_no_log
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/chat.twoja-domena.pl/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/chat.twoja-domena.pl/privkey.pem
# Upstream TLS: verified, SNI = upstream name (ProxyPreserveHost Off
# sends the upstream name as Host - reactive.chat answers 421 otherwise).
SSLProxyEngine on
SSLProxyVerify require
# Apache checks only ONE certificate deep by default; the upstream chain
# (leaf, intermediate, root) is longer: "Certificate Chain too long".
SSLProxyVerifyDepth 5
SSLProxyCheckPeerName on
SSLProxyCACertificateFile /etc/ssl/certs/ca-certificates.crt
ProxyRequests Off
ProxyPreserveHost Off
ProxyAddHeaders Off
# Whatever the browser sends under these names never reaches upstream.
RequestHeader unset X-RC-Proxy-Key early
RequestHeader unset X-RC-Client-IP early
RequestHeader unset Cookie early
RequestHeader unset Authorization early
# Longest path first. flushpackets=on on /rc_wss/: if a visitor's network
# blocks WebSockets, the widget falls back to Server-Sent Events / long
# polling on this path, and those must not be buffered.
ProxyPass "/rc_wss/" "https://ws.reactive.chat/rc_wss/" upgrade=websocket timeout=3600 flushpackets=on
ProxyPass "/api/offline/" "https://ws.reactive.chat/api/offline/" timeout=30
ProxyPass "/api/suche/" "https://ws.reactive.chat/api/suche/" timeout=120 flushpackets=on
ProxyPass "/" "https://cdn.reactive.chat/"
<Location "/rc_wss/">
RequestHeader set X-RC-Proxy-Key "__RC_PROXY_KEY__"
RequestHeader set X-RC-Client-IP "expr=%{REMOTE_ADDR}"
</Location>
<Location "/api/offline/">
RequestHeader set X-RC-Proxy-Key "__RC_PROXY_KEY__"
RequestHeader set X-RC-Client-IP "expr=%{REMOTE_ADDR}"
Header unset Set-Cookie
</Location>
<Location "/api/suche/">
RequestHeader set X-RC-Proxy-Key "__RC_PROXY_KEY__"
RequestHeader set X-RC-Client-IP "expr=%{REMOTE_ADDR}"
Header unset Set-Cookie
</Location>
</VirtualHost>
# Apache < 2.4.47 has no upgrade=websocket. Instead of the first ProxyPass:
# RewriteEngine on
# RewriteCond %{HTTP:Upgrade} =websocket [NC]
# RewriteRule ^/rc_wss/(.*) "wss://ws.reactive.chat/rc_wss/$1" [P,L]
# ProxyPass "/rc_wss/" "https://ws.reactive.chat/rc_wss/" timeout=3600 flushpackets=on
Caddy
Caddy pobiera certyfikat sam, WebSockety nie wymagają osobnego ustawienia. header_up z wartością zastępuje to, co przeglądarka wysłała pod tą nazwą.
# reactive.chat - own domain (first-party proxy) for site key SITE_KEY
# Host: chat.twoja-domena.pl
#
# Caddy 2 obtains the certificate itself. WebSockets need no extra setting.
# The proxy key is a secret: never put it into a web page or a repository.
# header_up with a value REPLACES what the browser sent under that name.
# If you enable access logging (log directive), skip the HTTP fallback
# requests - they carry a short-lived token in the query string:
# log_skip /rc_wss/h/* (Caddy < 2.8: skip_log /rc_wss/h/*)
chat.twoja-domena.pl {
handle /rc_wss/* {
reverse_proxy https://ws.reactive.chat {
header_up Host ws.reactive.chat
header_up X-RC-Proxy-Key "__RC_PROXY_KEY__"
header_up X-RC-Client-IP {remote_host}
header_up -Cookie
header_up -Authorization
transport http {
tls_server_name ws.reactive.chat
}
flush_interval -1
}
}
handle /api/offline/* {
reverse_proxy https://ws.reactive.chat {
header_up Host ws.reactive.chat
header_up X-RC-Proxy-Key "__RC_PROXY_KEY__"
header_up X-RC-Client-IP {remote_host}
header_up -Cookie
header_up -Authorization
header_down -Set-Cookie
transport http {
tls_server_name ws.reactive.chat
}
}
}
handle /api/suche/* {
reverse_proxy https://ws.reactive.chat {
header_up Host ws.reactive.chat
header_up X-RC-Proxy-Key "__RC_PROXY_KEY__"
header_up X-RC-Client-IP {remote_host}
header_up -Cookie
header_up -Authorization
header_down -Set-Cookie
transport http {
tls_server_name ws.reactive.chat
}
# The answer is a stream (Server-Sent Events): pass it on unbuffered.
flush_interval -1
}
}
handle {
reverse_proxy https://cdn.reactive.chat {
header_up Host cdn.reactive.chat
header_up -X-RC-Proxy-Key
header_up -X-RC-Client-IP
header_up -Cookie
header_up -Authorization
header_down -Set-Cookie
transport http {
tls_server_name cdn.reactive.chat
}
}
}
}
Klucz proxy
- Rotacja. Utwórz nowy klucz od razu wystawia nowy klucz. Dotychczasowy działa jeszcze 24 godziny, żeby można było wpisać nowy bez przerwy w działaniu; potem sprawdź ponownie. Ważne są najwyżej dwa klucze: kolejna rotacja w ciągu tych 24 godzin od razu unieważnia najstarszy.
- Usuwanie. Usuń klucz natychmiast unieważnia klucz, a także stary klucz z rotacji, który jeszcze działa. Usuń własną domenę usuwa host i klucz razem. Wcześniej przywróć na swojej stronie zwykły fragment kodu.
- Gdy klucza brakuje lub jest błędny, czat działa dalej: oba nagłówki po prostu nie są wtedy brane pod uwagę. Wszyscy odwiedzający mają jednak adres Twojego proxy. Ponieważ ochrona przed nadużyciami liczy połączenia i żądania według adresu, może wtedy ograniczyć lub zablokować całe Twoje proxy – a tym samym wszystkich odwiedzających naraz. Dotyczy to także formularza offline.
- Jeden projekt na klucz. Klucz należy do dokładnie jednego projektu i jego zarejestrowanego hosta. Jeśli przez proxy z ważnym kluczem zgłosi się widżet z kluczem strony innego projektu, połączenie czatu zostaje odrzucone. Dla kolejnego projektu skonfiguruj osobną subdomenę z osobnym kluczem.
- Gdy klucz wyciekł: kto go zna, może podawać dla Twojego projektu dowolne adresy odwiedzających. Usuń go, potem utwórz nowy i wpisz go w proxy. Do tego czasu czat działa dalej, tylko z adresem Twojego proxy.
Rozwiązywanie problemów
HTTP 421 (Misdirected Request)
Nasz serwer odrzuca nagłówek Host: proxy wysyła Twoją własną nazwę zamiast nazwy celu. Nagłówek Host i SNI muszą być nazwą celu – w nginx proxy_set_header Host oraz proxy_ssl_server_name on z proxy_ssl_name, w Apache ProxyPreserveHost Off, w Caddy header_up Host i tls_server_name.
HTTP 502 lub błędy SSL w drodze do celu
Proxy nie może nawiązać połączenia TLS z nami albo nie ufa certyfikatowi.
- Apache: jeśli w logu błędów jest „Certificate Chain too long”, brakuje
SSLProxyVerifyDepth 5. - nginx: czy ścieżka w
proxy_ssl_trusted_certificatejest prawidłowa (patrz wyżej dla RHEL i CentOS)? Czy ustawionoproxy_ssl_server_name on? - Ogólnie: Twój serwer musi mieć prawo nawiązywać wychodzące połączenia na porcie 443.
HTTP 413 przy przesyłaniu załączników
Przesyłanie plików idzie przez /rc_wss/. Bez własnego ustawienia nginx przyjmuje tylko 1 MB; dlatego szablon ustawia client_max_body_size 32m w sekcji dla /rc_wss/. Jeśli przed Twoim proxy stoi load balancer lub CDN, potrzebuje co najmniej tego samego limitu.
Połączenie czatu bez upgrade
Test zgłasza „Brak upgrade WebSocket” wraz ze statusem HTTP, który otrzymał zamiast tego. Czat działa wtedy dalej w trybie awaryjnym HTTP, ale łączy się dopiero po dwóch nieudanych próbach WebSocket.
- nginx: w sekcji
/rc_wss/muszą byćproxy_http_version 1.1,proxy_set_header Upgrade $http_upgradeiproxy_set_header Connection "upgrade". - Apache: wersja od 2.4.47 z
upgrade=websocketi włączonym mod_proxy_wstunnel; dla starszych wersji rozwiązanie zastępcze na końcu szablonu. - Urządzenia przed proxy: CDN lub load balancer przed Twoim proxy musi przepuszczać WebSockety.
HTTP 401 lub 403 przy formularzu offline
- 401: coś po drodze wymaga uwierzytelnienia, zwykle ochrona hasłem na hoście Twojego proxy.
/api/offline/musi być osiągalne bez logowania. - 403 jako uwaga o pochodzeniu: żądanie do nas dociera, ale pochodzenie nie pasuje do projektu. W „Dozwolonych źródłach” projektu musi być domena Twojej strony – ta, na której osadzono czat, a nie subdomena czatu.
- 403 z komunikatem „Odpowiedź nie pochodzi od reactive.chat”: odmowa pochodzi z miejsca przed nami, na przykład z zapory aplikacji webowej (WAF) lub reguły dostępu na Twoim serwerze.
DNS wskazuje na adres prywatny
Test zgłasza adres niepubliczny, jeśli co najmniej jeden adres nazwy jest prywatny, lokalny lub zarezerwowany (na przykład 10.0.0.0/8, 192.168.0.0/16, 100.64.0.0/10 lub fc00::/7). Częste przyczyny to rekord z wewnętrznego DNS albo wewnętrzny load balancer. Twoi odwiedzający też nie osiągną takich adresów; publiczny rekord musi wskazywać na adres publiczny.
Sprawdzenie ręczne
Adres testowy z kroku 3 możesz wywołać sam:
curl -s https://chat.twoja-domena.pl/rc_wss/eigene-domain-probe
Przy prawidłowej konfiguracji odpowiedź brzmi:
{"rc":"eigene-domain-probe","v":1,"schluessel":"gueltig","client_ip":"gesetzt","site":"SITE_KEY","host":"chat.twoja-domena.pl"}
Wartości są niemieckimi słowami: schluessel (klucz) to gueltig (ważny), unbekannt (nieznany) lub fehlt (brak); client_ip to gesetzt (ustawiony), fehlt (brak) lub ungueltig (nieprawidłowy). site i host pojawiają się tylko przy ważnym kluczu. Odpowiedź nigdy nie zawiera adresu.
Stan na: