blob: de28468e8e76e6d00727070c3b4e5a64f8d1ad18 [file] [log] [blame]
#!/bin/bash
#
# module.sh - mysql
#
# Copyright 2019 Luigi Santivetti <luigi.santivetti@gmail.com>
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
declare -r module="mysql"
source $common_sh
module_enable $module
declare -r etc_d="$mod_rootfs_d/etc"
declare -r initdb_d="$mod_docker_d"
declare -r var_d="$mod_rootfs_d/var"
declare -r mycnf_d="$etc_d/mysql"
declare -r mysql_d="$var_d/lib/mysql"
declare -r log_d="$var_d/log/mysql"
declare -ir mysql_uid="999"
declare -ir mysql_has_dummy_certs=1
if [ $mysql_has_dummy_certs -eq 1 ]; then
declare -r certificates_d="$mod_staging_d/${module}_dummy_cert"
declare -r ca_key_f="$certificates_d/${module}_dummy-ca-key.pem"
declare -r ca_f="$certificates_d/${module}_dummy-ca.pem"
declare -r server_key_f="$certificates_d/${module}_dummy-server-key.pem"
declare -r server_req_f="$certificates_d/${module}_dummy-server-req.pem"
declare -r server_cert_f="$certificates_d/${module}_dummy-server-cert.pem"
declare -r client_key_f="$certificates_d/${module}_dummy-client-key.pem"
declare -r client_req_f="$certificates_d/${module}_dummy-client-req.pem"
declare -r client_cert_f="$certificates_d/${module}_dummy-client-cert.pem"
# Dup ca to avoid bind mounting the same file twice
declare -r ca_dup_f="$certificates_d/${module}_dummy-ca-dup.pem"
else
lets -l -e "official CA certificates not supported"
exit 1
fi
declare -r certificates_l="$etc_d/mysql_ssl"
# Output files
declare -r dockerfile="Dockerfile"
declare -r dockerfile_f="$mod_docker_d/$dockerfile"
declare -r initdb_f="$initdb_d/initdb.sql"
declare -r mycnf_f="$mycnf_d/my.cnf"
declare -r log_error_f="$log_d/error.txt"
declare -r log_general_f="$log_d/general.txt"
declare -r log_query_f="$log_d/query.txt"
declare -r mysql_cli_bang_f="$mod_docker_d/mysql-cli.sh"
declare -ar mod_more_dirs=( \
$etc_d $initdb_d $var_d $mycnf_d $log_d $mysql_d \
)
declare -ar mod_more_files=( $mycnf_f $initdb_f $dockerfile_f $mysql_cli_bang_f )
declare -ar mod_more_trefs=( mycnf_t initdb_t dockerfile_t mysql_cli_bang_t )
function tod_watch
{
__watch_module_common || return $s_err
}
function tod_doins
{
__doins_module_common || return $s_err
__mysql_do_log_files || return $s_err
# Use certificates provided by Apache
__mysql_do_dummy_cert || return $s_err
__mysql_do_links || return $s_err
}
function tod_clins
{
__clins_module_common || return $s_err
__mysql_undo_log_files || return $s_err
}
function tod_upins
{
__upins_module_common || return $s_err
# Use ceritificates provided by Apache
__mysql_do_dummy_cert || return $s_err
}
function tod_doall
{
tod_doins
}
function tod_upall
{
tod_upins
}
function __mysql_do_dummy_cert_helper
{
# Credits:
# https://techsparx.com/software-development/docker/damp/mysql-ssl-connection.html
local -r OPENSSL_SUBJ="/C=US/ST=Utopia/L=Neverland"
local -r OPENSSL_CA="${OPENSSL_SUBJ}/CN=dummy-CA"
local -r OPENSSL_SERVER="${OPENSSL_SUBJ}/CN=dummy-server"
local -r OPENSSL_CLIENT="${OPENSSL_SUBJ}/CN=dummy-client"
# Generate new CA certificate ca.pem file.
openssl genrsa 2048 > $ca_key_f
# TODO This has interaction that must be automated
openssl req -new -x509 -nodes -days 3600 \
-subj "${OPENSSL_CA}" \
-key $ca_key_f -out $ca_f
# Create the server-side certificates
# This has more interaction that must be automated
openssl req -newkey rsa:2048 -days 3600 -nodes \
-subj "${OPENSSL_SERVER}" \
-keyout $server_key_f -out $server_req_f
openssl rsa -in $server_key_f -out $server_key_f
openssl x509 -req -in $server_req_f -days 3600 \
-CA $ca_f -CAkey $ca_key_f -set_serial 01 -out $server_cert_f
# Create the client-side certificates
openssl req -newkey rsa:2048 -days 3600 -nodes \
-subj "${OPENSSL_CLIENT}" \
-keyout $client_key_f -out $client_req_f
openssl rsa -in $client_key_f -out $client_key_f
openssl x509 -req -in $client_req_f -days 3600 \
-CA $ca_f -CAkey $ca_key_f -set_serial 01 -out $client_cert_f
# Verify the certificates are correct
openssl verify -CAfile \
$ca_f $server_cert_f $client_cert_f || return $s_err
# Duplicate ca as it needs to be mounted client side
cp -ar $ca_f $ca_dup_f
set_mode "0644" $mysql_uid $ca_f \
$server_key_f $server_req_f $server_cert_f || return $s_err
# WARNING! The only client expected is apache. This can break other clients
set_mode "0644" "www-data" \
$ca_dup_f $client_key_f $client_cert_f || return $s_err
set_mode "0600" $mysql_uid $ca_key_f || return $s_err
set_mode "0755" root $certificates_d || return $s_err
}
function __mysql_do_dummy_cert
{
if [ $mysql_has_dummy_certs -eq 1 ]; then
if [ ! -d $certificates_d ]; then
mkdir -p $certificates_d && \
pushd $certificates_d >/dev/null || return $s_err
__mysql_do_dummy_cert_helper 2>&1 | lets -l -x "openssl"
case "${PIPESTATUS[0]}" in
$s_err ) lets -l -e "failed to make dummy certificates"
popd >/dev/null; return $s_err ;;
esac
popd >/dev/null
fi
fi;
lets -l -i "$module SSL cert from: ${certificates_d#$script_dir/}"
return $s_ok
}
function __mysql_do_links
{
# NOTE: container path must match localhost path
#
# i.e.
# localhost:/etc container:/etc OK
# localhost:/home/luigi container:/home/??? NOT OK
#
ln -sf "${certificates_d}" "${certificates_l}"
}
function __mysql_do_log_files
{
sudo touch $log_error_f $log_general_f $log_query_f || {
lets -l -e "failed to touch log files"; return $s_err
}
set_mode "0755" $mysql_uid $log_d || {
lets -l -e "failed to set mode $log_d"; return $s_err
}
set_mode "0644" $mysql_uid $log_error_f $log_general_f $log_query_f || {
lets -l -e "failed to set mode log files"; return $s_err
}
}
function __mysql_undo_log_files
{
sudo rm -f $log_error_f $log_general_f $log_query_f || {
lets -l -e "failed remove log files"; return $s_err
}
__mysql_do_log_files
}