71 lines
2.5 KiB
YAML
Executable File
71 lines
2.5 KiB
YAML
Executable File
---
|
|
# fix-ssh-host-keys.yaml
|
|
#
|
|
# Detects cloned VMs that share the same SSH host key and regenerates a
|
|
# unique key set on each one, then refreshes the controller's known_hosts.
|
|
#
|
|
# Run with host key checking disabled for this one remediation pass,
|
|
# since known_hosts is currently in a conflicted state:
|
|
#
|
|
# ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook fix-ssh-host-keys.yaml
|
|
#
|
|
# The `duplicate_fingerprint` guard means only hosts presenting the shared
|
|
# key get touched. Hosts with an already-unique key are left alone.
|
|
|
|
- name: Regenerate shared SSH host keys on cloned guests
|
|
hosts: all
|
|
become: true
|
|
gather_facts: false
|
|
vars:
|
|
# The shared key every clone is currently presenting.
|
|
duplicate_fingerprint: "SHA256:AZekUU+Wwn6S6sCjGD0SdkhVgj3WVqVdiVYa1AXYW8A"
|
|
tasks:
|
|
- name: Read current ED25519 host key fingerprint
|
|
ansible.builtin.command:
|
|
cmd: ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
|
|
register: hostkey_fp
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
- name: Regenerate host keys if this host shares the duplicate key
|
|
when: duplicate_fingerprint in (hostkey_fp.stdout | default(''))
|
|
block:
|
|
- name: Remove existing host keys
|
|
ansible.builtin.shell:
|
|
cmd: rm -f /etc/ssh/ssh_host_*
|
|
# rm on a glob isn't idempotent-reportable; treat as changed.
|
|
changed_when: true
|
|
|
|
- name: Generate a fresh unique set of host keys
|
|
ansible.builtin.command:
|
|
cmd: ssh-keygen -A
|
|
changed_when: true
|
|
|
|
- name: Restart SSH so the new key is served
|
|
ansible.builtin.service:
|
|
name: ssh
|
|
state: restarted
|
|
|
|
- name: Note that this host was remediated
|
|
ansible.builtin.debug:
|
|
msg: "{{ inventory_hostname }} had the shared key and was regenerated."
|
|
|
|
- name: Refresh known_hosts on the Ansible controller
|
|
hosts: localhost
|
|
gather_facts: false
|
|
vars:
|
|
known_hosts_path: "{{ lookup('env', 'HOME') }}/.ssh/known_hosts"
|
|
target_hosts: "{{ groups['all'] | difference(['localhost']) }}"
|
|
tasks:
|
|
- name: Remove stale entries for every managed host
|
|
ansible.builtin.command:
|
|
cmd: "ssh-keygen -f {{ known_hosts_path }} -R {{ item }}"
|
|
loop: "{{ target_hosts }}"
|
|
changed_when: false
|
|
|
|
- name: Rescan and add current keys
|
|
ansible.builtin.shell:
|
|
cmd: "ssh-keyscan -t ed25519,rsa,ecdsa {{ item }} >> {{ known_hosts_path }}"
|
|
loop: "{{ target_hosts }}"
|
|
changed_when: true
|