This method is designed to fully take over the distribution of SSH Keys, meaning if you use this method you, or individual users, can no longer manually add their own keys to the systems.
./roles/ssh-keys/tasks/main.yml:
---
- name: Making sure .ssh directories exists
ansible.builtin.file:
path: /root/.ssh/
state: directory
mode: '0700'
- name: Distributing admin-ssh-keys, /root/.ssh/authorized_keys
template:
src: authorized_keys
dest: /root/.ssh/authorized_keys
mode: 0700
vars:
username: root
- name: Making sure .ssh directories exists for users
ansible.builtin.file:
path: /home/{{ item.username }}/.ssh
state: directory
mode: '0700'
loop: "{{ sshkeys | json_query(_query) | flatten | unique }}"
when: item.username != "root" and item.hostname == ansible_fqdn
vars:
_query: "[].hosts"
- name: Distributing user-ssh-keys
template:
src: authorized_keys
dest: /home/{{ item.username }}/.ssh/authorized_keys
mode: 0700
loop: "{{ sshkeys | json_query(_query) | flatten | unique }}"
when: item.username != "root" and item.hostname == ansible_fqdn
vars:
_query: "[].hosts"
username: "{{item.username}}"
- name: Fetching
getent:
database: passwd
- name: Building lookup table
set_fact:
managedkeys: "{{ managedkeys | default({}) | combine( {item.hostname: [item.username]} , list_merge='append') }}"
loop: "{{ sshkeys | json_query(_query) | flatten | unique }}"
when: item.username != "root" #and item.hostname == ansible_fqdn
vars:
managedkeys: {}
_query: "[].hosts"
- name: Removing un-managed authorized_keys
debug:
msg: User {{ item }} found
loop: "{{ getent_passwd.keys()|list }}"
when: item not in managedkeys[ansible_fqdn] and item != "root"
- name: Removing un-managed (all) authorized_keys2
file:
path: ~{{item}}/.ssh/authorized_keys2
state: absent
loop: "{{ getent_passwd.keys()|list }}"
./roles/ssh-keys/tasks/authorized_keys
# This file is maintained by Ansible, changes will be automatically overwritten
# Username: {{username}}
{%- for sshkey in sshkeys -%}
{%- if sshkey.admin is defined and sshkey.admin and username == "root" %}
# {{sshkey.owner}}
{{sshkey["key"]}}
{%- else -%}
{%- if sshkey["hosts"] is defined -%}
{%- for host in sshkey.hosts -%}
{%- if ansible_fqdn == host.hostname and username == host.username %}
# {{sshkey.owner}}
ZZZ {{sshkey["key"]}}
{%- endif -%}
{%- endfor -%}
{%- endif -%}
{%- endif -%}
{%- endfor %}
# This file is maintained by Ansible, changes will be automatically overwritten
And finally ./roles/ssh-keys/vars/main.yaml
sshkeys:
- owner: Firstname Lastname
admin: true
key: ssh-rsa AAAA.....PQZ firstname@laptop
- owner: Another firstname another lastname
admin: true
key: ssh-rsa AAAA.....QJE another@workstation
- owner: Automated backup
key: ssh-rsa AAAA.....EMT backup@backupcluster
hosts:
- hostname: targetsystem.mydomain.com
username: backup
- hostname: targetsystem.mydomain.com
username: mysql
- hostname: anothertarget.mydomain.com
username: backup
This will install Firstnames and Another firstnames ssh keys on the root account on all servers targeted with this task, and the automated backup key on targetsystem user backup and mysql and finally on anothertarget user backup.
Every other key on the system will be deleted every time this script is being run, it checks every .ssh folder in every homedir for authorized_keys and authorized_keys2 files and deletes them, unless the homedir belongs to one of the above users. Authorized_keys2 er always deleted since we don’t use them.
If you don’t want this functionality you can remove either both or one of the last blocks in the tasks/main.yaml