initial commit
This commit is contained in:
commit
ff1cfedadf
6 changed files with 186 additions and 0 deletions
70
README.md
Normal file
70
README.md
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
# Certificates
|
||||||
|
|
||||||
|
This module creates and signs Certificates using multiple backends, including letsencrypt.
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
All configuration is to be placed inside the `certificates` dict.
|
||||||
|
|
||||||
|
```
|
||||||
|
# configuration for all backends, see below for options for all backends
|
||||||
|
backends:
|
||||||
|
letsencrypt: *letsencrypt-backend-config*
|
||||||
|
selfsigned: *selfsigned-backend-config*
|
||||||
|
|
||||||
|
# default options for certificates
|
||||||
|
defaults:
|
||||||
|
country: "SU"
|
||||||
|
province: "CYBER"
|
||||||
|
city: "Cyberspace"
|
||||||
|
org: "Tyrell Corporation"
|
||||||
|
mail: "example@example.com"
|
||||||
|
ou: "cyber"
|
||||||
|
cn: ~
|
||||||
|
san: []
|
||||||
|
|
||||||
|
# name: certificate name, value: config for a certificate. See below for definition
|
||||||
|
certs: *certificate-config*
|
||||||
|
```
|
||||||
|
|
||||||
|
**certificate-config:**
|
||||||
|
All settings here overwrite the default setting for a certificate.
|
||||||
|
```
|
||||||
|
# Country (string)
|
||||||
|
country: "SU"
|
||||||
|
|
||||||
|
# Province (string)
|
||||||
|
province: "CYBER"
|
||||||
|
|
||||||
|
# City (string)
|
||||||
|
city: "Cyberspace"
|
||||||
|
|
||||||
|
# Organisation (string)
|
||||||
|
org: "Tyrell Corporation"
|
||||||
|
|
||||||
|
# Mailaddress (string)
|
||||||
|
mail: "example@example.com"
|
||||||
|
|
||||||
|
# organizational unit name (string)
|
||||||
|
ou: "cyber"
|
||||||
|
|
||||||
|
# common name (string), will be set to first SAN if set to None
|
||||||
|
cn: ~
|
||||||
|
|
||||||
|
# subject alt names (list of strings)
|
||||||
|
san: []
|
||||||
|
```
|
||||||
|
|
||||||
|
### Backends
|
||||||
|
#### Letsencrypt
|
||||||
|
#### Selfsigned
|
||||||
|
|
||||||
|
## Paths
|
||||||
|
|
||||||
|
Certificates are stored at a defined location:
|
||||||
|
|
||||||
|
* key: `/etc/ssl/private/<cetname>.key`
|
||||||
|
* certificate: `/etc/ssl/<certname>.crt`
|
||||||
|
* CSR: `/etc/ssl/<certname>.csr`
|
||||||
|
* chain: `/etc/ssl/<certname>.chain.crt`
|
||||||
|
* key, certificate and chain combined: `/etc/ssl/private/<certname>.complete.pem`
|
||||||
16
defaults/main.yml
Normal file
16
defaults/main.yml
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
certificates:
|
||||||
|
backends:
|
||||||
|
letsencrypt:
|
||||||
|
remainingdays: 28
|
||||||
|
challange: dns-01
|
||||||
|
challangeserver: []
|
||||||
|
selfsigned: ~
|
||||||
|
defaults:
|
||||||
|
country: "SU"
|
||||||
|
province: "CYBER"
|
||||||
|
city: "Cyberspace"
|
||||||
|
org: "Tyrell Corporation"
|
||||||
|
mail: "example@example.com"
|
||||||
|
ou: "cyber"
|
||||||
|
cn: ~
|
||||||
|
certs: {}
|
||||||
33
tasks/common_cert.yml
Normal file
33
tasks/common_cert.yml
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
- set_fact:
|
||||||
|
basepath: "/etc/ssl"
|
||||||
|
- set_fact:
|
||||||
|
cert_paths:
|
||||||
|
csrpath: "{{ basepath + '/' + certname + '.csr' }}"
|
||||||
|
keypath: "{{ basepath + '/private/' + certname + '.key' }}"
|
||||||
|
certpath: "{{ basepath + '/' + certname + '.crt' }}"
|
||||||
|
chainpath: "{{ basepath + '/' + certname + '.chain.crt' }}"
|
||||||
|
fullpath: "{{ basepath + '/private/' + certname + '.complete.pem' }}"
|
||||||
|
- set_fact:
|
||||||
|
cert: "{{ certificates.defaults|combine(cert_paths, certificates.certs[certname]|d({}), {'name': certname} ) }}"
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
verbosity: 1
|
||||||
|
var: cert
|
||||||
|
|
||||||
|
- name: "generate key for {{ certname }}"
|
||||||
|
openssl_privatekey:
|
||||||
|
path: "{{ cert.keypath }}"
|
||||||
|
size: 4096
|
||||||
|
type: RSA
|
||||||
|
mode: 0640
|
||||||
|
owner: root
|
||||||
|
group: ssl-cert
|
||||||
|
|
||||||
|
- name: "generate csr for {{ certname }}"
|
||||||
|
openssl_csr:
|
||||||
|
path: "{{ cert.csrpath }}"
|
||||||
|
privatekey_path: "{{ cert.keypath }}"
|
||||||
|
common_name: "{% if cert.cn %}{{ cert.cn }}{% else %}{{ cert.san[0] }}{% endif %}"
|
||||||
|
subject_alt_name: "{{ cert.san | map('regex_replace', '^', 'DNS:') | list }}"
|
||||||
|
register: task_generate_csr
|
||||||
|
|
||||||
36
tasks/letsencrypt_cert.yml
Normal file
36
tasks/letsencrypt_cert.yml
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
- include_tasks: common_cert.yml
|
||||||
|
|
||||||
|
- name: "get challange for {{ certname }}"
|
||||||
|
acme_certificate: &acmetask
|
||||||
|
force: "{{ task_generate_csr is changed }}"
|
||||||
|
acme_version: 2
|
||||||
|
terms_agreed: yes
|
||||||
|
acme_directory: "https://acme-v02.api.letsencrypt.org/directory"
|
||||||
|
account_key: /etc/ssl/letsencrypt_account.key
|
||||||
|
csr: "{{ cert.csrpath }}"
|
||||||
|
dest: "{{ cert.certpath }}"
|
||||||
|
fullchain_dest: "{{ cert.chainpath }}"
|
||||||
|
remaining_days: "{{ certificates.backends.letsencrypt.remainingdays }}"
|
||||||
|
challenge: "{{ certificates.backends.letsencrypt.challange }}"
|
||||||
|
register: challenge
|
||||||
|
|
||||||
|
- name: "setup challenge server for {{ certname }} (dns challange)"
|
||||||
|
when:
|
||||||
|
- challenge is changed
|
||||||
|
- certificates.backends.letsencrypt.challange == "dns-01"
|
||||||
|
delegate_to: "{{ item.0 }}"
|
||||||
|
loop: "{{ certificates.backends.letsencrypt.challangeserver|product(challenge.challenge_data.keys()|list)|list }}"
|
||||||
|
command:
|
||||||
|
argv:
|
||||||
|
- "/usr/local/bin/pdns.py"
|
||||||
|
- "{{ challenge.challenge_data[item.1]['dns-01'].record }}"
|
||||||
|
- "{{ challenge.challenge_data[item.1]['dns-01'].resource_value }}"
|
||||||
|
|
||||||
|
- name: "setup challenge server for {{ certname }} (http challange)"
|
||||||
|
debug: msg=a
|
||||||
|
|
||||||
|
|
||||||
|
- name: "get certificate {{ certname }}"
|
||||||
|
acme_certificate:
|
||||||
|
<<: *acmetask
|
||||||
|
data: "{{ challenge }}"
|
||||||
7
tasks/letsencrypt_setup.yml
Normal file
7
tasks/letsencrypt_setup.yml
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
- name: generate letsencrypt account key
|
||||||
|
openssl_privatekey:
|
||||||
|
path: /etc/ssl/letsencrypt_account.key
|
||||||
|
size: 4096
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0600
|
||||||
24
tasks/main.yml
Normal file
24
tasks/main.yml
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
- name: install crypto dependencies
|
||||||
|
apt:
|
||||||
|
pkg:
|
||||||
|
- openssl
|
||||||
|
- python3-openssl
|
||||||
|
- python3-cryptography
|
||||||
|
|
||||||
|
- name: add group ssl-cert
|
||||||
|
group:
|
||||||
|
name: ssl-cert
|
||||||
|
system: true
|
||||||
|
|
||||||
|
- name: set private folder owner
|
||||||
|
file:
|
||||||
|
path: /etc/ssl/private
|
||||||
|
mode: 0750
|
||||||
|
owner: root
|
||||||
|
group: ssl-cert
|
||||||
|
|
||||||
|
- import_tasks: letsencrypt_setup.yml
|
||||||
|
- include_tasks: "{{ certificates.certs[certname].backend|default(certificates.defaults.backend) }}_cert.yml"
|
||||||
|
loop: "{{ certificates.certs.keys()|list }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: certname
|
||||||
Loading…
Add table
Add a link
Reference in a new issue