Commit fe7e44d8 authored by Julius Goryavsky's avatar Julius Goryavsky

MDEV-21192: SST failing when enabling IPV6

The following features have been added:

1) Automatic addition of the pf = ip6 option for socat
   when it can be recognized by the format of the connection
   address;
2) Automatically add or remove extra commas at the beginning
   and at the end of sockopt, for example, sockopt='pf=ip6'
   and sockopt=',pf=ip6' work equally well;

Also, due to interference in the code of the get_transfer()
function, I also refactored it and now:

3) encrypt = 4 is supported not only for xtrabackup-v2,
   but also for mariabackup - this can help with migration
   from Percona;
4) Improved setting of 'commonname' option for encrypt=3
   and encrypt=4 modes;
parent 81f94c26
...@@ -34,4 +34,3 @@ bind-address=:: ...@@ -34,4 +34,3 @@ bind-address=::
[SST] [SST]
transferfmt=@ENV.MTR_GALERA_TFMT transferfmt=@ENV.MTR_GALERA_TFMT
streamfmt=xbstream streamfmt=xbstream
sockopt=",pf=ip6"
...@@ -38,4 +38,5 @@ bind-address=:: ...@@ -38,4 +38,5 @@ bind-address=::
[SST] [SST]
transferfmt=@ENV.MTR_GALERA_TFMT transferfmt=@ENV.MTR_GALERA_TFMT
streamfmt=xbstream streamfmt=xbstream
# Not needed, but left here for debugging:
sockopt=",pf=ip6" sockopt=",pf=ip6"
...@@ -24,6 +24,3 @@ wsrep_provider_options='base_host=[::1];base_port=@mysqld.3.#galera_port;gmcast. ...@@ -24,6 +24,3 @@ wsrep_provider_options='base_host=[::1];base_port=@mysqld.3.#galera_port;gmcast.
wsrep_sst_receive_address='[::1]:@mysqld.3.#sst_port' wsrep_sst_receive_address='[::1]:@mysqld.3.#sst_port'
wsrep_node_incoming_address='[::1]:@mysqld.3.port' wsrep_node_incoming_address='[::1]:@mysqld.3.port'
bind-address=:: bind-address=::
[SST]
sockopt=",pf=ip6"
...@@ -24,6 +24,3 @@ wsrep_provider_options='base_host=[::1];base_port=@mysqld.3.#galera_port;gmcast. ...@@ -24,6 +24,3 @@ wsrep_provider_options='base_host=[::1];base_port=@mysqld.3.#galera_port;gmcast.
wsrep_sst_receive_address='[::1]:@mysqld.3.#sst_port' wsrep_sst_receive_address='[::1]:@mysqld.3.#sst_port'
wsrep_node_incoming_address='[::1]:@mysqld.3.port' wsrep_node_incoming_address='[::1]:@mysqld.3.port'
bind-address=:: bind-address=::
[SST]
sockopt=",pf=ip6"
...@@ -29,6 +29,3 @@ wsrep_provider_options='base_host=[::1];base_port=@mysqld.3.#galera_port;gmcast. ...@@ -29,6 +29,3 @@ wsrep_provider_options='base_host=[::1];base_port=@mysqld.3.#galera_port;gmcast.
wsrep_sst_receive_address='[::1]:@mysqld.3.#sst_port' wsrep_sst_receive_address='[::1]:@mysqld.3.#sst_port'
wsrep_node_incoming_address='[::1]:@mysqld.3.port' wsrep_node_incoming_address='[::1]:@mysqld.3.port'
bind-address=:: bind-address=::
[SST]
sockopt=",pf=ip6"
...@@ -1021,3 +1021,25 @@ check_for_version() ...@@ -1021,3 +1021,25 @@ check_for_version()
[ $z1 -lt $z2 ] && return 1 [ $z1 -lt $z2 ] && return 1
return 0 return 0
} }
trim_string()
{
if [ -n "$BASH_VERSION" ]; then
local pattern="[![:space:]${2:-}]"
local x="${1#*$pattern}"
local z=${#1}
x=${#x}
if [ $x -ne $z ]; then
local y="${1%$pattern*}"
y=${#y}
x=$(( $z-$x-1 ))
y=$(( $y-$x+1 ))
printf '%s' "${1:$x:$y}"
else
printf ''
fi
else
local pattern="[[:space:]${2:-}]"
echo "$1" | sed -E "s/^$pattern+|$pattern+\$//g"
fi
}
...@@ -34,8 +34,6 @@ ecode=0 ...@@ -34,8 +34,6 @@ ecode=0
ssyslog="" ssyslog=""
ssystag="" ssystag=""
MARIABACKUP_PID="" MARIABACKUP_PID=""
SST_PORT=""
REMOTEIP=""
tcert="" tcert=""
tpem="" tpem=""
tkey="" tkey=""
...@@ -94,7 +92,7 @@ declare -a RC ...@@ -94,7 +92,7 @@ declare -a RC
MARIABACKUP_BIN="$(command -v mariabackup)" MARIABACKUP_BIN="$(command -v mariabackup)"
if [ ! -x "$MARIABACKUP_BIN" ]; then if [ ! -x "$MARIABACKUP_BIN" ]; then
wsrep_log_error 'mariabackup binary not found in $PATH' wsrep_log_error 'mariabackup binary not found in path'
exit 42 exit 42
fi fi
...@@ -214,8 +212,6 @@ get_keys() ...@@ -214,8 +212,6 @@ get_keys()
get_transfer() get_transfer()
{ {
TSST_PORT="$SST_PORT"
if [ $tfmt = 'nc' ]; then if [ $tfmt = 'nc' ]; then
wsrep_log_info "Using netcat as streamer" wsrep_log_info "Using netcat as streamer"
wsrep_check_programs nc wsrep_check_programs nc
...@@ -237,7 +233,7 @@ get_transfer() ...@@ -237,7 +233,7 @@ get_transfer()
wsrep_log_info "Using traditional netcat as streamer" wsrep_log_info "Using traditional netcat as streamer"
tcmd="$tcmd -l -p" tcmd="$tcmd -l -p"
fi fi
tcmd="$tcmd $TSST_PORT" tcmd="$tcmd $SST_PORT"
else else
# Check to see if netcat supports the '-N' flag. # Check to see if netcat supports the '-N' flag.
# -N Shutdown the network socket after EOF on stdin # -N Shutdown the network socket after EOF on stdin
...@@ -259,7 +255,7 @@ get_transfer() ...@@ -259,7 +255,7 @@ get_transfer()
wsrep_log_info "Using traditional netcat as streamer" wsrep_log_info "Using traditional netcat as streamer"
tcmd="$tcmd -q0" tcmd="$tcmd -q0"
fi fi
tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT" tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $SST_PORT"
fi fi
else else
tfmt='socat' tfmt='socat'
...@@ -267,8 +263,38 @@ get_transfer() ...@@ -267,8 +263,38 @@ get_transfer()
wsrep_log_info "Using socat as streamer" wsrep_log_info "Using socat as streamer"
wsrep_check_programs socat wsrep_check_programs socat
if [ $encrypt -eq 2 -o $encrypt -eq 3 ] && ! socat -V | grep -q -F 'WITH_OPENSSL 1'; then if [ -n "$sockopt" ]; then
wsrep_log_error "Encryption requested, but socat is not OpenSSL enabled (encrypt=$encrypt)" sockopt=$(trim_string "$sockopt" ',')
if [ -n "$sockopt" ]; then
sockopt=",$sockopt"
fi
fi
# Add an option for ipv6 if needed:
if [ $WSREP_SST_OPT_HOST_IPv6 -eq 1 ]; then
# If sockopt contains 'pf=ip6' somewhere in the middle,
# this will not interfere with socat, but exclude the trivial
# cases when sockopt contains 'pf=ip6' as prefix or suffix:
if [ "$sockopt" = "${sockopt#,pf=ip6}" -a \
"$sockopt" = "${sockopt%,pf=ip6}" ]
then
sockopt=",pf=ip6$sockopt"
fi
fi
if [ $encrypt -lt 2 ]; then
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
tcmd="socat -u TCP-LISTEN:$SST_PORT,reuseaddr$sockopt stdio"
else
tcmd="socat -u stdio TCP:$REMOTEIP:$SST_PORT$sockopt"
fi
return
fi
if ! socat -V | grep -q -F 'WITH_OPENSSL 1'; then
wsrep_log_error "******** FATAL ERROR ************************************************ "
wsrep_log_error "* Encryption requested, but socat is not OpenSSL enabled (encrypt=$encrypt) *"
wsrep_log_error "********************************************************************* "
exit 2 exit 2
fi fi
...@@ -281,11 +307,21 @@ get_transfer() ...@@ -281,11 +307,21 @@ get_transfer()
exit 2 exit 2
fi fi
if ! check_for_version "$SOCAT_VERSION" "1.7.3"; then local action='Decrypting'
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
tcmd="socat -u openssl-listen:$SST_PORT,reuseaddr"
else
tcmd="socat -u stdio openssl-connect:$REMOTEIP:$SST_PORT"
action='Encrypting'
fi
if ! check_for_version "$SOCAT_VERSION" '1.7.3'; then
# socat versions < 1.7.3 will have 512-bit dhparams (too small) # socat versions < 1.7.3 will have 512-bit dhparams (too small)
# so create 2048-bit dhparams and send that as a parameter: # so create 2048-bit dhparams and send that as a parameter:
check_for_dhparams check_for_dhparams
sockopt=",dhparam='$ssl_dhparams'$sockopt" if [ -n "$ssl_dhparams" ]; then
tcmd="$tcmd,dhparam='$ssl_dhparams'"
fi
fi fi
if [ $encrypt -eq 2 ]; then if [ $encrypt -eq 2 ]; then
...@@ -294,15 +330,10 @@ get_transfer() ...@@ -294,15 +330,10 @@ get_transfer()
wsrep_log_error "Both PEM and CRT files required" wsrep_log_error "Both PEM and CRT files required"
exit 22 exit 22
fi fi
tcmd="$tcmd,cert='$tpem',cafile='$tcert'$sockopt"
stagemsg="$stagemsg-OpenSSL-Encrypted-2" stagemsg="$stagemsg-OpenSSL-Encrypted-2"
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then wsrep_log_info "$action with cert=$tpem, cafile=$tcert"
wsrep_log_info "Decrypting with cert=${tpem}, cafile=${tcert}" elif [ $encrypt -eq 3 -o $encrypt -eq 4 ]; then
tcmd="socat -u openssl-listen:$TSST_PORT,reuseaddr,cert='$tpem',cafile='$tcert'$sockopt stdio"
else
wsrep_log_info "Encrypting with cert=${tpem}, cafile=${tcert}"
tcmd="socat -u stdio openssl-connect:$REMOTEIP:$TSST_PORT,cert='$tpem',cafile='$tcert'$sockopt"
fi
elif [ $encrypt -eq 3 ]; then
wsrep_log_info "Using openssl based encryption with socat: with key and crt" wsrep_log_info "Using openssl based encryption with socat: with key and crt"
if [ -z "$tpem" -o -z "$tkey" ]; then if [ -z "$tpem" -o -z "$tkey" ]; then
wsrep_log_error "Both certificate and key files required" wsrep_log_error "Both certificate and key files required"
...@@ -310,36 +341,34 @@ get_transfer() ...@@ -310,36 +341,34 @@ get_transfer()
fi fi
stagemsg="$stagemsg-OpenSSL-Encrypted-3" stagemsg="$stagemsg-OpenSSL-Encrypted-3"
if [ -z "$tcert" ]; then if [ -z "$tcert" ]; then
# no verification if [ $encrypt -eq 4 ]; then
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then wsrep_log_error "Peer certificate required if encrypt=4"
wsrep_log_info "Decrypting with cert=${tpem}, key=${tkey}, verify=0" exit 22
tcmd="socat -u openssl-listen:$TSST_PORT,reuseaddr,cert='$tpem',key='$tkey',verify=0$sockopt stdio"
else
wsrep_log_info "Encrypting with cert=${tpem}, key=${tkey}, verify=0"
tcmd="socat -u stdio openssl-connect:$REMOTEIP:$TSST_PORT,cert='$tpem',key='$tkey',verify=0$sockopt"
fi fi
# no verification
tcmd="$tcmd,cert='$tpem',key='$tkey',verify=0$sockopt"
wsrep_log_info "$action with cert=$tpem, key=$tkey, verify=0"
else else
# CA verification # CA verification
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then
wsrep_log_info "Decrypting with cert=${tpem}, key=${tkey}, cafile=${tcert}" CN_option=",commonname='$WSREP_SST_OPT_REMOTE_USER'"
tcmd="socat -u openssl-listen:$TSST_PORT,reuseaddr,cert='$tpem',key='$tkey',cafile='$tcert'$sockopt stdio" elif [ $encrypt -eq 4 ]; then
CN_option=",commonname=''"
elif is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then
CN_option=',commonname=localhost'
else else
CN_option="" CN_option=",commonname='$WSREP_SST_OPT_HOST_UNSECAPED'"
if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then
CN_option=",commonname='$WSREP_SST_OPT_REMOTE_USER'"
elif is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then
CN_option=',commonname=localhost'
fi
wsrep_log_info "Encrypting with cert=${tpem}, key=${tkey}, cafile=${tcert}"
tcmd="socat -u stdio openssl-connect:$REMOTEIP:$TSST_PORT,cert='$tpem',key='$tkey',cafile='$tcert'$CN_option$sockopt"
fi fi
tcmd="$tcmd,cert='$tpem',key='$tkey',cafile='$tcert'$CN_option$sockopt"
wsrep_log_info "$action with cert=$tpem, key=$tkey, cafile=$tcert"
fi fi
else else
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then wsrep_log_info "Unknown encryption mode: encrypt=$encrypt"
tcmd="socat -u TCP-LISTEN:$TSST_PORT,reuseaddr$sockopt stdio" exit 22
else fi
tcmd="socat -u stdio TCP:$REMOTEIP:$TSST_PORT$sockopt"
fi if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
tcmd="$tcmd stdio"
fi fi
fi fi
} }
...@@ -347,7 +376,7 @@ get_transfer() ...@@ -347,7 +376,7 @@ get_transfer()
get_footprint() get_footprint()
{ {
pushd "$WSREP_SST_OPT_DATA" 1>/dev/null pushd "$WSREP_SST_OPT_DATA" 1>/dev/null
payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c | awk 'END { print $1 }') payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c -s | awk 'END { print $1 }')
if [ "$compress" != 'none' ]; then if [ "$compress" != 'none' ]; then
# QuickLZ has around 50% compression ratio # QuickLZ has around 50% compression ratio
# When compression/compaction used, the progress is only an approximate. # When compression/compaction used, the progress is only an approximate.
...@@ -440,7 +469,7 @@ read_cnf() ...@@ -440,7 +469,7 @@ read_cnf()
sockopt=$(parse_cnf sst sockopt "") sockopt=$(parse_cnf sst sockopt "")
progress=$(parse_cnf sst progress "") progress=$(parse_cnf sst progress "")
ttime=$(parse_cnf sst time 0) ttime=$(parse_cnf sst time 0)
cpat='.*galera\.cache$\|.*sst_in_progress$\|.*\.sst$\|.*gvwstate\.dat$\|.*grastate\.dat$\|.*\.err$\|.*\.log$\|.*RPM_UPGRADE_MARKER$\|.*RPM_UPGRADE_HISTORY$' cpat='.*\.pem$\|.*galera\.cache$\|.*sst_in_progress$\|.*\.sst$\|.*gvwstate\.dat$\|.*grastate\.dat$\|.*\.err$\|.*\.log$\|.*RPM_UPGRADE_MARKER$\|.*RPM_UPGRADE_HISTORY$'
[ "$OS" = 'FreeBSD' ] && cpat=$(echo "$cpat" | sed 's/\\|/|/g') [ "$OS" = 'FreeBSD' ] && cpat=$(echo "$cpat" | sed 's/\\|/|/g')
cpat=$(parse_cnf sst cpat "$cpat") cpat=$(parse_cnf sst cpat "$cpat")
scomp=$(parse_cnf sst compressor "") scomp=$(parse_cnf sst compressor "")
...@@ -807,8 +836,6 @@ monitor_process() ...@@ -807,8 +836,6 @@ monitor_process()
done done
} }
wsrep_check_programs "$MARIABACKUP_BIN"
[ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE" [ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
if [ "$WSREP_SST_OPT_ROLE" != 'joiner' -a "$WSREP_SST_OPT_ROLE" != 'donor' ]; then if [ "$WSREP_SST_OPT_ROLE" != 'joiner' -a "$WSREP_SST_OPT_ROLE" != 'donor' ]; then
...@@ -842,7 +869,6 @@ INNODB_DATA_HOME_DIR=$(pwd -P) ...@@ -842,7 +869,6 @@ INNODB_DATA_HOME_DIR=$(pwd -P)
cd "$OLD_PWD" cd "$OLD_PWD"
if [ $ssyslog -eq 1 ]; then if [ $ssyslog -eq 1 ]; then
if [ -n "$(command -v logger)" ]; then if [ -n "$(command -v logger)" ]; then
wsrep_log_info "Logging all stderr of SST/mariabackup to syslog" wsrep_log_info "Logging all stderr of SST/mariabackup to syslog"
...@@ -860,70 +886,65 @@ if [ $ssyslog -eq 1 ]; then ...@@ -860,70 +886,65 @@ if [ $ssyslog -eq 1 ]; then
else else
wsrep_log_error "logger not in path: $PATH. Ignoring" wsrep_log_error "logger not in path: $PATH. Ignoring"
fi fi
INNOAPPLY="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply" INNOAPPLY="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply"
INNOMOVE="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move" INNOMOVE="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move"
INNOBACKUP="2> >(logger -p daemon.err -t ${ssystag}innobackupex-backup)" INNOBACKUP="2> >(logger -p daemon.err -t ${ssystag}innobackupex-backup)"
else else
if [ $sstlogarchive -eq 1 ]
then
ARCHIVETIMESTAMP=$(date "+%Y.%m.%d-%H.%M.%S.%N")
if [ $sstlogarchive -eq 1 ] if [ -n "$sstlogarchivedir" ]; then
then if [ ! -d "$sstlogarchivedir" ]; then
ARCHIVETIMESTAMP=$(date "+%Y.%m.%d-%H.%M.%S.%N") mkdir -p "$sstlogarchivedir"
fi
if [ -n "$sstlogarchivedir" ]; then
if [ ! -d "$sstlogarchivedir" ]; then
mkdir -p "$sstlogarchivedir"
fi fi
fi
if [ -e "$INNOAPPLYLOG" ] if [ -e "$INNOAPPLYLOG" ]
then
if [ -n "$sstlogarchivedir" ]
then then
newfile=$(basename "$INNOAPPLYLOG") if [ -n "$sstlogarchivedir" ]
newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" then
else newfile=$(basename "$INNOAPPLYLOG")
newfile="$INNOAPPLYLOG.$ARCHIVETIMESTAMP" newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
else
newfile="$INNOAPPLYLOG.$ARCHIVETIMESTAMP"
fi
wsrep_log_info "Moving '$INNOAPPLYLOG' to '$newfile'"
mv "$INNOAPPLYLOG" "$newfile"
gzip "$newfile"
fi fi
wsrep_log_info "Moving '$INNOAPPLYLOG' to '$newfile'"
mv "$INNOAPPLYLOG" "$newfile"
gzip "$newfile"
fi
if [ -e "$INNOMOVELOG" ] if [ -e "$INNOMOVELOG" ]
then
if [ -n "$sstlogarchivedir" ]
then then
newfile=$(basename "$INNOMOVELOG") if [ -n "$sstlogarchivedir" ]
newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" then
else newfile=$(basename "$INNOMOVELOG")
newfile="$INNOMOVELOG.$ARCHIVETIMESTAMP" newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
else
newfile="$INNOMOVELOG.$ARCHIVETIMESTAMP"
fi
wsrep_log_info "Moving '$INNOMOVELOG' to '$newfile'"
mv "$INNOMOVELOG" "$newfile"
gzip "$newfile"
fi fi
wsrep_log_info "Moving '$INNOMOVELOG' to '$newfile'"
mv "$INNOMOVELOG" "$newfile"
gzip "$newfile"
fi
if [ -e "$INNOBACKUPLOG" ] if [ -e "$INNOBACKUPLOG" ]
then
if [ -n "$sstlogarchivedir" ]
then then
newfile=$(basename "$INNOBACKUPLOG") if [ -n "$sstlogarchivedir" ]
newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" then
else newfile=$(basename "$INNOBACKUPLOG")
newfile="$INNOBACKUPLOG.$ARCHIVETIMESTAMP" newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
else
newfile="$INNOBACKUPLOG.$ARCHIVETIMESTAMP"
fi
wsrep_log_info "Moving '$INNOBACKUPLOG' to '$newfile'"
mv "$INNOBACKUPLOG" "$newfile"
gzip "$newfile"
fi fi
wsrep_log_info "Moving '$INNOBACKUPLOG' to '$newfile'"
mv "$INNOBACKUPLOG" "$newfile"
gzip "$newfile"
fi fi
fi
INNOAPPLY="&> '$INNOAPPLYLOG'" INNOAPPLY="&> '$INNOAPPLYLOG'"
INNOMOVE="&> '$INNOMOVELOG'" INNOMOVE="&> '$INNOMOVELOG'"
INNOBACKUP="2> '$INNOBACKUPLOG'" INNOBACKUP="2> '$INNOBACKUPLOG'"
fi fi
setup_commands() setup_commands()
...@@ -1001,9 +1022,9 @@ then ...@@ -1001,9 +1022,9 @@ then
send_donor "$DATA" "$stagemsg-gtid" send_donor "$DATA" "$stagemsg-gtid"
# Restore the transport commmand to its original state
tcmd="$ttcmd" tcmd="$ttcmd"
# Restore the transport commmand to its original state
if [ -n "$progress" ]; then if [ -n "$progress" ]; then
get_footprint get_footprint
tcmd="$pcmd | $tcmd" tcmd="$pcmd | $tcmd"
...@@ -1015,7 +1036,7 @@ then ...@@ -1015,7 +1036,7 @@ then
wsrep_log_info "Sleeping before data transfer for SST" wsrep_log_info "Sleeping before data transfer for SST"
sleep 10 sleep 10
wsrep_log_info "Streaming the backup to joiner at ${REMOTEIP}:${SST_PORT}" wsrep_log_info "Streaming the backup to joiner at $REMOTEIP:$SST_PORT"
# Add compression to the head of the stream (if specified) # Add compression to the head of the stream (if specified)
if [ -n "$scomp" ]; then if [ -n "$scomp" ]; then
...@@ -1030,8 +1051,8 @@ then ...@@ -1030,8 +1051,8 @@ then
iopts="$iopts --databases-exclude='lost+found'" iopts="$iopts --databases-exclude='lost+found'"
if [ ${FORCE_FTWRL:-0} -eq 1 ]; then if [ ${FORCE_FTWRL:-0} -eq 1 ]; then
wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL" wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL"
iopts="$iopts --no-backup-locks" iopts="$iopts --no-backup-locks"
fi fi
# if compression is enabled for backup files, then add the # if compression is enabled for backup files, then add the
...@@ -1052,8 +1073,8 @@ then ...@@ -1052,8 +1073,8 @@ then
set -e set -e
if [ ${RC[0]} -ne 0 ]; then if [ ${RC[0]} -ne 0 ]; then
wsrep_log_error "${MARIABACKUP_BIN} finished with error: ${RC[0]}. " \ wsrep_log_error "mariabackup finished with error: ${RC[0]}. " \
"Check syslog or ${INNOBACKUPLOG} for details" "Check syslog or '$INNOBACKUPLOG' for details"
exit 22 exit 22
elif [ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]; then elif [ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]; then
wsrep_log_error "$tcmd finished with error: ${RC[1]}" wsrep_log_error "$tcmd finished with error: ${RC[1]}"
...@@ -1185,7 +1206,7 @@ then ...@@ -1185,7 +1206,7 @@ then
then then
if [ -d "$DATA/.sst" ]; then if [ -d "$DATA/.sst" ]; then
wsrep_log_info "WARNING: Stale temporary SST directory: ${DATA}/.sst from previous state transfer. Removing" wsrep_log_info "WARNING: Stale temporary SST directory: '$DATA/.sst' from previous state transfer. Removing"
rm -rf "$DATA/.sst" rm -rf "$DATA/.sst"
fi fi
mkdir -p "$DATA/.sst" mkdir -p "$DATA/.sst"
...@@ -1300,21 +1321,21 @@ then ...@@ -1300,21 +1321,21 @@ then
timeit "mariabackup prepare stage" "$INNOAPPLY" timeit "mariabackup prepare stage" "$INNOAPPLY"
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
wsrep_log_error "${MARIABACKUP_BIN} apply finished with errors. Check syslog or ${INNOAPPLYLOG} for details" wsrep_log_error "mariabackup apply finished with errors. Check syslog or '$INNOAPPLYLOG' for details"
exit 22 exit 22
fi fi
MAGIC_FILE="$TDATA/$INFO_FILE" MAGIC_FILE="$TDATA/$INFO_FILE"
wsrep_log_info "Moving the backup to ${TDATA}" wsrep_log_info "Moving the backup to ${TDATA}"
timeit "mariabackup move stage" "$INNOMOVE" timeit "mariabackup move stage" "$INNOMOVE"
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
wsrep_log_info "Move successful, removing ${DATA}" wsrep_log_info "Move successful, removing ${DATA}"
rm -rf "$DATA" rm -rf "$DATA"
DATA="$TDATA" DATA="$TDATA"
else else
wsrep_log_error "Move failed, keeping ${DATA} for further diagnosis" wsrep_log_error "Move failed, keeping ${DATA} for further diagnosis"
wsrep_log_error "Check syslog or ${INNOMOVELOG} for details" wsrep_log_error "Check syslog or '$INNOMOVELOG' for details"
exit 22 exit 22
fi fi
......
...@@ -261,16 +261,20 @@ then ...@@ -261,16 +261,20 @@ then
;; ;;
'VERIFY_CA') 'VERIFY_CA')
VERIFY_OPT='verifyChain = yes' VERIFY_OPT='verifyChain = yes'
# check if the address is an ip-address (v4 or v6): if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then
if echo "$WSREP_SST_OPT_HOST_UNESCAPED" | \ CHECK_OPT="checkHost = $WSREP_SST_OPT_REMOTE_USER"
grep -q -E '^([0-9]+(\.[0-9]+){3,3}|[0-9a-fA-F]?(\:[0-9a-fA-F]*)+)$'
then
CHECK_OPT="checkIP = $WSREP_SST_OPT_HOST_UNESCAPED"
else else
CHECK_OPT="checkHost = $WSREP_SST_OPT_HOST" # check if the address is an ip-address (v4 or v6):
fi if echo "$WSREP_SST_OPT_HOST_UNESCAPED" | \
if is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then grep -q -E '^([0-9]+(\.[0-9]+){3,3}|[0-9a-fA-F]*(\:[0-9a-fA-F]*)+)$'
CHECK_OPT_LOCAL="checkHost = localhost" then
CHECK_OPT="checkIP = $WSREP_SST_OPT_HOST_UNESCAPED"
else
CHECK_OPT="checkHost = $WSREP_SST_OPT_HOST"
fi
if is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then
CHECK_OPT_LOCAL="checkHost = localhost"
fi
fi fi
;; ;;
*) *)
......
...@@ -32,8 +32,8 @@ ecode=0 ...@@ -32,8 +32,8 @@ ecode=0
ssyslog="" ssyslog=""
ssystag="" ssystag=""
XTRABACKUP_PID="" XTRABACKUP_PID=""
tca=""
tcert="" tcert=""
tpem=""
tkey="" tkey=""
sockopt="" sockopt=""
progress="" progress=""
...@@ -224,20 +224,9 @@ verify_file_exists() ...@@ -224,20 +224,9 @@ verify_file_exists()
get_transfer() get_transfer()
{ {
TSST_PORT="$WSREP_SST_OPT_PORT" if [ $tfmt = 'nc' ]; then
if [[ $tfmt == 'nc' ]];then
wsrep_log_info "Using netcat as streamer" wsrep_log_info "Using netcat as streamer"
wsrep_check_programs nc wsrep_check_programs nc
if [[ $encrypt -eq 2 || $encrypt -eq 3 || $encrypt -eq 4 ]]; then
wsrep_log_error "******** FATAL ERROR *********************** "
wsrep_log_error "* Using SSL encryption (encrypt= 2, 3, or 4) "
wsrep_log_error "* is not supported when using nc(netcat). "
wsrep_log_error "******************************************** "
exit 22
fi
tcmd="nc" tcmd="nc"
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
if nc -h 2>&1 | grep -q 'ncat'; then if nc -h 2>&1 | grep -q 'ncat'; then
...@@ -256,7 +245,7 @@ get_transfer() ...@@ -256,7 +245,7 @@ get_transfer()
wsrep_log_info "Using traditional netcat as streamer" wsrep_log_info "Using traditional netcat as streamer"
tcmd="$tcmd -l -p" tcmd="$tcmd -l -p"
fi fi
tcmd="$tcmd $TSST_PORT" tcmd="$tcmd $SST_PORT"
else else
# Check to see if netcat supports the '-N' flag. # Check to see if netcat supports the '-N' flag.
# -N Shutdown the network socket after EOF on stdin # -N Shutdown the network socket after EOF on stdin
...@@ -278,113 +267,118 @@ get_transfer() ...@@ -278,113 +267,118 @@ get_transfer()
wsrep_log_info "Using traditional netcat as streamer" wsrep_log_info "Using traditional netcat as streamer"
tcmd="$tcmd -q0" tcmd="$tcmd -q0"
fi fi
tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT" tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $SST_PORT"
fi fi
else else
tfmt='socat' tfmt='socat'
wsrep_log_info "Using socat as streamer" wsrep_log_info "Using socat as streamer"
wsrep_check_programs socat wsrep_check_programs socat
donor_extra="" if [ -n "$sockopt" ]; then
joiner_extra="" sockopt=$(trim_string "$sockopt" ',')
if [[ $encrypt -eq 2 || $encrypt -eq 3 || $encrypt -eq 4 ]]; then if [ -n "$sockopt" ]; then
if ! socat -V | grep -q WITH_OPENSSL; then sockopt=",$sockopt"
wsrep_log_error "******** FATAL ERROR ****************** "
wsrep_log_error "* socat is not openssl enabled. "
wsrep_log_error "* Unable to encrypt SST communications. "
wsrep_log_error "*************************************** "
exit 2
fi fi
fi
# Determine the socat version # Add an option for ipv6 if needed:
SOCAT_VERSION=$(socat -V 2>&1 | grep -m1 -oe '[0-9]\.[0-9][\.0-9]*') if [ $WSREP_SST_OPT_HOST_IPv6 -eq 1 ]; then
if [ -z "$SOCAT_VERSION" ]; then # If sockopt contains 'pf=ip6' somewhere in the middle,
wsrep_log_error "******** FATAL ERROR ******************" # this will not interfere with socat, but exclude the trivial
wsrep_log_error "* Cannot determine the socat version. *" # cases when sockopt contains 'pf=ip6' as prefix or suffix:
wsrep_log_error "***************************************" if [ "$sockopt" = "${sockopt#,pf=ip6}" -a \
exit 2 "$sockopt" = "${sockopt%,pf=ip6}" ]
then
sockopt=",pf=ip6$sockopt"
fi fi
if ! check_for_version "$SOCAT_VERSION" "1.7.3"; then fi
# socat versions < 1.7.3 will have 512-bit dhparams (too small)
# so create 2048-bit dhparams and send that as a parameter: if [ $encrypt -lt 2 ]; then
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]]; then if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
# dhparams check (will create ssl_dhparams if needed) tcmd="socat -u TCP-LISTEN:$SST_PORT,reuseaddr$sockopt stdio"
check_for_dhparams
joiner_extra=",dhparam='$ssl_dhparams'"
fi
else else
# socat version >= 1.7.3, checks to see if the peername matches tcmd="socat -u stdio TCP:$REMOTEIP:$SST_PORT$sockopt"
# the hostname, then set commonname="" to disable the peername
# checks:
donor_extra=',commonname=""'
fi fi
return
fi fi
if [[ $encrypt -eq 2 ]]; then if ! socat -V | grep -q -F 'WITH_OPENSSL 1'; then
wsrep_log_warning "**** WARNING **** encrypt=2 is deprecated and will be removed in a future release" wsrep_log_error "******** FATAL ERROR ************************************************ "
wsrep_log_info "Using openssl based encryption with socat: with crt and ca" wsrep_log_error "* Encryption requested, but socat is not OpenSSL enabled (encrypt=$encrypt) *"
wsrep_log_error "********************************************************************* "
exit 2
fi
verify_file_exists "$tcert" "Both certificate and CA files are required." \ # Determine the socat version
"Please check the 'tcert' option. " SOCAT_VERSION=$(socat -V 2>&1 | grep -m1 -oe '[0-9]\.[0-9][\.0-9]*')
verify_file_exists "$tca" "Both certificate and CA files are required." \ if [ -z "$SOCAT_VERSION" ]; then
"Please check the 'tca' option. " wsrep_log_error "******** FATAL ERROR ******************"
wsrep_log_error "* Cannot determine the socat version. *"
wsrep_log_error "***************************************"
exit 2
fi
stagemsg+="-OpenSSL-Encrypted-2" local action='Decrypting'
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
wsrep_log_info "Decrypting with CERT: $tcert, CA: $tca" tcmd="socat -u openssl-listen:$SST_PORT,reuseaddr"
tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert='${tcert}',cafile='${tca}'${joiner_extra}${sockopt} stdio" else
else tcmd="socat -u stdio openssl-connect:$REMOTEIP:$SST_PORT"
wsrep_log_info "Encrypting with CERT: $tcert, CA: $tca" action='Encrypting'
tcmd="socat -u stdio openssl-connect:${WSREP_SST_OPT_HOST}:${TSST_PORT},cert='${tcert}',cafile='${tca}'${donor_extra}${sockopt}" fi
fi
elif [[ $encrypt -eq 3 ]];then
wsrep_log_warning "**** WARNING **** encrypt=3 is deprecated and will be removed in a future release"
wsrep_log_info "Using openssl based encryption with socat: with key and crt"
verify_file_exists "$tcert" "Both certificate and key files are required." \ if ! check_for_version "$SOCAT_VERSION" '1.7.3'; then
"Please check the 'tcert' option. " # socat versions < 1.7.3 will have 512-bit dhparams (too small)
verify_file_exists "$tkey" "Both certificate and key files are required." \ # so create 2048-bit dhparams and send that as a parameter:
"Please check the 'tkey' option. " check_for_dhparams
tcmd="$tcmd,dhparam='$ssl_dhparams'"
fi
stagemsg+="-OpenSSL-Encrypted-3" if [ $encrypt -eq 2 ]; then
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then wsrep_log_info "Using openssl based encryption with socat: with crt and pem"
wsrep_log_info "Decrypting with CERT: $tcert, KEY: $tkey" if [ -z "$tpem" -o -z "$tcert" ]; then
tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert='${tcert}',key='${tkey}',verify=0${joiner_extra}${sockopt} stdio" wsrep_log_error "Both PEM and CRT files required"
else exit 22
wsrep_log_info "Encrypting with CERT: $tcert, KEY: $tkey"
tcmd="socat -u stdio openssl-connect:${WSREP_SST_OPT_HOST}:${TSST_PORT},cert='${tcert}',key='${tkey}',verify=0${sockopt}"
fi fi
elif [[ $encrypt -eq 4 ]]; then tcmd="$tcmd,cert='$tpem',cafile='$tcert'$sockopt"
wsrep_log_info "Using openssl based encryption with socat: with key, crt, and ca" stagemsg="$stagemsg-OpenSSL-Encrypted-2"
wsrep_log_info "$action with cert=$tpem, cafile=$tcert"
verify_file_exists "$ssl_ca" "CA, certificate, and key files are required." \ elif [ $encrypt -eq 3 -o $encrypt -eq 4 ]; then
"Please check the 'ssl-ca' option. " wsrep_log_info "Using openssl based encryption with socat: with key and crt"
verify_file_exists "$ssl_cert" "CA, certificate, and key files are required." \ if [ -z "$tpem" -o -z "$tkey" ]; then
"Please check the 'ssl-cert' option. " wsrep_log_error "Both certificate and key files required"
verify_file_exists "$ssl_key" "CA, certificate, and key files are required." \ exit 22
"Please check the 'ssl-key' option. " fi
stagemsg="$stagemsg-OpenSSL-Encrypted-3"
# Check to see that the key matches the cert if [ -z "$tcert" ]; then
verify_cert_matches_key $ssl_cert $ssl_key if [ $encrypt -eq 4 ]; then
wsrep_log_error "Peer certificate required if encrypt=4"
stagemsg+="-OpenSSL-Encrypted-4" exit 22
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]]; then fi
wsrep_log_info "Decrypting with CERT: $ssl_cert, KEY: $ssl_key, CA: $ssl_ca" # no verification
tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert='${ssl_cert}',key='${ssl_key}',cafile='${ssl_ca}',verify=1${joiner_extra}${sockopt} stdio" tcmd="$tcmd,cert='$tpem',key='$tkey',verify=0$sockopt"
wsrep_log_info "$action with cert=$tpem, key=$tkey, verify=0"
else else
wsrep_log_info "Encrypting with CERT: $ssl_cert, KEY: $ssl_key, CA: $ssl_ca" # CA verification
tcmd="socat -u stdio openssl-connect:${WSREP_SST_OPT_HOST}:${TSST_PORT},cert='${ssl_cert}',key='${ssl_key}',cafile='${ssl_ca}',verify=1${donor_extra}${sockopt}" if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then
CN_option=",commonname='$WSREP_SST_OPT_REMOTE_USER'"
elif [ $encrypt -eq 4 ]; then
CN_option=",commonname=''"
elif is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then
CN_option=',commonname=localhost'
else
CN_option=",commonname='$WSREP_SST_OPT_HOST_UNSECAPED'"
fi
tcmd="$tcmd,cert='$tpem',key='$tkey',cafile='$tcert'$CN_option$sockopt"
wsrep_log_info "$action with cert=$tpem, key=$tkey, cafile=$tcert"
fi fi
else else
if [[ $encrypt -eq 1 ]]; then wsrep_log_info "Unknown encryption mode: encrypt=$encrypt"
wsrep_log_warning "**** WARNING **** encrypt=1 is deprecated and will be removed in a future release" exit 22
fi fi
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]]; then if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
tcmd="socat -u TCP-LISTEN:${TSST_PORT},reuseaddr${sockopt} stdio" tcmd="$tcmd stdio"
else
tcmd="socat -u stdio TCP:${WSREP_SST_OPT_HOST}:${TSST_PORT}${sockopt}"
fi
fi fi
fi fi
} }
...@@ -435,8 +429,8 @@ read_cnf() ...@@ -435,8 +429,8 @@ read_cnf()
{ {
sfmt=$(parse_cnf sst streamfmt "xbstream") sfmt=$(parse_cnf sst streamfmt "xbstream")
tfmt=$(parse_cnf sst transferfmt "socat") tfmt=$(parse_cnf sst transferfmt "socat")
tca=$(parse_cnf sst tca "") tcert=$(parse_cnf sst tca "")
tcert=$(parse_cnf sst tcert "") tpem=$(parse_cnf sst tcert "")
tkey=$(parse_cnf sst tkey "") tkey=$(parse_cnf sst tkey "")
encrypt=$(parse_cnf sst encrypt 0) encrypt=$(parse_cnf sst encrypt 0)
sockopt=$(parse_cnf sst sockopt "") sockopt=$(parse_cnf sst sockopt "")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment