diff options
author | Julius Goryavsky <julius.goryavsky@mariadb.com> | 2021-05-25 05:08:25 +0200 |
---|---|---|
committer | Julius Goryavsky <julius.goryavsky@mariadb.com> | 2021-05-25 05:08:25 +0200 |
commit | fe7e44d8ad5d7fe9c91f476353a3e1749f18afc6 (patch) | |
tree | ee6601096fe010f4013085a8a1f5ed5e7d4642da /scripts | |
parent | 81f94c26a4fb60345e260ba25f39315f3d9a6f3b (diff) | |
download | mariadb-git-fe7e44d8ad5d7fe9c91f476353a3e1749f18afc6.tar.gz |
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;
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/wsrep_sst_common.sh | 22 | ||||
-rw-r--r-- | scripts/wsrep_sst_mariabackup.sh | 225 | ||||
-rw-r--r-- | scripts/wsrep_sst_rsync.sh | 22 | ||||
-rw-r--r-- | scripts/wsrep_sst_xtrabackup-v2.sh | 196 |
4 files changed, 253 insertions, 212 deletions
diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index ceab62b4c56..261912b86ad 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -1021,3 +1021,25 @@ check_for_version() [ $z1 -lt $z2 ] && return 1 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 +} diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index 530d3e49256..0fdc765ff8b 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -34,8 +34,6 @@ ecode=0 ssyslog="" ssystag="" MARIABACKUP_PID="" -SST_PORT="" -REMOTEIP="" tcert="" tpem="" tkey="" @@ -94,7 +92,7 @@ declare -a RC MARIABACKUP_BIN="$(command -v mariabackup)" 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 fi @@ -214,8 +212,6 @@ get_keys() get_transfer() { - TSST_PORT="$SST_PORT" - if [ $tfmt = 'nc' ]; then wsrep_log_info "Using netcat as streamer" wsrep_check_programs nc @@ -237,7 +233,7 @@ get_transfer() wsrep_log_info "Using traditional netcat as streamer" tcmd="$tcmd -l -p" fi - tcmd="$tcmd $TSST_PORT" + tcmd="$tcmd $SST_PORT" else # Check to see if netcat supports the '-N' flag. # -N Shutdown the network socket after EOF on stdin @@ -259,7 +255,7 @@ get_transfer() wsrep_log_info "Using traditional netcat as streamer" tcmd="$tcmd -q0" fi - tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT" + tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $SST_PORT" fi else tfmt='socat' @@ -267,8 +263,38 @@ get_transfer() wsrep_log_info "Using socat as streamer" wsrep_check_programs socat - if [ $encrypt -eq 2 -o $encrypt -eq 3 ] && ! socat -V | grep -q -F 'WITH_OPENSSL 1'; then - wsrep_log_error "Encryption requested, but socat is not OpenSSL enabled (encrypt=$encrypt)" + if [ -n "$sockopt" ]; then + 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 fi @@ -281,11 +307,21 @@ get_transfer() exit 2 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) # so create 2048-bit dhparams and send that as a parameter: check_for_dhparams - sockopt=",dhparam='$ssl_dhparams'$sockopt" + if [ -n "$ssl_dhparams" ]; then + tcmd="$tcmd,dhparam='$ssl_dhparams'" + fi fi if [ $encrypt -eq 2 ]; then @@ -294,15 +330,10 @@ get_transfer() wsrep_log_error "Both PEM and CRT files required" exit 22 fi + tcmd="$tcmd,cert='$tpem',cafile='$tcert'$sockopt" stagemsg="$stagemsg-OpenSSL-Encrypted-2" - if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then - wsrep_log_info "Decrypting with cert=${tpem}, cafile=${tcert}" - 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 "$action with cert=$tpem, cafile=$tcert" + elif [ $encrypt -eq 3 -o $encrypt -eq 4 ]; then wsrep_log_info "Using openssl based encryption with socat: with key and crt" if [ -z "$tpem" -o -z "$tkey" ]; then wsrep_log_error "Both certificate and key files required" @@ -310,36 +341,34 @@ get_transfer() fi stagemsg="$stagemsg-OpenSSL-Encrypted-3" if [ -z "$tcert" ]; then - # no verification - if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then - wsrep_log_info "Decrypting with cert=${tpem}, key=${tkey}, verify=0" - 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" + if [ $encrypt -eq 4 ]; then + wsrep_log_error "Peer certificate required if encrypt=4" + exit 22 fi + # no verification + tcmd="$tcmd,cert='$tpem',key='$tkey',verify=0$sockopt" + wsrep_log_info "$action with cert=$tpem, key=$tkey, verify=0" else # CA verification - if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then - wsrep_log_info "Decrypting with cert=${tpem}, key=${tkey}, cafile=${tcert}" - tcmd="socat -u openssl-listen:$TSST_PORT,reuseaddr,cert='$tpem',key='$tkey',cafile='$tcert'$sockopt stdio" + 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="" - 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" + 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 else - if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then - tcmd="socat -u TCP-LISTEN:$TSST_PORT,reuseaddr$sockopt stdio" - else - tcmd="socat -u stdio TCP:$REMOTEIP:$TSST_PORT$sockopt" - fi + wsrep_log_info "Unknown encryption mode: encrypt=$encrypt" + exit 22 + fi + + if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then + tcmd="$tcmd stdio" fi fi } @@ -347,7 +376,7 @@ get_transfer() get_footprint() { 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 # QuickLZ has around 50% compression ratio # When compression/compaction used, the progress is only an approximate. @@ -440,7 +469,7 @@ read_cnf() sockopt=$(parse_cnf sst sockopt "") progress=$(parse_cnf sst progress "") 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') cpat=$(parse_cnf sst cpat "$cpat") scomp=$(parse_cnf sst compressor "") @@ -807,8 +836,6 @@ monitor_process() done } -wsrep_check_programs "$MARIABACKUP_BIN" - [ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE" if [ "$WSREP_SST_OPT_ROLE" != 'joiner' -a "$WSREP_SST_OPT_ROLE" != 'donor' ]; then @@ -842,7 +869,6 @@ INNODB_DATA_HOME_DIR=$(pwd -P) cd "$OLD_PWD" if [ $ssyslog -eq 1 ]; then - if [ -n "$(command -v logger)" ]; then wsrep_log_info "Logging all stderr of SST/mariabackup to syslog" @@ -860,70 +886,65 @@ if [ $ssyslog -eq 1 ]; then else wsrep_log_error "logger not in path: $PATH. Ignoring" fi - INNOAPPLY="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply" INNOMOVE="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move" INNOBACKUP="2> >(logger -p daemon.err -t ${ssystag}innobackupex-backup)" - else + if [ $sstlogarchive -eq 1 ] + then + ARCHIVETIMESTAMP=$(date "+%Y.%m.%d-%H.%M.%S.%N") -if [ $sstlogarchive -eq 1 ] -then - ARCHIVETIMESTAMP=$(date "+%Y.%m.%d-%H.%M.%S.%N") - - if [ -n "$sstlogarchivedir" ]; then - if [ ! -d "$sstlogarchivedir" ]; then - mkdir -p "$sstlogarchivedir" + if [ -n "$sstlogarchivedir" ]; then + if [ ! -d "$sstlogarchivedir" ]; then + mkdir -p "$sstlogarchivedir" + fi fi - fi - if [ -e "$INNOAPPLYLOG" ] - then - if [ -n "$sstlogarchivedir" ] + if [ -e "$INNOAPPLYLOG" ] then - newfile=$(basename "$INNOAPPLYLOG") - newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" - else - newfile="$INNOAPPLYLOG.$ARCHIVETIMESTAMP" + if [ -n "$sstlogarchivedir" ] + then + newfile=$(basename "$INNOAPPLYLOG") + newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" + else + newfile="$INNOAPPLYLOG.$ARCHIVETIMESTAMP" + fi + wsrep_log_info "Moving '$INNOAPPLYLOG' to '$newfile'" + mv "$INNOAPPLYLOG" "$newfile" + gzip "$newfile" fi - wsrep_log_info "Moving '$INNOAPPLYLOG' to '$newfile'" - mv "$INNOAPPLYLOG" "$newfile" - gzip "$newfile" - fi - if [ -e "$INNOMOVELOG" ] - then - if [ -n "$sstlogarchivedir" ] + if [ -e "$INNOMOVELOG" ] then - newfile=$(basename "$INNOMOVELOG") - newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" - else - newfile="$INNOMOVELOG.$ARCHIVETIMESTAMP" + if [ -n "$sstlogarchivedir" ] + then + newfile=$(basename "$INNOMOVELOG") + newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" + else + newfile="$INNOMOVELOG.$ARCHIVETIMESTAMP" + fi + wsrep_log_info "Moving '$INNOMOVELOG' to '$newfile'" + mv "$INNOMOVELOG" "$newfile" + gzip "$newfile" fi - wsrep_log_info "Moving '$INNOMOVELOG' to '$newfile'" - mv "$INNOMOVELOG" "$newfile" - gzip "$newfile" - fi - if [ -e "$INNOBACKUPLOG" ] - then - if [ -n "$sstlogarchivedir" ] + if [ -e "$INNOBACKUPLOG" ] then - newfile=$(basename "$INNOBACKUPLOG") - newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" - else - newfile="$INNOBACKUPLOG.$ARCHIVETIMESTAMP" + if [ -n "$sstlogarchivedir" ] + then + newfile=$(basename "$INNOBACKUPLOG") + newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" + else + newfile="$INNOBACKUPLOG.$ARCHIVETIMESTAMP" + fi + wsrep_log_info "Moving '$INNOBACKUPLOG' to '$newfile'" + mv "$INNOBACKUPLOG" "$newfile" + gzip "$newfile" fi - wsrep_log_info "Moving '$INNOBACKUPLOG' to '$newfile'" - mv "$INNOBACKUPLOG" "$newfile" - gzip "$newfile" fi -fi - INNOAPPLY="&> '$INNOAPPLYLOG'" INNOMOVE="&> '$INNOMOVELOG'" INNOBACKUP="2> '$INNOBACKUPLOG'" - fi setup_commands() @@ -1001,9 +1022,9 @@ then send_donor "$DATA" "$stagemsg-gtid" + # Restore the transport commmand to its original state tcmd="$ttcmd" - # Restore the transport commmand to its original state if [ -n "$progress" ]; then get_footprint tcmd="$pcmd | $tcmd" @@ -1015,7 +1036,7 @@ then wsrep_log_info "Sleeping before data transfer for SST" 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) if [ -n "$scomp" ]; then @@ -1030,8 +1051,8 @@ then iopts="$iopts --databases-exclude='lost+found'" if [ ${FORCE_FTWRL:-0} -eq 1 ]; then - wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL" - iopts="$iopts --no-backup-locks" + wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL" + iopts="$iopts --no-backup-locks" fi # if compression is enabled for backup files, then add the @@ -1052,8 +1073,8 @@ then set -e if [ ${RC[0]} -ne 0 ]; then - wsrep_log_error "${MARIABACKUP_BIN} finished with error: ${RC[0]}. " \ - "Check syslog or ${INNOBACKUPLOG} for details" + wsrep_log_error "mariabackup finished with error: ${RC[0]}. " \ + "Check syslog or '$INNOBACKUPLOG' for details" exit 22 elif [ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]; then wsrep_log_error "$tcmd finished with error: ${RC[1]}" @@ -1185,7 +1206,7 @@ then 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" fi mkdir -p "$DATA/.sst" @@ -1300,21 +1321,21 @@ then timeit "mariabackup prepare stage" "$INNOAPPLY" 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 fi MAGIC_FILE="$TDATA/$INFO_FILE" + wsrep_log_info "Moving the backup to ${TDATA}" timeit "mariabackup move stage" "$INNOMOVE" - if [ $? -eq 0 ]; then wsrep_log_info "Move successful, removing ${DATA}" rm -rf "$DATA" DATA="$TDATA" else 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 fi diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index f954046382c..0cc13ee4191 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -261,16 +261,20 @@ then ;; 'VERIFY_CA') VERIFY_OPT='verifyChain = yes' - # check if the address is an ip-address (v4 or v6): - if echo "$WSREP_SST_OPT_HOST_UNESCAPED" | \ - 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" + if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then + CHECK_OPT="checkHost = $WSREP_SST_OPT_REMOTE_USER" else - CHECK_OPT="checkHost = $WSREP_SST_OPT_HOST" - fi - if is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then - CHECK_OPT_LOCAL="checkHost = localhost" + # check if the address is an ip-address (v4 or v6): + if echo "$WSREP_SST_OPT_HOST_UNESCAPED" | \ + 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 + 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 ;; *) diff --git a/scripts/wsrep_sst_xtrabackup-v2.sh b/scripts/wsrep_sst_xtrabackup-v2.sh index b0d5c0aedf1..b5ede2b29cb 100644 --- a/scripts/wsrep_sst_xtrabackup-v2.sh +++ b/scripts/wsrep_sst_xtrabackup-v2.sh @@ -32,8 +32,8 @@ ecode=0 ssyslog="" ssystag="" XTRABACKUP_PID="" -tca="" tcert="" +tpem="" tkey="" sockopt="" progress="" @@ -224,20 +224,9 @@ verify_file_exists() get_transfer() { - TSST_PORT="$WSREP_SST_OPT_PORT" - - if [[ $tfmt == 'nc' ]];then + if [ $tfmt = 'nc' ]; then wsrep_log_info "Using netcat as streamer" 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" if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then if nc -h 2>&1 | grep -q 'ncat'; then @@ -256,7 +245,7 @@ get_transfer() wsrep_log_info "Using traditional netcat as streamer" tcmd="$tcmd -l -p" fi - tcmd="$tcmd $TSST_PORT" + tcmd="$tcmd $SST_PORT" else # Check to see if netcat supports the '-N' flag. # -N Shutdown the network socket after EOF on stdin @@ -278,113 +267,118 @@ get_transfer() wsrep_log_info "Using traditional netcat as streamer" tcmd="$tcmd -q0" fi - tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT" + tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $SST_PORT" fi else tfmt='socat' + wsrep_log_info "Using socat as streamer" wsrep_check_programs socat - donor_extra="" - joiner_extra="" - if [[ $encrypt -eq 2 || $encrypt -eq 3 || $encrypt -eq 4 ]]; then - if ! socat -V | grep -q WITH_OPENSSL; then - 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 + if [ -n "$sockopt" ]; then + sockopt=$(trim_string "$sockopt" ',') + if [ -n "$sockopt" ]; then + sockopt=",$sockopt" fi + fi - # Determine the socat version - SOCAT_VERSION=$(socat -V 2>&1 | grep -m1 -oe '[0-9]\.[0-9][\.0-9]*') - if [ -z "$SOCAT_VERSION" ]; then - wsrep_log_error "******** FATAL ERROR ******************" - wsrep_log_error "* Cannot determine the socat version. *" - wsrep_log_error "***************************************" - exit 2 + # 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 - if ! check_for_version "$SOCAT_VERSION" "1.7.3"; then - # socat versions < 1.7.3 will have 512-bit dhparams (too small) - # so create 2048-bit dhparams and send that as a parameter: - if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]]; then - # dhparams check (will create ssl_dhparams if needed) - check_for_dhparams - joiner_extra=",dhparam='$ssl_dhparams'" - 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 - # socat version >= 1.7.3, checks to see if the peername matches - # the hostname, then set commonname="" to disable the peername - # checks: - donor_extra=',commonname=""' + tcmd="socat -u stdio TCP:$REMOTEIP:$SST_PORT$sockopt" fi + return fi - if [[ $encrypt -eq 2 ]]; then - wsrep_log_warning "**** WARNING **** encrypt=2 is deprecated and will be removed in a future release" - wsrep_log_info "Using openssl based encryption with socat: with crt and ca" + 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 + fi - verify_file_exists "$tcert" "Both certificate and CA files are required." \ - "Please check the 'tcert' option. " - verify_file_exists "$tca" "Both certificate and CA files are required." \ - "Please check the 'tca' option. " + # Determine the socat version + SOCAT_VERSION=$(socat -V 2>&1 | grep -m1 -oe '[0-9]\.[0-9][\.0-9]*') + if [ -z "$SOCAT_VERSION" ]; then + wsrep_log_error "******** FATAL ERROR ******************" + wsrep_log_error "* Cannot determine the socat version. *" + wsrep_log_error "***************************************" + exit 2 + fi - stagemsg+="-OpenSSL-Encrypted-2" - if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then - wsrep_log_info "Decrypting with CERT: $tcert, CA: $tca" - tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert='${tcert}',cafile='${tca}'${joiner_extra}${sockopt} stdio" - else - wsrep_log_info "Encrypting with CERT: $tcert, CA: $tca" - tcmd="socat -u stdio openssl-connect:${WSREP_SST_OPT_HOST}:${TSST_PORT},cert='${tcert}',cafile='${tca}'${donor_extra}${sockopt}" - 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" + 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 - verify_file_exists "$tcert" "Both certificate and key files are required." \ - "Please check the 'tcert' option. " - verify_file_exists "$tkey" "Both certificate and key files are required." \ - "Please check the 'tkey' option. " + if ! check_for_version "$SOCAT_VERSION" '1.7.3'; then + # socat versions < 1.7.3 will have 512-bit dhparams (too small) + # so create 2048-bit dhparams and send that as a parameter: + check_for_dhparams + tcmd="$tcmd,dhparam='$ssl_dhparams'" + fi - stagemsg+="-OpenSSL-Encrypted-3" - if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then - wsrep_log_info "Decrypting with CERT: $tcert, KEY: $tkey" - tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert='${tcert}',key='${tkey}',verify=0${joiner_extra}${sockopt} stdio" - else - 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}" + if [ $encrypt -eq 2 ]; then + wsrep_log_info "Using openssl based encryption with socat: with crt and pem" + if [ -z "$tpem" -o -z "$tcert" ]; then + wsrep_log_error "Both PEM and CRT files required" + exit 22 fi - elif [[ $encrypt -eq 4 ]]; then - wsrep_log_info "Using openssl based encryption with socat: with key, crt, and ca" - - verify_file_exists "$ssl_ca" "CA, certificate, and key files are required." \ - "Please check the 'ssl-ca' option. " - verify_file_exists "$ssl_cert" "CA, certificate, and key files are required." \ - "Please check the 'ssl-cert' option. " - verify_file_exists "$ssl_key" "CA, certificate, and key files are required." \ - "Please check the 'ssl-key' option. " - - # Check to see that the key matches the cert - verify_cert_matches_key $ssl_cert $ssl_key - - stagemsg+="-OpenSSL-Encrypted-4" - if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]]; then - wsrep_log_info "Decrypting with CERT: $ssl_cert, KEY: $ssl_key, CA: $ssl_ca" - 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',cafile='$tcert'$sockopt" + stagemsg="$stagemsg-OpenSSL-Encrypted-2" + wsrep_log_info "$action with cert=$tpem, cafile=$tcert" + elif [ $encrypt -eq 3 -o $encrypt -eq 4 ]; then + wsrep_log_info "Using openssl based encryption with socat: with key and crt" + if [ -z "$tpem" -o -z "$tkey" ]; then + wsrep_log_error "Both certificate and key files required" + exit 22 + fi + stagemsg="$stagemsg-OpenSSL-Encrypted-3" + if [ -z "$tcert" ]; then + if [ $encrypt -eq 4 ]; then + wsrep_log_error "Peer certificate required if encrypt=4" + exit 22 + fi + # no verification + tcmd="$tcmd,cert='$tpem',key='$tkey',verify=0$sockopt" + wsrep_log_info "$action with cert=$tpem, key=$tkey, verify=0" else - wsrep_log_info "Encrypting with CERT: $ssl_cert, KEY: $ssl_key, CA: $ssl_ca" - 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}" + # CA verification + 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 else - if [[ $encrypt -eq 1 ]]; then - wsrep_log_warning "**** WARNING **** encrypt=1 is deprecated and will be removed in a future release" - fi + wsrep_log_info "Unknown encryption mode: encrypt=$encrypt" + exit 22 + fi - if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]]; then - tcmd="socat -u TCP-LISTEN:${TSST_PORT},reuseaddr${sockopt} stdio" - else - tcmd="socat -u stdio TCP:${WSREP_SST_OPT_HOST}:${TSST_PORT}${sockopt}" - fi + if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then + tcmd="$tcmd stdio" fi fi } @@ -435,8 +429,8 @@ read_cnf() { sfmt=$(parse_cnf sst streamfmt "xbstream") tfmt=$(parse_cnf sst transferfmt "socat") - tca=$(parse_cnf sst tca "") - tcert=$(parse_cnf sst tcert "") + tcert=$(parse_cnf sst tca "") + tpem=$(parse_cnf sst tcert "") tkey=$(parse_cnf sst tkey "") encrypt=$(parse_cnf sst encrypt 0) sockopt=$(parse_cnf sst sockopt "") |