1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-07 00:04:31 +03:00

MDEV-27181: Galera SST scripts should use ssl_capath for CA directory

1. Galera SST scripts should use ssl_capath (not ssl_ca) for CA
   directory. The current implementation tries to automatically
   detect the path using the trailing slash in the ssl_ca variable
   value, but this approach is not compatible with the server
   configuration. Now, by analogy with the server, SST scripts
   also use a separate ssl_capath variable. In addition, a similar
   tcapath variable has been added for the old-style configuration
   (in the "sst" section).
2. Openssl utility detection made more reliable.
3. Removed extra spaces in automatically generated command lines -
   to simplify debugging of the SST scripts.
4. In general, the code for detecting the presence or absence of
   auxiliary utilities has been improved - it is made more reliable
   in some configurations (and for shells other than bash).
This commit is contained in:
Julius Goryavsky
2021-12-14 03:47:59 +01:00
parent 660cfe4782
commit 30bf0bca8f
19 changed files with 1172 additions and 258 deletions

View File

@@ -19,6 +19,9 @@
set -u
# Setting the path for some utilities on CentOS
export PATH="$PATH:/usr/sbin:/usr/bin:/sbin:/bin"
WSREP_SST_OPT_BYPASS=0
WSREP_SST_OPT_BINLOG=""
WSREP_SST_OPT_BINLOG_INDEX=""
@@ -384,10 +387,8 @@ case "$1" in
skip_mysqld_arg=1
;;
'--innodb-force-recovery')
if [ -n "$value" ]; then
if [ "$value" -ne 0 ]; then
INNODB_FORCE_RECOVERY="$value"
fi
if [ -n "$value" -a "$value" != "0" ]; then
INNODB_FORCE_RECOVERY="$value"
fi
skip_mysqld_arg=1
;;
@@ -584,7 +585,8 @@ get_binlog()
if [ -n "$WSREP_SST_OPT_ADDR_PORT" ]; then
if [ -n "$WSREP_SST_OPT_PORT" ]; then
if [ "$WSREP_SST_OPT_PORT" != "$WSREP_SST_OPT_ADDR_PORT" ]; then
echo "WSREP_SST: [ERROR] port in --port=$WSREP_SST_OPT_PORT differs from port in --address=$WSREP_SST_OPT_ADDR" >&2
echo "WSREP_SST: [ERROR] port in --port=$WSREP_SST_OPT_PORT" \
"differs from port in --address=$WSREP_SST_OPT_ADDR" >&2
exit 2
fi
else
@@ -616,8 +618,19 @@ fi
readonly WSREP_SST_OPT_ADDR
readonly WSREP_SST_OPT_ADDR_PORT
# try to use my_print_defaults, mysql and mysqldump that come with the sources
# (for MTR suite)
commandex()
{
if [ -n "$BASH_VERSION" ]; then
command -v "$1" || :
elif [ -x "$1" ]; then
echo "$1"
else
which "$1" || :
fi
}
# try to use my_print_defaults, mysql and mysqldump that come
# with the sources (for MTR suite):
script_binary=$(dirname "$0")
SCRIPTS_DIR=$(cd "$script_binary"; pwd -P)
EXTRA_DIR="$SCRIPTS_DIR/../extra"
@@ -626,13 +639,13 @@ CLIENT_DIR="$SCRIPTS_DIR/../client"
if [ -x "$CLIENT_DIR/mariadb" ]; then
MYSQL_CLIENT="$CLIENT_DIR/mariadb"
else
MYSQL_CLIENT="$(command -v mariadb)"
MYSQL_CLIENT=$(commandex 'mariadb')
fi
if [ -x "$CLIENT_DIR/mariadb-dump" ]; then
MYSQLDUMP="$CLIENT_DIR/mariadb-dump"
else
MYSQLDUMP="$(command -v mariadb-dump)"
MYSQLDUMP=$(commandex 'mariadb-dump')
fi
wsrep_log()
@@ -663,7 +676,7 @@ if [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then
elif [ -x "$EXTRA_DIR/my_print_defaults" ]; then
MY_PRINT_DEFAULTS="$EXTRA_DIR/my_print_defaults"
else
MY_PRINT_DEFAULTS="$(command -v my_print_defaults)"
MY_PRINT_DEFAULTS=$(commandex 'my_print_defaults')
if [ -z "$MY_PRINT_DEFAULTS" ]; then
wsrep_log_error "my_print_defaults not found in path"
exit 2
@@ -673,16 +686,16 @@ fi
readonly MY_PRINT_DEFAULTS
wsrep_defaults="$WSREP_SST_OPT_DEFAULTS"
wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_EXTRA_DEFAULTS"
wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT"
wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_EXTRA_DEFAULTS:+ }$WSREP_SST_OPT_EXTRA_DEFAULTS"
wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_SUFFIX_DEFAULT:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT"
readonly WSREP_SST_OPT_CONF="$wsrep_defaults"
readonly WSREP_SST_OPT_CONF="${wsrep_defaults:+ }$wsrep_defaults"
wsrep_defaults="$WSREP_SST_OPT_DEFAULT"
wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_EXTRA_DEFAULT"
wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT"
wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_EXTRA_DEFAULT:+ }$WSREP_SST_OPT_EXTRA_DEFAULT"
wsrep_defaults="$wsrep_defaults${WSREP_SST_OPT_SUFFIX_DEFAULT:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT"
readonly WSREP_SST_OPT_CONF_UNQUOTED="$wsrep_defaults"
readonly WSREP_SST_OPT_CONF_UNQUOTED="${wsrep_defaults:+ }$wsrep_defaults"
#
# User can specify mariabackup specific settings that will be used during sst
@@ -819,8 +832,7 @@ if wsrep_auth_not_set; then
fi
# Splitting WSREP_SST_OPT_AUTH as "user:password" pair:
if ! wsrep_auth_not_set
then
if ! wsrep_auth_not_set; then
# Extract username as shortest prefix up to first ':' character:
WSREP_SST_OPT_AUTH_USER="${WSREP_SST_OPT_AUTH%%:*}"
if [ -z "$WSREP_SST_OPT_USER" ]; then
@@ -848,8 +860,7 @@ readonly WSREP_SST_OPT_USER
readonly WSREP_SST_OPT_PSWD
readonly WSREP_SST_OPT_AUTH
if [ -n "$WSREP_SST_OPT_REMOTE_AUTH" ]
then
if [ -n "$WSREP_SST_OPT_REMOTE_AUTH" ]; then
# Split auth string at the last ':'
readonly WSREP_SST_OPT_REMOTE_USER="${WSREP_SST_OPT_REMOTE_AUTH%%:*}"
readonly WSREP_SST_OPT_REMOTE_PSWD="${WSREP_SST_OPT_REMOTE_AUTH#*:}"
@@ -860,8 +871,7 @@ fi
readonly WSREP_SST_OPT_REMOTE_AUTH
if [ -n "$WSREP_SST_OPT_DATA" ]
then
if [ -n "$WSREP_SST_OPT_DATA" ]; then
SST_PROGRESS_FILE="$WSREP_SST_OPT_DATA/sst_in_progress"
else
SST_PROGRESS_FILE=""
@@ -870,13 +880,14 @@ fi
wsrep_cleanup_progress_file()
{
[ -n "$SST_PROGRESS_FILE" -a \
-f "$SST_PROGRESS_FILE" ] && rm -f "$SST_PROGRESS_FILE" 2>/dev/null || true
-f "$SST_PROGRESS_FILE" ] && \
rm -f "$SST_PROGRESS_FILE" 2>/dev/null || :
}
wsrep_check_program()
{
local prog="$1"
local cmd=$(command -v "$prog")
local cmd=$(commandex "$prog")
if [ -z "$cmd" ]; then
echo "'$prog' not found in PATH"
return 2 # no such file or directory
@@ -898,9 +909,9 @@ wsrep_check_programs()
wsrep_check_datadir()
{
if [ -z "$WSREP_SST_OPT_DATA" ]
then
wsrep_log_error "The '--datadir' parameter must be passed to the SST script"
if [ -z "$WSREP_SST_OPT_DATA" ]; then
wsrep_log_error \
"The '--datadir' parameter must be passed to the SST script"
exit 2
fi
}
@@ -912,10 +923,10 @@ get_openssl()
return
fi
# Let's look for openssl:
OPENSSL_BINARY="$(command -v openssl)"
OPENSSL_BINARY=$(commandex 'openssl')
if [ -z "$OPENSSL_BINARY" ]; then
OPENSSL_BINARY='/usr/bin/openssl'
if [ -z "$OPENSSL_BINARY" ]; then
if [ ! -x "$OPENSSL_BINARY" ]; then
OPENSSL_BINARY=""
fi
fi
@@ -928,13 +939,12 @@ get_openssl()
wsrep_gen_secret()
{
get_openssl
if [ -n "$OPENSSL_BINARY" ]
then
if [ -n "$OPENSSL_BINARY" ]; then
echo $("$OPENSSL_BINARY" rand -hex 16)
else
printf "%04x%04x%04x%04x%04x%04x%04x%04x" \
$RANDOM $RANDOM $RANDOM $RANDOM \
$RANDOM $RANDOM $RANDOM $RANDOM
$RANDOM $RANDOM $RANDOM $RANDOM \
$RANDOM $RANDOM $RANDOM $RANDOM
fi
}
@@ -968,14 +978,14 @@ is_local_ip()
fi
# Now let's check if the given address is assigned to
# one of the network cards:
local ip_util="$(command -v ip)"
local ip_util=$(commandex 'ip')
if [ -n "$ip_util" ]; then
# ip address show ouput format is " inet[6] <address>/<mask>":
"$ip_util" address show \
| grep -E "^[[:space:]]*inet.? [^[:space:]]+/" -o \
| grep -F " $1/" >/dev/null && return 0
else
local ifconfig_util="$(command -v ifconfig)"
local ifconfig_util=$(commandex 'ifconfig')
if [ -n "$ifconfig_util" ]; then
# ifconfig output format is " inet[6] <address> ...":
"$ifconfig_util" \
@@ -992,15 +1002,15 @@ check_sockets_utils()
sockstat_available=0
ss_available=0
[ -n "$(command -v lsof)" ] && lsof_available=1
[ -n "$(command -v sockstat)" ] && sockstat_available=1
[ -n "$(command -v ss)" ] && ss_available=1
[ -n "$(commandex lsof)" ] && lsof_available=1
[ -n "$(commandex sockstat)" ] && sockstat_available=1
[ -n "$(commandex ss)" ] && ss_available=1
if [ $lsof_available -eq 0 -a \
$sockstat_available -eq 0 -a \
$ss_available -eq 0 ]
then
wsrep_log_error "Neither lsof, nor sockstat or ss tool was found in " \
wsrep_log_error "Neither lsof, nor sockstat or ss tool was found in" \
"the PATH. Make sure you have it installed."
exit 2 # ENOENT
fi
@@ -1085,26 +1095,38 @@ check_for_dhparams()
#
verify_ca_matches_cert()
{
local ca="$1"
local cert="$2"
local path=${3:-0}
local cert="$1"
local ca="$2"
local cap="$3"
# If the openssl utility is not installed, then
# we will not do this certificate check:
get_openssl
if [ -z "$OPENSSL_BINARY" ]; then
wsrep_log_info "openssl utility not found"
return
fi
local not_match=0
local readable=1; [ ! -r "$cert" ] && readable=0
[ -n "$ca" ] && [ ! -r "$ca" ] && readable=0
[ -n "$cap" ] && [ ! -r "$cap" ] && readable=0
if [ $path -eq 0 ]; then
"$OPENSSL_BINARY" verify -verbose -CAfile "$ca" "$cert" >/dev/null 2>&1 || not_match=1
else
"$OPENSSL_BINARY" verify -verbose -CApath "$ca" "$cert" >/dev/null 2>&1 || not_match=1
if [ readable -eq 0 ]; then
wsrep_log_error \
"Both PEM file and CA file (or path) must be readable"
exit 22
fi
local not_match=0
local errmsg
errmsg=$("$OPENSSL_BINARY" verify -verbose \
${ca:+ -CAfile} ${ca:+ "$ca"} \
${cap:+ -CApath} ${cap:+ "$cap"} \
"$cert" 2>&1) || not_match=1
if [ $not_match -eq 1 ]; then
wsrep_log_info "run: \"$OPENSSL_BINARY\" verify -verbose${ca:+ -CAfile \"$ca\"}${cap:+ -CApath \"$cap\"} \"$cert\""
wsrep_log_info "output: $errmsg"
wsrep_log_error "******** FATAL ERROR ********************************************"
wsrep_log_error "* The certifcate and CA (certificate authority) do not match. *"
wsrep_log_error "* It does not appear that the certificate was issued by the CA. *"
@@ -1124,12 +1146,18 @@ verify_ca_matches_cert()
#
verify_cert_matches_key()
{
local cert_path="$1"
local key_path="$2"
local cert="$1"
local key="$2"
if [ ! -r "$key" -o ! -r "$cert" ]; then
wsrep_log_error "Both the certificate file and the key file" \
"must be readable"
exit 22
fi
# If the diff utility is not installed, then
# we will not do this certificate check:
if [ -z "$(command -v diff)" ]; then
if [ -z "$(commandex diff)" ]; then
return
fi
@@ -1142,13 +1170,13 @@ verify_cert_matches_key()
# Generate the public key from the cert and the key.
# They should match (otherwise we can't create an SSL connection).
if ! diff <("$OPENSSL_BINARY" x509 -in "$cert_path" -pubkey -noout 2>/dev/null) \
<("$OPENSSL_BINARY" pkey -in "$key_path" -pubout 2>/dev/null) >/dev/null 2>&1
if ! diff <("$OPENSSL_BINARY" x509 -in "$cert" -pubkey -noout 2>/dev/null) \
<("$OPENSSL_BINARY" pkey -in "$key" -pubout 2>/dev/null) >/dev/null 2>&1
then
wsrep_log_error "******************* FATAL ERROR ****************"
wsrep_log_error "* The certifcate and private key do not match. *"
wsrep_log_error "* Please check your certificate and key files. *"
wsrep_log_error "************************************************"
wsrep_log_error "******************* FATAL ERROR *****************"
wsrep_log_error "* The certificate and private key do not match. *"
wsrep_log_error "* Please check your certificate and key files. *"
wsrep_log_error "*************************************************"
exit 22
fi
}
@@ -1305,9 +1333,9 @@ get_proc()
elif [ "$OS" = 'Darwin' -o "$OS" = 'FreeBSD' ]; then
nproc=$(sysctl -n hw.ncpu)
fi
set -e
if [ -z "$nproc" ] || [ $nproc -eq 0 ]; then
nproc=1
fi
set -e
fi
}