Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wishlist: functionnality to generate users SSH key #89

Open
daks opened this issue Apr 5, 2017 · 10 comments
Open

Wishlist: functionnality to generate users SSH key #89

daks opened this issue Apr 5, 2017 · 10 comments

Comments

@daks
Copy link
Member

daks commented Apr 5, 2017

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.

@Sjd-Risca
Copy link

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

@daks
Copy link
Member Author

daks commented Jul 5, 2017

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.

@0xf10e
Copy link
Contributor

0xf10e commented Jul 7, 2017

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.

@daks
Copy link
Member Author

daks commented Jul 7, 2017

@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.

@0xf10e
Copy link
Contributor

0xf10e commented Jul 7, 2017

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…

@daks
Copy link
Member Author

daks commented Jul 7, 2017

No open salt master, so servers (and servers' pool) are manually added.

I don't understand how I could run this sequence of actions

  • on server1, generate a key. Worse solution with a ssh-genkey command
  • propagate this key to master
  • propagate this key to all other servers in the pool

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.

@alxwr
Copy link
Member

alxwr commented Jul 8, 2017

@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. :-)

@daks
Copy link
Member Author

daks commented Jul 10, 2017

@alxwr thanks for all this code :) As soon as this problem returns on our priority list, I'll try it.

@noelmcloughlin
Copy link
Member

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>    

@zatricky
Copy link

zatricky commented Jun 2, 2018

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants