diff --git a/library/roles/mysql/defaults/main.yml b/library/roles/mysql/defaults/main.yml index b8752818..38475a43 100644 --- a/library/roles/mysql/defaults/main.yml +++ b/library/roles/mysql/defaults/main.yml @@ -2,10 +2,14 @@ mysql_enabled: True mysql_pkg_state: present mysql_conf_dir: /etc/mysql/conf.d +mysql_service_conf_dir: /etc/mysql/mysql.conf.d mysql_socket: /run/mysqld/mysqld.sock mysql_data_dir: /var/lib/mysql mysql_log_dir: /var/log/mysql +mysql_use_ssl: True +mysql_letsencrypt_certificates: True + # python-mysqldb is needed by ansible to manage users and databases mysql_packages_list: - mysql-server diff --git a/library/roles/mysql/files/letsencrypt-mysql-hook.sh b/library/roles/mysql/files/letsencrypt-mysql-hook.sh new file mode 100644 index 00000000..aaa74c55 --- /dev/null +++ b/library/roles/mysql/files/letsencrypt-mysql-hook.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +H_NAME=$( hostname -f ) +LE_CERTS_DIR=/var/lib/acme/live/$H_NAME +LE_LOG_DIR=/var/log/letsencrypt +LE_LOG_FILE="${LE_LOG_DIR}/mysql.log" +MYSQL_CERTDIR=/var/lib/mysql + +DATE=$( date ) + +[ ! -d $LE_LOG_DIR ] && mkdir $LE_LOG_DIR +echo "$DATE" >> $LE_LOG_FILE + +if [ -f "/etc/default/acme_sh_request_env" ] ; then + # shellcheck source=/etc/default/acme_sh_request_env + source "/etc/default/acme_sh_request_env" +else + echo "No letsencrypt default file" >> $LE_LOG_FILE +fi + +echo "Copying the cert files" >> $LE_LOG_FILE +if [ ! -f ${MYSQL_CERTDIR}/ca.pem ] ; then + /bin/cp -f "${LE_CERTS_DIR}/fullchain" ${MYSQL_CERTDIR}/ca.pem + chown mysql:mysql ${MYSQL_CERTDIR}/ca.pem +fi + +/bin/cp -f "${LE_CERTS_DIR}/privkey" ${MYSQL_CERTDIR}/client-key.pem +chmod 400 ${MYSQL_CERTDIR}/client-key.pem +chown mysql:mysql ${MYSQL_CERTDIR}/client-key.pem + +/bin/cp -f "${LE_CERTS_DIR}/cert" ${MYSQL_CERTDIR}/client-cert.pem +chmod 440 ${MYSQL_CERTDIR}/client-cert.pem +chown mysql:mysql ${MYSQL_CERTDIR}/client-cert.pem + +echo "Reload the mysql service" >> $LE_LOG_FILE +if [ -x /bin/systemctl ] ; then + systemctl reload mysql >> $LE_LOG_FILE 2>&1 +else + service mysql reload >> $LE_LOG_FILE 2>&1 +fi + +echo "Done." >> $LE_LOG_FILE + +exit 0 diff --git a/library/roles/mysql/tasks/main.yml b/library/roles/mysql/tasks/main.yml index 3a0aaa56..be17d3af 100644 --- a/library/roles/mysql/tasks/main.yml +++ b/library/roles/mysql/tasks/main.yml @@ -9,4 +9,7 @@ when: mysql_enabled | bool - import_tasks: mysql-backup.yml when: mysql_enabled | bool +- import_tasks: mysql-letsencrypt.yml + when: mysql_letsencrypt_certificates | bool + diff --git a/library/roles/mysql/tasks/mysql-conf.yml b/library/roles/mysql/tasks/mysql-conf.yml index 33265b6d..da9cb005 100644 --- a/library/roles/mysql/tasks/mysql-conf.yml +++ b/library/roles/mysql/tasks/mysql-conf.yml @@ -1,18 +1,24 @@ --- -- name: Create the data directory - file: dest={{ mysql_data_dir }} state=directory owner=mysql group=mysql mode=0700 - tags: [ 'mysql', 'mariadb', 'mysql-conf' ] +- name: Manage the MySQL configuration files + block: + - name: Create the data directory + file: dest={{ mysql_data_dir }} state=directory owner=mysql group=mysql mode=0700 + + - name: Create the log directory + file: dest={{ mysql_log_dir }} state=directory owner=mysql group=adm mode=1750 + + - name: Install the main configuration files. + template: src={{ item }}.cnf.j2 dest={{ mysql_conf_dir }}/{{ item }}.cnf owner=root group=root mode=0644 + with_items: + - client + - mysql-clients + notify: Restart mysql + + - name: Install the main configuration files. + template: src={{ item }}.cnf.j2 dest={{ mysql_service_conf_dir }}/mysqld.cnf owner=root group=root mode=0644 + with_items: + - server + notify: Restart mysql -- name: Create the log directory - file: dest={{ mysql_log_dir }} state=directory owner=mysql group=adm mode=1750 - tags: [ 'mysql', 'mariadb', 'mysql-conf' ] - -- name: Install the main configuration files. - template: src={{ item }}.cnf.j2 dest={{ mysql_conf_dir }}/{{ item }}.cnf owner=root group=root mode=0644 - with_items: - - client - - server - - mysql-clients - when: mysql_enabled - notify: Restart mysql - tags: [ 'mysql', 'mariadb', 'mysql-conf' ] + when: mysql_enabled | bool + tags: [ 'mysql', 'mariadb', 'mysql_conf' ] diff --git a/library/roles/mysql/tasks/mysql-letsencrypt.yml b/library/roles/mysql/tasks/mysql-letsencrypt.yml new file mode 100644 index 00000000..00e75d74 --- /dev/null +++ b/library/roles/mysql/tasks/mysql-letsencrypt.yml @@ -0,0 +1,30 @@ +--- +- name: Manage the letsencrypt configuration + block: + - name: Check if the letsencrypt certificates are in place + stat: path={{ letsencrypt_acme_certs_dir }}/privkey + register: letsencrypt_keyfile + + - name: Copy the letsencrypt certificate key into the right place + copy: src={{ letsencrypt_acme_certs_dir }}/privkey dest=/var/lib/mysql/client-key.pem owner=mysql group=mysql mode=0400 remote_src=yes force=yes + when: letsencrypt_keyfile.stat.exists is defined and letsencrypt_keyfile.stat.exists | bool + notify: Restart mysql + + - name: Copy the letsencrypt public certificate into the right place + copy: src={{ letsencrypt_acme_certs_dir }}/cert dest=/var/lib/mysql/client-cert.pem owner=mysql group=mysql mode=0444 remote_src=yes force=yes + when: letsencrypt_keyfile.stat.exists is defined and letsencrypt_keyfile.stat.exists | bool + notify: Restart mysql + + - name: Copy the letsencrypt CA certificate into the right place + copy: src={{ letsencrypt_acme_certs_dir }}/fullchain dest=/var/lib/mysql/ca.pem owner=mysql group=mysql mode=0444 remote_src=yes force=yes + when: letsencrypt_keyfile.stat.exists is defined and letsencrypt_keyfile.stat.exists | bool + notify: Restart mysql + + - name: Create the acme hooks directory if it does not yet exist + file: dest={{ letsencrypt_acme_sh_services_scripts_dir }} state=directory owner=root group=root + + - name: Install a script that fix the letsencrypt certificate for mysql and then reload the service + copy: src=letsencrypt-mysql-hook.sh dest={{ letsencrypt_acme_sh_services_scripts_dir }}/mysql owner=root group=root mode=4555 + + when: letsencrypt_acme_sh_install is defined and letsencrypt_acme_sh_install | bool + tags: [ 'mysql', 'mariadb', 'letsencrypt', 'mysql_letsencrypt' ] \ No newline at end of file diff --git a/library/roles/mysql/templates/server.cnf.j2 b/library/roles/mysql/templates/server.cnf.j2 index 07311ec5..b2d006ab 100644 --- a/library/roles/mysql/templates/server.cnf.j2 +++ b/library/roles/mysql/templates/server.cnf.j2 @@ -2,17 +2,33 @@ # The MariaDB server [mysqld] +user = mysql +{% if mysql_listen_on_ext_int %} +bind-address = 0.0.0.0 +{% else %} +bind-address = 127.0.0.1 +{% endif %} port = {{ mysql_db_port }} socket = {{ mysql_socket }} -max_connections = {{ mysql_db_max_connections }} +basedir = /usr datadir = {{ mysql_data_dir }} log_error = {{ mysql_log_dir }}/error.log skip-external-locking +# Point the following paths to different dedicated disks +tmpdir = /tmp +lc-messages-dir = /usr/share/mysql + +# +# * Fine Tuning +# +max_connections = {{ mysql_db_max_connections }} key_buffer_size = 16M max_allowed_packet = {{ mysql_max_allowed_packet }} table_open_cache = 512 sort_buffer_size = 8M net_buffer_length = 8K +thread_stack = 192K +thread_cache_size = 8 read_buffer_size = {{ mysqld_db_read_buffer_size }} read_rnd_buffer_size = {{ mysql_db_read_rnd_buffer_size }} myisam_sort_buffer_size = 16M @@ -31,24 +47,21 @@ ft_min_word_len = {{ mysqld_ft_min_word_lenght }} {% endif %} ft_boolean_syntax = '{{ mysql_ft_boolean_syntax | default('+ -><()~*:\"\"&|') }}' -# Point the following paths to different dedicated disks -#tmpdir = /tmp/ +# +# * Query Cache Configuration +# +query_cache_limit = 1M +query_cache_size = 16M -# Instead of skip-networking the default is now to listen only on -# localhost which is more compatible and is not less secure. -{% if mysql_listen_on_ext_int %} -bind-address = 0.0.0.0 -{% else %} -bind-address = 127.0.0.1 -{% endif %} {% if mysql_binary_logging %} server-id={{ mysql_server_id }} # Enable binary logging. This is required for acting as a MASTER in a # replication configuration. You also need the binary log if you need # the ability to do point in time recovery from your latest backup. -log-bin=mysql-bin - +log-bin={{ mysql_log_dir }}/mysql-bin.log +expire_logs_days = 10 +max_binlog_size = 100M # binary logging format - mixed recommended binlog_format=mixed {% endif %} @@ -66,5 +79,11 @@ innodb_log_buffer_size = {{ mysql_db_innodb_log_buffer_size }} innodb_flush_log_at_trx_commit = 1 innodb_lock_wait_timeout = 50 +{% if mysql_use_ssl %} +ssl-ca=/var/lib/mysql/ca.pem +ssl-cert=/var/lib/mysql/client-cert.pem +ssl-key=/var/lib/mysql/client-key.pem +{% endif %} + [mysqld_safe] open-files-limit = {{ mysql_safe_open_files_limit }}