Update with community.crypto collection modules

This commit is contained in:
sfigato 2021-01-24 00:20:24 +01:00
parent 9bf495b79c
commit 92391f3d52
Signed by: blallo
GPG Key ID: 0CBE577C9B72DC3F
11 changed files with 318 additions and 110 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/.vagrant/
/certs/

35
Vagrantfile vendored Normal file
View File

@ -0,0 +1,35 @@
# This guide is optimized for Vagrant 1.7 and above.
# Although versions 1.6.x should behave very similarly, it is recommended
# to upgrade instead of disabling the requirement below.
Vagrant.require_version ">= 1.7.0"
Vagrant.configure(2) do |config|
config.vm.box = "debian/buster64"
config.vm.synced_folder ".", "/vagrant", disabled: true
# Disable the new default behavior introduced in Vagrant 1.7, to
# ensure that all Vagrant machines will use the same SSH key pair.
# See https://github.com/mitchellh/vagrant/issues/5005
config.ssh.insert_key = false
config.vm.provider :libvirt do |lv|
lv.cpus = 1
lv.memory = 512
end
config.vm.define "srv1" do |m|
m.vm.hostname = "srv1"
m.vm.network :private_network, ip: "192.168.123.30", libvirt__dhcp_enabled: false
end
config.vm.define "srv2" do |m|
m.vm.hostname = "srv2"
m.vm.network :private_network, ip: "192.168.123.31", libvirt__dhcp_enabled: false
end
config.vm.provision "ansible" do |ansible|
#ansible.become = true
ansible.verbose = "v"
ansible.playbook = "playbook.yml"
ansible.inventory_path = "inventory.yml"
end
end

2
ansible.cfg Normal file
View File

@ -0,0 +1,2 @@
[defaults]
roles_path = /root/.ansible/roles/:../

0
certs/.gitkeep Normal file
View File

18
inventory.yml Normal file
View File

@ -0,0 +1,18 @@
---
all:
hosts:
srv1:
ansible_host: 192.168.123.30
srv2:
ansible_host: 192.168.123.31
vars:
cert_dir: ./certs
generate_ca_cert: true
generate_client_cert: true
generate_server_cert: true
tls_ca_email: me@example.org
tls_ca_country: EU
tls_ca_state: Italy
tls_ca_locality: Rome
tls_ca_organization: Example Inc.
tls_ca_organizationalunit: SysAdmins

5
playbook.yml Normal file
View File

@ -0,0 +1,5 @@
---
- name: Run role
hosts: all
roles:
- role: generate-tls-certs

3
requirements.yml Normal file
View File

@ -0,0 +1,3 @@
---
collections:
- community.crypto

View File

