Search code examples
salt-project

Saltstack. How to create ssh keys per user per server and exchange it


How can I create ssh private and public keys for user per server during installation, and then add new created public keys for different users on different servers?

For example:

server 1

  • user1 has public key in authorized_keys - server1(user2,user3),server2(user1,user2,user3)
  • user2 has public key in authorized_keys - server1(user1,user3),server2(user1,user2,user3)
  • user3 has public key in authorized_keys - server1(user1,user2),server2(user1,user2,user3)

server 2

  • user1 has public key in authorized_keys - server1(user1,user2,user3),server2(user2,user3)
  • user2 has public key in authorized_keys - server1(user1,user2,user3),server2(user1,user3)
  • user3 has public key in authorized_keys - server1(user1,user2,user3),server2(user1,user2)

I know how to create the keys( public, private), but how can I exchange these keys between servers, two or more?


Solution

  • If you look in the documentation you'll find the ssh_auth.present state. https://docs.saltstack.com/en/latest/ref/states/all/salt.states.ssh_auth.html#salt.states.ssh_auth.present

    To dynamically populate the authorized keys, I use pillar data as the source of truth. To make sure the user and his or her public keys are on the appropriate servers I'll use a salt state such as this example:

    cat /srv/salt/server_users.sls

    {% set users = pillar.get('server_users') %}
    
    {% for user in users %}
    
    {{ user }}_setup:
      user.present
    
    {{ user }}_sshkey:
      ssh_auth.present:
        - source: salt://pubkeys/{{ user }}.pub
        - user: {{ user }}
    
    {% endfor }}
    

    Then I drop all my users' public keys into the /srv/salt/pubkeys/ directory.

    At this point I set up either flat file pillars or an external pillar that will give each server a pillar key of server_users whose value is a list of users that I want to have exist on that particular server and have ssh keys deployed.

    An example of a flat file pillar would look something like this.

    cat /srv/pillar/top.sls

    base:
      'server01':
        - users.server01
      'server02':
        - users.server02
    

    cat /srv/pillar/users/server01.sls

    server_users:
      - sarah
      - joe
      - kari
      - kanchan
    

    cat /srv/pillar/users/server02.sls

    server_users:
      - kanchan
      - john
      - sumit
    

    So in this example kanchan would have access to both servers while the other users would only have access to one of the servers.