shinysdr icon indicating copy to clipboard operation
shinysdr copied to clipboard

Build in reverse proxy or other solution for not requiring two ports

Open kpreid opened this issue 4 years ago • 3 comments

The requirement to configure two server ports is occasionally problematic. It would be nice if we could eliminate it. Options:

  1. Migrate WebSocket server code from txWS to Autobahn, another Twisted library which integrates WebSockets and HTTP instead of requiring separate transports. I made some attempt at doing this in https://github.com/kpreid/shinysdr-morgue/tree/autobahn but was stymied by various cases of unhandled errors being silently discarded as I attempted to migrate the code.

  2. Launch a reverse proxy as a subprocess, configuring it to talk to autoassigned local ports, so that the user only needs to specify the single port they want. (Supporting reverse proxies at all was issue #92.)

This issue will probably be about the second option.

kpreid avatar Apr 19 '20 17:04 kpreid

I had success running ShinySDR behind a nginx reverse proxy using just one port for exposing both the HTTP and the websocket endpoint. The trick is to use a path-rewrite to dispatch the requests:

Assuming HTTP runs on 8100, websocket on 8101:

shinysdr:

    http_endpoint='tcp:8100',
    ws_endpoint='tcp:8101',

    http_base_url='https://fqdn.org/',
    ws_base_url='wss://fqdn.org/ws/',

nginx site:

location ~ ^/ws/(.*) {
                proxy_pass_request_headers on;
                proxy_pass http://127.0.0.1:8101/$1$is_args$args;
                proxy_http_version 1.1;

                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "Upgrade";

                proxy_cache_bypass $http_upgrade;
                proxy_buffering off;
                proxy_ignore_client_abort off;
                break;
        }

        location / {
                proxy_pass http://127.0.0.1:8100;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                break;
        }

This setup can further be used to add SSL, but there careful tuning is necessary to achive low latency:

listen 443 ssl http2; # important: use http2
ssl_session_cache shared:SSL:1m; # holds approx 4000 sessions
ssl_session_timeout 1h; # 1 hour during which sessions can be re-used
ssl_session_tickets on;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
gzip off; # when using http, we should disable gzip (already compressed)

The only issue is that when using SSL I regularly run into issue #125 during startup of the web-gui in Chrome. However, when the startup is successful, everything runs smooth. In Firefox, this issue does not appear.

fmoessbauer avatar Jun 07 '20 12:06 fmoessbauer

Thanks for the info!

May I have your permission to incorporate that nginx configuration as a template into ShinySDR under ShinySDR's GPL license? (I'm asking explicitly because it's not in the form of a pull request and I'm not sure whether that counts for the automatic licensing in GitHub's TOS.)

kpreid avatar Jun 07 '20 16:06 kpreid

Hi @kpreid, yes you can freely use this configuration. If it helps, I can also create a pull request but I'm fine if you just include that.

fmoessbauer avatar Jun 07 '20 17:06 fmoessbauer