Archived

This forum has been archived. Please start a new discussion on GitHub.

Issues proxying WebSockets using Apache

Hi,

I have a code using Ice 3.6.5 that uses Glacier to route connections through our firewall and it all works fine as long as I allow the relevant port. The server is a C++ code and the client is a web page using the Ice JS mapping.

I've been trying to change this so that the link to Glacier uses port 443 (along with the rest of the website) and gets proxied by my Apache web server. However, when the web page tries to connect it fails, and the Glacier logs show:

02/20/20 12:53:27.717 glacier2router: Network: trying to accept ws connection
local address = ::ffff:172.17.0.2:4063
remote address = ::ffff:172.17.0.2:35612
-- 02/20/20 12:53:27.718 glacier2router: Network: ws connection HTTP upgrade request failed
local address = ::ffff:172.17.0.2:4063
remote address = ::ffff:172.17.0.2:35612
WSTransceiver.cpp:381: Ice::ProtocolException:
protocol exception:
unsupported HTTP version
-- 02/20/20 12:53:27.718 glacier2router: Network: failed to accept ws connection
local address = ::ffff:172.17.0.2:4063
remote address = ::ffff:172.17.0.2:35612
WSTransceiver.cpp:381: Ice::ProtocolException:
protocol exception:
unsupported HTTP version


My default router is setup as follows:

iceInitData.properties.setProperty("Ice.Default.Router", "Glacier2/router:wss -h " + serverBaseUrl + " -p 443 -r /ice");

where "serverBaseUrl" is the FQDN of the server.


The relevant section of my Apache config is:

ProxyPass /ice ws://172.17.0.2:4063
ProxyPassReverse /ice ws://172.17.0.2:4063

where 172.17.0.2 is the local IP address of the server.

I have another two lines that proxy WS requests to a Glassfish web server that work fine.

ProxyPass /sim/logs/ ws://localhost:8580/sim/logs/
ProxyPassReverse /sim/logs/ ws://localhost:8580/sim/logs/


My glacier config is:

Glacier2.Client.Endpoints=wss -h * -p 4064:ws -h * -p 4063
Glacier2.Server.Endpoints=tcp -h 172.17.0.2
Glacier2.PermissionsVerifier=Glacier2/NullPermissionsVerifier
Glacier2.Client.ForwardContext=1
Glacier2.Server.ForwardContext=1

Ice.Plugin.IceSSL=IceSSL:createIceSSL
IceSSL.DefaultDir=/home/websim/daemons
IceSSL.CAs=chain.pem
IceSSL.CertFile=certificate.pfx
IceSSL.VerifyPeer=0

Glacier2.SessionTimeout=3600
Ice.Default.Locator=IceGrid/Locator:tcp -h 172.17.0.2 -p 4061
Glacier2.SessionManager=IceGrid/SessionManager

Glacier2.Server.Trace.Request=1
Glacier2.Trace.Session=1
Glacier2.Trace.RoutingTable=0
Glacier2.Client.Trace.Reject=0
Glacier2.Client.Trace.Request=0

Ice.LogFile=glacier.log
Ice.Trace.Network=3


Any help would be appreciated.

Jason

Comments

  • xdm
    xdm La Coruña, Spain

    Hi Jason,

    Are you redirecting wss traffic to the ws port? according to you configuration 4063 is ws, 4064 is wss, I think you need a separate rule in your proxy for forwarding WSS to the correct port.

  • Yes I am. External traffic (i.e. the broswer) uses https/wss. Apache then proxies Ice traffic to ws, and web traffic to my Payara web server as http - so basically Apache deals with SSL stuff. This has two benefits:

    1. I only need one port (443) open
    2. I can replace the certificate at will and just get Apache to re-read it. That doesn't seem possible with Glacier without restarting.

    A little update - I have just replaced Apache with nginx and everything works fine. So there is something about Apache/my Apache config file.

  • xdm
    xdm La Coruña, Spain

    I have the impression that your Apache configuration was sending the encrypted request to the WS endpoint and the Protocol exception is being throw because of that, Ice was expecting a plain ws request but got an wss request.