Skip to content

Commit

Permalink
correct healthcheck.sh under --require-secure-transport
Browse files Browse the repository at this point in the history
require-secure-transport on the server mandates that tls or
unix socket be used. The healthcheck user doesn't have explict
tls credentials, so would have failed. 11.4+ would have
tls negiotated, except in MariaDB#594 it was disabled for people that
didn't configure ssl-ca correctly.

To resolve this _process_sql adds an explict --protocol socket
to get around the default configuration of 'protocol=tcp' in
.my-healthcheck.sh. The protocol=tcp was there to catch people
who put `healthcheck.sh --innodb_initialized` to discover it
checked that in the starting phase of the container, without
a tcp connection being available, it still returned true.

We work around this my making a connection test always
occur in the healthcheck.

Remove the protocol=tcp from the generation of .my-healthcheck.cnf
files.

--connect, as a method that requires to test the connection,
we add a mechanims that examines @@skip_networking and considers
that if false, the connection is viable. We made a unix socket
connection to do the test, which is active the same time as tcp
sockets are.

This alternate --connect method would have only worked the
credentials of the healthcheck user where valid. If it isn't
fall back to looking for "Can't connect".

Closes: MariaDB#596
  • Loading branch information
grooverdan committed Jun 25, 2024
1 parent fb46c56 commit 5133ff8
Show file tree
Hide file tree
Showing 29 changed files with 337 additions and 57 deletions.
2 changes: 1 addition & 1 deletion .test/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,7 @@ fi
--network=container:"$master_host" \
--health-cmd='healthcheck.sh --replication_io --replication_sql --replication_seconds_behind_master=0 --replication' \
--health-interval=3s \
"$image" --server-id=2 --port 3307)
"$image" --server-id=2 --port 3307 --require-secure-transport=1)

c="${DOCKER_LIBRARY_START_TIMEOUT:-10}"
until docker exec "$cid" healthcheck.sh --connect --replication_io --replication_sql --replication_seconds_behind_master=0 --replication || [ "$c" -eq 0 ]
Expand Down
2 changes: 1 addition & 1 deletion 10.11-ubi/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ create_healthcheck_users() {
local maskPreserve
maskPreserve=$(umask -p)
umask 0077
echo -e "[mariadb-client]\\nport=$PORT\\nsocket=$SOCKET\\nuser=healthcheck\\npassword=$healthCheckConnectPass\\nprotocol=tcp\\n" > "$DATADIR"/.my-healthcheck.cnf
echo -e "[mariadb-client]\\nport=$PORT\\nsocket=$SOCKET\\nuser=healthcheck\\npassword=$healthCheckConnectPass\\n" > "$DATADIR"/.my-healthcheck.cnf
$maskPreserve
}

Expand Down
26 changes: 23 additions & 3 deletions 10.11-ubi/healthcheck.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
# different from elsewhere.
#
# Note * though denied error message will result in error log without
# any permissions.
# any permissions. USAGE recommend to avoid this.

set -eo pipefail

Expand All @@ -42,6 +42,7 @@ _process_sql()
${def['file']:+--defaults-file=${def['file']}} \
${def['extra_file']:+--defaults-extra-file=${def['extra_file']}} \
${def['group_suffix']:+--defaults-group-suffix=${def['group_suffix']}} \
--protocol socket \
-B "$@"
}

Expand All @@ -55,6 +56,16 @@ _process_sql()
# isn't tested.
connect()
{
local s
# short cut mechanism, to work with --require-secure-transport
s=$(_process_sql --skip-column-names -e 'select @@skip_networking')
case "$s" in
0|1)
connect_s=$s
return "$s";
;;
esac
# falling back to this if there wasn't a connection answer.
set +e +o pipefail
# (on second extra_file)
# shellcheck disable=SC2086
Expand All @@ -68,9 +79,11 @@ connect()
set -eo pipefail
if (( "$ret" == 0 )); then
# grep Matched "Can't connect" so we fail
return 1
connect_s=1
else
connect_s=0
fi
return 0
return $connect_s
}