@ -1,20 +1,65 @@
--- ---
- name: Check if the CA private key exists
delegate_to: localhost
ansible.builtin.stat:
path: "{{ cert_dir }}/{{ tls_ca_key }}"
register: ca_key
- name: Generate CA private key - name: Generate CA private key
local_action: delegate_to: localhost
module: openssl_privatekey community.crypto.openssl_privatekey:
path: "{{ cert_dir }}/{{ tls_ca_key }}" path: "{{ cert_dir }}/{{ tls_ca_key }}"
size: "{{ tls_ca_key_size }}" size: "{{ tls_ca_key_size }}"
run_once: true run_once: true
when: not ca_key.stat.exists
- name: Generate self-signed cert for CA - name: Check if the CA CSR exists
local_action: delegate_to: localhost
module: | stat:
shell if [ ! -e {{cert_dir}}/{{tls_ca_cert}} ] path: "{{ cert_dir }}/{{ tls_ca_csr }}"
then register: ca_csr
openssl req -x509 -new -days {{tls_ca_valid_days}} -sha256 -nodes -key {{cert_dir}}/{{tls_ca_key}} -out {{cert_dir}}/{{tls_ca_cert}} \
-subj "{% if tls_ca_country is defined%}/C={{tls_ca_country}}{% endif %}{% if tls_ca_state is defined%}/ST={{tls_ca_state}}{% endif %}{% if tls_ca_locality is defined %}/L={{tls_ca_locality}}{% endif %}{% if tls_ca_organization is defined %}/O={{tls_ca_organization}}{% endif %}{% if tls_ca_organizationalunit is defined %}/OU={{tls_ca_organizationalunit}}{% endif %}/CN={{tls_ca_commonname}}{% if tls_ca_email is defined %}/emailAddress={{tls_ca_email}}{% endif %}" - name: Create CSR for CA
fi delegate_to: localhost
args: community.crypto.openssl_csr:
executable: /bin/bash path: "{{ cert_dir }}/{{ tls_ca_csr }}"
ignore_errors: true privatekey_path: "{{ cert_dir }}/{{ tls_ca_key }}"
run_once: true basic_constraints:
- "CA:TRUE"
common_name: "{{ tls_ca_commonname|default('') }}"
country_name: "{{ tls_ca_country|default('') }}"
state_or_province_name: "{{ tls_ca_state|default('') }}"
locality_name: "{{ tls_ca_locality|default('') }}"
organization_name: "{{ tls_ca_organization|default('') }}"
organizational_unit_name: "{{ tls_ca_organizationalunit|default('') }}"
email_address: "{{ tls_ca_email }}"
use_common_name_for_san: no
when: not ca_csr.stat.exists
- name: Check if the CA cert exists
delegate_to: localhost
stat:
path: "{{ cert_dir }}/{{ tls_ca_cert }}"
register: ca_cert
- name: Create and sign server cert for CA
delegate_to: localhost
community.crypto.x509_certificate:
path: "{{ cert_dir }}/{{ tls_ca_cert }}"
privatekey_path: "{{ cert_dir }}/{{ tls_ca_key }}"
csr_path: "{{ cert_dir }}/{{ tls_ca_csr }}"
selfsigned_not_after: "+{{ tls_ca_valid_days }}d"
provider: selfsigned
when: not ca_cert.stat.exists
register: ca_cert_file
- name: Copy the CA certificate to the remote machine
copy:
src: "{{ cert_dir }}/{{ tls_ca_cert }}"
dest: /etc/ssl/certs/
mode: 0644
owner: root
group: root
force: yes
backup: yes
when: ca_cert_file.changed

View File

