Initial commit
This commit is contained in:
commit
1296c4595b
82
README.md
Normal file
82
README.md
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
Generate TLS certificates
|
||||||
|
=========================
|
||||||
|
Generates self-signed CA, client and server certificates. Runs locally on control machine. **Note:** Ansible crypto modules do not support self-signed certs, using `shell` command instead as required.
|
||||||
|
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
- For server certificates, must specify Ansible inventory file; FQDN must also be set as hostname in inventory file
|
||||||
|
|
||||||
|
|
||||||
|
Role Variables
|
||||||
|
--------------
|
||||||
|
See `defaults/main.yml`
|
||||||
|
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
------------
|
||||||
|
- Refer to [Ansible Crypto modules](http://docs.ansible.com/ansible/latest/modules/list_of_crypto_modules.html)
|
||||||
|
|
||||||
|
|
||||||
|
Example Playbook
|
||||||
|
----------------
|
||||||
|
**generate-certs.yaml:**
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
# ansible-playbook generate-certs.yaml -i localhost,
|
||||||
|
# ansible-playbook generate-certs.yaml -i inventory.yaml
|
||||||
|
|
||||||
|
- hosts: all
|
||||||
|
|
||||||
|
gather_facts: false
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- include_vars: vars.yaml
|
||||||
|
|
||||||
|
- name: Generate certs
|
||||||
|
import_role:
|
||||||
|
name: generate-tls-certs
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**vars.yaml:**
|
||||||
|
```
|
||||||
|
---
|
||||||
|
cert_dir: ./certs
|
||||||
|
generate_ca_cert: true
|
||||||
|
generate_client_cert: true
|
||||||
|
generate_server_cert: true
|
||||||
|
|
||||||
|
# -------
|
||||||
|
# CA CERT
|
||||||
|
# -------
|
||||||
|
tls_ca_cert: my-ca.pem
|
||||||
|
tls_ca_csr: my-ca.csr
|
||||||
|
tls_ca_key: my-ca.key
|
||||||
|
tls_ca_country: CA
|
||||||
|
tls_ca_state: Ontario
|
||||||
|
tls_ca_locality: Toronto
|
||||||
|
tls_ca_organization: My Company Inc.
|
||||||
|
tls_ca_organizationalunit: IT
|
||||||
|
tls_ca_commonname: My Certificate Authority
|
||||||
|
|
||||||
|
# -----------
|
||||||
|
# CLIENT CERT
|
||||||
|
# -----------
|
||||||
|
tls_client_cert: my-client.pem
|
||||||
|
tls_client_key: my-client.key
|
||||||
|
tls_client_csr: my-client.csr
|
||||||
|
tls_client_commonname: My Client
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
BSD
|
||||||
|
|
||||||
|
|
||||||
|
Author Information
|
||||||
|
------------------
|
||||||
|
[EasyPath IT Solutions Inc.](https://www.easypath.ca)
|
44
defaults/main.yml
Normal file
44
defaults/main.yml
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
---
|
||||||
|
# defaults file for generate-tls-certs
|
||||||
|
|
||||||
|
# Do not put trailing slash "/"
|
||||||
|
cert_dir: ./certs
|
||||||
|
generate_ca_cert: false
|
||||||
|
generate_client_cert: false
|
||||||
|
generate_server_cert: false
|
||||||
|
|
||||||
|
# -------
|
||||||
|
# CA CERT
|
||||||
|
# -------
|
||||||
|
tls_ca_cert: ca.pem
|
||||||
|
tls_ca_csr: ca.csr
|
||||||
|
tls_ca_key: ca.key
|
||||||
|
tls_ca_key_size: 4096
|
||||||
|
# 10 years
|
||||||
|
tls_ca_valid_days: 3650
|
||||||
|
# tls_ca_country:
|
||||||
|
# tls_ca_state:
|
||||||
|
# tls_ca_locality:
|
||||||
|
# tls_ca_organization:
|
||||||
|
# tls_ca_organizationalunit:
|
||||||
|
tls_ca_commonname: Certificate Authority
|
||||||
|
#tls_ca_email:
|
||||||
|
|
||||||
|
# -----------
|
||||||
|
# CLIENT CERT
|
||||||
|
# -----------
|
||||||
|
tls_client_cert: client.pem
|
||||||
|
tls_client_key: client.key
|
||||||
|
tls_client_csr: client.csr
|
||||||
|
tls_client_key_size: 4096
|
||||||
|
tls_client_commonname: Client
|
||||||
|
tls_client_extfile: extfile-client.cnf
|
||||||
|
# 2 years
|
||||||
|
tls_client_valid_days: 730
|
||||||
|
|
||||||
|
# -----------
|
||||||
|
# SERVER CERT
|
||||||
|
# -----------
|
||||||
|
# 2 years
|
||||||
|
tls_server_valid_days: 730
|
||||||
|
tls_server_key_size: 4096
|
61
meta/main.yml
Normal file
61
meta/main.yml
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
galaxy_info:
|
||||||
|
author: Aman Babra
|
||||||
|
description: Generates self-signed CA, client and server certificates
|
||||||
|
company: EasyPath IT Solutions Inc.
|
||||||
|
|
||||||
|
# If the issue tracker for your role is not on github, uncomment the
|
||||||
|
# next line and provide a value
|
||||||
|
# issue_tracker_url: http://example.com/issue/tracker
|
||||||
|
|
||||||
|
# Some suggested licenses:
|
||||||
|
# - BSD (default)
|
||||||
|
# - MIT
|
||||||
|
# - GPLv2
|
||||||
|
# - GPLv3
|
||||||
|
# - Apache
|
||||||
|
# - CC-BY
|
||||||
|
license: BSD
|
||||||
|
|
||||||
|
min_ansible_version: 2.4
|
||||||
|
|
||||||
|
# If this a Container Enabled role, provide the minimum Ansible Container version.
|
||||||
|
# min_ansible_container_version:
|
||||||
|
|
||||||
|
# Optionally specify the branch Galaxy will use when accessing the GitHub
|
||||||
|
# repo for this role. During role install, if no tags are available,
|
||||||
|
# Galaxy will use this branch. During import Galaxy will access files on
|
||||||
|
# this branch. If Travis integration is configured, only notifications for this
|
||||||
|
# branch will be accepted. Otherwise, in all cases, the repo's default branch
|
||||||
|
# (usually master) will be used.
|
||||||
|
#github_branch:
|
||||||
|
|
||||||
|
#
|
||||||
|
# platforms is a list of platforms, and each platform has a name and a list of versions.
|
||||||
|
#
|
||||||
|
# platforms:
|
||||||
|
# - name: Fedora
|
||||||
|
# versions:
|
||||||
|
# - all
|
||||||
|
# - 25
|
||||||
|
# - name: SomePlatform
|
||||||
|
# versions:
|
||||||
|
# - all
|
||||||
|
# - 1.0
|
||||||
|
# - 7
|
||||||
|
# - 99.99
|
||||||
|
|
||||||
|
galaxy_tags:
|
||||||
|
- tls
|
||||||
|
- openssl
|
||||||
|
- certificates
|
||||||
|
- security
|
||||||
|
# List tags for your role here, one per line. A tag is a keyword that describes
|
||||||
|
# and categorizes the role. Users find roles by searching for tags. Be sure to
|
||||||
|
# remove the '[]' above, if you add tags to this list.
|
||||||
|
#
|
||||||
|
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
|
||||||
|
# Maximum 20 tags per role.
|
||||||
|
|
||||||
|
dependencies: []
|
||||||
|
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
|
||||||
|
# if you add dependencies to this list.
|
80
tasks/main.yml
Normal file
80
tasks/main.yml
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
---
|
||||||
|
# tasks file for generate-tls-certs
|
||||||
|
|
||||||
|
- name: Generate CA private key
|
||||||
|
local_action:
|
||||||
|
module: openssl_privatekey
|
||||||
|
path: "{{cert_dir}}/{{tls_ca_key}}"
|
||||||
|
size: "{{tls_ca_key_size}}"
|
||||||
|
run_once: true
|
||||||
|
when: generate_ca_cert
|
||||||
|
|
||||||
|
- name: Generate self-signed cert for CA
|
||||||
|
local_action:
|
||||||
|
module: >
|
||||||
|
shell 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 %}"
|
||||||
|
ignore_errors: true
|
||||||
|
run_once: true
|
||||||
|
when: generate_ca_cert
|
||||||
|
|
||||||
|
- name: Generate client private key
|
||||||
|
local_action:
|
||||||
|
module: openssl_privatekey
|
||||||
|
path: "{{cert_dir}}/{{tls_client_key}}"
|
||||||
|
size: "{{tls_client_key_size}}"
|
||||||
|
run_once: true
|
||||||
|
when: generate_client_cert
|
||||||
|
|
||||||
|
- name: Generate CSR and key for client cert
|
||||||
|
local_action:
|
||||||
|
module: >
|
||||||
|
shell openssl req -newkey rsa:{{tls_client_key_size}} -nodes -subj "/CN={{tls_client_commonname}}"
|
||||||
|
-keyout "{{cert_dir}}/{{tls_client_key}}" -out "{{cert_dir}}/{{tls_client_csr}}"
|
||||||
|
ignore_errors: true
|
||||||
|
run_once: true
|
||||||
|
when: generate_client_cert
|
||||||
|
|
||||||
|
- name: Add required extension for client authentication
|
||||||
|
local_action:
|
||||||
|
module: >
|
||||||
|
shell echo extendedKeyUsage = clientAuth >> {{cert_dir}}/{{tls_client_extfile}}
|
||||||
|
ignore_errors: true
|
||||||
|
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: Sign client cert request with CA
|
||||||
|
local_action:
|
||||||
|
module: >
|
||||||
|
shell openssl x509 -req -sha256 -days {{tls_client_valid_days}} -CA {{cert_dir}}/{{tls_ca_cert}} -CAkey {{cert_dir}}/{{tls_ca_key}}
|
||||||
|
-set_serial {{ 999999999 | random }} -in {{cert_dir}}/{{tls_client_csr}} -out {{cert_dir}}/{{tls_client_cert}} -extfile {{cert_dir}}/{{tls_client_extfile}}
|
||||||
|
ignore_errors: true
|
||||||
|
run_once: true
|
||||||
|
when: generate_client_cert
|
||||||
|
|
||||||
|
# Generate server cert
|
||||||
|
- name: Create CSR for server cert
|
||||||
|
local_action:
|
||||||
|
module: >
|
||||||
|
shell openssl req -newkey rsa:{{tls_server_key_size}} -nodes -subj "/CN={{inventory_hostname}}"
|
||||||
|
-keyout "{{cert_dir}}/{{inventory_hostname_short}}.key" -out "{{cert_dir}}/{{inventory_hostname_short}}.csr"
|
||||||
|
ignore_errors: true
|
||||||
|
when: generate_server_cert
|
||||||
|
|
||||||
|
- name: Generate certificate extensions file
|
||||||
|
local_action:
|
||||||
|
module: template
|
||||||
|
src: templates/server-cert-extfile.cnf.j2
|
||||||
|
dest: "{{cert_dir}}/{{inventory_hostname_short}}-extfile.cnf"
|
||||||
|
when: generate_server_cert
|
||||||
|
|
||||||
|
- name: Sign server cert request by CA
|
||||||
|
local_action:
|
||||||
|
module: >
|
||||||
|
shell 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"
|
||||||
|
-extfile "{{cert_dir}}/{{inventory_hostname_short}}-extfile.cnf"
|
||||||
|
ignore_errors: true
|
||||||
|
when: generate_server_cert
|
3
templates/server-cert-extfile.cnf.j2
Normal file
3
templates/server-cert-extfile.cnf.j2
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
subjectAltName = DNS:{{inventory_hostname}},DNS:{{inventory_hostname_short}},IP:{{(alt_interface_ip is defined) | ternary(alt_interface_ip, ansible_host)}},IP:0.0.0.0,IP:127.0.0.1
|
||||||
|
|
||||||
|
extendedKeyUsage = serverAuth
|
Loading…
Reference in New Issue
Block a user