Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comfiguring Apache for socket.io and SSL / WSS

As the title suggests, I'm trying to get Apache and Socket.io (node.js) to play nicely, especially on SSL. Currently, the client app at https://www.example.com uses Socket.io over SSL to connect to the server at [SSL protocol]://socket.example.com/socket.io/?query_stuff*. The connection to wss:// always fails, so Socket.io degrades to https://, which works fine. But I would like to take advantage of the websocket protocol and not rely on polling over http(s).

Linux & Apache

Server version: Apache/2.4.7 (Ubuntu)

Relevant mods: mod_proxy, mod_proxy_http, mod_proxy_wstunnel, mod_rewrite, mod_ssl

Iptables: I have opened ports 80, 443, and 9000.

VirtualHost:

I created a virtualhost on *:443 called socket.example.com. It's intended purpose is to reverse proxy [wss,https]://socket.example.com/ to point to the socket.io server running at http://localhost:9000/. Here it is, with extraneous bits removed:

<VirtualHost *:443>
    ServerName socket.example.com
    DocumentRoot /var/www/example/socket.io/

    RewriteEngine On
    RewriteCond %{REQUEST_URI}  ^/socket.io             [NC]
    RewriteCond %{QUERY_STRING} transport=websocket     [NC]
    RewriteRule /(.*)           wss://localhost:9000/$1 [P,L]

    ## I have also tried the following RewriteRules: ##
    # RewriteRule /(.*)         http://localhost:9000/$1 [P,L]
    # RewriteRule /(.*)         http://localhost:9000/socket.io/$1 [P,L]

    SSLEngine on
    SSLCertificateFile    /etc/letsencrypt/live/www.example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/keys/0001_key-certbot.pem
    SSLCACertificateFile  /etc/letsencrypt/ca-bundle.pem

    SSLProxyEngine On
    ProxyRequests Off
    ProxyPreserveHost On
    ProxyVia Full

    ProxyPass / http://localhost:9000/
    ProxyPassReverse / http://localhost:9000/
</VirtualHost>

Success using PHP websockets over SSL

Before switching to node.js for my websocket server, I used the above Apache VirtualHost to successfully route wss://socket.example.com/ws_daemon.php to ws://localhost:9000/ws_daemon.php. In this scenario I 1. removed the rewrite rules and 2. changed the ProxyPass settings to:

ProxyPass / ws://localhost:9000/
ProxyPassReverse / ws://localhost:9000/

But the same logic does not seem to carry over to socket.io.

At this point I've run out of ideas. Any help would be greatly appreciated!

like image 515
Bryce Avatar asked Oct 28 '25 08:10

Bryce


1 Answers

If you are using the <Location> block, you should add the following lines to it:

RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteRule /socket.io/(.*) ws://localhost:3000/socket.io/$1 [P]
like image 67
Sam Avatar answered Oct 29 '25 22:10

Sam