Skip to content

GEANT/ansible_role_users

Repository files navigation

Ansible role to configure multiple users accounts

This takes into account all the options that ansible.builtin.user supports, but replaces and extends SSH related ones.

SSH related options

ssh_authorized_keys

A list of public keys, these are taken to be 'exclusive'. Normally it is only possible to have one "command" option per key. If you configure a pubkey entry as a dict with a pubkey and commands key (list), then a shell wrapper script will be installed as the command, and that script in turn will allow all the commands. See below for an example

ssh_config

An inline snippet of SSH client configuration, saved as ~/.ssh/config. If you need templating, see below

ssh_config_template

Not supported anymore. Use ssh_config and do a template lookup. For example, instead of this:

ssh_config_template: custom_ssh_config.j2

Use this:

ssh_config: "{{ lookup('ansible.builtin.template', 'custom_ssh_config.j2') }}"

ssh_keypairs

A list of dictionaries that represent SSH keypairs. Each keypair should at least have a dest and private key:

- dest: id_ed25519
  private: |
    -----BEGIN OPENSSH PRIVATE KEY-----
    b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAE...
    ....
    -----END OPENSSH PRIVATE KEY-----

The above example will write the private key to a file ~/.ssh/id_ed25519, and it will extract the public key from the private key and write that to ~/.ssh/id_ed25519.pub.

You can optionally configure the public key explicitly:

- dest: id_ed25519
  private: |
    -----BEGIN OPENSSH PRIVATE KEY-----
    b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAE...
    ....
    -----END OPENSSH PRIVATE KEY-----
  public: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJQiAuSXCK+Vhnzsbgj4sBOyoZ5nB0d+8b7Vocs+gU2p with some comments

If you do not want a public key at all (not very useful because the public key is contained in the private key anyway), then set public to false:

- dest: id_ed25519
  private: |
    -----BEGIN OPENSSH PRIVATE KEY-----
    b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAE...
    ....
    -----END OPENSSH PRIVATE KEY-----
  public: false

It is also possible to supply a present key (boolean), which can be useful to make sure the keypair (both private and public parts) is removed when set to false:

- dest: id_ed25519
  private: |
    -----BEGIN OPENSSH PRIVATE KEY-----
    b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAE...
    ....
    -----END OPENSSH PRIVATE KEY-----
  present: false

sudo_config

Optional snippet of sudo config, which is templated to /etc/sudoers.d/account_{{ name }}. FIXME: handle cleanup better

Examples

This playbook uses the role twice:

---
- hosts: servers
  become: true

  roles:
    - role: ansible_role_users
      vars:
        # Very minimal example
        user_accounts:
          - name: user1
          - name: user2
          - name: user3


    - role: ansible_role_users
      vars:
        # Some defaults for all user accounts
        users_user_ssh_authorized_keys_exclusive: yes
        users_user_shell: /bin/dash
        users_user_group: websvc
        users_user_system_user: yes
        users_user_system_group: yes
        # Then the actual users
        user_accounts:
          - name: user4
            password: "{{ 'hackme' | password_hash('sha512', 'mysalt') }}"
            comment: System account for the web services
            home: /opt/user4
            ssh_authorized_keys:
              pubkeys:
                - ssh-ed25519 AAAAC3NzaC1lZDI1iweE....
                - "command=/usr/bin/rsync --foo --bar" ssh-rsa AAAAB3NzaC1yc2EAAAADAQAD....
                - ssh-ed25519 AAAAC3NzaC1lZDIDDJ72....
            ssh_keypairs:
              - dest: git_deploy_key
                private: |
                  -----BEGIN OPENSSH PRIVATE KEY-----
                  b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9u....
                  -----END OPENSSH PRIVATE KEY-----
            ssh_config: |
              Host gitlab.uni.edu
              IdentityFile git_deploy_key
              IdentitiesOnly yes
          - name: user5
            password: "{{ 'hackmetoo' | password_hash('sha512', 'mysalt') }}"
            comment: Another system account for a web service
            ssh_authorized_keys:
              pubkeys:
                - ssh-ed25519 AAAAC3NzaC1lZDI1iweE....
                - ssh-rsa AAAAB3NzaC1yc2EAAAADAQAD....
                - command="/usr/bin/whoami" ssh-ed25519 AAAAC3NzaC1lZDIDDJ72....
          - name: admin2
            password: "{{ 'hackme2' | password_hash('sha512', 'mysalt') }}"
            comment: Extra admin account with passwordless sudo
            ssh_authorized_keys:
              pubkeys:
                - ssh-ed25519 AAAAC3NzaC1lZDI1iweE....
                # Allow multiple commands for a single key
                - pubkey: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAVQU41erftVORV0eYWfBlRjIqDujxzbRsmZ4G0L0xWY
                  commands:
                    - /usr/bin/true
                    - sudo rsync --server --sender -vlogDtprRe.iLsfxCIvu --files-from=- --from0 . /
                    - /usr/bin/whoami
            sudo_config: "ALL=(ALL) NOPASSWD:ALL"
          - name: nagios
            # Useful to pin uid/gid ahead of the software installation
            uid: 110
            gid: 118
            ssh_keypairs:
              - dest: github_cloning_key
                private: |
                  -----BEGIN OPENSSH PRIVATE KEY-----
                  b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQ....
                  -----END OPENSSH PRIVATE KEY-----
                # Only deploy keypair if a condition is true
                present: "{{ (github_checks_repos | length > 0) }}"

Requirements

  • Ansible galaxy collections:
    • community.crypto
    • ansible.posix

License

BSD

Author Information

Dick Visser dick.visser@geant.org