Vvv: Pre-add GitHub as SSH known_host and persist SSH agent through user switch

Created on 19 May 2014  路  6Comments  路  Source: Varying-Vagrant-Vagrants/VVV

There's this dreaded issue I've seen come up over and over again when the (non-TTY) provisioner tries to connect to private GitHub repos, but either fails because it doesn't have the proper SSH agent or because it is connecting to an un-known_host, and since it is not a TTY the user can't manually verify the authenticity of the host.

I found that SSH agent can be made to persist after user switches via addomg Defaults env_keep+=SSH_AUTH_SOCK to /etc/sudoers:

# Make sure SSH agent forwarding persists across switching users (so that GitHub is added to known hosts)
if ! grep -sq -E 'Defaults  *env_keep+=SSH_AUTH_SOCK' /etc/sudoers; then
    echo "Add SSH_AUTH_SOCK to sudoers config"
    # TODO: We're supposed to use visudo to modify this file?
    echo 'Defaults  env_keep+=SSH_AUTH_SOCK' >> /etc/sudoers
fi

The other problem is harder, and I haven't found a solution to the ol':

The authenticity of host 'github.com (192.30.252.129)' can't be established.
RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
Are you sure you want to continue connecting (yes/no)?

I've tried the following two approaches, but both without success:

# Attempt to prevent non-TTY failure to connect to GitHub since user cannot accept to add host to known_hosts
if ! grep -sq 'Host 192.30.252.*' /etc/ssh/ssh_config; then
    echo "Add GitHub IP whitelist to global ssh_config"
    echo -e '\nHost 192.30.252.*\n  StrictHostKeyChecking no\n  UserKnownHostsFile=/dev/null' >> /etc/ssh/ssh_config
fi

# Manually add GitHub's public key for all IPs in range
host_key='ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ=='
for i in {0..255}; do
    known_host_line="192.30.252.$i $host_key"
    if ! grep -sq "$known_host_line" /etc/ssh/ssh_known_hosts; then
        echo "Add known_host 192.30.252.$i"
        echo "$known_host_line" >> /etc/ssh/ssh_known_hosts
    fi
done

I'm specifically targeting GitHub repos here, but it would be great to add recognition for popular hosts out of the box.

enhancement patch

Most helpful comment

@LoreleiAurora and I discussed this yesterday and decided it would probably make sense to create a known_hosts file somewhere in the config directory that would by default be prepopulated with the host keys for github, bitbucket and gitlab. It would be possible for it to be modified manually though.

Then the provisioner should move these into the relevant locations in the VM (/root/.ssh/known_hosts and ~/.ssh/known_hosts).

All 6 comments

Here's how we currently handle these issues in CFTP's VVV development environment provisioner:

SSH Connection

For this we use a robot user which has been added, with keys, to the various services we need, e.g. GitHub. This user is only ever added with read permissions, because we distribute the private SSH key with all our development environments (which are private repos, so the key is not made publicly available on the open web, but is in many people's hands). We then use ssh-agent to load these keys and execute any commands necessary, for example:

ssh-agent bash -c "ssh-add ssh/cftp_deploy_id_rsa; git clone $REPO_SSH_URL htdocs;"

SSH Fingerprints

I wrestled with the SSH fingerprint recognition issue for _ages_. Currently we add pre-generated signatures for GitHub and GitLab in our vvv-init.sh with this code:

mkdir -p /root/.ssh
touch /root/.ssh/known_hosts
IFS=$'\n'
for KNOWN_HOST in $(cat "ssh/known_hosts"); do
    if ! grep -Fxq "$KNOWN_HOST" /root/.ssh/known_hosts; then
        echo "Adding host to SSH known_hosts for user 'root': $KNOWN_HOST"
        echo $KNOWN_HOST >> /root/.ssh/known_hosts
    fi
done

I found a how-to on generating SSH fingerprints with ssh-keyscan, and use it to generate fingerprints which we store ready for that bash snippet above to add them to the Vagrant root user's SSH known_hosts.

General VVV

I'd be somewhat OK to see common fingerprints added to known_hosts in that it lowers the barrier to entry for provisioning. I'm slightly concerned that it starts to stray outside my perception of the VVV remit, but I might just be overly concerned.

This is what I have done to fix this issue.
In Vagrant file I added the following line above config.ssh.forward_agent = true

config.ssh.private_key_path = [ '~/.vagrant.d/insecure_private_key', '~/.ssh/id_rsa' ]

Then, in provision.sh, before any connection to private repo I added this:

# add github to the list of known_hosts
# see http://rshestakov.wordpress.com/2014/01/26/how-to-make-vagrant-and-puppet-to-clone-private-github-repo/
if [[ ! -d /root/.ssh ]]; then
  echo "Add github.com to known_hosts"
  mkdir /root/.ssh && touch /root/.ssh/known_hosts && ssh-keyscan -H github.com >> /root/.ssh/known_hosts && chmod 600 /root/.ssh/known_hosts
fi

On initial vagrant up output looks like this:

==> default: Add github.com to known_hosts
==> default: # github.com SSH-2.0-libssh-0.6.0
==> default: Downloading githubprivaterepo
==> default: Cloning into '/srv/www/githubprivaterepo'...
==> default: Warning: Permanently added the RSA host key for IP address '192.30.252.129' to the list of known hosts.
==> default: Checking out files:   0% (6/6884)
etcetera.....

This woks well provided the host machine has the keys needed in the right places.

Hope this helps someone.

+1 for this. I just ran into the same problem, I used the approach suggested in https://github.com/mitchellh/vagrant/issues/1303#issue-9781811 to fix it.

@LoreleiAurora and I discussed this yesterday and decided it would probably make sense to create a known_hosts file somewhere in the config directory that would by default be prepopulated with the host keys for github, bitbucket and gitlab. It would be possible for it to be modified manually though.

Then the provisioner should move these into the relevant locations in the VM (/root/.ssh/known_hosts and ~/.ssh/known_hosts).

Now available by adding trusted-hosts as a utility
Will be made part of the main provisioner in the next release

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings