どのようにお手伝いできますか?

ご用件を簡単にお知らせください。メールで返信します。

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
トップページへ

独自ドメインとファーストパーティープロキシ

Webサイトのサブドメインからウィジェット、チャット接続、オフラインフォーム、Smart Answerを配信:プロキシキー、実際の訪問者アドレス、nginx・Apache・Caddy用テンプレート。

独自ドメインでは、chat.your-company.comなど、Webサイトのサブドメインを通してチャットを運用します。運営側のサーバーがウィジェットのリクエストを受け、リバースプロキシとしてreactive.chatに転送します。このページはサーバーの管理者向けです。編集担当者向けの短い説明は、独自ドメイン(ファーストパーティー)にあります。

サブドメインを経由するもの

得られる効果:

次の点は変わりません。

要件

設定

  1. アカウントでプロジェクトを開き、埋め込み → 独自ドメインを設定に進みます。
  2. 1. ホストにchat.your-company.comなどの名前を入力し、保存します。
  3. 2. プロキシキーでキーを作成をクリックします。キーはrcpx_で始まり、表示は1回だけです。保存するのはハッシュだけです。プロキシ設定のみに置き、Webページ、ブラウザーのスクリプト、リポジトリには絶対に含めないでください。
  4. 3. サーバー設定でサーバー用のテンプレートを取得します。キーの作成直後にはキーが入り、その後は__RC_PROXY_KEY__を表示します。nginx -tまたはapachectl configtestで設定をテストし、サーバーを再読み込みします。
  5. 5. 確認で今すぐ確認をクリックします(最大10秒に1回)。メッセージは作成しません。
  6. 5つの確認がすべて「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フォールバックのアドレスを導きます。他の属性はすべてそのままです(scriptタグのリファレンス)。

プロキシが転送する内容

すべての経路で、次を適用します。

/rc_wss/、/api/offline/、/api/suche/では、各リクエストに2つのヘッダーを設定します。

「設定」とは、ブラウザーが同じ名前で送った値を上書きすることです。配信ネットワークへの経路では、両方を削除します。

ロードバランサーやCDNの背後では、最初に見えるのは機器のアドレスです。実際のアドレスを引き継ぐよう設定してください。nginxはreal_ip(set_real_ip_from、real_ip_header)、Apacheはmod_remoteip(RemoteIPHeader、RemoteIPTrustedProxy)、Caddyはtrusted_proxiesと、{remote_host}の代わりに{client_ip}を使います。この状況は確認機能では検出できず、有効なアドレスが設定されていることだけが分かります。

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以降)

ポート443のVirtualHostだけです。ポート80のリダイレクトと証明書は、他のホストと同じように設定します。SSLProxyVerifyDepth 5が必要です。ない場合、Apacheは転送先のチェーンを1段階しか検証せず、「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>

2.4.47より前のApacheは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
            }
        }
    }
}

5つの確認ステップ

各ステップには「OK」「エラー」「注意」「未確認」が表示されます。「OK」が5つの場合だけ合格です。確認はポート443のHTTPSのみで、リダイレクトなし、各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

最終更新: