Open daks opened 7 years ago
The need is clear and probably quite common.
An idea could be to setup a custom pillar module (like the one available for libvirt [0]), otherwise could be possible to use mine. What sounds best to you?
[0] https://docs.saltstack.com/en/develop/ref/pillar/all/salt.pillar.libvirt.html
I have not searched a lot about this problem, so I don't know the pros and cons of each method, and the implementation difficulty.
Why not just generate the keys on the master, put then into your nodes' pillar data under [users:*:ssh_auth]
and use the users-formula to distribute them?
This way it's also easier to add a passphrase to the private key.
@0xf10e this is possible in fact, but if you want each servers' pool to have a different key, and you want this to be 'dynamic' (pools are created regularly), you can't.
Is all of this creation of pools and users happening automagically with an open master? How does a host get assigned to a pool? Is any approval happening?
You could tie together reactors and runners and the salt mine to have pubkeys made available for the master to get and inject in all the other minions in this particular pool. I'm not sure though if this is in scope for this formula as it will get rather involved by itself…
No open salt master, so servers (and servers' pool) are manually added.
I don't understand how I could run this sequence of actions
Step 2 is my problem. How to add the key to server1 pillar data, so that it's available to others via mine? The key is a file, not strictly pillar data.
@daks I've got a working solution for SSH host keys. I even generate them, if they are missing. (Even wrote a workaround for salt-ssh
if you're interested.)
Everything is an add-on to this formula, so there’s the possibility of a PR in the future.
# states/openssh/config_with_mine.sls => generates the keys if necessary
include:
- openssh.config
extend:
{% for keyType in ['ecdsa', 'dsa', 'rsa', 'ed25519'] %}
{% if salt['pillar.get']('openssh:generate_' ~ keyType ~ '_keys', False) %}
ssh_generate_host_{{ keyType }}_key:
cmd.run:
- onchanges_in:
- module: mine_update
{% endif %}
{% endfor %}
# pillar/mine_functions.sls
mine_functions:
public_ssh_host_keys:
mine_function: cmd.run
cmd: cat /etc/ssh/ssh_host_*_key.pub 2>/dev/null
python_shell: True
public_ssh_hostname:
mine_function: grains.get
key: id
# states/mine/update.sls => updates the mine
mine_update:
module.run:
- name: mine.update
- onchanges:
# This is just my way to _always_ have a onchanges in mine_update.
- test: mine_update_only_on_change
mine_update_only_on_change:
test.succeed_without_changes: []
Pros: uses just Salt Mine and ssh-keygen
.
Cons: does not update all other hosts immediately. Could easily be added using a Reactor which is triggered on a special event (yet to be implemented in config_with_mine.sls
) and runs state.apply openssh.config
The (maye) difficult part is to formulate a mine function which will get all public SSH keys, because suddenly we're talking path conventions. ;-)
But could be as simple as this:
# pillar/mine_functions.sls
mine_functions:
[…]
public_ssh_user_keys:
mine_function: cmd.run
cmd: cat /home/*/.ssh/*.pub 2>/dev/null
python_shell: True
I hope, I'm helping. :-)
@alxwr thanks for all this code :) As soon as this problem returns on our priority list, I'll try it.
Hi @alxwr
Do I need to use your code to copy SSH host keys to salt-master authorized_hosts
file? i.e. instead of manual steps. thanks!!
ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub <ip_address-salt-master>
I didn't see this before. Re @0xf10e 's comment last year, as much as the master server may be "in control" of everything, I would never want users' private keys ever to be stored anywhere other than on the machine they would be used from. "Ever" includes when the keys are generated. The same goes for host keys.
My understanding is that currently the minions, if they don't already have host keys, are instructed to generate the host keys for themselves and the public portions are then distributed.
Hello,
This formula is already able to manage (push) SSH pubkeys for users. I wonder if adding users SSH key generation could be interesting?
My use case is the following: a specific pool of some servers where we want to generate SSH key for a user and then propagate each key to others servers in the pool.