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
This commit is contained in:
Frank Kloeker 2018-07-28 10:38:40 +02:00
parent 937fa0168d
commit 4fb2059a3b
6 changed files with 135 additions and 0 deletions

View File

@ -71,6 +71,15 @@ haproxy_ssl_ca_cert: /etc/ssl/certs/haproxy-ca.pem
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 }}" 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 }}"
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') }}" 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') }}"
haproxy_ssl_bind_options: "force-tlsv12" haproxy_ssl_bind_options: "force-tlsv12"
# activate letsencrypt option
haproxy_ssl_letsencrypt_enable: false
haproxy_ssl_letsencrypt_email: "example@example.com"
haproxy_ssl_letsencrypt_download_url: "https://dl.eff.org/certbot-auto"
haproxy_ssl_letsencrypt_config_path: "/etc/letsencrypt/live"
haproxy_ssl_letsencrypt_install_path: "/opt/letsencrypt"
haproxy_ssl_letsencrypt_cron_minute: "0"
haproxy_ssl_letsencrypt_cron_hour: "0"
haproxy_ssl_letsencrypt_cron_weekday: "0"
# hatop extra package URL and checksum # hatop extra package URL and checksum
haproxy_hatop_download_url: "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/hatop/hatop-0.7.7.tar.gz" haproxy_hatop_download_url: "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/hatop/hatop-0.7.7.tar.gz"

View File

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

View File

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

View File

@ -23,6 +23,13 @@
- include_tasks: haproxy_ssl_self_signed.yml - include_tasks: haproxy_ssl_self_signed.yml
when: when:
- haproxy_ssl | bool - haproxy_ssl | bool
- not haproxy_ssl_letsencrypt_enable | bool
- haproxy_user_ssl_cert is not defined or haproxy_user_ssl_key is not defined
- include_tasks: haproxy_ssl_letsencrypt.yml
when:
- haproxy_ssl | bool
- haproxy_ssl_letsencrypt_enable | bool
- haproxy_user_ssl_cert is not defined or haproxy_user_ssl_key is not defined - haproxy_user_ssl_cert is not defined or haproxy_user_ssl_key is not defined
- include_tasks: haproxy_ssl_user_provided.yml - include_tasks: haproxy_ssl_user_provided.yml

View File

@ -0,0 +1,79 @@
---
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
- name: Ensure haproxy_ssl_letsencrypt_install_path exists
file:
path: "{{ haproxy_ssl_letsencrypt_install_path }}"
state: directory
- name: Download certbot
get_url:
url: "{{ haproxy_ssl_letsencrypt_download_url }}"
dest: "{{ haproxy_ssl_letsencrypt_install_path }}"
mode: 0755
register: fetch_url
until: fetch_url is success
retries: 3
delay: 10
- name: Ensure file permissions certbot-auto
file:
path: "{{ haproxy_ssl_letsencrypt_install_path }}/{{ haproxy_ssl_letsencrypt_download_url | basename }}"
- name: Register Letsencrypt data dir
stat:
path: "{{ haproxy_ssl_letsencrypt_config_path }}/{{ external_lb_vip_address }}"
register: lcdatadir
- name: Stop haproxy for certbot activity
service:
name: "haproxy"
state: "stopped"
when: lcdatadir.stat.exists == False
- name: Create ssl cert with certbot
command: >
{{ haproxy_ssl_letsencrypt_install_path }}/{{ haproxy_ssl_letsencrypt_download_url | basename }} certonly
--standalone
--agree-tos
--non-interactive
--text
--rsa-key-size 4096
--email {{ haproxy_ssl_letsencrypt_email }}
--domains {{ external_lb_vip_address }}
creates: "{{ haproxy_ssl_letsencrypt_config_path }}/{{ external_lb_vip_address }}/fullchain.pem"
- name: Create new pem file for haproxy
assemble:
src: "{{ haproxy_ssl_letsencrypt_config_path }}/{{ external_lb_vip_address }}"
dest: "/etc/ssl/private/haproxy.pem"
regexp: '(privkey|fullchain).pem$'
notify:
- Restart haproxy
- name: Create letsencrypt_renew file
template:
src: letsencrypt_renew.j2
dest: /usr/local/bin/letsencrypt_renew
mode: 0755
force: yes
- name: Renew Letsencrypt Cert Cron
cron:
name: "Renew Letsencrypt Cert"
minute: "{{ haproxy_ssl_letsencrypt_cron_minute }}"
hour: "{{ haproxy_ssl_letsencrypt_cron_hour }}"
weekday: "{{ haproxy_ssl_letsencrypt_cron_weekday }}"
job: "/usr/local/bin/letsencrypt_renew"
user: "root"
state: present

View File

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