Score:1

Reverse proxy SSH using NGINX. (Subdomains to Docker containers running SSH)

jp flag

TDLR: x.a.se:22 and y.a.se:22 should accept and lead to machine x and machine y respectively. NGINX just coordinates traffic by reverse proxying.

Hi there awesome community, Oscar from Sweden here.

Current setup

I have a host machine that accepts a.se, let's call the host machine A. So ssh [email protected] leads to the SSH-service at port 22 on machine A. Machine A run docker containers: machine B and some other machines, lets focus on one container at a time.

Desired usage

I want this to happen:

  1. The user Bob operating machine B does not have access to machine A since the user is not trusted.
  2. User Bob connects to b.a.se:22 with SSH and gets a shell at machine B.

The problem

I don't know how to configure this. I think I'm looking for a reverse proxy of SSH. All my other endpoints are reversed proxied using NGINX since that is what I'm best at, so I'm looking into ngx_stream_proxy_module which can basically reverse proxy any TCP connections. The thing is that i cant wrap my head around how NGINX stream proxy should be able to distinguish between a.se, b.a.se and let's say n.a.se where n is any string.

If you have any questions regarding my setup or the question itself, please add a comment and i will add an edit to this question. Thanks in advance, any help and insight is much appreciated.

Note: The host machine runs Debian 11 and I have full access. I prefer Docker as a container manager and NGINX to route network traffic.

Note: I've added links to some of the most basic resources, this is not to poke fun of potential helpers, it's too aid in helping others who read this thread in the future asking the same question as I do now.

us flag
That is not possible. SSH does not have concept of virtual hosts that are required for this to work. SSH connects only to an IP address after it has resolved the domain name to IP address.
djdomi avatar
za flag
if you are not too lazy install guacamole via docker it will be nearly the same :) Else, you may try the similar things that will be used for smtp https://docs.nginx.com/nginx/admin-guide/mail-proxy/mail-proxy/
Oscar Andersson avatar
jp flag
Hi @djdomi do you mean Apache Guacamole? That will not work for me, I'm not interested in remote desktop, I want a encrypted remote shell. The email proxy would not work since it only supports POP3, IMAP and SMTP. Thanks.
Oscar Andersson avatar
jp flag
Thanks @TeroKilkanen :) Can you think of any other way? Maybe i can route [email protected] to the docker container B via a rule in sshd?
djdomi avatar
za flag
@OscarAndersson ....... You should think about the mention, the stream part is the same for any kind of proxy you like to use.
Oscar Andersson avatar
jp flag
@djdomi can you elaborate? I don't quite yet understand. Are the stream module and the email module proxy settings interchangeable?
Score:1
us flag

One can connect to the container by using host A as the jump host. However, this requires a user-account on host A for this purpose.

One can limit the jump host account so that there is no access to the server itself.

The limitation can be done in host A sshd_config.

Match user bob
    X11Forwarding no
    AllowTcpForwarding
    ForceCommand ssh bob@<container>

After setting this up, one can:

  1. ssh [email protected]
  2. Give host system password
  3. SSH daemon will force execute the SSH command to the container
  4. Give container password

One could also create a keypair on the host in bob account that would be used for authenticating to the container. Then the second password wouldn't be needed.

Oscar Andersson avatar
jp flag
Thanks Tero! This is exactly what I'm looking for. I will make the changes in `sshd_config`. What are the security implications of this, is the `ForceCommand` ran on the client or on the SSH service? Can the user bypass this? Of course I will have implemented security measures so that even if that happens no damage will be done. How would this keypair on the host work? I don't quite get how it would authenticate on the container. Thanks. :)
us flag
The `ForceCommand` is run on the SSH server, and the SSH daemon prevents user from running any other command.
Oscar Andersson avatar
jp flag
You're a Finnish god Tero! Great thanks from the other side of the big lake. What do you think about the problem when a user exits their docker container, they will be throw back into the host, right? Can i fix it with `ForceCommand sh -c "sudo docker exec -ti user-container0 /bin/bash"; exit` so that the SSH session automatically exits when the user leaves the shell (`/bin/bash`) in the container?
us flag
If you use the `ssh` command above, it connects to Docker container's SSH daemon. When user closes the shell launched by the SSH daemon, it will close the connection and host SSH will also close the connection. I don't know how the access via `docker` command works.
Oscar Andersson avatar
jp flag
Ooooh really, awesome! I did not realize that, I though your command was just a placeholder. So naive of me, huge thanks!
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.