Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
mikeggh opened this issue Jan 8, 2024 · 10 comments
Closed

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

mikeggh opened this issue Jan 8, 2024 · 10 comments

Comments

@mikeggh
Copy link

mikeggh commented Jan 8, 2024

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

@mpiraux
Copy link
Collaborator

mpiraux commented Jan 8, 2024

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.

@francoismichel
Copy link
Owner

francoismichel commented Jan 8, 2024

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.

@francoismichel
Copy link
Owner

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.

@mikeggh
Copy link
Author

mikeggh commented Jan 11, 2024

Thanks abunch! I'll give it a shot!

@mikeggh mikeggh closed this as completed Jan 11, 2024
@greygoody
Copy link

any update on this guys ? did this worked properly ?

@francoismichel
Copy link
Owner

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).

@jkhsjdhjs
Copy link

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

@greygoody
Copy link

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 ?

@jkhsjdhjs
Copy link

jkhsjdhjs commented Jul 12, 2024

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.

@GRbit
Copy link

GRbit commented Aug 14, 2024

This means you can co-locate ssh3 and your other web servers. I'm already doing it right now. :-)

Hi @francoismichel !
Can you please share your configs for caddy? I tried to configure it, but it looks like I'm doing something wrong. Also, I don't quite understand, if Caddy makes it's own let's encrypt certs, than how does ssh3 will make it's cert? Or one have to make caddy reverse proxy everything without let's encrypt certs?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants