Browse Source

Add feature Letsencrypt SSL certification

- installs certbot-auto
- generates and validates ssl cert
- installs cert in haproxy settings
- renew cert with cron

Change-Id: Iea59ec2893a988b184ca8bc70e1d273ac071551e
Frank Kloeker 8 months ago
parent
commit
4fb2059a3b

+ 9
- 0
defaults/main.yml View File

@@ -71,6 +71,15 @@ haproxy_ssl_ca_cert: /etc/ssl/certs/haproxy-ca.pem
71 71
 haproxy_ssl_self_signed_subject: "/C=US/ST=Texas/L=San Antonio/O=IT/CN={{ external_lb_vip_address }}/subjectAltName=IP.1={{ external_lb_vip_address }}"
72 72
 haproxy_ssl_cipher_suite: "{{ ssl_cipher_suite | default('ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS') }}"
73 73
 haproxy_ssl_bind_options: "force-tlsv12"
74
+# activate letsencrypt option
75
+haproxy_ssl_letsencrypt_enable: false
76
+haproxy_ssl_letsencrypt_email: "example@example.com"
77
+haproxy_ssl_letsencrypt_download_url: "https://dl.eff.org/certbot-auto"
78
+haproxy_ssl_letsencrypt_config_path: "/etc/letsencrypt/live"
79
+haproxy_ssl_letsencrypt_install_path: "/opt/letsencrypt"
80
+haproxy_ssl_letsencrypt_cron_minute: "0"
81
+haproxy_ssl_letsencrypt_cron_hour: "0"
82
+haproxy_ssl_letsencrypt_cron_weekday: "0"
74 83
 
75 84
 # hatop extra package URL and checksum
76 85
 haproxy_hatop_download_url: "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/hatop/hatop-0.7.7.tar.gz"

+ 19
- 0
doc/source/configure-haproxy.rst View File

@@ -143,6 +143,25 @@ be folded and formatted at 64 characters long. Single line certificates
143 143
 will not be accepted by HAProxy and will result in SSL validation failures.
144 144
 Please have a look here for information on `converting your certificate to
145 145
 various formats <https://search.thawte.com/support/ssl-digital-certificates/index?page=content&actp=CROSSLINK&id=SO26449>`_.
146
+If you want to use `LetsEncrypt SSL Service <https://letsencrypt.org/>`_
147
+you can activate the feature by providing the following configuration in
148
+``/etc/openstack_deploy/user_variables.yml``. Note that this requires
149
+that ``external_lb_vip_address`` in
150
+``/etc/openstack_deploy/openstack_user_config.yml`` is set to the
151
+external DNS address.
152
+
153
+.. code-block:: yaml
154
+
155
+   haproxy_ssl_letsencrypt_enable: true
156
+   haproxy_ssl_letsencrypt_email: example@example.com
157
+
158
+.. warning::
159
+
160
+   There is no certificate distribution implementation at this time, so
161
+   this will only work for a single haproxy-server environment.  The
162
+   renewal is automatically handled via CRON and currently will shut
163
+   down haproxy briefly during the certificate renewal.  The
164
+   haproxy shutdown/restart will result in a brief service interruption.
146 165
 
147 166
 .. _Securing services with SSL certificates: http://docs.openstack.org/project-deploy-guide/openstack-ansible/draft/app-advanced-config-sslcertificates.html
148 167
 

+ 10
- 0
releasenotes/notes/letsencrypt-ssl-certification-129a80cb88d8e6ff.yaml View File

@@ -0,0 +1,10 @@
1
+---
2
+features:
3
+  - |
4
+    If Horizon dashboard of OSA installation has a public FQDN, is it
5
+    now possible to use LetsEncrypt certification service. Certificate
6
+    will be generated within HAProxy installation and a cron entry to
7
+    renew the certificate daily will be setup.
8
+    Note that there is no certificate distribution implementation at
9
+    this time, so this will only work for a single haproxy-server
10
+    environment.

+ 7
- 0
tasks/haproxy_ssl.yml View File

@@ -23,6 +23,13 @@
23 23
 - include_tasks: haproxy_ssl_self_signed.yml
24 24
   when:
25 25
     - haproxy_ssl | bool
26
+    - not haproxy_ssl_letsencrypt_enable | bool
27
+    - haproxy_user_ssl_cert is not defined or haproxy_user_ssl_key is not defined
28
+
29
+- include_tasks: haproxy_ssl_letsencrypt.yml
30
+  when:
31
+    - haproxy_ssl | bool
32
+    - haproxy_ssl_letsencrypt_enable | bool
26 33
     - haproxy_user_ssl_cert is not defined or haproxy_user_ssl_key is not defined
