antoniomika / sish

HTTP(S)/WS(S)/TCP Tunnels to localhost using only SSH.
https://ssi.sh
MIT License
3.84k stars 297 forks source link

Question about sish x nginx x websockets #268

Closed XeroxDev closed 1 year ago

XeroxDev commented 1 year ago

Hey. I've a kinda "hacky" setup of sish and need a bit of help.

Setup

docker-compose.yml

version: '3.7'

services:
  sish:
    image: antoniomika/sish:latest
    container_name: sish
    volumes:
      - ./pubkeys:/pubkeys
      - ./keys:/keys
    ports:
      - "rport:rport"
      - "rport2:80"
    command: |
      --ssh-address=:rport
      --http-address=:80
      --authentication=true
      --https=false
      --authentication-keys-directory=/pubkeys
      --private-keys-directory=/keys
      --bind-random-ports=false
      --bind-random-subdomains=false
      --domain=my-domain
      --admin-console=true
      --admin-console-token=random-token
      --log-to-client=true
      --ping-client=true
      --https-ondemand-certificate=false
      --bind-any-host=true
      --authentication-password=""
    restart: always

id-sub.domain.tld.conf

map $http_upgrade $connection_upgrade {
    default Upgrade;
    '' close;
}

server {
    listen 80;
    listen [::]:80;
    server_name sub.domain.tld *.sub.domain.tld;
    return 301 https://$http_host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name sub.domain.tld *.sub.domain.tld;

    ssl_certificate /path/to/cert/fullchain.pem;
    ssl_certificate_key /path/to/cert/privkey.pem;

    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://sish:rport2;

        proxy_set_header    Host $host;
        proxy_set_header    Upgrade $http_upgrade;
        proxy_set_header    Connection $connection_upgrade;
        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header    X-Forwarded-Proto $scheme;
        proxy_set_header    X-Forwarded-Host $host;
        proxy_cache_bypass  $http_upgrade;
        proxy_buffering     off;
        proxy_http_version  1.1;
        proxy_hide_header   X-Frame-Options;
        proxy_cache_bypass  $http_upgrade;

        proxy_pass_header Set-Cookie;
        proxy_connect_timeout 7d;
        proxy_read_timeout 7d;
        proxy_send_timeout 7d;
    }
}

Explaination

I know, this is not the best setup. I just tried to accomplish an nginx reverse proxy to sish. I don't need sish to create certs, because I've already a wildcard for it (with automatic refresh).

The reason why I disabled "https" in sish and use "sish http:80" was: It kept trying generating own and even after adding

      --https-ondemand-certificate=false
      --bind-any-host=true

It didn't worked and just threw errors. So I disabled it completely and make an normal http connection on the machine itself and it worked.

Issue

Connection etc works, but I've issues with web sockets...

I've a DotNet Blazor Server setup (which uses websockets / signalr) but after 5 secs of inactivity, the reconnect screen occurs 452-95-max

Client CLI says: 810-874-max

Server Logs are saying: 1618-1035-max


Maybe you know the issue? Or can help me setting it up correctly?

And thank you for the awesome work!


Btw. I've created a small powershell script which can be added to the users profile so the usage is a bit easier.

function sish {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true,Position=0)]
        [string]$LocalAddress,
        [Parameter(Position=1)]
        [string]$SubDomain = ""
    )

    if ($LocalAddress -eq "admin") {
        Start-Process "https://sub.domain.tld/_sish/console?x-authorization=token"
        return "Opening Admin-Panel"
    }

    if ($SubDomain) {
        $SubDomain += ":"
    }

    # Execute the SSH command
    & ssh -p SSHPORT -R ${SubDomain}80:$LocalAddress sub.domain.tld
}

Usage: sish local-address subdomain (optional) Example: sish localhost:5000 dpb

antoniomika commented 1 year ago

This is because sish supports setting an idle-timeout on a connection that hasn't written/read any data.

You can either increase the ping interval in your websocket app, increase the timeout duration, or disable this functionality entirely using:

--idle-connection                                         Enable connection idle timeouts for reads and writes (default true)
--idle-connection-timeout duration                        Duration to wait for activity before closing a connection for all reads and writes (default 5s)

You likely will be fine with disabling this functionality (--idle-connection=false)

XeroxDev commented 1 year ago

That worked, thank you very much!

Keep up this awesome work and have a nice day.