Re-Use SSH Config Inside Docker Containers with WSL2

Docker and WSL have been getting more and more chummy lately. The Docker Desktop WSL2 backend integrates Docker containers with the “official” integrated Windows/Linux ecosystem (boy that still feels a little weird to write…) and gains performance perks in the process.

However, I ran into some trouble recently getting SSH to work inside of a Docker container. As I’ve written about before, I like to bind-in my credentials from my host machine, rather than proliferating credentials into containers. When a container needs to SSH out to the wider world, that means binding in my .ssh directory from the host, e.g. with a docker-compose.yml:

    volumes: 
      - type: bind
        source: ${HOME}${USERPROFILE}/.ssh
        target: /home/${DEV_USER:-abapa}/.ssh

Only one problem: volumes mounted from the Windows side are mounted via <a href="https://docs.microsoft.com/en-us/archive/blogs/wsl/wsl-file-system-support">drvfs</a>, which by default projects all files as having mode 777 on the Linux side. And SSH will refuse to use certificate files that are world-writeable.

After a bunch of research and some trial-and-error, I found a solution that’s working right now (2020-10-24). Recent versions of drvfs allow NTFS-hosted files to have fake Linux-side effective permissions attached to them, via NTFS extended attributes. And the docker-desktop distro that Docker Desktop installs has this feature enabled:

PS> wsl -d docker-desktop
# cat /etc/wsl.conf
[automount]
root = /mnt/host
crossDistro = true
options = "metadata"

Notice the options = "metadata" line in /etc/wsl.conf.

So the trick was to open a WSL terminal in that distro and set the desired effective owner and file permissions:

PS> wsl -d docker-desktop
caroline:/tmp/docker-desktop-root/mnt/host/c/Users/avdi_000/.ssh# chown -R 1000:1000 .
caroline:/tmp/docker-desktop-root/mnt/host/c/Users/avdi_000/.ssh# chmod -R u=rwX .

These aren’t “real” file attributes, since Windows has a very different permissions model from Linux. But they get saved as file attributes and treated as the effective file permissions inside WSL distros with metadata enabled.

Notes:

  • -R makes the change recursive through directories.
  • User/group 1000 are a common default user/group ID for containers.
  • File mode u=rwX recursively sets files to readable/writeable by owner, and directories read/write/traversable by owner.

1 comment

  1. or in a vscode devcontainer configuration that uses a Dockerfile:

    “mounts”: [ “source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home//.ssh,type=bind” ]

Leave a Reply

Your email address will not be published. Required fields are marked *