Skip to content

Instantly share code, notes, and snippets.

@MichaelEischer
Last active February 2, 2024 15:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MichaelEischer/fec2ddf1267e3caca796813340044552 to your computer and use it in GitHub Desktop.
Save MichaelEischer/fec2ddf1267e3caca796813340044552 to your computer and use it in GitHub Desktop.
Chain host sshd to GitLab container

Chain host sshd to GitLab container

The GitLab container comes with an embedded ssh daemon to provide secure access to the git repositories. This ssh daemon inside the container must be accessible via the ssh port (Port 22) of the host machine. However, this usually conflicts with the ssh daemon run by the host machine.

This document describes how the host and the container ssh can be chained to work nevertheless.

Setup

Setting up the chained ssh conntecting requires changes to both the host and the container.

Host setup

Run everything as root, unless stated otherwise! The git user must not own its home base folder!

Create a git user on the host if not present. The git user needs a working shell to allow users to connect.

addgroup --system --gid 998 git
adduser --system --uid 998 --group git --home /home/git --shell /bin/bash
chown -R root:root /home/git

Setup ssh

# generate ssh key
mkdir -m=700 /home/git/.ssh
ssh-keygen -f /home/git/.ssh/id_rsa -N ''
touch /home/git/.ssh/known_hosts
chown -R git:git /home/git/.ssh

# the command and key are passed 
cat >/home/git/.ssh/config <<EOF
Host *
        SendEnv WRAPPER_ORIGINAL_COMMAND
        SendEnv WRAPPER_KEY_ID
EOF

Install the gitlab-shell forwarder

mkdir -p /home/git/gitlab-shell/bin
cat >/home/git/gitlab-shell/bin/gitlab-shell <<EOF
#!/bin/bash
WRAPPER_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" WRAPPER_KEY_ID="$1" exec ssh -i ~/.ssh/id_rsa -p 8322 localhost /bin/false
EOF

Create folder to mount into gitlab

mkdir /home/git/data
cp /home/git/.ssh/id_rsa.pub /home/git/data/git_relay_key
ln -s /home/git/.ssh/authorized_keys /home/git/data/authorized_keys

Container setup

Create a separate folder for build a modified gitlab container. Create bash file called gitlab-shell-wrapper inside that folder.

#!/bin/bash
unset SSH_ORIGINAL_COMMAND
if [[ "$WRAPPER_ORIGINAL_COMMAND" != "" ]]; then
	export SSH_ORIGINAL_COMMAND="$WRAPPER_ORIGINAL_COMMAND"
fi
exec /home/git/gitlab-shell/bin/gitlab-shell "$WRAPPER_KEY_ID"

Mark the script as executable chmod +x gitlab-shell-wrapper.

Create a Dockerfile

FROM sameersbn/gitlab:latest
# update the userid once, not on every container spawn as it can be quite slow
RUN groupmod -o -g 998 git  && \
    sed -i -e "s|:1000:998:|:998:998:|" /etc/passwd && \
    find ${GITLAB_HOME} -print0 | xargs -0 -L100 -P8 chown -h git:

# setup ssh
RUN echo 'Match User git\n\
	ForceCommand /home/git/gitlab-shell-wrapper\n\
	AuthorizedKeysFile /home/git/data/.ssh/git_relay_key\n\
	AcceptEnv WRAPPER_ORIGINAL_COMMAND\n\
	AcceptEnv WRAPPER_KEY_ID' >> /etc/ssh/sshd_config
COPY gitlab-shell-wrapper /home/git/gitlab-shell-wrapper

Assembling all parts

It is highly recommended to start the gitlab container using a docker-compose.yml file. The following settings are required for the modified gitlab container:

    volumes:
    - /home/git/data:/home/git/data/.ssh
    ports:
    - "127.0.0.1:8322:22"
    environment:
    - GITLAB_SSH_PORT=22
    - USERMAP_UID=998
    - USERMAP_GID=998

Start the gitlab container and wait for it to startup. The following step is only necessary on first setup:

Run /home/git/gitlab-shell/bin/gitlab-shell as git user on the host and accept the host key.

It may be necessary to rebuild the authorized_keys file, see https://docs.gitlab.com/ce/administration/raketasks/maintenance.html#rebuild-authorized_keys-file

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment