私はそれが働いている。
シナリオ
------------- ---------------- ----------
| Browser |<----->| Apache httpd |<----->| Tomcat |
| | SSL | 2.4.9 | SSL | 7.0.52 |
------------- ---------------- ----------
Apache httpd を介したブラウザー WebSocket、Tomcat の Web アプリへのリバース プロキシ。すべて SSL フロントツーバック。
各パーツの構成は次のとおりです。
ブラウザ クライアント
url: の末尾の「/」に注意してくださいwss://host/app/ws/
。正しい wss ProxyPass ディレクティブ (Apache 構成セクションのさらに下に表示) を一致させ、 への 301 リダイレクトを防止する必要がありましたhttps://host/app/ws
。つまり、バックエンドの wss スキームではなく、https スキームを使用してリダイレクトしていました。
テストページ
<!doctype html>
<body>
<script type="text/javascript">
var connection = new WebSocket("wss://host/app/ws/");
connection.onopen = function () {
console.log("connected");
};
connection.onclose = function () {
console.log("onclose");
};
connection.onerror = function (error) {
console.log(error);
};
</script>
</body>
</html>
アパッチ httpd
私は Apache httpd 2.4.9 を使用しています。これはすぐにmod_proxy_wstunnelを提供します。ただし、提供されているmod_proxy_wstunnel.soは、 wss:// スキームを使用する場合、SSL をサポートしていません。バックエンド (Tomcat) に平文で接続しようとすることになり、SSL ハンドシェイクに失敗します。ここでバグを参照してください。そのため、バグ レポートで提案されている修正に従って、mod_proxy_wstunnel.cに自分でパッチを適用する必要があります。3行の簡単な変更です。
Suggested correction,
314a315
> int is_ssl = 0;
320a322
> is_ssl = 1;
344c346
< backend->is_ssl = 0;
---
> backend->is_ssl = is_ssl;
次に、モジュールを再構築し、新しいmod_proxy_wstunnel.soを古いものに置き換えます。
Apache httpd のビルド
必要なモジュールをビルドするために使用した (2.4.9) コマンドを次に示します。それらすべてが必要なわけではないかもしれません。
./configure --prefix=/usr/local/apache --with-included-apr --enable-alias=shared
--enable-authz_host=shared --enable-authz_user=shared
--enable-deflate=shared --enable-negotiation=shared
--enable-proxy=shared --enable-ssl=shared --enable-reqtimeout=shared
--enable-status=shared --enable-auth_basic=shared
--enable-dir=shared --enable-authn_file=shared
--enable-autoindex=shared --enable-env=shared --enable-php5=shared
--enable-authz_default=shared --enable-cgi=shared
--enable-setenvif=shared --enable-authz_groupfile=shared
--enable-mime=shared --enable-proxy_http=shared
--enable-proxy_wstunnel=shared
最後のスイッチに注意してください--enable-proxy_wstunnel=shared
。最初は、--enable-proxy-wstunnel=shared
うまくビルドできたように見えたが、結果の .so ファイルを使用すると最終的には機能しませんでした。違いを見ます?"proxy_wstunnel"
ダッシュではなくアンダースコアを使用するようにしてください。
Apache httpd 構成
httpd.conf
...
LoadModule proxy_module modules/mod_proxy.so
...
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
...
LoadModule ssl_module modules/mod_ssl.so
...
Include conf/extra/httpd-ssl.conf
...
LogLevel debug
ProxyRequests off
# Note, this is the preferred ProxyPass configuration, and *should* be equivalent
# to the same inline version below, but it does NOT WORK!
#<Location /app/ws/>
# ProxyPass wss://localhost:8443/app/ws
# ProxyPassReverse wss://localhost:8443/app/ws
#</Location>
#<Location /app/>
# ProxyPass https://localhost:8443/app/
# ProxyPassReverse https://localhost:8443/app/
#</Location>
# NOTE: Pay strict attention to the slashes "/" or lack thereof!
# WebSocket url endpoint
ProxyPass /app/ws/ wss://localhost:8443/app/ws
ProxyPassReverse /app/ws/ wss://localhost:8443/app/ws
# Everything else
ProxyPass /app/ https://localhost:8443/app/
ProxyPassReverse /app/ https://localhost:8443/app/
上記の構成で私のメモが表示されなかった場合は、もう一度ここに示します。スラッシュ「/」またはその欠如に細心の注意を払ってください!
また、Apache ログに wss 接続が作成されてから閉じられたというデバッグ ログ ステートメントが表示されている場合は、私が行ったように mod_reqtimeout が有効になっている可能性があるため、ロードされていないことを確認してください。
#LoadModule reqtimeout_module modules/mod_reqtimeout.so
トムキャット
HTTP コネクタが正しく設定されていると仮定すると、Tomcat で設定することはあまりありません。デバッグを支援するために、次のような を作成すると便利であることがわかりました$CATALINA_HOME/bin/setenv.sh
。
setenv.sh
CATALINA_OPTS=$CATALINA_OPTS" -Djavax.net.debug=all -Djavax.net.debug=ssl:handshake:verbose"
これにより、変更した mod_proxy_wstunnel.so が wss:// に対して機能しているかどうかを確認できました。機能していない場合、catalina.out ログ ファイルには次のように表示されます。
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
http-nio-8443-exec-1, SEND TLSv1 ALERT: fatal, description = internal_error
http-nio-8443-exec-1, WRITE: TLSv1 Alert, length = 2
http-nio-8443-exec-1, called closeOutbound()
http-nio-8443-exec-1, closeOutboundInternal()
最終的な考え
私は Apache httpd 2.4.9 を使用していますが、 mod_proxy_wstunnel のバックポートをバージョン 2.2.x に適用できる場所を見てきました。上記の私のメモがそれらの古いバージョンに適用できることを願っています。