Add backend TLS between MariaDB and ProxySQL

This commit adds TLS connection between ProxySQL and MariaDB.
Frontend TLS ( between services and ProxySQL) will be
added in another commit.

Parialy Implements: mariadb-ssl-support

Change-Id: I154cbb096469c5515c9d8156c2c1c5dd07b95849
Signed-off-by: Matus Jenca <matus.jenca@dnation.cloud>
This commit is contained in:
Matus Jenca 2024-04-15 17:01:54 +02:00 committed by Michal Arbet
parent 0fac8bc4c6
commit 23413d4e0f
19 changed files with 176 additions and 10 deletions

View File

@ -85,6 +85,7 @@ database_user: "root"
database_port: "3306" database_port: "3306"
database_connection_recycle_time: 10 database_connection_recycle_time: 10
database_max_pool_size: 1 database_max_pool_size: 1
database_enable_tls_backend: "{{ 'yes' if ((kolla_enable_tls_backend | bool ) and ( enable_proxysql | bool)) else 'no' }}"
#################### ####################
# Container engine options # Container engine options

View File

@ -77,3 +77,17 @@
dest: "{{ kolla_certificates_dir }}/rabbitmq-key.pem" dest: "{{ kolla_certificates_dir }}/rabbitmq-key.pem"
when: when:
- rabbitmq_enable_tls | bool - rabbitmq_enable_tls | bool
- name: Copy backend TLS certificate and key for Mariadb
copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "0660"
remote_src: true
with_items:
- src: "{{ kolla_tls_backend_cert }}"
dest: "{{ kolla_certificates_dir }}/mariadb-cert.pem"
- src: "{{ kolla_tls_backend_key }}"
dest: "{{ kolla_certificates_dir }}/mariadb-key.pem"
when:
- database_enable_tls_backend | bool

View File

@ -221,8 +221,6 @@
- Restart haproxy container - Restart haproxy container
- include_tasks: copy-certs.yml - include_tasks: copy-certs.yml
when:
- kolla_copy_ca_into_containers | bool
- name: Copying over haproxy start script - name: Copying over haproxy start script
vars: vars:

View File

@ -4,3 +4,13 @@
role: service-cert-copy role: service-cert-copy
vars: vars:
project_services: "{{ loadbalancer_services }}" project_services: "{{ loadbalancer_services }}"
when:
- kolla_copy_ca_into_containers | bool
- name: "Copy certificates and keys for MariaDB "
import_role:
role: service-cert-copy
vars:
project_services: "{{ loadbalancer_services }}"
project_name: mariadb
when: database_enable_tls_backend | bool

View File

@ -25,5 +25,24 @@
"owner": "proxysql", "owner": "proxysql",
"perm": "0700" "perm": "0700"
} }
{% if database_enable_tls_backend | bool %},
{
"source": "{{ container_config_directory }}/ca-certificates/root.crt",
"dest": "/etc/proxysql/certs/root.crt",
"owner": "proxysql",
"perm": "0600"
},
{
"source": "{{ container_config_directory }}/mariadb-cert.pem",
"dest": "/etc/proxysql/certs/mariadb-cert.pem",
"owner": "proxysql",
"perm": "0600"
},
{
"source": "{{ container_config_directory }}/mariadb-key.pem",
"dest": "/etc/proxysql/certs/mariadb-key.pem",
"owner": "proxysql",
"perm": "0600"
}{% endif %}
] ]
} }

View File

@ -32,6 +32,16 @@ mysql_variables:
monitor_ping_interval: "{{ mariadb_monitor_ping_interval }}" monitor_ping_interval: "{{ mariadb_monitor_ping_interval }}"
monitor_ping_timeout: "{{ mariadb_monitor_ping_timeout }}" monitor_ping_timeout: "{{ mariadb_monitor_ping_timeout }}"
monitor_ping_max_failures: "{{ mariadb_monitor_ping_max_failures }}" monitor_ping_max_failures: "{{ mariadb_monitor_ping_max_failures }}"
monitor_connect_timeout: 6000
connect_timeout_client: 100000
connect_timeout_server: 30000
connect_timeout_server_max: 100000
{% if database_enable_tls_backend | bool %}
ssl_p2s_ca: "/etc/proxysql/certs/root.crt"
ssl_p2s_cert: "/etc/proxysql/certs/mariadb-cert.pem"
ssl_p2s_key: "/etc/proxysql/certs/mariadb-key.pem"
have_ssl: true
{% endif %}
mysql_servers: mysql_servers:
{% for shard_id, shard in mariadb_shards_info.shards.items() %} {% for shard_id, shard in mariadb_shards_info.shards.items() %}
@ -49,6 +59,9 @@ mysql_servers:
max_replication_lag: {{ proxysql_backend_max_replication_lag }} max_replication_lag: {{ proxysql_backend_max_replication_lag }}
weight : {{ WEIGHT }} weight : {{ WEIGHT }}
comment : "Writer {{ host }}" comment : "Writer {{ host }}"
{% if database_enable_tls_backend | bool %}
use_ssl: 1
{% endif %}
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}

View File

@ -60,7 +60,7 @@
- groups[mariadb_shard_group + '_port_alive_True'] is defined - groups[mariadb_shard_group + '_port_alive_True'] is defined
- inventory_hostname in groups[mariadb_shard_group + '_port_alive_True'] - inventory_hostname in groups[mariadb_shard_group + '_port_alive_True']
- kolla_action != "config" - kolla_action != "config"
listen: restart mariadb listen: Restart mariadb container
- name: Start MariaDB on new nodes - name: Start MariaDB on new nodes
group_by: group_by:
@ -70,7 +70,7 @@
- groups[mariadb_shard_group + '_port_alive_False'] is defined - groups[mariadb_shard_group + '_port_alive_False'] is defined
- inventory_hostname in groups[mariadb_shard_group + '_port_alive_False'] - inventory_hostname in groups[mariadb_shard_group + '_port_alive_False']
- kolla_action != "config" - kolla_action != "config"
listen: restart mariadb listen: Restart mariadb container
- name: Restart mariadb-clustercheck container - name: Restart mariadb-clustercheck container
vars: vars:
@ -86,7 +86,7 @@
dimensions: "{{ service.dimensions }}" dimensions: "{{ service.dimensions }}"
environment: "{{ service.environment }}" environment: "{{ service.environment }}"
listen: listen:
- restart mariadb-clustercheck - Restart mariadb-clustercheck container
when: when:
- kolla_action != "config" - kolla_action != "config"
- service | service_enabled_and_mapped_to_host - service | service_enabled_and_mapped_to_host

View File

@ -12,4 +12,4 @@
healthcheck: "{{ item.value.healthcheck | default(omit) }}" healthcheck: "{{ item.value.healthcheck | default(omit) }}"
with_dict: "{{ mariadb_services | select_services_enabled_and_mapped_to_host }}" with_dict: "{{ mariadb_services | select_services_enabled_and_mapped_to_host }}"
notify: notify:
- "restart {{ item.key }}" - "Restart {{ item.key }} container"

View File

@ -44,7 +44,7 @@
become: true become: true
with_dict: "{{ mariadb_services | select_services_enabled_and_mapped_to_host }}" with_dict: "{{ mariadb_services | select_services_enabled_and_mapped_to_host }}"
notify: notify:
- "restart {{ item.key }}" - "Restart {{ item.key }} container"
- name: Copying over config.json files for mariabackup - name: Copying over config.json files for mariabackup
vars: vars:
@ -72,4 +72,6 @@
become: true become: true
when: service | service_enabled_and_mapped_to_host when: service | service_enabled_and_mapped_to_host
notify: notify:
- restart mariadb - Restart mariadb container
- include_tasks: copy-certs.yml

View File

