Update with community.crypto collection modules
This commit is contained in:
parent
9bf495b79c
commit
92391f3d52
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/.vagrant/
|
||||||
|
/certs/
|
35
Vagrantfile
vendored
Normal file
35
Vagrantfile
vendored
Normal 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
2
ansible.cfg
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[defaults]
|
||||||
|
roles_path = /root/.ansible/roles/:../
|
0
certs/.gitkeep
Normal file
0
certs/.gitkeep
Normal file
18
inventory.yml
Normal file
18
inventory.yml
Normal 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
5
playbook.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
- name: Run role
|
||||||
|
hosts: all
|
||||||
|
roles:
|
||||||
|
- role: generate-tls-certs
|
3
requirements.yml
Normal file
3
requirements.yml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
collections:
|
||||||
|
- community.crypto
|
|
@ -1,20 +1,65 @@
|
||||||
---
|
---
|
||||||
- name: Generate CA private key
|
- name: Check if the CA private key exists
|
||||||
local_action:
|
delegate_to: localhost
|
||||||
module: openssl_privatekey
|
ansible.builtin.stat:
|
||||||
path: "{{cert_dir}}/{{tls_ca_key}}"
|
path: "{{ cert_dir }}/{{ tls_ca_key }}"
|
||||||
size: "{{tls_ca_key_size}}"
|
register: ca_key
|
||||||
run_once: true
|
|
||||||
|
|
||||||
- name: Generate self-signed cert for CA
|
- name: Generate CA private key
|
||||||
local_action:
|
delegate_to: localhost
|
||||||
module: |
|
community.crypto.openssl_privatekey:
|
||||||
shell if [ ! -e {{cert_dir}}/{{tls_ca_cert}} ]
|
path: "{{ cert_dir }}/{{ tls_ca_key }}"
|
||||||
then
|
size: "{{ tls_ca_key_size }}"
|
||||||
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 %}"
|
|
||||||
fi
|
|
||||||
args:
|
|
||||||
executable: /bin/bash
|
|
||||||
ignore_errors: true
|
|
||||||
run_once: true
|
run_once: true
|
||||||
|
when: not ca_key.stat.exists
|
||||||
|
|
||||||
|
- name: Check if the CA CSR exists
|
||||||
|
delegate_to: localhost
|
||||||
|
stat:
|
||||||
|
path: "{{ cert_dir }}/{{ tls_ca_csr }}"
|
||||||
|
register: ca_csr
|
||||||
|
|
||||||
|
- name: Create CSR for CA
|
||||||
|
delegate_to: localhost
|
||||||
|
community.crypto.openssl_csr:
|
||||||
|
path: "{{ cert_dir }}/{{ tls_ca_csr }}"
|
||||||
|
privatekey_path: "{{ cert_dir }}/{{ tls_ca_key }}"
|
||||||
|
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
|
||||||
|
|
|
@ -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: Generate client private key
|
- name: Check if the client private key exists
|
||||||
local_action:
|
delegate_to: localhost
|
||||||
module: openssl_privatekey
|
stat:
|
||||||
path: "{{cert_dir}}/{{tls_client_key}}"
|
path: "{{ cert_dir }}/{{ tls_client_key }}"
|
||||||
size: "{{tls_client_key_size}}"
|
register: client_key
|
||||||
run_once: true
|
|
||||||
when: generate_client_cert
|
|
||||||
|
|
||||||
- name: Generate CSR and key for client cert
|
- name: Generate client private key
|
||||||
local_action:
|
delegate_to: localhost
|
||||||
module: |
|
community.crypto.openssl_privatekey:
|
||||||
shell if [ ! -e {{cert_dir}}/{{tls_client_csr}} ]
|
path: "{{ cert_dir }}/{{ tls_client_key }}"
|
||||||
then
|
size: "{{ tls_client_key_size}}"
|
||||||
openssl req -newkey rsa:{{tls_client_key_size}} -nodes -subj "/CN={{tls_client_commonname}}" \
|
when:
|
||||||
-keyout "{{cert_dir}}/{{tls_client_key}}" -out "{{cert_dir}}/{{tls_client_csr}}"
|
- not client_key.stat.exists
|
||||||
fi
|
- generate_client_cert
|
||||||
args:
|
register: client_key_file
|
||||||
executable: /bin/bash
|
|
||||||
ignore_errors: true
|
|
||||||
run_once: true
|
|
||||||
when: generate_client_cert
|
|
||||||
|
|
||||||
- name: Add required extension for client authentication
|
- name: Copy the key on the server
|
||||||
local_action:
|
become: yes
|
||||||
module: >
|
copy:
|
||||||
shell echo extendedKeyUsage = clientAuth >> {{cert_dir}}/{{tls_client_extfile}}
|
src: "{{ cert_dir }}/{{ tls_client_key}}"
|
||||||
ignore_errors: true
|
dest: /etc/ssl/local/certs/
|
||||||
run_once: true
|
mode: 0644
|
||||||
when: generate_client_cert
|
owner: root
|
||||||
|
group: root
|
||||||
|
when: client_key_file.changed
|
||||||
|
|
||||||
# @AB TODO: using OpenSSL CA serial file does not always generate unique serial when running playbook against multiple hosts
|
- name: Check if the client CSR exists
|
||||||
- name: Sign client cert request with CA
|
delegate_to: localhost
|
||||||
local_action:
|
stat:
|
||||||
module: |
|
path: "{{ cert_dir }}/{{ tls_client_csr }}"
|
||||||
shell if [ ! -e {{cert_dir}}/{{tls_client_cert}} ]
|
register: client_csr
|
||||||
then
|
|
||||||
openssl x509 -req -sha256 -days {{tls_client_valid_days}} -CA {{cert_dir}}/{{tls_ca_cert}} -CAkey {{cert_dir}}/{{tls_ca_key}} \
|
- name: Generate CSR and key for client cert
|
||||||
-set_serial {{ 999999999 | random }} -in {{cert_dir}}/{{tls_client_csr}} -out {{cert_dir}}/{{tls_client_cert}} -extfile {{cert_dir}}/{{tls_client_extfile}}
|
delegate_to: localhost
|
||||||
fi
|
community.crypto.openssl_csr:
|
||||||
args:
|
path: "{{ cert_dir }}/{{ tls_client_csr }}"
|
||||||
executable: /bin/bash
|
privatekey_path: "{{ cert_dir }}/{{ tls_client_key }}"
|
||||||
ignore_errors: true
|
common_name: "{{ tls_client_commonname }}"
|
||||||
run_once: true
|
extended_key_usage:
|
||||||
when: generate_client_cert
|
- clientAuth
|
||||||
|
when:
|
||||||
|
- not client_csr.stat.exists
|
||||||
|
- generate_client_cert
|
||||||
|
|
||||||
|
- name: Check if the client cert exists
|
||||||
|
delegate_to: localhost
|
||||||
|
stat:
|
||||||
|
path: "{{ cert_dir }}/{{ tls_client_cert }}"
|
||||||
|
register: client_crt
|
||||||
|
|
||||||
|
- name: Create and sign server cert request by CA
|
||||||
|
delegate_to: localhost
|
||||||
|
community.crypto.x509_certificate:
|
||||||
|
path: "{{ cert_dir }}/{{ tls_client_cert }}"
|
||||||
|
csr_path: "{{ cert_dir }}/{{ tls_client_csr }}"
|
||||||
|
ownca_not_after: "+{{ tls_client_valid_days }}d"
|
||||||
|
ownca_path: "{{ cert_dir }}/{{ tls_ca_cert }}"
|
||||||
|
ownca_privatekey_path: "{{ cert_dir }}/{{ tls_ca_key }}"
|
||||||
|
provider: ownca
|
||||||
|
when:
|
||||||
|
- not client_crt.stat.exists
|
||||||
|
- generate_client_cert
|
||||||
|
register: client_cert_file
|
||||||
|
|
||||||
|
- 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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -1,20 +1,19 @@
|
||||||
---
|
---
|
||||||
# tasks file for generate-tls-certs
|
# tasks file for generate-tls-certs
|
||||||
|
- name: Generate CA cert
|
||||||
- name: Generate CA cert
|
include_tasks: generate-ca-cert.yaml
|
||||||
import_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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user