7

As you already read in the title I am currently running multiple docker containers which are used as git servers and normally should run under port 22. This is obviously not working, but my requests would be the following.

Have the following available on port 22:

  • git@HOST - redirected to gitlab docker container
  • bitbucket@HOST - redirected to bitbucket container
  • root@HOST - ( I am not working as root at all, but for understanding reasons ) normal SSH Access to the Docker Mainhost.

I know that I would have to sync ssh keys across containers and accounts, but this would not be a big issue, but I have no Idea if it would be possible to build an redirect system.

One approach of mine would be to use ForceCommand but I would not be able to Redirect the SSH Key used...

Another idea would be to have a small tool on port 22 running which just routes the complete requests between all SSH daemons, but I have not (yet?) found such a tool and do not know if it would be possible to build such a tool for security reasons.

3

3 Answers 3

2

I don't think you really need to "redirect the ssh key used", you can create a key/cert per user who has her key as authorized_keys, and then you can use ssh -i $key $final_destination via ForceCommand.

If you would use AuthorizedKeysCommand you can query a central repository of public keys, this could return 2 lines - one for real users public ssh key and the second for an "internal public ssh key", you can distinguish those two lines with a comment and query this repository for a key based on info from which host you do the query. Eg. on jump host you could filter the public key which has for example this comment 'foouser@', on final destination you could on the contrary query foouser's public key with comment '@internal'. With recent OpenSSH, you could on jump host use ExposeAuthInfo sshd option to know which public ssh key was used to login into jump host, then you could re-query central repository for the keys and grep one which matches one in $SSH_USER_AUTH. This way would would know based on returned line with public ssh key and comment which private key to use to do ssh to final destination.

The user does not really care how she logged into final host, especially if it is not an interactive shell.

AuthorizedKeysCommand on jumphost and final destination:

#!/bin/sh                                                                                                             
user=$1 # git !
filter=$2 # @$

cat /home/git/.ssh/authorized_keys 2>/dev/null | grep "${filter:-@$}"
exit 0

sshd_config on jump host:

ExposeAuthInfo yes
Match User git
    AuthorizedKeysCommand /path/to/authorizedkeyscommand git # @$ as default
    ForceCommand /path/to/forcecommand git

AuthorizedKeysCommand can return:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILleQxrxxxxxxxxxxxxxxxxxxx foouser@

ForceCommand on jump host:

#!/bin/ksh
set -x

user=$1 # git

if [[ -r ${SSH_USER_AUTH} ]]; then
    pubkey="$(cat ${SSH_USER_AUTH} | cut -d' ' -f2-)"
    realuser=$(/path/to/authorizedkeyscommand git | grep "${pubkey}" | sed 's/^.* \([^@]*\)@$/\1/' )
    [[ -n ${realuser} ]] && exec ssh -i $HOME/${realuser}_key <final_destination> "${SSH_ORIGINAL_COMMAND:-}"
else
    exit 1
fi

Something like this...

1

There was a current (2021) working solution published as a medium article to share the host ssh port with the gitlab container. It should also be applicable to a bitbucket container.

It uses a proxy script to forward the ssh connections of the git user into the gitlab container.

The interesting part starts with the headline "Forwarding SSH for git user (Reusing port 22)"

https://pezhvak.medium.com/how-to-spin-up-gitlab-on-docker-reusable-host-ports-2cfd220c74b0

5
  • 1
    The git user on the host system that the article describes must match the uid of the git user in the gitlab container. If there is a uid conflict or you don't want to match the uid, you can use bindfs to ensure that the host git user will be able to access authorized_keys file from the container via your fstab: /opt/gitlab/data/.ssh/ /home/git/.ssh/ fuse.bindfs auto,ro 0 0 Apr 5, 2022 at 20:48
  • Nice, I didn't know that possibility. But it is also possible to set the UID and GID of the git user in the container to the ones on the host in GITLAB_OMNIBUS_CONFIG. Its also described in the article.
    – Fl0v0
    Apr 6, 2022 at 7:24
  • 1
    It is possible but in our case it was causing the container to fail - according to gitlab it is not supported anymore: gitlab.com/gitlab-org/omnibus-gitlab/-/issues/4924 Apr 7, 2022 at 8:09
  • @DominikHeidler Thank you for the hint. It worked in my case with version 14.9.2-ce.0
    – Fl0v0
    Apr 7, 2022 at 11:56
  • I forgot to mention that the mount options force-user=git,force-group=git would need to be used here to match the container uid/gid to the uid/gid of the git user on the host. Apr 20, 2022 at 10:42
1

I was not happy with any of the solutions I found on the internet. What I ended up with is the folowing.

I have a docker container running like the following docker -v /srv/gitlab/data:/var/opt/gitlab gitlab. After inspecting gitlab directory I found that there is /srv/gitlab/data/.ssh/authorized_keys file maintained with all the keys needed for ssh authentication. The file contains the following:

command="/opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell key-1",no-port-forwarding,no-.....

The best would be to use the file for authentication to re-use the same set of public keys on the host and then forward the commands to inside the docker container.

Match User git                                                                                                                                   
     X11Forwarding no                                                                                                                             
     AllowTcpForwarding no                                                                                                                        
     PermitTTY no                                                                                                                                 
     AuthorizedKeysCommandUser root                                                                                                               
     AuthorizedKeysCommand /usr/bin/cat /srv/gitlab/data/.ssh/authorized_keys

The AuthorizedKeysCommandUser and AuthorizedKeysCommand can be replaced by AuthorizedFile if you create the git user with the same UID as inside the docker containe. In case of GitLab, the git user has UID 998.

Then I created a shell script /opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell on host (sadly) with the content:

#!/bin/sh
exec docker exec gitlab env SSH_CONNECTION="$SSH_CONNECTION" "$0" "$@"

Funny enough, because the path to the script is the same on host and inside the docker container, I can reuse the "$0". The method works, although I consider it rather to be a work-around.

1
  • Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    May 17 at 10:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .