Adding SSL Support
This commit is contained in:
parent
4daa6d2d0b
commit
828a542896
10 changed files with 162 additions and 6 deletions
|
@ -4,12 +4,16 @@ Ansible playbook that provisions a group of servers to run mariadb as a Galera C
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
If you are using HaProxy as a front end to the cluster, you will need to create a user for the health checks to work properly. The user does not need to be able to access any databases, it just needs to be able to authenticate against the server.
|
If you are using HaProxy as a front end to the cluster **without SSL**, you will need to create a user for the health checks to work properly. The user does not need to be able to access any databases, it just needs to be able to authenticate against the server.
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
CREATE USER 'haproxy_check'@'10.10.10.253' WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 0 MAX_STATEMENT_TIME 0.0000000001;
|
CREATE USER 'haproxy_check'@'10.10.10.253' WITH MAX_QUERIES_PER_HOUR 1 MAX_UPDATES_PER_HOUR 0 MAX_STATEMENT_TIME 0.0000000001;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you are using HaProxy as a front end to the cluster **with SSL**, use default tcp checks to validate the service is available as HaProxy does not support the SSL settings for mysql.
|
||||||
|
|
||||||
|
If this is the first install, the `mariadb_cluster_bootstrap` variable will need to be set to true to bootstrap the cluster.
|
||||||
|
|
||||||
## Variables
|
## Variables
|
||||||
|
|
||||||
| Variable | Required | Default | Description |
|
| Variable | Required | Default | Description |
|
||||||
|
@ -43,6 +47,9 @@ You can view the status of the cluster by running the following command.
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
SHOW GLOBAL STATUS LIKE 'wsrep_%';
|
SHOW GLOBAL STATUS LIKE 'wsrep_%';
|
||||||
|
SHOW GLOBAL VARIABLES LIKE 'have_ssl';
|
||||||
|
SHOW SESSION STATUS LIKE 'Ssl_cipher';
|
||||||
|
SHOW GLOBAL VARIABLES LIKE 'require_secure_transport';
|
||||||
```
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
4
collections/requirements.yml
Normal file
4
collections/requirements.yml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
collections:
|
||||||
|
- community.general
|
||||||
|
- community.crypto
|
|
@ -3,3 +3,7 @@
|
||||||
|
|
||||||
mariadb_cluster_wsrep_cluster_name: "my_wsrep_cluster"
|
mariadb_cluster_wsrep_cluster_name: "my_wsrep_cluster"
|
||||||
mariadb_cluster_access_ip: ""
|
mariadb_cluster_access_ip: ""
|
||||||
|
mariadb_cluster_master: "{{ groups['mariadb_cluster'][0] }}"
|
||||||
|
mariadb_cluster_ssl: true
|
||||||
|
mariadb_cluster_bootstrap: false
|
||||||
|
mariadb_cluster_cert_length: "+7300d"
|
||||||
|
|
|
@ -17,3 +17,4 @@
|
||||||
|
|
||||||
- name: Bootstrap Galera
|
- name: Bootstrap Galera
|
||||||
include_tasks: tasks/bootstrap-galera.yml
|
include_tasks: tasks/bootstrap-galera.yml
|
||||||
|
when: mariadb_cluster_bootstrap == true
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
|
|
||||||
- name: Stop MariaDB on first MariaDB Galera cluster node
|
- name: Stop MariaDB on first MariaDB Galera cluster node
|
||||||
service: name=mariadb state=stopped
|
service: name=mariadb state=stopped
|
||||||
when: inventory_hostname == groups['mariadb_cluster'][0]
|
when: inventory_hostname == mariadb_cluster_master
|
||||||
|
|
||||||
- name: Bootstrap first MariaDB Galera cluster node
|
- name: Bootstrap first MariaDB Galera cluster node
|
||||||
command: galera_new_cluster
|
command: galera_new_cluster
|
||||||
when: inventory_hostname == groups['mariadb_cluster'][0]
|
when: inventory_hostname == mariadb_cluster_master
|
||||||
|
|
||||||
- name: Restart the other MariaDB Galera cluster nodes
|
- name: Restart the other MariaDB Galera cluster nodes
|
||||||
service: name=mariadb state=restarted
|
service: name=mariadb state=restarted
|
||||||
when: inventory_hostname != groups['mariadb_cluster'][0]
|
when: inventory_hostname != mariadb_cluster_master
|
||||||
|
|
39
roles/mariadb_cluster/tasks/certificates-server.yml
Normal file
39
roles/mariadb_cluster/tasks/certificates-server.yml
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
---
|
||||||
|
# file: roles/mariadb_cluster/tasks/certificates-server.yml
|
||||||
|
|
||||||
|
|
||||||
|
- name: "{{ hostvars[item]['ansible_hostname'] }} - Create private key"
|
||||||
|
community.crypto.openssl_privatekey:
|
||||||
|
path: /etc/ssl/galera/server.key
|
||||||
|
|
||||||
|
- name: "{{ hostvars[item]['ansible_hostname'] }} - Check if server certificate exists"
|
||||||
|
stat:
|
||||||
|
path: "/etc/ssl/galera/server.pem"
|
||||||
|
register: serverCertCheck
|
||||||
|
|
||||||
|
- name: "{{ hostvars[item]['ansible_hostname'] }} - CSR"
|
||||||
|
block:
|
||||||
|
- name: "{{ hostvars[item]['ansible_hostname'] }} - Create CSR for new certificate"
|
||||||
|
community.crypto.openssl_csr_pipe:
|
||||||
|
privatekey_path: /etc/ssl/galera/server.key
|
||||||
|
common_name: "{{ hostvars[item]['ansible_hostname'] }}"
|
||||||
|
subject_alt_name:
|
||||||
|
- "DNS:{{ mariadb_cluster_wsrep_cluster_name }}"
|
||||||
|
register: csr
|
||||||
|
|
||||||
|
- name: "{{ hostvars[item]['ansible_hostname'] }} - Sign certificate with CA"
|
||||||
|
community.crypto.x509_certificate_pipe:
|
||||||
|
csr_content: "{{ csr.csr }}"
|
||||||
|
provider: ownca
|
||||||
|
ownca_path: /etc/ssl/galera/ca-certificate.pem
|
||||||
|
ownca_privatekey_path: /etc/ssl/galera/ca-certificate.key
|
||||||
|
ownca_not_after: "{{ mariadb_cluster_cert_length }}"
|
||||||
|
ownca_not_before: "-1d"
|
||||||
|
delegate_to: "{{ mariadb_cluster_master }}"
|
||||||
|
register: certificate
|
||||||
|
|
||||||
|
- name: "{{ hostvars[item]['ansible_hostname'] }} - Write certificate file"
|
||||||
|
copy:
|
||||||
|
dest: /etc/ssl/galera/server.pem
|
||||||
|
content: "{{ certificate.certificate }}"
|
||||||
|
when: not serverCertCheck.stat.exists
|
67
roles/mariadb_cluster/tasks/certificates.yml
Normal file
67
roles/mariadb_cluster/tasks/certificates.yml
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
---
|
||||||
|
# file: roles/mariadb_cluster/tasks/certificates.yml
|
||||||
|
|
||||||
|
- name: Ensure directory exists for local self-signed TLS certs
|
||||||
|
file:
|
||||||
|
path: /etc/ssl/galera/
|
||||||
|
state: directory
|
||||||
|
owner: mysql
|
||||||
|
group: mysql
|
||||||
|
recurse: true
|
||||||
|
|
||||||
|
- name: CA Setup
|
||||||
|
block:
|
||||||
|
- name: Generate an OpenSSL private key
|
||||||
|
community.crypto.openssl_privatekey:
|
||||||
|
path: /etc/ssl/galera/ca-certificate.key
|
||||||
|
|
||||||
|
- name: Create certificate signing request (CSR) for CA certificate
|
||||||
|
community.crypto.openssl_csr_pipe:
|
||||||
|
privatekey_path: /etc/ssl/galera/ca-certificate.key
|
||||||
|
common_name: Galera-Ansible
|
||||||
|
use_common_name_for_san: false
|
||||||
|
basic_constraints:
|
||||||
|
- 'CA:TRUE'
|
||||||
|
basic_constraints_critical: true
|
||||||
|
key_usage:
|
||||||
|
- keyCertSign
|
||||||
|
key_usage_critical: true
|
||||||
|
register: ca_csr
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Create self-signed CA certificate from CSR
|
||||||
|
community.crypto.x509_certificate:
|
||||||
|
path: /etc/ssl/galera/ca-certificate.pem
|
||||||
|
csr_content: "{{ ca_csr.csr }}"
|
||||||
|
privatekey_path: /etc/ssl/galera/ca-certificate.key
|
||||||
|
selfsigned_not_after: "{{ mariadb_cluster_cert_length }}"
|
||||||
|
provider: selfsigned
|
||||||
|
|
||||||
|
- name: Copy ca-certificate locally for transfer
|
||||||
|
fetch:
|
||||||
|
src: /etc/ssl/galera/ca-certificate.pem
|
||||||
|
dest: /tmp/galera-ca-certificate.pem
|
||||||
|
flat: yes
|
||||||
|
when: inventory_hostname == mariadb_cluster_master
|
||||||
|
|
||||||
|
- name: Transfer ca cert to other members
|
||||||
|
copy:
|
||||||
|
src: /tmp/galera-ca-certificate.pem
|
||||||
|
dest: /etc/ssl/galera/ca-certificate.pem
|
||||||
|
owner: mysql
|
||||||
|
group: mysql
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Server Certificates
|
||||||
|
include_tasks: certificates-server.yml
|
||||||
|
loop: "{{ groups['mariadb_cluster'] }}"
|
||||||
|
loop_control:
|
||||||
|
extended: yes
|
||||||
|
|
||||||
|
- name: Ensure mysql has permissions to access certs
|
||||||
|
file:
|
||||||
|
path: /etc/ssl/galera/
|
||||||
|
state: directory
|
||||||
|
owner: mysql
|
||||||
|
group: mysql
|
||||||
|
recurse: true
|
|
@ -11,13 +11,24 @@
|
||||||
- mariadb-server
|
- mariadb-server
|
||||||
- galera
|
- galera
|
||||||
state: latest
|
state: latest
|
||||||
|
tags: packages
|
||||||
|
|
||||||
- name: Update galera config
|
- name: Update galera config
|
||||||
template:
|
template:
|
||||||
src: "galera.cnf.j2"
|
src: "galera.cnf.j2"
|
||||||
dest: "/etc/my.cnf.d/galera.cnf"
|
dest: "/etc/my.cnf.d/z-galera.cnf"
|
||||||
notify: Bootstrap Galera
|
notify: Bootstrap Galera
|
||||||
|
|
||||||
|
- name: Certificates tasks
|
||||||
|
include_tasks: certificates.yml
|
||||||
|
when: mariadb_cluster_ssl == true
|
||||||
|
|
||||||
|
- name: Update ssl config
|
||||||
|
template:
|
||||||
|
src: "ssl.cnf.j2"
|
||||||
|
dest: "/etc/my.cnf.d/z-ssl.cnf"
|
||||||
|
when: mariadb_cluster_ssl == true
|
||||||
|
|
||||||
- name: Enable firewall rule for MySQL access
|
- name: Enable firewall rule for MySQL access
|
||||||
firewalld:
|
firewalld:
|
||||||
port: 3306/tcp
|
port: 3306/tcp
|
||||||
|
@ -29,11 +40,12 @@
|
||||||
|
|
||||||
- name: "Enable firewall rule for MySQL access to Access IP"
|
- name: "Enable firewall rule for MySQL access to Access IP"
|
||||||
firewalld:
|
firewalld:
|
||||||
rich_rule: 'rule family="ipv4" source address="{{ mariadb_cluster_access_ip }}" port port="3306" protocol="tcp" accept'
|
rich_rule: 'rule family="ipv4" source address="{{ item }}" port port="3306" protocol="tcp" accept'
|
||||||
permanent: yes
|
permanent: yes
|
||||||
state: enabled
|
state: enabled
|
||||||
immediate: yes
|
immediate: yes
|
||||||
notify: Reload firewalld
|
notify: Reload firewalld
|
||||||
|
loop: "{{ mariadb_cluster_access_ip }}"
|
||||||
when: mariadb_cluster_access_ip != ""
|
when: mariadb_cluster_access_ip != ""
|
||||||
|
|
||||||
- name: Setup access for other servers
|
- name: Setup access for other servers
|
||||||
|
@ -66,6 +78,12 @@
|
||||||
dest: /etc/systemd/system/mariadb.service.d/override.conf
|
dest: /etc/systemd/system/mariadb.service.d/override.conf
|
||||||
notify: Daemon Reload
|
notify: Daemon Reload
|
||||||
|
|
||||||
|
- name: Set selinux nis_enabled
|
||||||
|
seboolean:
|
||||||
|
name: nis_enabled
|
||||||
|
state: true
|
||||||
|
persistent: true
|
||||||
|
|
||||||
- name: Flush handlers
|
- name: Flush handlers
|
||||||
meta: flush_handlers
|
meta: flush_handlers
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,11 @@ wsrep_on=1
|
||||||
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
|
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
|
||||||
|
|
||||||
# Provider specific configuration options
|
# Provider specific configuration options
|
||||||
|
{% if mariadb_cluster_ssl == true %}
|
||||||
|
wsrep_provider_options="socket.ssl_key=/etc/ssl/galera/server.key;socket.ssl_cert=/etc/ssl/galera/server.pem;socket.ssl_ca=/etc/ssl/galera/ca-certificate.pem"
|
||||||
|
{% else %}
|
||||||
#wsrep_provider_options=
|
#wsrep_provider_options=
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
# Logical cluster name. Should be the same for all nodes.
|
# Logical cluster name. Should be the same for all nodes.
|
||||||
wsrep_cluster_name="{{ mariadb_cluster_wsrep_cluster_name }}"
|
wsrep_cluster_name="{{ mariadb_cluster_wsrep_cluster_name }}"
|
||||||
|
|
12
roles/mariadb_cluster/templates/ssl.cnf.j2
Normal file
12
roles/mariadb_cluster/templates/ssl.cnf.j2
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# MySQL Server
|
||||||
|
[mysqld]
|
||||||
|
ssl-ca = /etc/ssl/galera/ca-certificate.pem
|
||||||
|
ssl-key = /etc/ssl/galera/server.key
|
||||||
|
ssl-cert = /etc/ssl/galera/server.pem
|
||||||
|
require_secure_transport = 1
|
||||||
|
|
||||||
|
# MySQL Client Configuration
|
||||||
|
[mysql]
|
||||||
|
ssl-ca = /etc/ssl/galera/ca-certificate.pem
|
||||||
|
ssl-key = /etc/ssl/galera/server.key
|
||||||
|
ssl-cert = /etc/ssl/galera/server.pem
|
Loading…
Reference in a new issue