diff options
author | Julius Goryavsky <julius.goryavsky@mariadb.com> | 2021-05-23 01:11:19 +0200 |
---|---|---|
committer | Julius Goryavsky <julius.goryavsky@mariadb.com> | 2021-05-23 01:20:43 +0200 |
commit | c88e9342f37fff6d7757e4f7c6dcc5a7c44e2217 (patch) | |
tree | 18576e0401b1715f1b04e1415eedb54c842c2bb2 | |
parent | f70b11c8c9f0febb281511550df0de269fba191b (diff) | |
download | mariadb-git-c88e9342f37fff6d7757e4f7c6dcc5a7c44e2217.tar.gz |
MDEV-25759: is_local_ip function can come to incorrect conclusion
The is_local_ip function that used in Galera SST scripts now
incorrectly identifies ip-addresses falling under the "127.0.0.0/8"
netmask as non-local ip, although they certainly belong to the
loopback interface. This commit fixes this flaw.
-rw-r--r-- | scripts/wsrep_sst_common.sh | 39 | ||||
-rw-r--r-- | scripts/wsrep_sst_rsync.sh | 26 |
2 files changed, 49 insertions, 16 deletions
diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index f4ac2e9936d..952a37f75d2 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -875,7 +875,9 @@ get_openssl() readonly OPENSSL_BINARY } +# # Generate a string equivalent to 16 random bytes +# wsrep_gen_secret() { get_openssl @@ -889,16 +891,36 @@ wsrep_gen_secret() fi } +# +# Checking if the address passed to us is local. +# If the second parameter is nonzero, then this function +# does not check for matches with local domain names: +# is_local_ip() { - [ "$1" = '127.0.0.1' ] && return 0 - [ "$1" = '127.0.0.2' ] && return 0 - [ "$1" = 'localhost' ] && return 0 - [ "$1" = '[::1]' ] && return 0 - [ "$1" = "$(hostname -s)" ] && return 0 - [ "$1" = "$(hostname -f)" ] && return 0 - [ "$1" = "$(hostname -d)" ] && return 0 - + # Rapid recognition of the most common cases: + [ "$1" = '127.0.0.1' -o \ + "$1" = '127.0.0.2' -o \ + "$1" = 'localhost' -o \ + "$1" = '[::1]' ] && return 0 + # If the address starts with "127." this is probably a local + # address, but we need to clarify what follows this prefix: + if [ "${1#127.}" != "$1" ]; then + # All 127.0.0.0/8 addresses are local: + if echo "$1" | grep -q -E '^127\.[0-9]+\.[0-9]+\.[0-9]+$'; then + return 0 + fi + fi + # If the second parameter is nonzero, then we will skip + # the domain name check: + if [ "${2:-0}" -eq 0 ]; then + # We consider all the names of a given host to be local addresses: + [ "$1" = "$(hostname -s)" -o \ + "$1" = "$(hostname -f)" -o \ + "$1" = "$(hostname -d)" ] && return 0 + fi + # Now let's check if the given address is assigned to + # one of the network cards: local ip_util="$(command -v ip)" if [ -n "$ip_util" ]; then # ip address show ouput format is " inet[6] <address>/<mask>": @@ -914,7 +936,6 @@ is_local_ip() | grep -F " $1 " >/dev/null && return 0 fi fi - return 1 } diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index 92f77eec331..f954046382c 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -250,19 +250,27 @@ else CAFILE_OPT="" fi +VERIFY_OPT="" +CHECK_OPT="" +CHECK_OPT_LOCAL="" if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ] then case "$SSLMODE" in 'VERIFY_IDENTITY') VERIFY_OPT='verifyPeer = yes' - CHECK_OPT="" ;; 'VERIFY_CA') VERIFY_OPT='verifyChain = yes' - if is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then - CHECK_OPT='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_UNESCAPED' + CHECK_OPT="checkHost = $WSREP_SST_OPT_HOST" + fi + if is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then + CHECK_OPT_LOCAL="checkHost = localhost" fi ;; *) @@ -273,9 +281,6 @@ then wsrep_log_error "Can't have ssl-mode='$SSLMODE' without CA file" exit 22 # EINVAL fi -else - VERIFY_OPT="" - CHECK_OPT="" fi STUNNEL="" @@ -310,6 +315,7 @@ connect = $WSREP_SST_OPT_HOST_UNESCAPED:$WSREP_SST_OPT_PORT TIMEOUTclose = 0 ${VERIFY_OPT} ${CHECK_OPT} +${CHECK_OPT_LOCAL} EOF fi @@ -566,6 +572,9 @@ foreground = yes pid = $STUNNEL_PID debug = warning client = no +${VERIFY_OPT} +${CHECK_OPT} +${CHECK_OPT_LOCAL} [rsync] accept = $STUNNEL_ACCEPT exec = $(command -v rsync) @@ -583,6 +592,9 @@ foreground = yes pid = $STUNNEL_PID debug = warning client = no +${VERIFY_OPT} +${CHECK_OPT} +${CHECK_OPT_LOCAL} [rsync] accept = $STUNNEL_ACCEPT exec = $SHELL |