francoismichel / ssh3

SSH3: faster and rich secure shell using HTTP/3, checkout our article here: https://arxiv.org/abs/2312.08396 and our Internet-Draft: https://datatracker.ietf.org/doc/draft-michel-ssh3/

Home Page:https://arxiv.org/abs/2312.08396

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Any concept/idea to share with NGINX/SSL port 443?

mikeggh opened this issue · comments

Is there any way, or prior engineering put into sharing a port such as SSL/nginx to allow the 'secret path' to connect?

For authentication to pass thru a proxy such as NGINX, some modifications to the protocol has to be made. Currently the authentication is tied to the QUIC connection authentication, which breaks the proxy model. François has started working on this here, #89, and more details are available there.

Also, this might be a duplicate of #67.

You currently can already use nginx to do multiplexing based on the server name (not the URI path parameter yet), all you need is nginx version 1.25.3 (with http3 support) and you just need to configure it to proxy QUIC connections towards your ssh3 server based on the server name you chose.

For instance, let's say you have the hostname example.org. You have nginx listening on the UDP open port 443 on your machine and you have your SSH3 server listening on port 4444. You can attribute the ssh3.example.org server name to your ssh3 server (you need the certificate for it).

If you have all that configured, you can do something like below in your nginx config and it should work:

stream {
        map $ssl_preread_server_name $name {
            ssh3.example.org   ssh3;
        }

        upstream ssh3 {
            server 127.0.0.1:443;
        }

        server {
            listen      443 udp;
            proxy_pass  ssh3;
            ssl_preread on;
        }
}

And you can add other HTTP/3 services by adding other upstreams and adding them in the map.

This is not explicitly discussed in the nginx doc, but the following ref may still help you: https://nginx.org/en/docs/stream/ngx_stream_ssl_preread_module.html

The advantage of that solution is that the proxy does not decrypt your traffic and therefore does not have to be trusted. The disadvantage is that is is less flexible.

For reverse proxies support (i.e. ones that decrypt the HTTP requests and handle stuff basd on the actual requests), we need more time for quic implementations and HTTP/3 standardisation to move forward:

  • quic-go currently does not support HTTP/3 datagrams, so we rely on pure quic datagrams that cannot be proxied properly
  • SSH3 relies on HTTP/3 Extended CONNECT and the specification does not specify ways to proxy the streams and datagrams opened by the peers. The most advanced protocol using Extended CONNECT is WebTransport and it is not standardized yet, no proxy provides support for WebTransport yet. Once it gets standardized and supported by proxies, we would like to have SSH3 adopt its semantics so that it can be proxied properly, but we will probably have to wait a few months for that. :-)

So it is coming and it will be really nice as we'll be able to run several SSH3 connections with isolated authentication contects over the same HTTP/3 connection, but we need to wait a bit for reverse proxies.

Thanks abunch! I'll give it a shot!

any update on this guys ? did this worked properly ?

Hi !
The easiest way to do that would be to rely on SNI multiplexing as it does not require implementing a terminating proxy.
Currently, nginx does not support SNI forwarding (I thought it did, but it actually doesn't).
That being said, I recently implemented SNI multiplexing on top of Caddy as a layer4 plugin.
It works, I will clean up the code and release it in the coming days (it is still experimental but already works well for domestic use case).

So if I'm not missing anything, Caddy will probably be the first Open Source server implementation that has QUIC SNI multiplexing. This means you can co-locate ssh3 and your other web servers. I'm already doing it right now. :-)

Right now, the Caddy plugin requires a fork of caddy-l4 as long as an important PR for UDP is not merged (mholt/caddy-l4#141).

Currently, nginx does not support SNI forwarding (I thought it did, but it actually doesn't).

It actually does via the ngx_stream_ssl_preread module, which provides the $ssl_preread_server_name variable.

https://nginx.org/en/docs/stream/ngx_stream_ssl_preread_module.html

commented

Currently, nginx does not support SNI forwarding (I thought it did, but it actually doesn't).

It actually does via the ngx_stream_ssl_preread module, which provides the $ssl_preread_server_name variable.

nginx.org/en/docs/stream/ngx_stream_ssl_preread_module.html

did you test it yourself ? is it actually working or is it based on documents ?

I use it to proxy HTTPS connections based on SNI. Didn't test it with ssh3, but as it's also using SNI it should work exactly the same.

EDIT: Ah, my bad. It may not work as ssh3 uses QUIC instead, which I didn't test with nginx.