# INNODB_INITIALIZED
Expand Down Expand Up @@ -225,6 +238,7 @@ fi
declare -A repl
declare -A def
nodefaults=
connect_s=
datadir=/var/lib/mysql
if [ -f $datadir/.my-healthcheck.cnf ]; then
def['extra_file']=$datadir/.my-healthcheck.cnf
Expand Down Expand Up @@ -351,3 +365,9 @@ while [ $# -gt 0 ]; do
fi
shift
done
if [ -z "$connect_s" ]; then
# we didn't do a connnect test, so the current success status is suspicious
# return what connect thinks.
connect
exit $?
fi
2 changes: 1 addition & 1 deletion 10.11/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ create_healthcheck_users() {
local maskPreserve
maskPreserve=$(umask -p)
umask 0077
echo -e "[mariadb-client]\\nport=$PORT\\nsocket=$SOCKET\\nuser=healthcheck\\npassword=$healthCheckConnectPass\\nprotocol=tcp\\n" > "$DATADIR"/.my-healthcheck.cnf
echo -e "[mariadb-client]\\nport=$PORT\\nsocket=$SOCKET\\nuser=healthcheck\\npassword=$healthCheckConnectPass\\n" > "$DATADIR"/.my-healthcheck.cnf
$maskPreserve
}

Expand Down
26 changes: 23 additions & 3 deletions 10.11/healthcheck.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
# different from elsewhere.
#
# Note * though denied error message will result in error log without
# any permissions.
# any permissions. USAGE recommend to avoid this.

set -eo pipefail

Expand All @@ -42,6 +42,7 @@ _process_sql()
${def['file']:+--defaults-file=${def['file']}} \
${def['extra_file']:+--defaults-extra-file=${def['extra_file']}} \
${def['group_suffix']:+--defaults-group-suffix=${def['group_suffix']}} \
--protocol socket \
-B "$@"
}

Expand All @@ -55,6 +56,16 @@ _process_sql()
# isn't tested.
connect()
{
local s
# short cut mechanism, to work with --require-secure-transport
s=$(_process_sql --skip-column-names -e 'select @@skip_networking')
case "$s" in
0|1)
connect_s=$s
return "$s";
;;
esac
# falling back to this if there wasn't a connection answer.
set +e +o pipefail
# (on second extra_file)
# shellcheck disable=SC2086
Expand All @@ -68,9 +79,11 @@ connect()
set -eo pipefail
if (( "$ret" == 0 )); then
# grep Matched "Can't connect" so we fail
return 1
connect_s=1
else
connect_s=0
fi
return 0
return $connect_s
}

# INNODB_INITIALIZED
Expand Down Expand Up @@ -225,6 +238,7 @@ fi
declare -A repl
declare -A def
nodefaults=
connect_s=
datadir=/var/lib/mysql
if [ -f $datadir/.my-healthcheck.cnf ]; then
def['extra_file']=$datadir/.my-healthcheck.cnf
Expand Down Expand Up @@ -351,3 +365,9 @@ while [ $# -gt 0 ]; do
fi
shift
done
if [ -z "$connect_s" ]; then
# we didn't do a connnect test, so the current success status is suspicious
# return what connect thinks.
connect
exit $?
fi
2 changes: 1 addition & 1 deletion 10.5/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ create_healthcheck_users() {
local maskPreserve
maskPreserve=$(umask -p)
umask 0077
echo -e "[mariadb-client]\\nport=$PORT\\nsocket=$SOCKET\\nuser=healthcheck\\npassword=$healthCheckConnectPass\\nprotocol=tcp\\n" > "$DATADIR"/.my-healthcheck.cnf
echo -e "[mariadb-client]\\nport=$PORT\\nsocket=$SOCKET\\nuser=healthcheck\\npassword=$healthCheckConnectPass\\n" > "$DATADIR"/.my-healthcheck.cnf
$maskPreserve
}

Expand Down
26 changes: 23 additions & 3 deletions 10.5/healthcheck.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
# different from elsewhere.
#
# Note * though denied error message will result in error log without
# any permissions.
# any permissions. USAGE recommend to avoid this.

set -eo pipefail

Expand All @@ -42,6 +42,7 @@ _process_sql()
${def['file']:+--defaults-file=${def['file']}} \
${def['extra_file']:+--defaults-extra-file=${def['extra_file']}} \
${def['group_suffix']:+--defaults-group-suffix=${def['group_suffix']}} \
--protocol socket \
-B "$@"
}

Expand All @@ -55,6 +56,16 @@ _process_sql()
# isn't tested.
connect()
{
local s
# short cut mechanism, to work with --require-secure-transport
s=$(_process_sql --skip-column-names -e 'select @@skip_networking')
case "$s" in
0|1)
connect_s=$s
return "$s";
;;
esac
# falling back to this if there wasn't a connection answer.
set +e +o pipefail
# (on second extra_file)
# shellcheck disable=SC2086
Expand All @@ -68,9 +79,11 @@ connect()
set -eo pipefail
if (( "$ret" == 0 )); then
# grep Matched "Can't connect" so we fail
return 1
connect_s=1
else
connect_s=0
fi
return 0
return $connect_s
}

# INNODB_INITIALIZED
Expand Down Expand Up @@ -225,6 +238,7 @@ fi
declare -A repl
declare -A def
nodefaults=
connect_s=
datadir=/var/lib/mysql
if [ -f $datadir/.my-healthcheck.cnf ]; then
def['extra_file']=$datadir/.my-healthcheck.cnf
Expand Down Expand Up @@ -351,3 +365,9 @@ while [ $# -gt 0 ]; do
fi
shift
done
if [ -z "$connect_s" ]; then
# we didn't do a connnect test, so the current success status is suspicious
# return what connect thinks.
connect
exit $?
fi
2 changes: 1 addition & 1 deletion 10.6-ubi/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ create_healthcheck_users() {
local maskPreserve
maskPreserve=$(umask -p)
umask 0077
echo -e "[mariadb-client]\\nport=$PORT\\nsocket=$SOCKET\\nuser=healthcheck\\npassword=$healthCheckConnectPass\\nprotocol=tcp\\n" > "$DATADIR"/.my-healthcheck.cnf
echo -e "[mariadb-client]\\nport=$PORT\\nsocket=$SOCKET\\nuser=healthcheck\\npassword=$healthCheckConnectPass\\n" > "$DATADIR"/.my-healthcheck.cnf
$maskPreserve
}

Expand Down
26 changes: 23 additions & 3 deletions 10.6-ubi/healthcheck.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
# different from elsewhere.
#
# Note * though denied error message will result in error log without
# any permissions.
# any permissions. USAGE recommend to avoid this.

set -eo pipefail

Expand All @@ -42,6 +42,7 @@ _process_sql()
${def['file']:+--defaults-file=${def['file']}} \
${def['extra_file']:+--defaults-extra-file=${def['extra_file']}} \
${def['group_suffix']:+--defaults-group-suffix=${def['group_suffix']}} \
--protocol socket \
-B "$@"
}

Expand All @@ -55,6 +56,16 @@ _process_sql()
# isn't tested.
connect()
{
local s
# short cut mechanism, to work with --require-secure-transport
s=$(_process_sql --skip-column-names -e 'select @@skip_networking')
case "$s" in
0|1)
connect_s=$s
return "$s";
;;
esac
# falling back to this if there wasn't a connection answer.
set +e +o pipefail
# (on second extra_file)
# shellcheck disable=SC2086
Expand All @@ -68,9 +79,11 @@ connect()
set -eo pipefail
if (( "$ret" == 0 )); then
# grep Matched "Can't connect" so we fail
return 1
connect_s=1
else
connect_s=0
fi
return 0
return $connect_s
}

# INNODB_INITIALIZED
Expand Down Expand Up @@ -225,6 +238,7 @@ fi
declare -A repl
declare -A def
nodefaults=
connect_s=
datadir=/var/lib/mysql
if [ -f $datadir/.my-healthcheck.cnf ]; then
def['extra_file']=$datadir/.my-healthcheck.cnf
Expand Down Expand Up @@ -351,3 +365,9 @@ while [ $# -gt 0 ]; do
fi
shift
done
if [ -z "$connect_s" ]; then
# we didn't do a connnect test, so the current success status is suspicious
# return what connect thinks.
connect
exit $?
fi
2 changes: 1 addition & 1 deletion 10.6/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ create_healthcheck_users() {
local maskPreserve
maskPreserve=$(umask -p)
umask 0077
echo -e "[mariadb-client]\\nport=$PORT\\nsocket=$SOCKET\\nuser=healthcheck\\npassword=$healthCheckConnectPass\\nprotocol=tcp\\n" > "$DATADIR"/.my-healthcheck.cnf
echo -e "[mariadb-client]\\nport=$PORT\\nsocket=$SOCKET\\nuser=healthcheck\\npassword=$healthCheckConnectPass\\n" > "$DATADIR"/.my-healthcheck.cnf
$maskPreserve
}

Expand Down
26 changes: 23 additions & 3 deletions 10.6/healthcheck.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
# different from elsewhere.
#
# Note * though denied error message will result in error log without
# any permissions.
# any permissions. USAGE recommend to avoid this.

set -eo pipefail

Expand All @@ -42,6 +42,7 @@ _process_sql()
${def['file']:+--defaults-file=${def['file']}} \
${def['extra_file']:+--defaults-extra-file=${def['extra_file']}} \
${def['group_suffix']:+--defaults-group-suffix=${def['group_suffix']}} \
--protocol socket \
-B "$@"
}

Expand All @@ -55,6 +56,16 @@ _process_sql()
# isn't tested.
connect()
{
local s
# short cut mechanism, to work with --require-secure-transport
s=$(_process_sql --skip-column-names -e 'select @@skip_networking')
case "$s" in
0|1)
connect_s=$s
return "$s";
;;
esac
# falling back to this if there wasn't a connection answer.
set +e +o pipefail
# (on second extra_file)
# shellcheck disable=SC2086
Expand All @@ -68,9 +79,11 @@ connect()
set -eo pipefail
if (( "$ret" == 0 )); then
# grep Matched "Can't connect" so we fail
return 1
connect_s=1
else
connect_s=0
fi
return 0
return $connect_s
}

# INNODB_INITIALIZED
Expand Down Expand Up @@ -225,6 +238,7 @@ fi
declare -A repl
declare -A def
nodefaults=
connect_s=
datadir=/var/lib/mysql
if [ -f $datadir/.my-healthcheck.cnf ]; then
def['extra_file']=$datadir/.my-healthcheck.cnf
Expand Down Expand Up @@ -351,3 +365,9 @@ while [ $# -gt 0 ]; do
fi
shift
done
if [ -z "$connect_s" ]; then
# we didn't do a connnect test, so the current success status is suspicious
# return what connect thinks.
connect
exit $?
fi
2 changes: 1 addition & 1 deletion 11.1/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ create_healthcheck_users() {
local maskPreserve
maskPreserve=$(umask -p)
umask 0077
echo -e "[mariadb-client]\\nport=$PORT\\nsocket=$SOCKET\\nuser=healthcheck\\npassword=$healthCheckConnectPass\\nprotocol=tcp\\n" > "$DATADIR"/.my-healthcheck.cnf
echo -e "[mariadb-client]\\nport=$PORT\\nsocket=$SOCKET\\nuser=healthcheck\\npassword=$healthCheckConnectPass\\n" > "$DATADIR"/.my-healthcheck.cnf
$maskPreserve
}

Expand Down
Loading

0 comments on commit 5133ff8

Please sign in to comment.