Чем мы можем помочь?

Кратко опишите вопрос; мы ответим по электронной почте.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
На главную

Собственный домен и прокси первой стороны

Как предоставлять файлы виджета, подключение чата, офлайн-форму и Smart Answer через поддомен сайта: ключ прокси, настоящий адрес посетителя и готовые шаблоны nginx, Apache и Caddy.

При собственном домене чат работает через поддомен сайта, например chat.your-company.com. Ваш сервер принимает запросы виджета и передаёт их reactive.chat как обратный прокси. Эта страница предназначена для администратора сервера. Краткая версия для редакторов — Собственный домен (first-party).

Что проходит через поддомен

Что вы получаете:

Чего это не означает:

Требования

Настройка

  1. В аккаунте откройте проект, раздел Встраивание → Настроить собственный домен.
  2. В 1. Хост укажите имя, например chat.your-company.com, и сохраните.
  3. В 2. Ключ прокси нажмите Создать ключ. Ключ начинается с rcpx_ и показывается ровно один раз; сохраняется только хеш. Ему место исключительно в конфигурации прокси, никогда на веб-странице, в браузерном скрипте или репозитории.
  4. В 3. Конфигурация сервера возьмите шаблон своего сервера. Сразу после создания ключа он уже в шаблоне; позднее там __RC_PROXY_KEY__. Проверьте конфигурацию (nginx -t или apachectl configtest) и перезагрузите сервер.
  5. В 5. Проверка нажмите Проверить сейчас (не чаще раза в 10 секунд). Сообщение не создаётся.
  6. Только когда все пять шагов показывают «OK», замените код встраивания кодом из 4. Код встраивания:
<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>

Виджет берёт расположение файлов из src, подключение чата из data-rc-ws-url и выводит из него адреса офлайн-формы, загрузок и резервного канала HTTP. Остальные атрибуты остаются прежними (Справочник по тегу скрипта).

Что прокси должен пересылать

Для всех маршрутов:

Для /rc_wss/, /api/offline/ и /api/suche/ прокси задаёт два заголовка в каждом запросе:

«Задаёт» означает, что всё присланное браузером под этими именами перезаписывается. На маршруте к сети доставки оба очищаются.

За балансировщиком нагрузки или CDN прокси сначала видит адрес этого устройства. Тогда настройте получение настоящего адреса: nginx real_ip (set_real_ip_from, real_ip_header), Apache mod_remoteip (RemoteIPHeader, RemoteIPTrustedProxy), Caddy trusted_proxies и {client_ip} вместо {remote_host}. Проверка этого не обнаруживает: она видит лишь, что задан корректный адрес.

Шаблон nginx

Страница аккаунта уже подставляет хост, целевые адреса и ключ; лучше копировать шаблон оттуда. Здесь версия для справки; места для подстановки — chat.your-company.com, SITE_KEY и __RC_PROXY_KEY__. В RHEL/CentOS набор CA находится в /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;
    }
}

Шаблон Apache (2.4.47 и новее)

Только VirtualHost для порта 443; перенаправление с порта 80 и сертификат настройте как для других хостов. SSLProxyVerifyDepth 5 обязателен; иначе Apache проверяет цепочку цели лишь на один уровень и сообщает «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>

Apache до 2.4.47 не поддерживает upgrade=websocket. В таком случае замените первую строку 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 2

header_up со значением заменяет всё, что браузер прислал под этим именем. Если включаете журналы доступа, исключите /rc_wss/h/* (log_skip, до 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
            }
        }
    }
}

Пять шагов проверки

Каждый шаг показывает «OK», «Ошибка», «Примечание» или «Не проверено». Проверка пройдена только при пяти «OK». Используется только HTTPS на порту 443, без перенаправлений, 5 секунд на шаг.

  1. Разрешение имени — есть A/AAAA, все адреса публичные. Следующие шаги подключаются именно к этому адресу.
  2. loader.js через ваш домен — файл загружается и сравнивается с нашим. Без подключения, ответа или действительного сертификата остальные шаги пропускаются. Перенаправление — ошибка; отличие файла указывает на кеш или неверную цель для /.
  3. Ключ и адрес посетителя — вызов /rc_wss/eigene-domain-probe. Возможные ошибки: нет X-RC-Proxy-Key; ключ неизвестен (сразу после создания возможна задержка до 30 секунд); X-RC-Client-IP отсутствует или неверен; ключ относится к другому проекту. Примечание — если ключ действителен, но зарегистрирован для другого хоста.
  4. WebSocket — wss://chat.your-company.com/rc_wss/ должен ответить HTTP 101 с подпротоколом rc.v1.
  5. Офлайн-форма — GET /api/offline/SITE_KEY должен ответить 405 (конечная точка принимает только POST; так сообщение не создаётся).

Проверочный адрес из шага 3 можно вызвать самостоятельно:

curl -s https://chat.your-company.com/rc_wss/eigene-domain-probe

При правильной настройке:

{"rc":"eigene-domain-probe","v":1,"schluessel":"gueltig","client_ip":"gesetzt","site":"SITE_KEY","host":"chat.your-company.com"}

Ключ прокси

Устранение неполадок

Далее: Транспорт и протокол · Безопасность и CSP

Обновлено: