2

Before all, yes I have checked other posts like this, this or even this among others.

This being said, let me expose my case:

It works on the dev-env (localhost) completely fine (of course, it doesn't require any proxy)

I also use this curl command to confirm:

curl 'http://localhost:9021/ws' \
  --http1.1 \
  -H 'Pragma: no-cache' \
  -H 'Sec-WebSocket-Key: W/ZEACBv+gi6xA1JeMaO/A==' \
  -H 'Upgrade: websocket' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: Upgrade' \
  -H 'Sec-WebSocket-Version: 13'

and it connects ok.

When I run it on the remote dev server, I have this Apache config:

<IfModule mod_ssl.c>
<VirtualHost *:443>
  ServerName dev.remote.com

  LogLevel warn
  ErrorLog "| /usr/bin/rotatelogs -l /home/user/log/dev.remote.com/error.%Y-%m-%d 86400"
  CustomLog "| /usr/bin/rotatelogs -l /home/user/log/dev.remote.com/access.%Y-%m-%d 86400" combined
  ServerSignature Off

  DocumentRoot /home/user/www/dev.remote.com

  <Directory /home/user/www/dev.remote.com>
    Options -Indexes +FollowSymLinks +MultiViews
    AllowOverride All
    Require all granted
  </Directory>

  <Location />
    Options FollowSymLinks
  </Location>

  #
  # Serve static files directly with Apache
  #

  ProxyPass /public !
  Alias /public /home/user/www/dev.remote.com/public

  <Directory /home/user/www/dev.remote.com/public>
    Options -Indexes +FollowSymLinks +MultiViews
    AllowOverride All
    Require all granted
  </Directory>

  ProxyPass /assets !
  Alias /assets /home/user/www/dev.remote.com/.next/static/assets

  <Directory /home/user/www/dev.remote.com/.next/static/assets>
    Options -Indexes +FollowSymLinks +MultiViews
    AllowOverride All
    Require all granted
  </Directory>

  #
  # Serve the rest with NodeJS/express
  #

  RewriteEngine On
  LogLevel alert rewrite:trace6

  RewriteCond %{HTTP:Connection} upgrade [NC]
  RewriteRule /ws  ws://localhost:9021/ws [P]

  ProxyPreserveHost On
  ProxyRequests off

  # WebSocket server (express) is on port 9021
  ProxyPass /ws  ws://localhost:9021/ws
  ProxyPassReverse /ws  ws://localhost:9021/ws

  # HTTP server (express) is on port 9020
  ProxyPass / http://localhost:9020/
  ProxyPassReverse / http://localhost:9020/

  <Proxy *>
    Require all granted
  </Proxy>


SSLCertificateFile /etc/letsencrypt/live/dev.remote.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/dev.remote.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

So 2 points here:

1. I'm sure the WebSocket server is working on the remote server by testing via ssh with the previous curl command. And it connects.

2. When I try opening the connection from the browser

ws = new WebSocket('wss://dev.remote.com/ws');

the mod_rewrite rule seems ok because the trace is like this:

[Fri May 28 17:37:16.272448 2021] [rewrite:trace2] [pid 15772] mod_rewrite.c(477): [client a.b.c.d:63015] a.b.c.d - - [dev.remote.com/sid#6916462d1a20][rid#69164d3530a0/initial] init rewrite engine with requested uri /ws
[Fri May 28 17:37:16.272475 2021] [rewrite:trace3] [pid 15772] mod_rewrite.c(477): [client a.b.c.d:63015] a.b.c.d - - [dev.remote.com/sid#6916462d1a20][rid#69164d3530a0/initial] applying pattern '/ws' to uri '/ws'
[Fri May 28 17:37:16.272505 2021] [rewrite:trace4] [pid 15772] mod_rewrite.c(477): [client a.b.c.d:63015] a.b.c.d - - [dev.remote.com/sid#6916462d1a20][rid#69164d3530a0/initial] RewriteCond: input='Upgrade' pattern='upgrade' [NC] => matched
[Fri May 28 17:37:16.272513 2021] [rewrite:trace2] [pid 15772] mod_rewrite.c(477): [client a.b.c.d:63015] a.b.c.d - - [dev.remote.com/sid#6916462d1a20][rid#69164d3530a0/initial] rewrite '/ws' -> 'ws://localhost:9021/ws'
[Fri May 28 17:37:16.272521 2021] [rewrite:trace2] [pid 15772] mod_rewrite.c(477): [client a.b.c.d:63015] a.b.c.d - - [dev.remote.com/sid#6916462d1a20][rid#69164d3530a0/initial] forcing proxy-throughput with ws://localhost:9021/ws
[Fri May 28 17:37:16.272529 2021] [rewrite:trace1] [pid 15772] mod_rewrite.c(477): [client a.b.c.d:63015] a.b.c.d - - [dev.remote.com/sid#6916462d1a20][rid#69164d3530a0/initial] go-ahead with proxy request proxy:ws://localhost:9021/ws [OK]

So I deduct the rules are working and it's actually making the request via proxy to :ws://localhost:9021/ws

But... there's no connection received in the WebSocket server. Therefore, I get this on Chrome:

WebSocket connection to 'wss://dev.remote.com/ws' failed

1 Answer 1

3

The key was to have proxy_wstunnel mod active >_<

In case it helps anyone...

cd /etc/apache2/mods-enabled
sudo ln -s ../mods-available/proxy_wstunnel.load

stupid error, but I was too focused on the configuration, and it was about enabled mods

Sign up to request clarification or add additional context in comments.

1 Comment

thank you, same situation for me!! sudo a2enmod proxy_wstunnel for the apache cli folks ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.