Domínio próprio e proxy first-party
Como servir os arquivos do widget, a conexão do chat, o formulário offline e o Smart Answer por um subdomínio do seu site, com chave de proxy, endereço real do visitante e modelos prontos para nginx, Apache e Caddy.
Com um domínio próprio, o chat funciona por um subdomínio do seu site, por exemplo, chat.your-company.com. Seu servidor recebe as requisições do widget e as encaminha ao reactive.chat como proxy reverso. Esta página se destina à pessoa que administra esse servidor. A versão resumida para editores está em Domínio próprio (first-party).
O que passa pelo subdomínio
- Arquivos do widget –
loader.js, o núcleo carregado depois (core.<hash>.js) e os outros módulos. - Conexão do chat – o WebSocket em
/rc_wss/, incluindo o fallback HTTP em/rc_wss/h/e os uploads de arquivos em/rc_wss/upload/. - Formulário offline –
POST /api/offline/<SITE_KEY>, quando não é possível estabelecer uma conexão com o chat. - Smart Answer –
/api/suche/, se você usar a resposta de IA na pesquisa do site.
O que você ganha:
- Nenhuma requisição a domínios de terceiros. Para essas rotas, os navegadores dos visitantes se comunicam apenas com seu subdomínio.
- Um endereço na sua Content Security Policy.
script-srceconnect-srclistam seu subdomínio em vez dos endereços do reactive.chat (detalhes em Segurança e CSP). - O endereço real do visitante chega. Seu proxy o informa em um cabeçalho dedicado, protegido por uma chave secreta. Os limites e bloqueios passam a contar por visitante, em vez de por proxy.
O que isso não significa:
- Não é hospedagem própria. Conversas, anexos e configurações continuam sendo tratados e armazenados pelo reactive.chat.
- Não define nada sobre consentimento. Um domínio próprio não muda quem trata os dados.
- Seu proxy vê o tráfego. O TLS termina no seu proxy; não registre corpos de requisição nele e mantenha
/rc_wss/h/fora do log de acesso (essas requisições levam um token de conexão de curta duração na query).
Requisitos
- Um servidor ou proxy reverso acessível publicamente por HTTPS na porta 443 e capaz de realizar conexões HTTPS de saída. Há modelos para nginx (com o módulo ssl), Apache 2.4.47 ou posterior e Caddy 2.
- Para Apache, os módulos
mod_ssl,mod_proxy,mod_proxy_http,mod_proxy_wstunnel,mod_headersemod_setenvif. - Um subdomínio usado apenas para o chat. O chat precisa do host inteiro; um caminho como
www.your-company.com/chat/não funciona. Informe somente o nome, semhttps://, porta ou caminho. Não são permitidos: endereços IP, terminações internas como.local,.lan,.internale nomes sobreactive.chat. - O mesmo domínio do site. O chat só é first-party se o subdomínio pertencer ao domínio do site no qual ele está incorporado.
- DNS (A e/ou AAAA) apenas com endereços públicos.
- Um certificado TLS para o subdomínio (os modelos nginx/Apache esperam os caminhos do certbot; o Caddy obtém o certificado por conta própria).
- Permissão para editar o projeto.
Configuração
- Na conta, abra o projeto, seção Incorporar → Configurar seu domínio próprio.
- Em 1. Host, informe o nome, por exemplo,
chat.your-company.com, e salve. - Em 2. Chave de proxy, clique em Gerar chave. A chave começa com
rcpx_e é exibida exatamente uma vez; apenas um hash é armazenado. Ela deve ficar exclusivamente na configuração do proxy, nunca em uma página da web, script de navegador ou repositório. - Em 3. Configuração do servidor, use o modelo do seu servidor. Logo após gerar a chave, ele a contém; depois, mostra
__RC_PROXY_KEY__. Teste a configuração (nginx -touapachectl configtest) e recarregue o servidor. - Em 5. Verificação, clique em Verificar agora (no máximo a cada 10 segundos). Nenhuma mensagem é criada.
- Somente quando todas as cinco etapas de verificação mostrarem “OK”, substitua o código de incorporação pelo de 4. Código de incorporação:
<script src="https://chat.your-company.com/loader.js"
data-rc-site-key="SITE_KEY"
data-rc-ws-url="wss://chat.your-company.com/rc_wss/"
async></script>
O widget obtém o local dos arquivos de src e a conexão do chat de data-rc-ws-url; a partir dela, deduz os endereços do formulário offline, dos uploads e do fallback HTTP. Todos os outros atributos permanecem como estão (Referência da tag script).
O que o proxy deve encaminhar
/rc_wss/→ servidor do chathttps://ws.reactive.chat/rc_wss/, com upgrade para WebSocket, tempo limite longo (nos modelos: 3600 s), sem buffering e limite de corpo de pelo menos 32 MB (uploads)./api/offline/→https://ws.reactive.chat/api/offline/(corpo pequeno, no modelo: 32 kB, 30 s)./api/suche/→https://ws.reactive.chat/api/suche/, sem buffering (a resposta é um fluxo de Server-Sent Events), corpo de até 8 kB, 120 s.- todo o restante → rede de distribuição
https://cdn.reactive.chat/.
Para todas as rotas:
- O cabeçalho Host e o SNI usam o nome do destino, não seu subdomínio. Um host desconhecido recebe HTTP 421 como resposta.
- O certificado do destino é verificado.
- Sem cookies nem credenciais.
CookieeAuthorizationdo navegador não são encaminhados, eSet-Cookienão é devolvido. - Sem redirecionamentos. Não é necessário cache; se você configurar um, mantenha-o curto para
loader.js, pois o arquivo não tem número de versão no nome (o núcleo tem; veja Arquitetura).
Para /rc_wss/, /api/offline/ e /api/suche/, o proxy define dois cabeçalhos em cada requisição:
- X-RC-Proxy-Key – sua chave
rcpx_…. - X-RC-Client-IP – o endereço do visitante conforme visto pelo proxy.
“Define” significa que qualquer valor enviado pelo navegador com esses nomes é sobrescrito. Na rota para a rede de distribuição, ambos são removidos.
Atrás de um balanceador de carga ou CDN, seu proxy vê primeiro o endereço desse dispositivo. Nesse caso, configure o uso do endereço real: nginx real_ip (set_real_ip_from, real_ip_header), Apache mod_remoteip (RemoteIPHeader, RemoteIPTrustedProxy), Caddy trusted_proxies e {client_ip} em vez de {remote_host}. A verificação não detecta esse caso; ela só vê que um endereço válido foi definido.
Modelo nginx
A página da conta já preenche o host, os endereços de destino e a chave; o melhor é copiar o modelo de lá. A versão aqui serve de referência; os marcadores são chat.your-company.com, SITE_KEY e __RC_PROXY_KEY__. No RHEL/CentOS, o pacote de certificados de AC fica em /etc/pki/tls/certs/ca-bundle.crt.
server {
listen 80;
listen [::]:80;
server_name chat.your-company.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-company.com;
ssl_certificate /etc/letsencrypt/live/chat.your-company.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/chat.your-company.com/privkey.pem;
# HTTP fallback (SSE / long polling): token in the query, do not 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;
}
# Chat connection (WebSocket) and uploads
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;
proxy_buffering off;
proxy_cache off;
client_max_body_size 32m;
proxy_request_buffering off;
}
# Offline form
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 (website search), answer as a stream
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;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 120s;
}
# Widget files
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;
}
}
Modelo Apache (2.4.47 ou posterior)
Apenas o VirtualHost da porta 443; configure o redirecionamento da porta 80 e o certificado como nos seus outros hosts. SSLProxyVerifyDepth 5 é obrigatório; caso contrário, o Apache verifica apenas um nível da cadeia do destino e informa “Certificate Chain too long”.
<VirtualHost *:443>
ServerName chat.your-company.com
SetEnvIf Request_URI "^/rc_wss/h/" rc_no_log
CustomLog ${APACHE_LOG_DIR}/chat.your-company.com_access.log combined env=!rc_no_log
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/chat.your-company.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/chat.your-company.com/privkey.pem
SSLProxyEngine on
SSLProxyVerify require
SSLProxyVerifyDepth 5
SSLProxyCheckPeerName on
SSLProxyCACertificateFile /etc/ssl/certs/ca-certificates.crt
ProxyRequests Off
ProxyPreserveHost Off
ProxyAddHeaders Off
RequestHeader unset X-RC-Proxy-Key early
RequestHeader unset X-RC-Client-IP early
RequestHeader unset Cookie early
RequestHeader unset Authorization early
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>
O Apache anterior à versão 2.4.47 não reconhece upgrade=websocket. Nesse caso, substitua a primeira linha ProxyPass por:
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
Modelo Caddy 2
header_up com um valor substitui o que o navegador enviou com esse nome. Se ativar logs de acesso, exclua /rc_wss/h/* (log_skip; antes do Caddy 2.8, skip_log).
chat.your-company.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
}
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
}
}
}
}
As cinco etapas de verificação
Cada etapa mostra “OK”, “Erro”, “Aviso” ou “não verificado”. A verificação só passa com cinco resultados “OK”. As verificações usam somente HTTPS na porta 443, sem redirecionamentos, com 5 segundos por etapa.
- Resolução de nomes – registros A/AAAA presentes, todos os endereços públicos. Todas as etapas seguintes se conectam exatamente a esse endereço.
- loader.js pelo seu domínio – o arquivo é carregado e comparado com o nosso. Sem conexão, resposta ou certificado válido, as etapas restantes são ignoradas. Um redirecionamento é um erro; um arquivo diferente indica um cache ou um destino incorreto para
/. - Chave e endereço do visitante – chamada de
/rc_wss/eigene-domain-probe. Erros possíveis:X-RC-Proxy-Keyausente; chave desconhecida (logo após criá-la, pode haver um atraso de até 30 segundos);X-RC-Client-IPausente ou inválido; a chave pertence a outro projeto. Há um aviso se a chave for válida, mas estiver cadastrada para outro host. - WebSocket –
wss://chat.your-company.com/rc_wss/deve responder com HTTP 101 e o subprotocolorc.v1. - Formulário offline –
GET /api/offline/SITE_KEYdeve responder com 405 (o endpoint só aceita POST; assim, nenhuma mensagem é criada).
Você pode chamar por conta própria o endereço de verificação da etapa 3:
curl -s https://chat.your-company.com/rc_wss/eigene-domain-probe
Quando configurado corretamente:
{"rc":"eigene-domain-probe","v":1,"schluessel":"gueltig","client_ip":"gesetzt","site":"SITE_KEY","host":"chat.your-company.com"}
- schluessel –
gueltig(válida),unbekannt(desconhecida) oufehlt(ausente). - client_ip –
gesetzt(definido),fehlt(ausente) ouungueltig(inválido). - site, host – somente com chave válida. A resposta nunca devolve um endereço.
A chave de proxy
- Rotação: Criar nova chave emite uma nova imediatamente; a anterior continua válida por 24 horas. Há no máximo duas chaves válidas: uma nova rotação dentro das 24 horas invalida a mais antiga imediatamente.
- Remoção: Remover chave a invalida imediatamente (inclusive uma antiga de uma rotação em andamento). Remover domínio próprio remove o host e a chave juntos; primeiro, volte ao código de incorporação anterior no site.
- Chave ausente ou incorreta: o chat continua funcionando, mas os dois cabeçalhos são ignorados. Todos os visitantes passam a aparecer com o endereço do proxy e, como a proteção contra abuso conta por endereço, ela pode limitar todo o proxy e, portanto, todos os visitantes de uma só vez.
- Um projeto por chave: se um widget com a chave do site de outro projeto se conectar por um proxy com chave válida, a conexão será rejeitada. Para outro projeto, você precisa de um subdomínio separado com chave própria.
- Chave vazada: qualquer pessoa que a conheça pode declarar endereços arbitrários de visitantes para seu projeto. Remova-a, gere uma nova e configure-a.
Solução de problemas
- HTTP 421 (Misdirected Request): o proxy envia seu nome como host em vez do nome do destino. nginx:
proxy_set_header Hostcomproxy_ssl_server_name on/proxy_ssl_name; Apache:ProxyPreserveHost Off; Caddy:header_up Hostetls_server_name. - HTTP 502 / erro de TLS para o destino: Apache sem
SSLProxyVerifyDepth 5; nginx com caminho incorreto emproxy_ssl_trusted_certificateou semproxy_ssl_server_name on; HTTPS de saída bloqueado. - HTTP 413 no upload: sem configuração, o nginx aceita apenas 1 MB; use
client_max_body_size 32mna seção/rc_wss/(e pelo menos o mesmo limite em um balanceador de carga à frente). - Sem upgrade para WebSocket:
Upgrade/Connectionnão são encaminhados. O chat passa a usar o fallback HTTP, mas só se conecta após duas tentativas malsucedidas de WebSocket. - 401 no formulário offline: há proteção por senha na frente de
/api/offline/. - 403 com aviso sobre a origem: o domínio do site (não o subdomínio do chat!) está ausente em Origens permitidas no projeto.
- 403 “A resposta não vem do reactive.chat”: um firewall ou regra de acesso à frente do destino recusa a requisição.
- DNS aponta para um endereço privado (
10.0.0.0/8,192.168.0.0/16,100.64.0.0/10,fc00::/7…): o registro público precisa apontar para um endereço público.
A seguir: Transporte e protocolo · Segurança e CSP
Última actualització: