campos
campos

Reputation: 305

How to redirect ssh requests in Nginx?

I'm using the gitea versioning system in a docker environment. The gitea used is a rootless type image.

The http port mapping is “8084:3000” and the ssh port mapping is “2224:2222”.

I generated the keys on my Linux host and added the generated public key to my Gitea account.

1.Test environment

Later I created the ssh config file nano /home/campos/.ssh/config :

Host localhost
  HostName localhost
  User git
  Port 2224
  IdentityFile ~/.ssh/id_rsa

After finishing the settings i created the myRepo repository and cloned it.

To perform the clone, I changed the url from ssh://git@localhost:2224/campos/myRepo.git to git@localhost:/campos/myRepo.git

To clone the repository I typed: git clone git@localhost:/campos/myRepo.git

This worked perfectly!

2.Production environment

However, when defining a reverse proxy and a domain name, it was not possible to clone the repository.

Before performing the clone, I changed the ssh configuration file:

Host gitea.domain.com
  HostName gitea.domain.com
  User git
  Port 2224
  IdentityFile ~/.ssh/id_rsa

Then I tried to clone the repository again:

git clone [email protected]:/campos/myRepo.git

A connection refused message was shown:

Cloning into 'myRepo'...
ssh: connect to host gitea.domain.com port 2224: Connection refused
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

I understand the message is because by default the proxy doesn't handle ssh requests.

Searching a bit, some links say to use "stream" in Nginx.

But I still don't understand how to do this configuration. I need to continue accessing my proxy server on port 22 and redirect port 2224 of the proxy to port 2224 of the docker host.

The gitea.conf configuration file i use is as follows:


server {
    listen              443 ssl http2;
    server_name         gitea.domain.com;

    # SSL
    ssl_certificate     /etc/nginx/ssl/mycert_bundle.crt;
    ssl_certificate_key /etc/nginx/ssl/mycert.key;


    # logging
    access_log          /var/log/nginx/gitea.access.log;
    error_log           /var/log/nginx/gitea.error.log warn;

    # reverse proxy
    location / {
        proxy_pass http://192.168.10.2:8084;
        include    myconfig/proxy.conf;
    }

}

# HTTP redirect
server {
    listen      80;
    server_name gitea.domain.com;
    return      301 https://gitea.domain.com$request_uri;
}

3. Redirection in Nginx

I spent several hours trying to understand how to configure Nginx's "stream" feature. Below is what I did.

At the end of the nginx.conf file I added:

stream {
include /etc/nginx/conf.d/stream;
}

In the stream file in conf.d, I added the content below:

upstream ssh-gitea {
    server 10.0.200.39:2224;
}

server {
    listen 2224;
    proxy_pass ssh-gitea;
}

I tested the Nginx configuration and restart your service:

nginx -t && systemctl restart nginx.service

I viewed whether ports 80,443, 22 and 2224 were open on the proxy server.

ss -tulpn

This configuration made it possible to perform the ssh clone of a repository with a domain name.

4. Clone with ssh correctly

After all the settings I made, I understood that it is possible to use the original url ssh://[email protected]:2224/campos/myRepo.git in the clone.

When typing the command git clone ssh://[email protected]:2224/campos/myRepo.git, it is not necessary to define the config file in ssh.

This link helped me:

https://discourse.gitea.io/t/password-is-required-to-clone-repository-using-ssh/5006/2

Upvotes: 6

Views: 20837

Answers (1)

Jon Hulka
Jon Hulka

Reputation: 1319

Another option is to use sslh. Its only purpose is to forward connections to the appropriate service (ssh or ssl) based on tests performed on the first data packet.

Here's how I set it up on Ubuntu Server based on https://ostechnix.com/sslh-share-port-https-ssh/:

Install sslh

sudo apt-get install sslh

The installer will ask whether to run as standalone or from inetd. I chose standalone.

Modify nginx configuration files - change

listen 443 ssl;

to

listen localhost:443 ssl;

Configure sslh – modify the DAEMON_OPTS line:

DAEMON_OPTS="--user sslh --listen 0.0.0.0:443 --ssh 127.0.0.1:22 --ssl 127.0.0.1:443 --pidfile /var/run/sslh/sslh.pid"

Restart the services:

sudo service nginx restart
sudo systemctl enable sslh
sudo systemctl start sslh

This requires the installation of another service, but it is the simplest way I could find to achieve ssh / ssl multiplexing.

Upvotes: 1

Related Questions