--- - name: Copy public key for signing ansible.builtin.fetch: src: /etc/ssh/ssh_host_ed25519_key.pub dest: "/srv/sshca/pubkeys/{{ inventory_hostname }}.pub" flat: true - name: Check status of public key ansible.builtin.stat: path: "/srv/sshca/pubkeys/{{ inventory_hostname }}.pub" changed_when: false failed_when: false check_mode: false delegate_to: localhost register: sshd_cert_pubkey - name: Check status of certificate ansible.builtin.stat: path: "/srv/sshca/pubkeys/{{ inventory_hostname }}-cert.pub" changed_when: false failed_when: false check_mode: false delegate_to: localhost register: sshd_cert_status - name: Get certificate info ansible.builtin.command: argv: - ssh-keygen - -L - -f - "/srv/sshca/pubkeys/{{ inventory_hostname }}-cert.pub" changed_when: false failed_when: false check_mode: false when: sshd_cert_status.stat.exists delegate_to: localhost register: sshd_cert_info - name: Sign certificate ansible.builtin.command: argv: - ssh-keygen - -s - "/srv/sshca/ca/ca.{{ ansible_date_time['year'] }}" - -I - "{{ inventory_hostname }}" - -h - -n - "{{ sshd_cert_hostnames | join(',') }}" - -V - -1h:+365d - -z - "{{ ansible_date_time.epoch }}" - "/srv/sshca/pubkeys/{{ inventory_hostname }}.pub" when: > not sshd_cert_status.stat.exists or sshd_cert_status.stat.mtime | int < sshd_cert_pubkey.stat.mtime | int or ( sshd_cert_info.stdout_lines | select('match', '^[ ]*Valid: ') | first | split() | last | to_datetime('%Y-%m-%dT%H:%M:%S') ).strftime('%s') | int < ansible_date_time.epoch | int + 2592000 delegate_to: localhost - name: Install certificate ansible.builtin.copy: dest: /etc/ssh/ssh_host_ed25519_key-cert.pub src: "/srv/sshca/pubkeys/{{ inventory_hostname }}-cert.pub" mode: "0644" owner: root group: "{{ ansible_wheel }}" notify: Restart sshd - name: Enable host certificate ansible.builtin.lineinfile: path: /etc/ssh/sshd_config line: HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub regexp: "^(# )?HostCertificate .*" insertafter: "^HostKey .*" validate: "sshd -t -f %s" notify: Restart sshd