git-server-docker icon indicating copy to clipboard operation
git-server-docker copied to clipboard

[Potential Security Issue] Leaking ssh host keys

Open AnixPasBesoin opened this issue 1 year ago • 5 comments

Issue

By default, ssh host keys provided by the user will be mounted on /tmp/host-keys, as shown in the provided docker-compose template:

...
environment:
# Path where the SSH host keys will be mounted in the container
# in order to replace the default keys
# SSH_HOST_KEYS_PATH: /tmp/host-keys
...

And latter on, these files are copied to /etc/ssh/ using:

...
if [ -n "${SSH_HOST_KEYS_PATH-}" ]; then
    if [ -d "${SSH_HOST_KEYS_PATH}" ]; then
        cd /etc/ssh
        rm -rf ssh_host_*
        cp "${SSH_HOST_KEYS_PATH}"/ssh_host_* .
        chmod 600 ssh_host_*
        chmod 644 ssh_host_*.pub
    else
        warn "Directory '${SSH_HOST_KEYS_PATH}' not found."
        warn "Default SSH host keys will be used instead."
    fi
fi
...

The issue with the above is that /tmp can be read by any user, which means that the private host key can be read by non-priveleged users...

Fix

  • Use a different default destination, and/or
  • Delete files once copied to /etc/ssh

AnixPasBesoin avatar Sep 19 '24 19:09 AnixPasBesoin

Hi, good point. I'll have a look at it. Thanks a lot for reporting this!

rockstorm101 avatar Sep 24 '24 14:09 rockstorm101

Hi @AnixPasBesoin, I've been looking at this.

I'm not sure how to handle this really. The user must and will mount their host keys wherever they want. I did a test and the private keys are generated already only readable by their owner (UID 1000 in the case shown below). When copied to the /etc/ssh they are purposely made read-only by the root user. And both directories /tmp/host-keys and /etc/ssh are accessible for any user. In this test case, the git user had UID 1005 which means it would not be able to read the private key in any of the two places. Correct me if I'm wrong but I think only the git user (apart from root) would be able to log onto this image, so there would be no security issue in this case. If the creator of the private keys and the git user happen to have the same UID, then yes, I guess the git user would be able to read it.

# ls -al /tmp/host-keys
[...]
drwxr-xr-x    2 1000     1000          4096 Aug 26  2022 .
-rw-------    1 1000     1000          2602 Apr 18  2022 ssh_host_rsa_key
-rw-r--r--    1 1000     1000           571 Apr 18  2022 ssh_host_rsa_key.pub
# ls -al /etc/ssh/
[...]
drwxr-xr-x    1 root     root          4096 Oct  5 12:32 .
-rw-------    1 root     root          2602 Oct  5 12:32 ssh_host_rsa_key
-rw-r--r--    1 root     root           571 Oct  5 12:32 ssh_host_rsa_key.pub
# cat /etc/passwd | grep git
git:x:1005:1005:Git User:/home/git:/usr/bin/git-shell
  • Use a different default destination, and/or

We could suggest to mount the keys somewhere more obfuscated but the user is free to mount them anywhere really.

  • Delete files once copied to /etc/ssh

Not an option since that would remove the original files from the host too.

I'm really out of ideas here so if you have any suggestions please let me know.

rockstorm101 avatar Oct 05 '24 19:10 rockstorm101

Hi @rockstorm101 I stumbled your project and will definitely try it out though do have some concerns about the way the host keys are used.

I really like the concept of volume mounting the secret keys to retain them externally and by doing this read-only one can prevent these to be changed or overwritten.

However, since every docker container created from an image (version) has the same host keys when shipped does not help as it effectively require you to use your own as anyone can obtain the host secret key and hence perform a man-in-the-middle attack more easily. (effectively voiding the authentication part of SSH in case of the default keys).

wouldn't it make sense to:

  • ship the image without any SSH host keys
  • at start up, in case they do not exist, generate new host keys (so move that from de Dockerfile into the startup script
  • require someone to to volume mount the keys at the location they are used (i.e. /etc/ssh/ssh_host_rsa_key and /etc/ssh/ssh_host_rsa_key.pub) and recommend to do this read-only

that way I think the issue from this ticket as well as the general setup could be addressed.

lindenaar avatar Oct 25 '25 08:10 lindenaar

at start up, in case they do not exist, generate new host keys (so move that from de Dockerfile into the startup script

I like this idea. I'll look into implementing this. Some users might be surprised to get different keys on every run though. I'll need to think about it.

  • require someone to to volume mount the keys at the location they are used (i.e. /etc/ssh/ssh_host_rsa_key and /etc/ssh/ssh_host_rsa_key.pub) and recommend to do this read-only

Private key would still be readable. So I don't see how this solves the alleged security issue. Plus this requires the user to mount two (or more) files as opposed to mounting a single folder. What am I missing?

rockstorm101 avatar Nov 10 '25 20:11 rockstorm101

@rockstorm101 I don't see the issue with leaking the host private key in my setup as sshd is running as root and can read the volume mounted private key while the git user cannot as the permissions only allow it to be read by root. Since there is nothing to copy via /tmp the permissions are and stay correct.

Drawback of this is indeed that this requires a volume mount of 2 files, though potentially that could be simplified by telling sshd to read the files from another folder using the HostKey directive. One potentially it may be possible to store this in an already volume-mounted /etc/ssh/ssh/sshd_config.d, though I have not tested this yet.

lindenaar avatar Nov 15 '25 13:11 lindenaar