Argo tunnel problem with websockets

websocket

#1

I have a problem with using websockets with Argo.

Our application has three components

  1. IIS7 hosting the static content (*.html, *.js, *.png, …) over HTTP on port 8003.
  2. Standalone application serving dynamic RESTful content over HTTP on port 1341.
  3. Another standalone application serving streaming content over a websocket (ws://) on port 7171.

I can create an argo tunnel with the command ./cloudflared --hostname host1.example.com --url http://server.internal and connect with my browser to `https://host1.example.com and see the static content loading. However I can also see it trying to connect to the other components using their internal hostnames and ports which obviously fails from outside the internal network.

What do I need to do to successfully tunnel all three internal sources?


#2

Argo tunnel probably only works on the ports a regular connection would work on, so attempts to connect to 1341 and 7171 will probably fail.

You’ll need to run a load balancer or proxy server that routes requests to the proper backend service, and point argo tunnel to that service.

What most websocket setups use is nginx as a proxy/load balancer between all of their application servers, and setting up a URL prefix for each of their services.

eg, an example nginx config for this:

server {
    ...
    location /ws/ {
        proxy_pass http://wsbackend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }
    location /static/ {
        proxy_pass http://staticbackend;
        proxy_http_version 1.1;
    }
    location / {
        proxy_pass http://mainbackend;
        proxy_http_version 1.1;
    }
}

There are other load balancing servers that can do something like the above, but I only have experience with nginx on this topic.

One more thing you could try is multiple hostnames for each of your backend services and just pointing static/dynamic/Websocket links to the proper subdomain, however that may make development more of a pain.


#3

Thanks for this.

I followed your suggestion, proxying everything through Nginx with the below config. I’m running IIS on my local machine as I had to make some changes to the static source to point to the proxy for the other resources.

server {
    listen       80;
    server_name  localhost;

    location /ws/ {
        proxy_pass http://host1:7171;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_read_timeout 86400s;
        proxy_send_timeout 86400s;
    }
    location /accountant/ {
        rewrite ^/accountant/(.*) /$1 break;
        proxy_pass http://host1:1341;
        proxy_http_version 1.1;
    }
    location / {
        proxy_pass http://localhost:8003;
        proxy_http_version 1.1;
    }
}

What I’m seeing now though is the tunnelled content is still trying to access the other resources at localhost (ws://localhost/ws/ and http://localhost/accountant/some/url)


#4

So I fixed the issue with the tunnelled content requesting http://localhost/accountant/some/url, it was because the static content origin server was using the full URL.

The issue with websockets persists though and I feel it may be related. I have no way of specifying the websocket URL as a relative one as it needs to begin with ws:// or wss://

Does the Argo tunnel not rewrite the content to reflect the new URLs?