ws: Websockets not working with HTTPS in an Apache Proxy (302 error?)
Hello, first of all, thanks for your awesome library. I was able to setup and get WS running in a breeze. Thanks.
I have a problem with ws, I’m unable to make websockets work on an apache proxy through HTTPS. Websockets are working properly if no (apache) http(s) proxy is used.
My setup: I have an apache server with multiple virtual hosts. I have a HTTPS webpage for myserver.com and the HTTPS API with node/express/ws in api.myserver.com subdomain through the proxy, that redirects the requests to the node.js instance (multiple instances on PM2) running on port 3333.
This is my apache virtual host for the subdomain:
<VirtualHost *:443>
ServerName api.myserver.com
ServerAdmin hello@myserver.com
DocumentRoot /var/www/html/myserver/api
Options -Indexes
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM
SSLCertificateFile /etc/apache2/certs/STAR_myserver_co.crt
SSLCertificateKeyFile /etc/apache2/certs/myserver_private_key.pem
SSLCertificateChainFile /etc/apache2/certs/STAR_myserver_co.ca-bundle
SSLProxyEngine On
ProxyPreserveHost On
ProxyRequests Off
# This is for websocket requests
ProxyPass /wss/ wss://localhost:3333/
ProxyPassReverse /wss/ wss://localhost:3333/
# This is for normal requests
ProxyPass / https://localhost:3333/
ProxyPassReverse / https://localhost:3333/
</VirtualHost>
This works OK for redirecting the connections to the node express backend. I have installed mod_proxy, mod_proxy_http and mod_proxy_wstunnel.
This is the node.js API backend: first, I initialize express, sessions, etc.
// express, session and mongodb session storage
var express = require('express')
var session = require('express-session')
var MongoStore = require('connect-mongo')(session)
var app = express()
// configure sessionStore and sessions, mongodb, etc...
// Certificates and credentials for HTTPS server
var fs = require('fs')
var privateKey = fs.readFileSync(__dirname + '/certs/myserver_private_key.pem', 'utf8')
var certificate = fs.readFileSync(__dirname + '/certs/myserver_cert.pem', 'utf8')
var ca = fs.readFileSync(__dirname + '/certs/myserver_ca.pem', 'utf8')
var credentials = {key: privateKey, cert: certificate, ca: ca}
app.enable('trust proxy')
app.set("trust proxy", 1)
And then I setup the HTTPS server securely, using the same certificates that in APACHE:
// Setup HTTPS server
var https = require('https')
var server = https.createServer(credentials, app)
server.listen(appPort, 'localhost', function () {
// Server up and running!
var host = server.address().address
var port = server.address().port
console.log('myserver listening at https://%s:%s', host, port)
})
Last, I setup the websocket connections:
// setup Websockets
wss = new WebSocketServer({ server: server })
wss.on('connection', function connection(ws) {
var cookies = cookie.parse(ws.upgradeReq.headers.cookie)
var sid = cookieParser.signedCookie(cookies["connect.sid"], myserver_secret)
// extract user credentials and data from cookie/sid,
// get the session object
sessionStore.get(sid, function (err, ss) {
...
})
})
Then my clients just try to connect to websockets securely (because, being a HTTPS app, I cannot use the ws:// insecure websockets connection):
window.WebSocket = window.WebSocket || window.MozWebSocket
webSocket = new WebSocket('wss://' + location.host + '/wss')
And then I get always the same error 302:
[Error] WebSocket connection to 'wss://api.myserver.com/wss' failed: Unexpected response code: 302
If I test on a local server directly to the node instance https://localhost:3333/ it’s working perfectly and websockets work as they should.
Any idea of how to solve this? Is there a problem with ws redirections made by Apache proxy modules?
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 7
- Comments: 19 (5 by maintainers)
Hi there! curiously enough, that fixed it 🎉. That extra “/” was really messing around with the Apache proxy configuration. I’m kind of pissed off of the lack of documentation on this existing on the internet.
Thank you very much for your support @lpinca, you really saved me from hours of banging my head against a wall. I was even thinking on dropping websockets altogether.
Thank you so very much!
@DigitalLeaves this super simple example works on my machine (no SSL)
Config:
The node server:
index.html:
Maybe it’s the trailing slash on
/wss/in your config?This works perfect
@nitin992503 yes, at the end it was a problem with the IP address, you need to pass the public IP through the path (I have no idea what you are doing), also I have to start apache on the server side
hello guys how are you?? i am having a similar error and i do not know what to do? Error during WebSocket handshake: Unexpected response code: 404, it does not connect to my app which is hosted at AWS - EC2 instance!! i would like to know if someone can help me?