Dominio personalizzato (first-party)
Distribuire widget, connessione della chat e modulo offline da un sottodominio del Suo sito: requisiti, configurazione, modelli per nginx, Apache e Caddy e risoluzione dei problemi.
Con un dominio personalizzato, la chat passa attraverso un sottodominio del Suo sito, ad esempio chat.your-domain.com. Il Suo server accetta le richieste del widget e le inoltra a reactive.chat come proxy inverso. Questa pagina è destinata a chi gestisce quel server.
A che cosa serve un dominio personalizzato
Passano attraverso il Suo sottodominio:
- i file del widget (
loader.jse il nucleo caricato in seguito), - la connessione della chat (WebSocket), inclusi gli allegati,
- il modulo offline, che interviene quando non è possibile stabilire la connessione della chat.
Di conseguenza:
- Nessuna richiesta a domini di terzi. Per questi percorsi, i browser dei visitatori comunicano solo con il Suo sottodominio, non con un dominio reactive.chat.
- Blocchi pubblicitari. Gli elenchi di filtri basati sul nome di dominio non riconoscono più la chat dal dominio reactive.chat.
- Un solo indirizzo per la Content Security Policy.
script-srceconnect-srcelencano il Suo sottodominio al posto degli indirizzi reactive.chat.connect-srclo richiede due volte: conwss://per la connessione della chat e conhttps://per modulo offline, caricamenti e fallback HTTP (quando un proxy blocca i WebSocket). - Arriva il vero indirizzo del visitatore. Il proxy ci comunica l’indirizzo del visitatore in un’intestazione dedicata, protetta da una chiave segreta. La protezione dagli abusi (limitazioni e blocchi) conta quindi per visitatore anziché per proxy e la conversazione mostra l’indirizzo del visitatore.
Che cosa non è
- Non è hosting autonomo. Il Suo server si limita a inoltrare. Conversazioni, allegati e impostazioni continuano a essere elaborati e conservati da reactive.chat, esattamente come senza dominio personalizzato.
- Non determina il consenso necessario. Se e per che cosa serva il consenso dei visitatori è una questione separata. Il dominio personalizzato non cambia chi tratta i dati. Le formulazioni per l’informativa sono nel testo per la Sua informativa sulla privacy.
- Il Suo server vede il traffico. La connessione TLS del visitatore termina sul proxy. Messaggi e allegati vengono brevemente decifrati lì, prima di essere inoltrati a noi nuovamente cifrati. Non registri i corpi delle richieste sul proxy.
Requisiti
- Un server o proxy inverso proprio, raggiungibile da Internet tramite HTTPS sulla porta 443 e in grado di aprire connessioni HTTPS in uscita. Sono disponibili modelli per nginx (con modulo ssl), Apache dalla versione 2.4.47 e Caddy 2.
- Per Apache, i moduli mod_ssl, mod_proxy, mod_proxy_http, mod_proxy_wstunnel e mod_headers. Solo dalla versione 2.4.47 Apache riconosce
upgrade=websocket; per le versioni precedenti, alla fine del modello è indicata un’alternativa con mod_rewrite. - Un sottodominio usato solo per la chat, ad esempio
chat.your-domain.com. La chat richiede l’intero host; un percorso comewww.your-domain.com/chat/non funziona. Inserisca solo il nome, senzahttps://, porta o percorso. Non sono consentiti indirizzi IP, suffissi interni come.local,.lano.internale nomi sotto reactive.chat. - Lo stesso dominio del sito. La chat è first-party solo se il sottodominio appartiene al dominio del sito in cui è incorporata. In caso contrario funziona comunque e la pagina dell’account segnala la differenza.
- Un record DNS (A e/o AAAA) che punti al Suo server. Tutti gli indirizzi del nome devono essere pubblici.
- Un certificato TLS per il sottodominio. I modelli nginx e Apache prevedono i percorsi di certbot (Let’s Encrypt); Caddy ottiene il certificato autonomamente.
- Il permesso di modificare il progetto nell’account reactive.chat.
Dietro un bilanciatore di carico o una CDN, il proxy vede inizialmente l’indirizzo di quel dispositivo anziché quello del visitatore. Configuri quindi l’acquisizione dell’indirizzo reale: in nginx il modulo real_ip (set_real_ip_from, real_ip_header), in Apache mod_remoteip (RemoteIPHeader, RemoteIPTrustedProxy), in Caddy l’opzione trusted_proxies e il segnaposto {client_ip} al posto di {remote_host}. La nostra verifica non può rilevare questo caso: vede solo che è impostato un indirizzo valido, non quale.
Configurazione passo dopo passo
- Aprire la pagina. Apra il progetto nell’account. Nella sezione «Incorporamento» trova il link Configura un dominio personalizzato.
- Inserire l’host. In «1. Host», inserisca il nome, ad esempio
chat.your-domain.com, e salvi. - Creare la chiave. In «2. Chiave del proxy», faccia clic su Genera chiave. La chiave inizia con
rcpx_e viene mostrata una sola volta; ne conserviamo solo un hash. La copi subito. È segreta e deve trovarsi solo nella configurazione del proxy, mai in una pagina web, uno script del browser o un repository. - Inserire il modello. In «3. Configurazione del server» trova modelli pronti per nginx, Apache e Caddy. Subito dopo la creazione contengono già la chiave; in seguito mostrano
__RC_PROXY_KEY__, da sostituire con la chiave. Se necessario adatti i percorsi dei certificati, verifichi la configurazione (nginx -toapachectl configtest) e ricarichi il server. - Verificare. In «5. Verifica», faccia clic su Verifica ora. Chiamiamo il sottodominio dall’esterno e verifichiamo separatamente cinque percorsi (vedere sotto). Non viene creato alcun messaggio. Una nuova verifica è possibile non prima di 10 secondi.
- Sostituire il codice. Solo quando tutti e cinque i passi mostrano «OK», sostituisca il codice attuale sul sito con quello di «4. Codice di incorporamento».
Il nuovo codice appare così: entrambi gli indirizzi puntano al Suo sottodominio:
<script src="https://chat.your-domain.com/loader.js"
data-rc-site-key="SITE_KEY"
data-rc-ws-url="wss://chat.your-domain.com/rc_wss/"
async></script>
Il widget ricava la posizione dei file da src e la connessione della chat da data-rc-ws-url; da quest’ultima deriva l’indirizzo del modulo offline. Gli altri attributi, come data-rc-locale, restano invariati; sono descritti in Incorporare il widget. Il codice nella pagina dell’account contiene anche il colore del marchio.
I cinque passi della verifica
Ogni passo mostra «OK», «Errore», «Nota» o «non verificato». La verifica è superata solo se tutti e cinque mostrano «OK»; una nota non conta come superamento. Le verifiche usano solo HTTPS sulla porta 443, non seguono reindirizzamenti e ogni passo dispone di 5 secondi.
- Risoluzione del nome. Il nome deve avere un record DNS e tutti i suoi indirizzi devono essere pubblici. Viene segnalata l’assenza sia di record A sia di record AAAA, oppure la presenza di almeno un indirizzo privato, locale o riservato: questi indirizzi non vengono verificati. Tutti i passi successivi si collegano esattamente all’indirizzo verificato qui.
- loader.js tramite il Suo dominio. Carichiamo
https://chat.your-domain.com/loader.jse confrontiamo il file con il nostro. Se non si ottengono connessione, risposta o certificato valido, i passi rimanenti vengono saltati («non verificato»). Se il proxy risponde con un reindirizzamento anziché il file, è un errore. Se il file differisce dal nostro, di solito la causa è una cache nel proxy o una destinazione errata per/. - Chiave e indirizzo del visitatore. Chiamiamo un indirizzo di verifica sotto
/rc_wss/. Il nostro server indica se ha ricevuto una chiave valida e un indirizzo del visitatore valido e a quale progetto appartiene la chiave. Possibili errori: manca l’intestazioneX-RC-Proxy-Key; la chiave è sconosciuta (errata, precedente o rimossa; subito dopo la creazione possono servire fino a 30 secondi); mancaX-RC-Client-IPo non contiene un indirizzo valido; la chiave appartiene a un altro progetto. Compare una nota se la chiave è valida ma registrata per un host diverso. - Connessione della chat (WebSocket). Apriamo una connessione WebSocket tramite
wss://chat.your-domain.com/rc_wss/e attendiamo HTTP 101 con protocollorc.v1. «Nessun upgrade WebSocket» significa che il proxy non inoltra le intestazioniUpgradeeConnection. - Modulo offline. Chiamiamo
https://chat.your-domain.com/api/offline/SITE_KEYcon GET. Il nostro endpoint risponde con HTTP 405 perché accetta solo POST: questo conferma che la richiesta ci raggiunge senza creare un messaggio. Altri risultati: origine rifiutata (una nota, vedere la risoluzione dei problemi), progetto non attivo, destinazione che richiede autenticazione (HTTP 401).
I passi da 2 a 5 possono anche segnalare HTTP 421 (intestazione Host, vedere la risoluzione dei problemi). Se il passo 3 o 5 indica «La risposta non proviene da reactive.chat», quel percorso punta a una destinazione errata nel proxy.
Che cosa deve inoltrare il proxy
/rc_wss/al server della chat reactive.chat, con upgrade WebSocket e timeout lungo (i modelli usano 3600 secondi). Gli allegati usano lo stesso percorso, fino a 32 MB per file a seconda del piano./api/offline/allo stesso server. Il widget vi invia il modulo offline.- Tutto il resto alla rete di distribuzione reactive.chat. Da lì arrivano
loader.jse gli altri file del widget.
Per tutti e tre i percorsi:
- Intestazione Host e SNI corrispondono al nome della destinazione, non al Suo sottodominio. Il nostro server risponde con HTTP 421 a un host sconosciuto.
- Il certificato della destinazione viene verificato.
- Nessun cookie e nessuna credenziale. Le intestazioni
CookieeAuthorizationdel browser non vengono inoltrate. - Nessun reindirizzamento. Non serve una cache. Se ne aggiunge una, mantenga breve la durata per
loader.js: il nome del file non contiene una versione.
Per /rc_wss/ e /api/offline/ il proxy imposta inoltre due intestazioni su ogni richiesta:
X-RC-Proxy-Key: la Sua chiave.X-RC-Client-IP: l’indirizzo del visitatore come lo vede il proxy.
«Imposta» significa che ciò che un browser invia con questi nomi viene sovrascritto e non ci raggiunge mai. Sul percorso verso la rete di distribuzione entrambe le intestazioni vengono rimosse; la chiave va solo al server della chat.
Fallback HTTP tramite il Suo dominio
Se la rete di un visitatore non lascia passare un WebSocket, il widget passa automaticamente al fallback HTTP. Usa lo stesso percorso /rc_wss/ e non richiede una voce aggiuntiva nel proxy. Servono due condizioni:
- Inoltrare le risposte senza buffering. Il proxy deve trasmettere immediatamente le risposte su
/rc_wss/: con nginxproxy_buffering offeproxy_cache off, con Apacheflushpackets=on, con Caddyflush_interval -1. I modelli sottostanti lo prevedono già. - HTTPS nella Content Security Policy.
connect-srcrichiede il sottodominio conwss://e conhttps://, ad esempioconnect-src 'self' wss://chat.your-domain.com https://chat.your-domain.com.
I modelli
I modelli seguenti corrispondono a quelli nella pagina dell’account. L’account inserisce già host, indirizzi di destinazione validi per il Suo account e, subito dopo la creazione, la chiave. È quindi preferibile copiare il modello da lì; le versioni qui riportate servono da riferimento. I segnaposto sono chat.your-domain.com, SITE_KEY e __RC_PROXY_KEY__.
nginx
Va inserito nel contesto http, ad esempio come /etc/nginx/conf.d/chat.your-domain.com.conf. Su RHEL e CentOS il bundle CA si trova in /etc/pki/tls/certs/ca-bundle.crt anziché in /etc/ssl/certs/ca-certificates.crt.
# reactive.chat - own domain (first-party proxy) for site key SITE_KEY
# Host: chat.your-domain.com
#
# Needs nginx >= 1.7 with the ssl module. Put this file into the http
# context (e.g. /etc/nginx/conf.d/chat.your-domain.com.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.your-domain.com;
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.your-domain.com;
ssl_certificate /etc/letsencrypt/live/chat.your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/chat.your-domain.com/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
Il modello contiene solo il VirtualHost per la porta 443. Configuri il reindirizzamento dalla porta 80 e il certificato come per gli altri host. SSLProxyVerifyDepth 5 è necessario: senza, Apache verifica solo un livello della catena del certificato della destinazione e la connessione fallisce con «Certificate Chain too long».
# reactive.chat - own domain (first-party proxy) for site key SITE_KEY
# Host: chat.your-domain.com
#
# 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.your-domain.com
# 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.your-domain.com_access.log combined env=!rc_no_log
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/chat.your-domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/chat.your-domain.com/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 ottiene il certificato autonomamente; i WebSocket non richiedono impostazioni aggiuntive. header_up con un valore sostituisce ciò che il browser ha inviato con quel nome.
# reactive.chat - own domain (first-party proxy) for site key SITE_KEY
# Host: chat.your-domain.com
#
# 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.your-domain.com {
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
}
}
}
}
La chiave del proxy
- Rotazione. Crea nuova chiave emette subito una nuova chiave. Quella precedente resta valida per 24 ore, consentendo di sostituirla senza interruzioni; in seguito ripeta la verifica. Esistono al massimo due chiavi valide: un’ulteriore rotazione entro le 24 ore invalida subito la più vecchia.
- Rimozione. Rimuovi chiave invalida immediatamente la chiave e anche un’eventuale vecchia chiave ancora valida dopo una rotazione. Rimuovi il dominio elimina insieme host e chiave. Prima ripristini sul sito il codice di incorporamento nella forma abituale.
- Se la chiave manca o è errata, la chat continua a funzionare: le due intestazioni non vengono valutate. Ogni visitatore appare però con l’indirizzo del proxy. Poiché la protezione dagli abusi conta connessioni e richieste per indirizzo, può limitare o bloccare l’intero proxy e quindi tutti i visitatori contemporaneamente. Vale anche per il modulo offline.
- Un progetto per chiave. Una chiave appartiene esattamente a un progetto e al relativo host registrato. Se un widget con la chiave del sito di un altro progetto si collega tramite un proxy con una chiave valida, la connessione della chat viene rifiutata. Per un ulteriore progetto, configuri un sottodominio distinto con la propria chiave.
- Se la chiave è stata divulgata: chiunque la conosca può dichiarare indirizzi arbitrari dei visitatori per il Suo progetto. La rimuova, ne crei una nuova e la inserisca nel proxy. Nel frattempo la chat continua a funzionare, ma con l’indirizzo del proxy.
Risoluzione dei problemi
HTTP 421 (Misdirected Request)
Il nostro server rifiuta l’intestazione Host: il proxy invia il Suo nome anziché quello della destinazione. Host e SNI devono corrispondere al nome della destinazione: in nginx proxy_set_header Host insieme a proxy_ssl_server_name on con proxy_ssl_name, in Apache ProxyPreserveHost Off, in Caddy header_up Host e tls_server_name.
HTTP 502 o errori SSL verso la destinazione
Il proxy non riesce a stabilire la connessione TLS verso di noi oppure non considera attendibile il certificato.
- Apache: se il registro degli errori indica «Certificate Chain too long», manca
SSLProxyVerifyDepth 5. - nginx: il percorso in
proxy_ssl_trusted_certificateè corretto (vedere sopra per RHEL e CentOS)? È impostatoproxy_ssl_server_name on? - In generale: il server deve poter aprire connessioni in uscita sulla porta 443.
HTTP 413 durante il caricamento degli allegati
I caricamenti passano per /rc_wss/. Senza un’impostazione specifica nginx accetta solo 1 MB; il modello imposta quindi client_max_body_size 32m nella sezione /rc_wss/. Se davanti al proxy si trova un bilanciatore di carico o una CDN, deve avere almeno lo stesso limite.
Connessione della chat senza upgrade
La verifica segnala «Nessun upgrade WebSocket» con lo stato HTTP ricevuto al suo posto. La chat continua tramite fallback HTTP, ma si collega solo dopo due tentativi WebSocket falliti.
- nginx: la sezione
/rc_wss/richiedeproxy_http_version 1.1,proxy_set_header Upgrade $http_upgradeeproxy_set_header Connection "upgrade". - Apache: versione 2.4.47 o successiva con
upgrade=websockete mod_proxy_wstunnel attivato; per le versioni precedenti, l’alternativa alla fine del modello. - Davanti al proxy: una CDN o un bilanciatore di carico deve lasciare passare i WebSocket.
HTTP 401 o 403 sul modulo offline
- 401: un componente lungo il percorso richiede autenticazione, solitamente una protezione con password sull’host del proxy.
/api/offline/deve essere raggiungibile senza autenticazione. - 403, come nota sull’origine: la richiesta ci raggiunge, ma l’origine non corrisponde al progetto. Le «Origini consentite» del progetto devono contenere il dominio del sito in cui è incorporata la chat, non il sottodominio della chat.
- 403 con «La risposta non proviene da reactive.chat»: il rifiuto proviene da un componente precedente, ad esempio un firewall per applicazioni web o una regola di accesso sul Suo server.
Il DNS punta a un indirizzo privato
La verifica segnala un indirizzo non pubblico se almeno un indirizzo del nome è privato, locale o riservato (ad esempio 10.0.0.0/8, 192.168.0.0/16, 100.64.0.0/10 o fc00::/7). Cause comuni sono un record del DNS interno o un bilanciatore interno. Neanche i visitatori possono raggiungere tali indirizzi; il record pubblico deve puntare a un indirizzo pubblico.
Verificare manualmente
Può chiamare personalmente l’indirizzo di verifica del passo 3:
curl -s https://chat.your-domain.com/rc_wss/eigene-domain-probe
Con una configurazione corretta, la risposta è:
{"rc":"eigene-domain-probe","v":1,"schluessel":"gueltig","client_ip":"gesetzt","site":"SITE_KEY","host":"chat.your-domain.com"}
I valori sono parole tedesche: schluessel (chiave) è gueltig (valida), unbekannt (sconosciuta) o fehlt (mancante); client_ip è gesetzt (impostato), fehlt (mancante) o ungueltig (non valido). site e host compaiono solo con una chiave valida. La risposta non contiene mai un indirizzo.
Approfondimenti nella documentazione
In dettaglio: Dominio personalizzato e proxy first-party. Tutti i capitoli sono nella documentazione.
Zadnje ažurirano: