Apache Proxy mod_proxy WebSocket

如何設定WebSocket轉導與分流,使用Apache 2.4.6(mod_proxy)

張書銘 2018/10/09 16:56:33
18610

如何設定WebSocket轉導與分流,使用Apache 2.4.6(mod_proxy)


簡介

一般來說WebSocket會走不同的port號,但對系統維運來說不可能把所有要使用系統的人都多開通這個port號,因此就必須要使用Apache Proxy透過不同的路徑來轉導到後端AP Server的WebSocket port。

作者

張書銘


如何設定WebSocket轉導與分流,使用Apache 2.4.6(mod_proxy)


前言

 一般來說WebSocket會走不同的port號,但對系統維運來說不可能把所有要使用系統的人都多開通這個port號,因此就必須要使用Apache Proxy透過不同的路徑來轉導到後端AP Server的WebSocket port。
 
以下圖來說,一般http頁面的架構是透過Apache Server將80 port轉導到AP(JBoss)的8080 port,但如果多了WebSocket的自訂port時該如何設定呢?後續將一步步說明。

環境準備

  1. Redhat Linux7
  2. Apache 2.4.6(mod_proxy) 
  3. JBoss EAP 6.2

mod_proxy設定

首先於Apache Proxy的設定檔httpd.conf中增加以下片段
 
主要是紅字兩段ProxyPass的設定
 
第一段用來設定根目錄下所有80 port的request都轉發到JBoss的ajp port(這邊設定為8009)
 
第二段則是本文的重點,將/websockets/games/的所有request都轉發到ws://且為4321 port(AP Server自定義的port)
 
 
註: 本文主要是針對WebSocket作法說明,因此一般http轉導作法就不多做贅述
  <VirtualHost *:80>
# Your domain name
ServerName 192.168.135.128
ProxyPreserveHost On
# The IP and port of JBoss EAP 6
# These represent the default values, if your HTTPD is on the same host
# as your JBoss EAP 6 managed domain or server
 
ProxyPass / ajp://localhost:8009/
ProxyPassReverse / ajp://localhost:8009/
 
ProxyPass "/websockets/game/" "ws://192.168.135.128:4321/websockets/game/"
ProxyPassReverse "/websockets/game/" "ws://192.168.135.128:4321/websockets/game/"
 
 
 
# The location of the HTML files, and access control information
<Location "/" >
Order allow,deny
Allow from all
</Location>
</VirtualHost>

JBoss設定參考

 standalone.xml部份設定內容如下
 
<subsystem xmlns="urn:jboss:domain:web:1.5" default-virtual-server="default-host" native="false">
<connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http" />
<connector name="ajp" protocol="AJP/1.3" scheme="http" socket-binding="ajp"/>
<virtual-server name="default-host" enable-welcome-root="true">
<alias name="localhost"/>
<alias name="example.com"/>
</virtual-server>
</subsystem>

問題排除

以上設定完成後,實際測試過程中遇到以下問題(沒權限),是Apache拋出來的(Log路徑在httpd/log/error_log)
 
 參考以下網址作法,執行下述指令後即可排除
 
/usr/sbin/setsebool httpd_can_network_connect 1
 
 

測試結果

 可透過Apache Proxy將80 port的request轉發到4321的WebSocket port,這樣的話就只需要開通Proxy -> AP Server之間的4321 port即可,一般使用者只需要能夠存取到80 port。測試畫面如下(使用兩個瀏覽器模擬兩個使用者透過WebSocket互傳訊息)。
 
紅框處使用80 port的websockets/game/路徑來存取,經過Apache Proxy後可正確轉發至4321 port完成WebSocket前端通訊的目的。
 
 
張書銘