-
Notifications
You must be signed in to change notification settings - Fork 2
/
get_certs.yml
150 lines (135 loc) · 5.34 KB
/
get_certs.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
---
- name: Get certificates
hosts: all
remote_user: root
vars_files: vars_with_secret.yml
vars:
acme_challenge_type: dns-01
acme_directory: https://acme-v02.api.letsencrypt.org/directory
acme_directory_test: https://acme-staging-v02.api.letsencrypt.org/directory
acme_version: 2
acme_email: [email protected]
letsencrypt_dir: /etc/letsencrypt
letsencrypt_keys_dir: /etc/letsencrypt/keys
letsencrypt_csrs_dir: /etc/letsencrypt/csrs
letsencrypt_certs_dir: /etc/letsencrypt/certs
letsencrypt_account_key: /etc/letsencrypt/account/account.key
api_url: "{{ 'https://api.digitalocean.com/v2/domains/'+dns_domain+'/records' }}"
dns_domain: egovstack.net
words: "{{ inventory_hostname.split('.') }}"
domain_name: "{{ words[0]+'.ext.'+'.'.join(words[1:]) }}"
domain_name_short: "{{ words[0]+'.ext' }}"
tasks:
- name: "Create required directories in /etc/letsencrypt"
file:
path: "/etc/letsencrypt/{{ item }}"
state: directory
owner: root
group: root
mode: u=rwx,g=x,o=x
with_items:
- account
- certs
- csrs
- keys
- name: "Generate a Let's Encrypt account key"
shell:
cmd: openssl genrsa 4096 | sudo tee {{ letsencrypt_account_key }}
creates: "{{ letsencrypt_account_key }}"
- name: "Generate Let's Encrypt private key"
shell:
cmd: openssl genrsa 4096 | sudo tee {{ letsencrypt_keys_dir }}/{{ domain_name }}.key
creates: "{{ letsencrypt_keys_dir }}/{{ domain_name }}.key"
- name: provide script for calculating subject alt name
copy:
content: |
LIST=
# for i in `ip addr | grep 'scope global' | tr '/' ' ' | awk '{print $2}'`; do LIST+="IP:$i,"; done; # LetsEncrypt do not certify IP
export ALT=${LIST}DNS:{{ domain_name }},DNS:{{ inventory_hostname }}
dest: "{{ letsencrypt_dir }}/fillALT.sh"
- name: provide conf for certificate request
copy:
content: |
default_md = sha256
[ req ]
default_bits = 2048
days = 7300
distinguished_name = req_distinguished_name
string_mask = utf8only
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
localityName = Locality Name (eg, city)
organizationalUnitName = Organizational Unit Name (eg, section)
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_max = 64
[ tls_alt ]
basicConstraints=critical,CA:TRUE,pathlen:0
keyUsage=nonRepudiation,keyEncipherment,digitalSignature,keyCertSign
subjectAltName=$ENV::ALT
dest: "{{ letsencrypt_dir }}/openssl.cnf"
- name: "Generate Let's Encrypt CSR"
shell: . {{ letsencrypt_dir }}/fillALT.sh; openssl req -new -nodes -out {{ letsencrypt_csrs_dir }}/{{ domain_name }}.csr -key {{ letsencrypt_keys_dir }}/{{ domain_name }}.key -config {{ letsencrypt_dir }}/openssl.cnf -subj "/CN={{ domain_name }}" -reqexts tls_alt
args:
executable: /bin/bash
- name: "Begin Let's Encrypt challenges"
acme_certificate:
acme_directory: "{{ acme_directory }}"
acme_version: "{{ acme_version }}"
account_key_src: "{{ letsencrypt_account_key }}"
account_email: "{{ acme_email }}"
terms_agreed: 1
challenge: "{{ acme_challenge_type }}"
csr: "{{ letsencrypt_csrs_dir }}/{{ domain_name }}.csr"
dest: "{{ letsencrypt_certs_dir }}/{{ domain_name }}.crt"
fullchain_dest: "{{ letsencrypt_certs_dir }}/fullchain_{{ domain_name }}.crt"
remaining_days: 91
register: acme_challenge_domain
- name: acme challenge domain debug
debug:
var: acme_challenge_domain
verbosity: 1
- name: add challenge address
uri:
method: POST
url: "{{ api_url }}"
headers:
authorization: Bearer {{ digital_ocean_token }}
body: '{{ api_body | to_json }}'
body_format: json
status_code: [200, 201]
vars:
record: "{{ item.value['dns-01'].record }}"
api_body:
type: TXT
name: "{{ record[:-(dns_domain | length)-1] }}"
data: "{{ item.value['dns-01'].resource_value }}"
loop: "{{ acme_challenge_domain.challenge_data | dict2items }}"
register: challenge_records
- name: POST result debug
debug:
var: challenge_records
verbosity: 1
- name: "Complete Let's Encrypt challenges"
acme_certificate:
acme_directory: "{{ acme_directory }}"
acme_version: "{{ acme_version }}"
account_key_src: "{{ letsencrypt_account_key }}"
account_email: "{{ acme_email }}"
challenge: "{{ acme_challenge_type }}"
csr: "{{ letsencrypt_csrs_dir }}/{{ domain_name }}.csr"
dest: "{{ letsencrypt_certs_dir }}/{{ domain_name }}.crt"
chain_dest: "{{ letsencrypt_certs_dir }}/chain_{{ domain_name }}.crt"
fullchain_dest: "{{ letsencrypt_certs_dir }}/fullchain_{{ domain_name }}"
data: "{{ acme_challenge_domain }}"
- name: delete challenge address
uri:
method: DELETE
url: "{{ api_url+'/'+(item.json.domain_record.id | string) }}"
headers:
authorization: Bearer {{ digital_ocean_token }}
status_code: [200, 204]
loop: "{{ challenge_records.results }}"
...