Key exchange approaches, drawbacks.

SSH key pairs are great, as we all know. Besides using them to control Ansible connections, I also use them with git for certain software deployments and with rsync and other sync tools to get production data to my QA and developer machines.

It’s always a bit painful, especially when I have to spin up a bunch of new test or QA machines, to carry out those important steps for non-interactive logins.

  1. Create a non-privileged sync user and it’s key pair.

  2. Get that user’s public key to the source server’s authorized_keys (usually a non-privileged user on the production server).

  3. Get the source server’s public host key into that user’s known_hosts.
    I see a couple ways to do that. The first is to just pregenerate some key pairs and just use the copy or template module to push them to servers. Simple, yes? Secure enough?

Another way is to do something like this (I have some custom modules that assist this job, none ready for prime time–just asking for feedback now). Not sure I like it, especially for transient test machines, but the prototype works.

  • hosts: sync_source
    user: root
    vars_files:

  • vars/sync.yaml
    tasks:

  • name: create read-only sync user
    action: user name=${sync_user} shell=/bin/bash comment=“Read only access to data for remote systems to sync from.”

  • name: create sync data directory
    action: file state=directory dest=${sync_data} owner=${sync_user}

  • name: get host fingerprint
    #Fetches all public keys (host, root, and every user)
    action: public_keys

  • hosts: sync_dest
    user: root
    vars_files:

  • vars/sync.yaml
    tasks:

  • name: create sync dest user (a.k.a. mirror user)
    action: user name=$mirror_user

  • name: create mirror user ssh keys
    action: command su $mirror_user -c ‘ssh-keygen -f $mirror_key -N “”’ creates=$mirror_key

  • name: fetch ssh public keys from sync dest
    action: public_keys

  • hosts: sync_source
    user: root
    vars_files:

  • vars/sync.yaml
    tasks:

  • name: insert sync client authorized_keys
    action: authorized_key user=${sync_user} key=${hostvars.for each host in sync dest
    #only_if: “The dest host has been reached and has public keys for the sync user.”

  • hosts: sync_dest
    user: root
    vars_files:

  • vars/sync.yaml
    tasks:

  • name: insert sync source host key
    action: known_hosts user=${sync_user} key=${hostvars.synchostsource.host}
    #only_if: “The dest host has been reached and has public keys for the sync user.”