initial commit

This commit is contained in:
nd 2019-10-13 17:49:12 +02:00
commit ff1cfedadf
No known key found for this signature in database
GPG key ID: 21B5CD4DEE3670E9
6 changed files with 186 additions and 0 deletions

70
README.md Normal file
View 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
View 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
View 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

View 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 }}"

View 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
View 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