@ -0,0 +1,7 @@
---
- name: "Copy certificates and keys for {{ project_name }}"
import_role:
role: service-cert-copy
vars:
project_services: "{{ mariadb_services }}"
when: database_enable_tls_backend | bool

View File

@ -11,7 +11,11 @@ default-character-set=utf8
basedir=/usr basedir=/usr
bind-address={{ api_interface_address }} bind-address={{ api_interface_address }}
port={{ mariadb_port }} port={{ mariadb_port }}
{% if database_enable_tls_backend | bool %}
ssl_ca=/etc/mariadb/certs/root.crt
ssl_cert=/etc/mariadb/certs/mariadb-cert.pem
ssl_key=/etc/mariadb/certs/mariadb-key.pem
{% endif %}
log_error=/var/log/kolla/mariadb/mariadb.log log_error=/var/log/kolla/mariadb/mariadb.log
log_bin=mysql-bin log_bin=mysql-bin

View File

@ -8,6 +8,25 @@
"owner": "mysql", "owner": "mysql",
"perm": "0600" "perm": "0600"
} }
{% if database_enable_tls_backend | bool %},
{
"source": "{{ container_config_directory }}/ca-certificates/root.crt",
"dest": "/etc/mariadb/certs/root.crt",
"owner": "mysql",
"perm": "0600"
},
{
"source": "{{ container_config_directory }}/mariadb-cert.pem",
"dest": "/etc/mariadb/certs/mariadb-cert.pem",
"owner": "mysql",
"perm": "0600"
},
{
"source": "{{ container_config_directory }}/mariadb-key.pem",
"dest": "/etc/mariadb/certs/mariadb-key.pem",
"owner": "mysql",
"perm": "0600"
}{% endif %}
], ],
"permissions": [ "permissions": [
{ {

View File

@ -245,7 +245,7 @@ workaround_ansible_issue_8743: yes
#kolla_copy_ca_into_containers: "no" #kolla_copy_ca_into_containers: "no"
#haproxy_backend_cacert: "{{ 'ca-certificates.crt' if kolla_base_distro in ['debian', 'ubuntu'] else 'ca-bundle.trust.crt' }}" #haproxy_backend_cacert: "{{ 'ca-certificates.crt' if kolla_base_distro in ['debian', 'ubuntu'] else 'ca-bundle.trust.crt' }}"
#haproxy_backend_cacert_dir: "/etc/ssl/certs" #haproxy_backend_cacert_dir: "/etc/ssl/certs"
#database_enable_tls_backend: "{{ 'yes' if kolla_enable_tls_backend | bool and enable_proxysql | bool else 'no' }}"
################## ##################
# Backend options # Backend options
################## ##################

View File

@ -0,0 +1,6 @@
---
features:
- |
Implements SSL between Proxysql and MariaDB
ProxySQL must be enabled in order for encryption to work
`Partial Blueprint mariadb-ssl-support <https://blueprints.launchpad.net/kolla-ansible/+spec/mariadb-ssl-support>`__

View File

@ -6,6 +6,9 @@ collections:
- name: ansible.posix - name: ansible.posix
source: https://galaxy.ansible.com source: https://galaxy.ansible.com
version: <2 version: <2
- name: ansible.utils
source: https://galaxy.ansible.com
version: <5
- name: community.crypto - name: community.crypto
source: https://galaxy.ansible.com source: https://galaxy.ansible.com
version: <3 version: <3

View File

@ -33,6 +33,10 @@ from jinja2 import TemplateNotFound
from kolla_ansible import kolla_address from kolla_ansible import kolla_address
from kolla_ansible import put_address_in_context from kolla_ansible import put_address_in_context
import os.path import os.path
try:
from ansible_collections.ansible.utils.plugins.filter import ipwrap
except ImportError:
from ansible_collections.ansible.netcommon.plugins.filter import ipwrap
class AbsolutePathLoader(BaseLoader): class AbsolutePathLoader(BaseLoader):
@ -57,6 +61,7 @@ def check(template, out, err, env=Environment(loader=AbsolutePathLoader(),
env.filters['password_hash'] = get_encrypted_password env.filters['password_hash'] = get_encrypted_password
env.filters['kolla_address'] = kolla_address env.filters['kolla_address'] = kolla_address
env.filters['put_address_in_context'] = put_address_in_context env.filters['put_address_in_context'] = put_address_in_context
env.filters['ipwrap'] = ipwrap
env.get_template(template) env.get_template(template)
out.write("%s: Syntax OK\n" % template) out.write("%s: Syntax OK\n" % template)
return 0 return 0

View File

@ -555,6 +555,16 @@
KOLLA_ANSIBLE_VENV_PATH: "{{ kolla_ansible_venv_path }}" KOLLA_ANSIBLE_VENV_PATH: "{{ kolla_ansible_venv_path }}"
CONTAINER_ENGINE: "{{ container_engine }}" CONTAINER_ENGINE: "{{ container_engine }}"
- name: Run test-proxysql.sh script
script:
cmd: test-proxysql.sh
executable: /bin/bash
chdir: "{{ kolla_ansible_src_dir }}"
when: scenario == "cells"
environment:
VIP: "{{ kolla_internal_vip_address }}"
TLS_ENABLED: "{{ tls_enabled }}"
- name: Run test-prometheus-opensearch.sh script - name: Run test-prometheus-opensearch.sh script
script: script:
cmd: test-prometheus-opensearch.sh cmd: test-prometheus-opensearch.sh

53
tests/test-proxysql.sh Executable file
View File

@ -0,0 +1,53 @@
#!/bin/bash
set -o xtrace
set -o pipefail
function test_proxysql_connection_logged {
mariadb -h $VIP -P$DATABASE_PORT -u$DATABASE_USER -p$DATABASE_PASSWORD -e 'SHOW TABLES'
}
function test_proxysql {
test_proxysql_connection_logged > /tmp/logs/ansible/test-proxysql 2>&1
result=$?
echo $result
if [[ $result != 0 ]]; then
echo "Testing ProxySQL failed. See ansible/test-proxysql for details"
else
echo "Successfully tested ProxySQL. See ansible/test-proxysql for details"
fi
return $result
}
function test_proxysql_ssl_connection {
query="SELECT SUBSTRING_INDEX(variable_value, ',', -1) AS '' FROM information_schema.session_status WHERE variable_name = 'Ssl_cipher' LIMIT 1;"
result=$(mariadb -h $VIP -P$DATABASE_PORT -u$DATABASE_USER -p$DATABASE_PASSWORD -e "$query" --silent)
echo $result
if [[ "$result" =~ ^[[:space:]]*$ || -z "${result}" ]]; then
echo "ERROR: SSL is not utilized in ProxySQL"
return 1
else
echo "SSL connection is working properly in proxysql"
return 0
fi
}
DATABASE_PORT="${DATABASE_PORT:-3306}"
DATABASE_USER="${DATABASE_USER:-root_shard_0}"
TLS_ENABLED="${TLS_ENABLED:-false}"
if [[ -z "${VIP}" ]]; then
echo "VIP not set"
exit 1
fi
if [[ -z "${DATABASE_PASSWORD}" ]]; then
DATABASE_PASSWORD=$(grep ^database_password /etc/kolla/passwords.yml | cut -d" " -f2)
fi
test_proxysql
if [ "$TLS_ENABLED" = true ]; then
test_proxysql_ssl_connection
fi

View File

@ -241,7 +241,9 @@
- ^requirements-core.yml - ^requirements-core.yml
- ^ansible/roles/nova/ - ^ansible/roles/nova/
- ^tests/templates/(inventory|globals-default.j2) - ^tests/templates/(inventory|globals-default.j2)
- ^ansible/roles/loadbalancer/
- ^tests/test-core-openstack.sh - ^tests/test-core-openstack.sh
- ^tests/test-proxysql.sh
vars: vars:
scenario: cells scenario: cells