254 lines
5.6 KiB
YAML
254 lines
5.6 KiB
YAML
---
|
|
#
|
|
# We have some tasks here in case this is a bare metal machine
|
|
# and we are provisioning it for the first time.
|
|
# virtual machines are handled in tasks/virt-instance-create
|
|
#
|
|
|
|
- name: make sure there is no old ssh host key for the host still around
|
|
local_action: known_hosts path={{item}} host={{ inventory_hostname }} state=absent
|
|
ignore_errors: true
|
|
with_items:
|
|
- /root/.ssh/known_hosts
|
|
when: birthday is defined
|
|
|
|
- name: gather ssh host key from new instance
|
|
local_action: command ssh-keyscan -t rsa {{ inventory_hostname }}
|
|
ignore_errors: true
|
|
register: hostkey
|
|
when: birthday is defined
|
|
|
|
- name: add new ssh host key (until we can sign it)
|
|
local_action: known_hosts path={{item}} key="{{ hostkey.stdout }}" host={{ inventory_hostname }} state=present
|
|
ignore_errors: true
|
|
with_items:
|
|
- /root/.ssh/known_hosts
|
|
when: birthday is defined
|
|
|
|
- name: make sure libselinux-python is installed
|
|
package: name=libselinux-python state=present
|
|
tags:
|
|
- basessh
|
|
- sshd_config
|
|
- config
|
|
- sshd
|
|
- selinux
|
|
when: ansible_distribution == 'RedHat' and ansible_distribution_major_version|int < 8
|
|
|
|
- name: make sure python3-libselinux is installed
|
|
package: name=python3-libselinux state=present
|
|
tags:
|
|
- basessh
|
|
- sshd_config
|
|
- config
|
|
- sshd
|
|
- selinux
|
|
when: ( ansible_distribution == 'Fedora' and ansible_distribution_major_version|int >= 30 ) or ( ansible_distribution == 'RedHat' and ansible_distribution_major_version|int >= 8 )
|
|
|
|
- name: check if sshd port is already known by selinux
|
|
shell: semanage port -l | grep ssh
|
|
register: sshd_selinux_port
|
|
check_mode: no
|
|
changed_when: false
|
|
failed_when: false
|
|
tags:
|
|
- basessh
|
|
- sshd_config
|
|
- config
|
|
- sshd
|
|
- selinux
|
|
- base
|
|
|
|
- name: allow alternate sshd port
|
|
command: semanage port -a -t ssh_port_t -p tcp {{ sshd_port }}
|
|
when: sshd_port in sshd_selinux_port
|
|
failed_when: false
|
|
tags:
|
|
- basessh
|
|
- sshd_config
|
|
- config
|
|
- sshd
|
|
- selinux
|
|
- base
|
|
|
|
- name: sshd_config
|
|
template: src=sshd_config dest=/etc/ssh/sshd_config mode=0600
|
|
notify:
|
|
- restart sshd
|
|
tags:
|
|
- basessh
|
|
- sshd_config
|
|
- config
|
|
- sshd
|
|
- base
|
|
|
|
- name: Determine SSH keys generated by this machine
|
|
find: paths=/etc/ssh
|
|
file_type=file
|
|
patterns="ssh_host_*_key"
|
|
register: ssh_key_files
|
|
tags:
|
|
- basessh
|
|
- sshd_cert
|
|
- sshd_config
|
|
- config
|
|
- sshd
|
|
- base
|
|
|
|
- name: Determine SSH keys never signed
|
|
stat: path="{{item.path}}-cert.pub"
|
|
with_items: "{{ssh_key_files.files}}"
|
|
register: ssh_cert_files
|
|
tags:
|
|
- basessh
|
|
- sshd_cert
|
|
- sshd_config
|
|
- config
|
|
- sshd
|
|
- base
|
|
|
|
- name: Set lists of certs to sign to empty
|
|
set_fact:
|
|
certs_to_sign: []
|
|
tags:
|
|
- basessh
|
|
- sshd_cert
|
|
- sshd_config
|
|
- config
|
|
- sshd
|
|
- base
|
|
|
|
- name: Set list of certs to sign
|
|
set_fact:
|
|
certs_to_sign: "{{ certs_to_sign + [item.item.path] }}"
|
|
with_items: "{{ssh_cert_files.results}}"
|
|
when: not item.stat.exists
|
|
tags:
|
|
- basessh
|
|
- sshd_cert
|
|
- sshd_config
|
|
- config
|
|
- sshd
|
|
- base
|
|
|
|
# Renew if last mod was more than 10 months ago
|
|
- name: Get soon-to-expire certificates to sign
|
|
set_fact:
|
|
certs_to_sign: "{{ certs_to_sign + [item.item.path] }}"
|
|
with_items: "{{ssh_cert_files.results}}"
|
|
when: "item.stat.exists and item.stat.mtime|int < (lookup('pipe', 'date +%s')|int - 25920000)"
|
|
tags:
|
|
- basessh
|
|
- sshd_cert
|
|
- sshd_config
|
|
- config
|
|
- sshd
|
|
- base
|
|
|
|
- set_fact:
|
|
pubkeydir: "/tmp/sshkeysign/{{inventory_hostname}}"
|
|
tags:
|
|
- basessh
|
|
- sshd_cert
|
|
- sshd_config
|
|
- config
|
|
- sshd
|
|
- base
|
|
|
|
- name: Create directory for storing pubkeys
|
|
file: path="{{pubkeydir}}"
|
|
owner=root
|
|
group=root
|
|
mode=0600
|
|
state=directory
|
|
delegate_to: localhost
|
|
run_once: true
|
|
changed_when: false
|
|
tags:
|
|
- basessh
|
|
- sshd_cert
|
|
- sshd_config
|
|
- config
|
|
- sshd
|
|
- base
|
|
|
|
- name: Get public keys for certs to sign
|
|
fetch: src="{{item}}.pub"
|
|
dest="{{pubkeydir}}"
|
|
fail_on_missing=false
|
|
with_items: "{{certs_to_sign}}"
|
|
tags:
|
|
- basessh
|
|
- sshd_cert
|
|
- sshd_config
|
|
- config
|
|
- sshd
|
|
- base
|
|
|
|
- name: Set some extra signing facts
|
|
set_fact:
|
|
sign_hostnames: "{{ssh_hostnames + [inventory_hostname]}}"
|
|
sign_validity: "-1h:+52w"
|
|
tags:
|
|
- basessh
|
|
- sshd_cert
|
|
- sshd_config
|
|
- config
|
|
- sshd
|
|
- base
|
|
|
|
# Currently, we use the epoch as serial. That's unique enough for now
|
|
- name: Sign the certificates
|
|
shell: "ssh-keygen -s {{private}}/files/ssh/{{env}}_ca_host_key -t rsa-sha2-256 -I {{inventory_hostname}} -h -n {{ sign_hostnames|join(',') }} -V {{sign_validity}} -z `date +%s` {{pubkeydir}}/{{inventory_hostname}}{{item}}.pub"
|
|
delegate_to: localhost
|
|
with_items: "{{certs_to_sign}}"
|
|
check_mode: no
|
|
tags:
|
|
- basessh
|
|
- sshd_cert
|
|
- sshd_config
|
|
- config
|
|
- sshd
|
|
- base
|
|
|
|
- name: Copy the certificates
|
|
copy: src="{{pubkeydir}}/{{inventory_hostname}}{{item}}-cert.pub"
|
|
dest="{{item}}-cert.pub"
|
|
with_items: "{{certs_to_sign}}"
|
|
register: certcopy
|
|
notify:
|
|
- restart sshd
|
|
tags:
|
|
- basessh
|
|
- sshd_cert
|
|
- sshd_config
|
|
- config
|
|
- sshd
|
|
- base
|
|
|
|
- name: Remove the generated certificates
|
|
local_action: file path="{{pubkeydir}}/{{inventory_hostname}}" state=absent
|
|
tags:
|
|
- basessh
|
|
- sshd_cert
|
|
- sshd_config
|
|
- config
|
|
- sshd
|
|
- base
|
|
|
|
- name: Restart sshd in case we just signed a new certificate so it gets applied
|
|
service: name=sshd state=restarted
|
|
when: certcopy.changed
|
|
tags:
|
|
- basessh
|
|
- sshd_cert
|
|
- sshd_config
|
|
- config
|
|
- sshd
|
|
- base
|
|
|
|
- name: make sure there is no old ssh host key for the host still around
|
|
local_action: known_hosts path={{item}} host={{ inventory_hostname }} state=absent
|
|
ignore_errors: true
|
|
with_items:
|
|
- /root/.ssh/known_hosts
|