私は Websocket と ELB を使用したことがありますが、それらを一緒に使用したことはありません。そのため、Elastic Load Balancer の HTTP フォワーダーが Websocket リクエストを理解していないことに気づきませんでした...
したがって、TCPフォワーダーを使用しているに違いないと思います。これは、別のポートを使用している理由を説明しています。もちろん、TCPフォワーダーはプロトコルを認識しないため、ヘッダーをまったく追加しません。
かなり一般的で単純に見えるオプションは、アプリケーションの http 側が、取得のために情報をキャッシュに格納するのではなく、情報をプッシュすることによって websocket 側に通知することです。環境に実装を困難または不可能にする障害物がないと仮定すると、スケーラブルで軽量です。
Websocket をロードする Web ページを生成するときに、文字列「ipv4:」とクライアントの IP (「192.168.1.1」など) を取得し、それらを連結して暗号化し、結果を URL フレンドリーにします。
/* pseudo-code */
base64_encode(aes_encrypt('ipv4:192.168.1.1','super_secret_key'))
128 ビットの aes を含むそのサンプル キーとそのサンプル IP アドレスを使用すると、次のようになります。
/* actual value returned by pseudo-code above */
1v5n2ybJBozw9Vz5HY5EDvXzEkcz2A4h1TTE2nKJMPk=
次に、websocket を含むページの html をレンダリングするときに、URL を動的に構築します。
ws = new WebSocket('ws://example.com/sock?client=1v5n2ybJBozw9Vz5HY5EDvXzEkcz2A4h1TTE2nKJMPk=');
Websocket からのクエリ文字列がコードにアクセスできると仮定すると、超秘密鍵を使用して、クエリ パラメーター "client" で見つかった文字列を base64_decode してから aes_decrypt し、"ipv4:" で始まることを確認できます。そうでない場合、それは正当な値ではありません。
もちろん、"ipv4:" (文字列の先頭) と "client" (クエリ パラメータ用) は任意の選択であり、実際の意味はありません。128 ビット AES の選択も恣意的でした。
もちろん、このセットアップの問題は、リプレイの影響を受けることです。特定のクライアント IP アドレスは常に同じ値を生成します。クライアントの IP アドレスを「情報目的」 (ロギングやデバッグなど) にのみ使用する場合は、これで十分な場合があります。より重要なことに使用している場合は、タイムスタンプを追加するなどして、この実装を拡張することをお勧めします。
'ipv4:192.168.1.1;valid:1356885663;'
受信側で、文字列をデコードし、タイムスタンプを確認します。安全と思われる秒間隔が +/- でない場合は、信頼しないでください。
これらの提案はすべて、websocket url を動的に生成する能力、それに接続するブラウザの能力、および websocket リクエストで URL のクエリ文字列部分にアクセスできるかどうかにかかっています...しかし、これらの部分がうまくいく場合は、たぶんこれが役立つでしょう。
追加の考え (コメントから):
上で提案したタイムスタンプはエポックからの秒数です。これにより、プラットフォームでステートフルネスを必要としないインクリメント カウンターが得られます。必要なのは、すべてのサーバー クロックが正しいことだけです。したがって、不要な複雑さを追加することはありません。復号化された値に含まれるタイムスタンプが (たとえば) サーバーの現在の時刻との差 (+/-) 5 秒未満の場合、認証されたクライアントを扱っていることがわかります。許可される時間間隔は、元のページをロードした後にクライアントが Websocket 接続を試行するのに妥当な最大時間に、すべてのサーバー クロックの最大スキューを加えた長さである必要があります。
もちろん、NAT を使用すると、複数の異なるユーザーが同じ送信元 IP アドレスの背後にいる可能性があります。また、可能性ははるかに低いですが、ユーザーが最初の http 接続を開始したソース IP とは異なるソース IP から実際に Websocket 接続を確立し、それでも非常に正当である可能性があることも事実です...認証ユーザーは、実際の送信元 IP よりも重要な値になる場合があります。
暗号化された文字列内に認証されたユーザーの ID も含めると、オリジン IP、ユーザー アカウント、および時刻に固有の値が 1 秒の精度で得られます。これはあなたが追加の塩で言及しているものだと思います。ユーザー アカウントを文字列に追加すると、必要な情報が得られます。
'ipv4:192.168.1.1;valid:1356885663;memberid:32767;'
TLS は、この暗号化された文字列が権限のない第三者によって発見されるのを防ぐ必要がありますが、生成された URL は、ユーザーのブラウザーの HTML ページの「ソースの表示」でクリア テキストで使用できるため、再生可能性の回避も重要です。今日は許可されているが、明日は許可されていないユーザーが、もはや有効ではないと認識される必要がある署名付き文字列でなりすましできるようになることは望ましくありません。タイムスタンプにキーを設定し、非常に小さな有効なウィンドウに収まるように要求すると、これを防ぐことができます。