Search code examples
phpdockerwebsocketratchet

Ratchet socket ws to wss


I have two Docker containers. One is app running on https, other is a web socket one running on Ratchet library.

When I'm on a Mac I have no issues connecting from https to ws, and I presume it is because Docker is running on 127.0.0.1 so I suppose there are some special rules which allow it.

Switching to Win machine the problem arises because Docker is on 192.168.99.100 and now connecting https to ws no longer works because browser is expecting https to wss connection. Just switching endpoint to wss:// instead of ws:// obviously doesn't work out of the box as the connection handshake naturally times out.

My socket container is not running nginx nor apache, it is a simple Ratchet server which ultimately just exposes the port I told it on outside.

Are there some good resources on how to switch to wss because I could find none.

This is what I've tried:

$server = IoServer::factory(new HttpServer($wsServer), $config['port'], '0.0.0.0', [
    'local_cert'        => __DIR__ . '/../config/cert.pem',
    'allow_self_signed' => true,
    'verify_peer'       => false,
    'ciphers'           => 'TLSv1.2'
]);

This code doesn't error out, but nor does it enable wss endpoint because the same thing is happening. How can I proceed and make this work? Also I've read somewhere that wss self signed certificates are not allowed. Can I use a signed cert on socket container and have app container on self signed certificate or they both need to use the same one?

EDIT:

since Ratchet removed SSL a while ago, I added the code to the IoServer::factory():

    public static function factory(MessageComponentInterface $component, $port = 80, $address = '0.0.0.0', array $sslContext = null) {
        $loop   = LoopFactory::create();
        $socket = new Reactor($address . ':' . $port, $loop);

        if (is_array($sslContext)) {
            $socket = new SecureReactor($socket, $loop, $sslContext);
        }

        return new static($component, $socket, $loop);
    }

But even without it, I tried it the other way also:

$server = new IoServer(new HttpServer($wsServer), new SecureServer($webSock, $loop, array(
        'local_cert'        => __DIR__ . '/../config/cert.pem',
        'allow_self_signed' => true,
        'verify_peer'       => false,
    )
));

Solution

  • I ended up starting Ratchet as-is (normal ws) and doing a nginx proxy pass on app side:

       location /ws {
            resolver 127.0.0.11 valid=30s;
            set $backend "http://container_name:port";
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
            proxy_set_header Host $host;
            proxy_pass $backend;
         }
    

    The resolver part ensures that nginx doesn't error out when you kill the container.