From 808f039b0993e047bff9302d42bb03bcc15e92ad Mon Sep 17 00:00:00 2001 From: "J. Hunter Hawke" Date: Wed, 2 Feb 2022 18:54:55 +0100 Subject: [PATCH] Added some example ansible configs (#813) --- .../ansible/smallstep-certs/defaults/main.yml | 18 ++++++++ .../ansible/smallstep-certs/tasks/main.yml | 44 +++++++++++++++++++ .../smallstep-install/defaults/main.yml | 2 + .../ansible/smallstep-install/tasks/main.yml | 29 ++++++++++++ .../ansible/smallstep-ssh/defaults/main.yml | 8 ++++ examples/ansible/smallstep-ssh/tasks/main.yml | 41 +++++++++++++++++ 6 files changed, 142 insertions(+) create mode 100644 examples/ansible/smallstep-certs/defaults/main.yml create mode 100644 examples/ansible/smallstep-certs/tasks/main.yml create mode 100644 examples/ansible/smallstep-install/defaults/main.yml create mode 100644 examples/ansible/smallstep-install/tasks/main.yml create mode 100644 examples/ansible/smallstep-ssh/defaults/main.yml create mode 100644 examples/ansible/smallstep-ssh/tasks/main.yml diff --git a/examples/ansible/smallstep-certs/defaults/main.yml b/examples/ansible/smallstep-certs/defaults/main.yml new file mode 100644 index 00000000..b4de90c5 --- /dev/null +++ b/examples/ansible/smallstep-certs/defaults/main.yml @@ -0,0 +1,18 @@ + + + +# Root cert for each will be saved in /etc/ssl/smallstep/ca/{{ ca_name }}/certs/root_ca.crt +smallstep_root_certs: [] +# - +# ca_name: your_ca +# ca_url: "https://certs.your_ca.ca.smallstep.com" +# ca_fingerprint: "56092...2200" + +# Each leaf cert will be saved in /etc/ssl/smallstep/leaf/{{ cert_subject }}/{{ cert_subject }}.crt|key +smallstep_leaf_certs: [] +# - +# ca_name: your_ca +# cert_subject: "{{ inventory_hostname }}" +# provisioner_name: "admin" +# provisioner_password: "{{ smallstep_ssh_provisioner_password }}" + diff --git a/examples/ansible/smallstep-certs/tasks/main.yml b/examples/ansible/smallstep-certs/tasks/main.yml new file mode 100644 index 00000000..a80a72a1 --- /dev/null +++ b/examples/ansible/smallstep-certs/tasks/main.yml @@ -0,0 +1,44 @@ + +- name: "Ensure provisioners directories exist" + file: + path: "/etc/ssl/smallstep/provisioners/{{ item.context }}/{{ item.provisioner_name }}" + state: directory + mode: 0600 + owner: root + group: root + with_items: "{{ smallstep_leaf_certs }}" + no_log: true + +- name: "Ensure provisioner passwords are up to date" + copy: + dest: "/etc/ssl/smallstep/provisioners/{{ item.context }}/{{ item.provisioner_name }}/provisioner-pass.txt" + content: "{{ item.provisioner_password }}" + mode: 0700 + owner: root + group: root + with_items: "{{ smallstep_leaf_certs }}" + no_log: true + +- name: "Get root certs for CAs" + command: + cmd: "step ca bootstrap --context {{ item.context }} --ca-url {{ item.ca_url }} --fingerprint {{ item.ca_fingerprint }}" + with_items: "{{ smallstep_root_certs }}" + no_log: true + +- name: "Get leaf certs" + command: + cmd: "step ca certificate --context {{ item.context }} {{ item.cert_subject }} {{ item.cert_path }} {{ item.key_path }} --force --console --provisioner {{ item.provisioner_name }} --provisioner-password-file /etc/ssl/smallstep/provisioners/{{ item.context }}/{{ item.provisioner_name }}/provisioner-pass.txt" + with_items: "{{ smallstep_leaf_certs }}" + no_log: true + +- name: Ensure cron to renew leaf certs is up to date + cron: + user: "root" + name: "renew leaf cert {{ item.cert_subject }}" + cron_file: smallstep + job: "step ca renew --context {{ item.context }} {{ item.cert_path }} {{ item.key_path }} --expires-in 6h --force >> /var/log/smallstep-{{ item.cert_subject }}.log 2>&1" + state: present + minute: "*/30" + with_items: "{{ smallstep_leaf_certs }}" + when: "{{ item.cron_renew }}" + no_log: true diff --git a/examples/ansible/smallstep-install/defaults/main.yml b/examples/ansible/smallstep-install/defaults/main.yml new file mode 100644 index 00000000..b3b5f067 --- /dev/null +++ b/examples/ansible/smallstep-install/defaults/main.yml @@ -0,0 +1,2 @@ +smallstep_install_step_version: 0.15.3 +smallstep_install_step_ssh_version: 0.19.1-1 diff --git a/examples/ansible/smallstep-install/tasks/main.yml b/examples/ansible/smallstep-install/tasks/main.yml new file mode 100644 index 00000000..083a7333 --- /dev/null +++ b/examples/ansible/smallstep-install/tasks/main.yml @@ -0,0 +1,29 @@ + +# These steps automate the installation guide here: +# https://smallstep.com/docs/sso-ssh/hosts/ + +- name: Download step binary + get_url: + url: "https://files.smallstep.com/step-linux-{{ smallstep_install_step_version }}" + dest: "/usr/local/bin/step-{{ smallstep_install_step_version }}" + mode: '0755' + +- name: Link binaries to correct version + file: + src: "/usr/local/bin/step-{{ smallstep_install_step_version }}" + dest: "{{ item }}" + state: link + with_items: + - /usr/bin/step + - /usr/local/bin/step + +- name: Link /usr/local/bin/step to correct binary version + file: + src: "/usr/local/bin/step-{{ smallstep_install_step_version }}" + dest: /usr/local/bin/step + state: link + +- name: Ensure step-ssh is installed + apt: + deb: "https://files.smallstep.com/step-ssh_{{ smallstep_install_step_ssh_version }}_amd64.deb" + state: present diff --git a/examples/ansible/smallstep-ssh/defaults/main.yml b/examples/ansible/smallstep-ssh/defaults/main.yml new file mode 100644 index 00000000..ae358948 --- /dev/null +++ b/examples/ansible/smallstep-ssh/defaults/main.yml @@ -0,0 +1,8 @@ +# If this host is behind a bastion this variable should contain the hostname of the bastion +smallstep_ssh_host_behind_bastion_name: "" +smallstep_ssh_host_is_bastion: false +smallstep_ssh_ca_url: "https://ssh.mycompany.ca.smallstep.com" +smallstep_ssh_ca_fingerprint: "XXXXXXXXXXXXXXX" + +# Whether or not to reinitialize the host even if it's already been installed +smallstep_ssh_force_reinit: true diff --git a/examples/ansible/smallstep-ssh/tasks/main.yml b/examples/ansible/smallstep-ssh/tasks/main.yml new file mode 100644 index 00000000..e3389663 --- /dev/null +++ b/examples/ansible/smallstep-ssh/tasks/main.yml @@ -0,0 +1,41 @@ + +# These steps automate the installation guide here: +# https://smallstep.com/docs/sso-ssh/hosts/ + +# TODO: Figure out how to make this idempotent instead of reinstalling on each run + +- name: Bootstrap node to connect to CA + command: "step ca bootstrap --context ssh --ca-url {{ smallstep_ssh_ca_url }} --fingerprint {{ smallstep_ssh_ca_fingerprint }} --force" +# when: smallstep_ssh_installed.changed or smallstep_ssh_force_reinit + +- name: Get a host SSH certificate + command: "step ssh certificate --context ssh {{ inventory_hostname }} /etc/ssh/ssh_host_ecdsa_key.pub --host --sign --provisioner=\"Service Account\" --token=\"{{ smallstep_ssh_enrollment_token }}\" --force" +# when: smallstep_ssh_installed.changed or smallstep_ssh_force_reinit + +- name: Configure SSHD (will be overwriten by the sshd template in Ansible later) + command: "step ssh config --context ssh --host --set Certificate=ssh_host_ecdsa_key-cert.pub --set Key=ssh_host_ecdsa_key" +# when: smallstep_ssh_installed.changed or smallstep_ssh_force_reinit + +- name: Activate SmallStep PAM/NSS modules and nohup sshd + command: "step-ssh activate {{ inventory_hostname }}" +# when: smallstep_ssh_installed.changed or smallstep_ssh_force_reinit + +- name: Generate host tags list + set_fact: + smallstep_ssh_host_tags_string: "{{ smallstep_ssh_host_tags | to_json | regex_replace('\\:\\ ','=') | regex_replace('\\{\\\"|,\\ \\\"', ' --tag \"') | regex_replace('[\\[\\]{}]') }}" + +- name: Generate command to register + set_fact: + smallstep_ssh_register_string: | + step-ssh-ctl register + --hostname {{ inventory_hostname }} + {% if not smallstep_ssh_host_is_bastion %}--bastion '{{ smallstep_ssh_host_behind_bastion_name|default("") }}'{% endif %} + {% if smallstep_ssh_host_is_bastion %}--is-bastion{% endif %} + {{ smallstep_ssh_host_tags_string }} + +- debug: var=smallstep_ssh_register_string + +- name: Register host with smallstep + command: "{{ smallstep_ssh_register_string }}" +# when: smallstep_ssh_installed.changed or smallstep_ssh_force_reinit +