@ -1,46 +1,87 @@
--- ---
- name: Ensure the custom directories to host certificates are present
become: yes
file:
state: directory
recurse: yes
path: "/etc/ssl/{{ item.path }}"
mode: "{{ item.mode }}"
owner: root
group: root
loop:
- {path: local/certs, mode: "0755"}
- {path: local/private, mode: "0700"}
- name: Check if the client private key exists
delegate_to: localhost
stat:
path: "{{ cert_dir }}/{{ tls_client_key }}"
register: client_key
- name: Generate client private key - name: Generate client private key
local_action: delegate_to: localhost
module: openssl_privatekey community.crypto.openssl_privatekey:
path: "{{ cert_dir }}/{{ tls_client_key }}" path: "{{ cert_dir }}/{{ tls_client_key }}"
size: "{{ tls_client_key_size}}" size: "{{ tls_client_key_size}}"
run_once: true when:
when: generate_client_cert - not client_key.stat.exists
- generate_client_cert
register: client_key_file
- name: Copy the key on the server
become: yes
copy:
src: "{{ cert_dir }}/{{ tls_client_key}}"
dest: /etc/ssl/local/certs/
mode: 0644
owner: root
group: root
when: client_key_file.changed
- name: Check if the client CSR exists
delegate_to: localhost
stat:
path: "{{ cert_dir }}/{{ tls_client_csr }}"
register: client_csr
- name: Generate CSR and key for client cert - name: Generate CSR and key for client cert
local_action: delegate_to: localhost
module: | community.crypto.openssl_csr:
shell if [ ! -e {{cert_dir}}/{{tls_client_csr}} ] path: "{{ cert_dir }}/{{ tls_client_csr }}"
then privatekey_path: "{{ cert_dir }}/{{ tls_client_key }}"
openssl req -newkey rsa:{{tls_client_key_size}} -nodes -subj "/CN={{tls_client_commonname}}" \ common_name: "{{ tls_client_commonname }}"
-keyout "{{cert_dir}}/{{tls_client_key}}" -out "{{cert_dir}}/{{tls_client_csr}}" extended_key_usage:
fi - clientAuth
args: when:
executable: /bin/bash - not client_csr.stat.exists
ignore_errors: true - generate_client_cert
run_once: true
when: generate_client_cert
- name: Add required extension for client authentication - name: Check if the client cert exists
local_action: delegate_to: localhost
module: > stat:
shell echo extendedKeyUsage = clientAuth >> {{cert_dir}}/{{tls_client_extfile}} path: "{{ cert_dir }}/{{ tls_client_cert }}"
ignore_errors: true register: client_crt
run_once: true
when: generate_client_cert
# @AB TODO: using OpenSSL CA serial file does not always generate unique serial when running playbook against multiple hosts - name: Create and sign server cert request by CA
- name: Sign client cert request with CA delegate_to: localhost
local_action: community.crypto.x509_certificate:
module: | path: "{{ cert_dir }}/{{ tls_client_cert }}"
shell if [ ! -e {{cert_dir}}/{{tls_client_cert}} ] csr_path: "{{ cert_dir }}/{{ tls_client_csr }}"
then ownca_not_after: "+{{ tls_client_valid_days }}d"
openssl x509 -req -sha256 -days {{tls_client_valid_days}} -CA {{cert_dir}}/{{tls_ca_cert}} -CAkey {{cert_dir}}/{{tls_ca_key}} \ ownca_path: "{{ cert_dir }}/{{ tls_ca_cert }}"
-set_serial {{ 999999999 | random }} -in {{cert_dir}}/{{tls_client_csr}} -out {{cert_dir}}/{{tls_client_cert}} -extfile {{cert_dir}}/{{tls_client_extfile}} ownca_privatekey_path: "{{ cert_dir }}/{{ tls_ca_key }}"
fi provider: ownca
args: when:
executable: /bin/bash - not client_crt.stat.exists
ignore_errors: true - generate_client_cert
run_once: true register: client_cert_file
when: generate_client_cert
- name: Copy the certificate to the remote machine
become: yes
copy:
src: "{{ cert_dir }}/{{ tls_client_cert }}"
dest: /etc/ssl/local/private
mode: 0600
owner: root
group: root
when: client_cert_file.changed

View File

