Spring Cloud Config Server using SSH key for Git and running in Docker Spring Cloud Config Server using SSH key for Git and running in Docker docker docker

Spring Cloud Config Server using SSH key for Git and running in Docker


First piece is the configuration. You want to ignore the standard private key and use one provided as an environment variable. (SSH_KEY). Also, the git repo is an EV (GIT_URL) but you can hardcode if you want.

spring:  cloud:    config:      server:        git:          uri:  ${GIT_URL}          ignore-local-ssh-settings: true          private-key: ${SSH_KEY}

Part 2 is tricky. For Dev, you want the key inline, so you need to use a pipe to prefix the block in YAML. (Note this key is throw away as in I just generated it and have now thrown it away)

private-key: |                    -----BEGIN RSA PRIVATE KEY-----                    MIIEpAIBAAKCAQEAszmCR06LVHk/kNYV6LoYgEfHlK4rp75sCsRJ7rdAbWNED+yB                    bneOm5gue0LGIhT7iTP9D7aN6bKVHv1SBconCA7Pa2NMA9epcMT5ecJc8ndpZOFn                    iqM77jmMMPvj8EIC06w5oK5zoYwpGotYQFHllf8M+20HtW2fZdPYAYwLcVdmc5tI                    vLoS+10qw5D3X9zrwk2Cbt37Iqnz1cHOQq+g7sxgVgt18aIKKeg0JslaGqSlWMoT                    ICUMHj89E4BMHj8ND8otSXHL+VhN+ghd7w1MpckxLWBsNs1+G1FuiJEVAtRq/j+8                    SOilxgifvI1LqpZ5kO01XFlmkcuN4NMT03qpcwIDAQABAoIBAB5oQGk2sz7mv1kk                    aV0tzaBeDUd1cWSpUw1UljKRFrY4ZEDLYH5MfH57iE9TWehIZRC3KFU1JMikitZS                    JktjK9IbKSfQFgKE4XOHh8gXqMteZRw/feCwpydYzic1ZUvK903QZ4qSbn3XGNYv                    FA79lhUny50Qt4EZkzSkh35js0FMSR9VmyXENxN6IgXUZyoaNAATr44Vkd488BY2                    7PvdOniemo8/8p4Ij0Aq9Q7rOtm77ZXjyFRX5mDTi2ndSllMEhVcWXHSii+ukbvF                    117Ns+8M7VWroNfRzI+Ilm/Xz/ePOLlNoYcY0h5+QM9vMPTX9Cpl5WofgOMK1sKd                    mSdI4ukCgYEA12kcu0aDyIrEPHcyaT9izSFply0Uon2QKS9EQn6cr83vaEGViamh                    f5q1coYouGnsLfbgKolEMKsYtbmJvInPFDCdc2x0Fmc207Wp1OECsN+HwElEXkrs                    uPDpGQgs5odjN5Grue9837920oG3UBBdVDAKly2dTOcvoWW+88seFSUCgYEA1P7f                    p78HDMQ8zTy5+3Rd4+lmJjPsY618XxSQ80j8Elrhi/DyTMA0XGc5c3cKRPmSj+JD                    GN34WQbw7JO2mKM7YJs+tkSBeTKce8F3cZQy1jy3LNHCtfXylOxmxOFKynV5h2b/                    jno+pGdmAPK5yvnGASd2eujtzt+AL07XiD2LnLcCgYEAsFRz131WfP/SuShdlLf1                    WbODKuQVIxojuwLdHo1kF6k805v0G/dGoxzycOgPRz41vj57q3Yn4qr8FC3n6PTq                    FT3idUyPDpO41r67Ye469KxWBHo1Q/aTJqTWOs5tatvixOcyqoa3MrUZQCI8+4YZ                    z8Nvt+b3/66zV6vhDtHzMx0CgYAvWW2M0+mUS/ecRHivzqGkrdkYewh87C8uz9qd                    SsdGqU9kla63oy7Ar+3Unkz5ImYTeGAkIgw4dlOOtBOugPMNOdXKHRaPQ9IHrO2J                    oUFf4OVzoDnhy4ge1SLPd6nxsgXPNPVwzfopABdr9Ima9sWusgAjuK5NA+ByI9vE                    HLJxpwKBgQCTM938cdx457ag1hS6EaEKyqljS1/B8ozptB4cy3h0hzw0crNmW84/                    1Lt9MJmeR4FrWitQkkVLZL3SrYzrP2i+uDd4wVVD5epvnGP/Bk6g05/eB9LgDRx/                    EeBgS282jUBkXZ6WpzqHCcku3Avs3ajzsC1WaEYx0tCiBxSkiJlaLQ==                    -----END RSA PRIVATE KEY-----

On the production front, you need to use a bash variable at the command prompt to store your key before you pass it to the Docker command that runs your container. Example:

$ pem=$( cat path_to_key )$ docker run -e "SSH_KEY=$pem" configserver

At this point you should have the application taken care of. Now all you need is to get past the ssh host not trusted problem. For this, add these lines in your Dockerfile. Replace "bitbucket.org" with whatever host you want. These commands create the ssh config directory, fix the permissions, and then create and populate the knownhosts file.

RUN mkdir -p /root/.sshRUN chmod 700 /root/.sshRUN ssh-keyscan bitbucket.org > /root/.ssh/known_hosts


I wanted to add a further twist on this, that would hopefully remove the need to mess around with SSH keys in the YAML file (or in env variables), which is usually A Bad Idea.

This revolves around the SSH Config file, so if the app does not have access to it, or it cannot be modified, this won't work (but I cannot think of any real-world situation in which this would apply, including Cloud deployments: either AWS Cloudformation templates, or Kubernetes ConfigMaps would provide useful workarounds).

The issue revolves (for the most part) around the (rather inexplicable) limitation of not being able to specify a private key file in the Spring Config application properties.

In your ~/.ssh/config file, you can add the following:

Host git-config    HostName github.myserver.example.com    User someone    IdentityFile /path/to/private_key

(I need to connect to a private GitHub Enterprise server and the user associated with the SSH key is not the same as the application server is being run under: this works just fine; if that's not the case, simply use github.com for the HostName, and omit the User)

Then, instead of using the actual GitHub URI, something like:

git@github.myserver.example.com:my-team/config-properties-demo.git

you replace git-config for the host:

spring:  cloud:    config:      server:        git:          uri: git@git-config:my-team/config-properties-demo.git          strictHostKeyChecking: false

It is indeed a bit cumbersome, but relatively easy to automate.A much preferable option would be for Spring Config to add another option that points to the private key material:

spring:  cloud:    config:      server:        git:          uri: git@github.myserver.example.com:my-team/config-properties-demo.git          user: someone          private_key_file: /path/to/private_key          strictHostKeyChecking: false

I guess this is one for the "enhancement requests" section...


Pardon the necro, but this is the #1 result on Google (from SO) when searching for how to do SSH authentication with Git repos when the config server is deployed to an environment with an ephemeral file system - and I believe I have found a way to do just that. Below is a gist of what I am currently doing to make that happen for my client.

https://gist.github.com/hanserya/43b00162741fa3022481301db60e8acd

It is definitely an ugly duckling, but is functional and should serve as solid footing for anyone that needs it. With this implementation, you'll be able to mount a volume to a container running the config server. Then, just configure the environment to use the volume as the SSH directory with the spring.cloud.config.server.git.sshLocation configuration key via whatever medium works best for you (env variables, bootstrap.yml, etc...)

Happy Coding!