Use haproxy_vip_binds stanza for Let's Encrypt
Currently Let's Encrypt is using `haproxy_bind_external_lb_vip_address` to identify naming of resulting certificate which might not match with expectations, as all other parts of code already do use `haproxy_vip_binds` for calculating resulting TLS path. This patch introduces `type` key for `haproxy_vip_binds` which is used to identify for which frontends Let's Encrypt certificate should be used as in most scenarios it's not gonna be issued for "internal" VIPs anyway due to dns-01 requirement. Also moving to single "source of truth" for VIP bindings allows to override and have control over this behaviour. Change-Id: Id07d9a0ea270d613b37b6adfa373d01a47f7421f
This commit is contained in:
parent
7e4ecd10b3
commit
65e53499f5
@ -290,6 +290,7 @@ haproxy_bind_internal_lb_vip_interface:
|
|||||||
# haproxy_vip_binds:
|
# haproxy_vip_binds:
|
||||||
# - address: '*'
|
# - address: '*'
|
||||||
# interface: bond0
|
# interface: bond0
|
||||||
|
# type: external
|
||||||
# - address: '192.168.0.10'
|
# - address: '192.168.0.10'
|
||||||
# pki_san_records:
|
# pki_san_records:
|
||||||
# - internal.cloud
|
# - internal.cloud
|
||||||
|
@ -222,35 +222,21 @@ Each HAProxy instance will be checking for certbot running on its own
|
|||||||
node plus each of the others, and direct any incoming acme-challenge
|
node plus each of the others, and direct any incoming acme-challenge
|
||||||
requests to the HAProxy instance which is performing a renewal.
|
requests to the HAProxy instance which is performing a renewal.
|
||||||
|
|
||||||
|
Domains which will be covered by Let's Encrypt certificate are defined
|
||||||
|
with ``haproxy_ssl_letsencrypt_domains`` variable, which can be set to
|
||||||
|
a list. By default certificate will be issued only for
|
||||||
|
``external_lb_vip_address``.
|
||||||
|
|
||||||
|
Another important aspect is defining a list of frontends, for which
|
||||||
|
issued certificate will be used.
|
||||||
|
By default, it is goind to be used only for VIPs with type ``external``.
|
||||||
|
You can control and define type by overriding a variable ``haproxy_vip_binds``.
|
||||||
|
|
||||||
It is necessary to configure certbot to bind to the HAproxy node local
|
It is necessary to configure certbot to bind to the HAproxy node local
|
||||||
internal IP address via the haproxy_ssl_letsencrypt_certbot_bind_address
|
internal IP address via the haproxy_ssl_letsencrypt_certbot_bind_address
|
||||||
variable in a H/A setup.
|
variable in a H/A setup.
|
||||||
|
|
||||||
Using Certificates from LetsEncrypt (legacy method)
|
.. _Securing services with SSL certificates: https://docs.openstack.org/openstack-ansible/latest/user/security/index.html
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
|
|
||||||
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: https://docs.openstack.org/project-deploy-guide/openstack-ansible/draft/app-advanced-config-sslcertificates.html
|
|
||||||
|
|
||||||
Configuring additional services
|
Configuring additional services
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -63,14 +63,14 @@
|
|||||||
src: "{{ haproxy_ssl_letsencrypt_config_path }}/{{ haproxy_ssl_letsencrypt_domains | first }}"
|
src: "{{ haproxy_ssl_letsencrypt_config_path }}/{{ haproxy_ssl_letsencrypt_domains | first }}"
|
||||||
dest: >-
|
dest: >-
|
||||||
{{
|
{{
|
||||||
haproxy_ssl_cert_path ~ '/haproxy_' ~ ansible_facts['hostname'] ~ '-' ~ (haproxy_bind_external_lb_vip_interface is truthy) | ternary(
|
haproxy_ssl_cert_path ~ '/haproxy_' ~ ansible_facts['hostname'] ~ '-' ~ (item.get('interface')) | ternary(
|
||||||
item ~ '-' ~ haproxy_bind_external_lb_vip_interface, item) ~ '.pem'
|
item.get('address') ~ '-' ~ item['interface'], item['address']) ~ '.pem'
|
||||||
}}
|
}}
|
||||||
regexp: '(privkey|fullchain).pem$'
|
regexp: '(privkey|fullchain).pem$'
|
||||||
owner: haproxy
|
owner: haproxy
|
||||||
group: haproxy
|
group: haproxy
|
||||||
mode: "0640"
|
mode: "0640"
|
||||||
with_items:
|
with_items:
|
||||||
- "{{ [haproxy_bind_external_lb_vip_address] + extra_lb_tls_vip_addresses }}"
|
- "{{ haproxy_vip_binds | selectattr('type', 'defined') | selectattr('type', 'eq', 'external') }}"
|
||||||
notify:
|
notify:
|
||||||
- Reload haproxy
|
- Reload haproxy
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# renew cert if required and copy to haproxy destination
|
# renew cert if required and copy to haproxy destination
|
||||||
|
|
||||||
{% for vip in [ haproxy_bind_external_lb_vip_address ] + extra_lb_tls_vip_addresses %}
|
{% for vip in haproxy_vip_binds | selectattr('type', 'defined') | selectattr('type', 'eq', 'external') %}
|
||||||
cat /etc/letsencrypt/live/{{ haproxy_ssl_letsencrypt_domains | first }}/{fullchain,privkey}.pem \
|
cat /etc/letsencrypt/live/{{ haproxy_ssl_letsencrypt_domains | first }}/{fullchain,privkey}.pem \
|
||||||
> {{ haproxy_ssl_cert_path ~ '/haproxy_' ~ ansible_facts['hostname'] ~ '-' ~ vip ~ '.pem' }}
|
> {{ haproxy_ssl_cert_path ~ '/haproxy_' ~ ansible_facts['hostname'] ~ '-' ~ (vip.get('interface')) | ternary(vip['address'] ~ '-' ~ vip.get('interface'), vip['address']) ~ '.pem' }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
systemctl reload haproxy
|
systemctl reload haproxy
|
||||||
|
@ -14,13 +14,13 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
_haproxy_vip_binds: |
|
_haproxy_vip_binds: |
|
||||||
{% set vip_binds = [{'address': haproxy_bind_external_lb_vip_address, 'interface': haproxy_bind_external_lb_vip_interface}] %}
|
{% set vip_binds = [{'address': haproxy_bind_external_lb_vip_address, 'interface': haproxy_bind_external_lb_vip_interface, 'type': 'external'}] %}
|
||||||
{% if haproxy_bind_internal_lb_vip_address != haproxy_bind_external_lb_vip_address or
|
{% if haproxy_bind_internal_lb_vip_address != haproxy_bind_external_lb_vip_address or
|
||||||
haproxy_bind_external_lb_vip_interface != haproxy_bind_internal_lb_vip_interface %}
|
haproxy_bind_external_lb_vip_interface != haproxy_bind_internal_lb_vip_interface %}
|
||||||
{% set _ = vip_binds.append({'address': haproxy_bind_internal_lb_vip_address, 'interface': haproxy_bind_internal_lb_vip_interface}) %}
|
{% set _ = vip_binds.append({'address': haproxy_bind_internal_lb_vip_address, 'interface': haproxy_bind_internal_lb_vip_interface, 'type': 'internal'}) %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for vip_address in extra_lb_tls_vip_addresses %}
|
{% for vip_address in extra_lb_tls_vip_addresses %}
|
||||||
{% set _ = vip_binds.append({'address': vip_address}) %}
|
{% set _ = vip_binds.append({'address': vip_address, 'type': 'external'}) %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{{ vip_binds }}
|
{{ vip_binds }}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user