@ -1,38 +1,96 @@
--- ---
# Generate server cert - name: Ensure the custom directories to host certificates are present
- name: Create CSR for server cert become: yes
local_action: file:
module: | state: directory
shell if [ ! -e {{cert_dir}}/{{inventory_hostname_short}}.csr ] recurse: yes
then path: "/etc/ssl/{{ item.path }}"
openssl req -newkey rsa:{{tls_server_key_size}} -nodes -subj "/CN={{inventory_hostname}}" \ mode: "{{ item.mode }}"
-keyout "{{cert_dir}}/{{inventory_hostname_short}}.key" -out "{{cert_dir}}/{{inventory_hostname_short}}.csr" owner: root
fi group: root
args: loop:
executable: /bin/bash - {path: local/certs, mode: "0755"}
ignore_errors: true - {path: local/private, mode: "0700"}
when: generate_server_cert
- name: Generate certificate extensions file - name: Check if the server private key exists
local_action: delegate_to: localhost
module: template stat:
src: templates/server-cert-extfile.cnf.j2 path: "{{ cert_dir }}/{{ inventory_hostname_short }}.key"
dest: "{{cert_dir}}/{{inventory_hostname_short}}-extfile.cnf" register: server_key
- name: Create PEM private key for server
delegate_to: localhost
community.crypto.openssl_privatekey:
path: "{{ cert_dir }}/{{ inventory_hostname_short }}.key"
when: not server_key.stat.exists
register: server_key_file
- name: Copy the key on the server
become: yes
copy:
src: "{{ cert_dir }}/{{ inventory_hostname_short }}.key"
dest: /etc/ssl/local/certs/
mode: 0644
owner: root
group: root
when: server_key_file.changed
- name: Check if the server CSR exists
delegate_to: localhost
stat:
path: "{{ cert_dir }}/{{ inventory_hostname_short }}.csr"
register: server_csr
- name: Create CSR for server cert
delegate_to: localhost
community.crypto.openssl_csr:
path: "{{ cert_dir }}/{{ inventory_hostname_short }}.csr"
privatekey_path: "{{ cert_dir }}/{{ inventory_hostname_short }}.key"
common_name: "{{ inventory_hostname_short }}"
when: when:
- not server_csr.stat.exists
- generate_server_cert
- not tls_server_enable_san
- name: Create CSR for server cert
delegate_to: localhost
community.crypto.openssl_csr:
path: "{{ cert_dir }}/{{ inventory_hostname_short }}.csr"
privatekey_path: "{{ cert_dir }}/{{ inventory_hostname_short }}.key"
common_name: "{{inventory_hostname_short}}"
subject_alt_name: "DNS:{{inventory_hostname}},DNS:{{inventory_hostname_short}},IP:{{(alt_interface_ip is defined) | ternary(alt_interface_ip, ansible_default_ipv4.address)}},IP:0.0.0.0,IP:127.0.0.1"
when:
- not server_csr.stat.exists
- generate_server_cert - generate_server_cert
- tls_server_enable_san - tls_server_enable_san
- name: Sign server cert request by CA - name: Check if the server cert exists
local_action: delegate_to: localhost
module: | stat:
shell if [ ! -e {{cert_dir}}/{{inventory_hostname_short}}.pem ] path: "{{ cert_dir }}/{{ inventory_hostname_short }}.pem"
then register: server_crt
openssl x509 -req -sha256 -days {{tls_server_valid_days}} \
-CA "{{cert_dir}}/{{tls_ca_cert}}" -CAkey "{{cert_dir}}/{{tls_ca_key}}" -set_serial {{ 999999999 | random }} \
-in "{{cert_dir}}/{{inventory_hostname_short}}.csr" -out "{{cert_dir}}/{{inventory_hostname_short}}.pem" {% if tls_server_enable_san %}-extfile "{{cert_dir}}/{{inventory_hostname_short}}-extfile.cnf"{% endif %}
fi - name: Create and sign server cert request by CA
args: delegate_to: localhost
executable: /bin/bash community.crypto.x509_certificate:
path: "{{ cert_dir }}/{{ inventory_hostname_short }}.pem"
csr_path: "{{ cert_dir }}/{{ inventory_hostname_short }}.csr"
ownca_not_after: "+{{ tls_server_valid_days }}d"
ownca_path: "{{ cert_dir }}/{{ tls_ca_cert }}"
ownca_privatekey_path: "{{ cert_dir }}/{{ tls_ca_key }}"
provider: ownca
ignore_errors: true ignore_errors: true
when: generate_server_cert when:
- not server_crt.stat.exists
- generate_server_cert
register: server_cert_file
- name: Copy the certificate to the remote machine
become: yes
copy:
src: "{{ cert_dir }}/{{ inventory_hostname_short }}.pem"
dest: /etc/ssl/local/private
mode: 0600
owner: root
group: root
when: server_cert_file.changed

View File

@ -1,20 +1,19 @@
--- ---
# tasks file for generate-tls-certs # tasks file for generate-tls-certs
- name: Generate CA cert - name: Generate CA cert
import_tasks: generate-ca-cert.yaml include_tasks: generate-ca-cert.yaml
when: when:
- generate_tls_certs - generate_tls_certs
- generate_ca_cert|bool - generate_ca_cert|bool
- name: Generate client cert - name: Generate client cert
import_tasks: generate-client-cert.yaml include_tasks: generate-client-cert.yaml
when: when:
- generate_tls_certs - generate_tls_certs
- generate_client_cert|bool - generate_client_cert|bool
- name: Generate server cert - name: Generate server cert
import_tasks: generate-server-cert.yaml include_tasks: generate-server-cert.yaml
when: when:
- generate_tls_certs - generate_tls_certs
- generate_server_cert|bool - generate_server_cert|bool