27 34
 
28 35
 - include_tasks: haproxy_ssl_user_provided.yml

+ 79
- 0
tasks/haproxy_ssl_letsencrypt.yml View File

@@ -0,0 +1,79 @@
1
+---
2
+# Licensed under the Apache License, Version 2.0 (the "License");
3
+# you may not use this file except in compliance with the License.
4
+# You may obtain a copy of the License at
5
+#
6
+#     http://www.apache.org/licenses/LICENSE-2.0
7
+#
8
+# Unless required by applicable law or agreed to in writing, software
9
+# distributed under the License is distributed on an "AS IS" BASIS,
10
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+# See the License for the specific language governing permissions and
12
+# limitations under the License.
13
+
14
+- name: Ensure haproxy_ssl_letsencrypt_install_path exists
15
+  file:
16
+    path: "{{ haproxy_ssl_letsencrypt_install_path }}"
17
+    state: directory
18
+
19
+- name: Download certbot
20
+  get_url:
21
+    url: "{{ haproxy_ssl_letsencrypt_download_url }}"
22
+    dest: "{{ haproxy_ssl_letsencrypt_install_path }}"
23
+    mode: 0755
24
+  register: fetch_url
25
+  until: fetch_url is success
26
+  retries: 3
27
+  delay: 10
28
+
29
+- name: Ensure file permissions certbot-auto
30
+  file:
31
+    path: "{{ haproxy_ssl_letsencrypt_install_path }}/{{ haproxy_ssl_letsencrypt_download_url | basename }}"
32
+
33
+- name: Register Letsencrypt data dir
34
+  stat:
35
+    path: "{{ haproxy_ssl_letsencrypt_config_path }}/{{ external_lb_vip_address }}"
36
+  register: lcdatadir
37
+
38
+- name: Stop haproxy for certbot activity
39
+  service:
40
+    name: "haproxy"
41
+    state: "stopped"
42
+  when: lcdatadir.stat.exists == False
43
+
44
+- name: Create ssl cert with certbot
45
+  command: >
46
+    {{ haproxy_ssl_letsencrypt_install_path }}/{{ haproxy_ssl_letsencrypt_download_url | basename }} certonly
47
+    --standalone
48
+    --agree-tos
49
+    --non-interactive
50
+    --text
51
+    --rsa-key-size 4096
52
+    --email {{ haproxy_ssl_letsencrypt_email }}
53
+    --domains {{ external_lb_vip_address }}
54
+    creates: "{{ haproxy_ssl_letsencrypt_config_path }}/{{ external_lb_vip_address }}/fullchain.pem"
55
+
56
+- name: Create new pem file for haproxy
57
+  assemble:
58
+    src: "{{ haproxy_ssl_letsencrypt_config_path }}/{{ external_lb_vip_address }}"
59
+    dest: "/etc/ssl/private/haproxy.pem"
60
+    regexp: '(privkey|fullchain).pem$'
61
+  notify:
62
+    - Restart haproxy
63
+
64
+- name: Create letsencrypt_renew file
65
+  template:
66
+    src: letsencrypt_renew.j2
67
+    dest: /usr/local/bin/letsencrypt_renew
68
+    mode: 0755
69
+    force: yes
70
+
71
+- name: Renew Letsencrypt Cert Cron
72
+  cron:
73
+    name: "Renew Letsencrypt Cert"
74
+    minute: "{{ haproxy_ssl_letsencrypt_cron_minute }}"
75
+    hour: "{{ haproxy_ssl_letsencrypt_cron_hour }}"
76
+    weekday: "{{ haproxy_ssl_letsencrypt_cron_weekday }}"
77
+    job: "/usr/local/bin/letsencrypt_renew"
78
+    user: "root"
79
+    state: present

+ 11
- 0
templates/letsencrypt_renew.j2 View File

@@ -0,0 +1,11 @@
1
+#!/bin/bash
2
+# renew cert if required and copy to haproxy destination
3
+
4
+certbot renew \
5
+    --standalone \
6
+    --pre-hook "systemctl stop haproxy" \
7
+
8
+cat /etc/letsencrypt/live/{{ external_lb_vip_address }}-0001/{fullchain,privkey}.pem \
9
+    > /etc/ssl/private/haproxy.pem
10
+
11
+systemctl restart haproxy

Loading…
Cancel
Save