Skip to content

Commit

Permalink
restore gosu suid bit when supervisor container stops
Browse files Browse the repository at this point in the history
  • Loading branch information
kaluzki committed Dec 27, 2020
1 parent 7ff76d6 commit 46fac91
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 32 deletions.
126 changes: 126 additions & 0 deletions src/opt/docker/bin/config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#!/usr/bin/env bash

shopt -s nullglob

###
# Check if current user is root
#
##
function rootCheck() {
# Root check
if [ "$(/usr/bin/whoami)" != "root" ]; then
echo "[ERROR] $* must be run as root"
exit 1
fi
}

###
# Create /docker.stdout and /docker.stderr
#
##
function createDockerStdoutStderr() {
# link stdout from docker
if [[ -n "$LOG_STDOUT" ]]; then
echo "Log stdout redirected to $LOG_STDOUT"
else
LOG_STDOUT="/proc/$$/fd/1"
fi

if [[ -n "$LOG_STDERR" ]]; then
echo "Log stderr redirected to $LOG_STDERR"
else
LOG_STDERR="/proc/$$/fd/2"
fi

ln -f -s "$LOG_STDOUT" /docker.stdout
ln -f -s "$LOG_STDERR" /docker.stderr
}
###
# Include script directory text inside a file
#
# $1 -> path
#
##
function includeScriptDir() {
if [[ -d "$1" ]]; then
for FILE in "$1"/*.sh; do
echo "-> Executing ${FILE}"
# run custom scripts, only once
. "$FILE"
done
fi
}

###
# Show deprecation notice
#
##
function deprecationNotice() {
echo ""
echo "###############################################################################"
echo "### THIS CALL IS DEPRECATED AND WILL BE REMOVED IN THE FUTURE"
echo "###"
echo "### $*"
echo "###"
echo "###############################################################################"
echo ""
}

###
# Run "entrypoint" scripts
#
##
function runEntrypoints() {
# try to find entrypoint task script
ENTRYPOINT_SCRIPT="/opt/docker/bin/entrypoint.d/${TASK}.sh"
if [ ! -f "$ENTRYPOINT_SCRIPT" ]; then
# use default
ENTRYPOINT_SCRIPT="/opt/docker/bin/entrypoint.d/default.sh"
fi

if [ ! -f "$ENTRYPOINT_SCRIPT" ]; then
exit 1
fi

. "$ENTRYPOINT_SCRIPT"
}

###
# Run "entrypoint" provisioning
#
##
function runProvisionEntrypoint() {
includeScriptDir "/opt/docker/provision/entrypoint.d"
includeScriptDir "/entrypoint.d"
}

###
# https://stackoverflow.com/questions/41451159/how-to-execute-a-script-when-i-terminate-a-docker-container
# https://hynek.me/articles/docker-signals/
#
##
function runTeardownEntrypoint() {
echo "Container stopped, performing teardown..."
includeScriptDir "/opt/docker/provision/entrypoint.d/teardown"
includeScriptDir "/entrypoint.d/teardown"
}

###
# List environment variables (based on prefix)
#
##
function envListVars() {
if [[ $# -eq 1 ]]; then
env | grep "^${1}" | cut -d= -f1
else
env | cut -d= -f1
fi
}

###
# Get environment variable (even with dots in name)
#
##
function envGetValue() {
awk "BEGIN {print ENVIRON[\"$1\"]}"
}
19 changes: 19 additions & 0 deletions src/opt/docker/bin/entrypoint.d/cli.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bash

#############################################
## Run CLI_SCRIPT from environment variable
#############################################

if [ -n "${CLI_SCRIPT}" ]; then
if [ -n "${CONTAINER_UID}" ]; then
# Run as EFFECTIVE_USER
shift
exec gosu "${CONTAINER_UID}" "${CLI_SCRIPT}" "$@"
else
# Run as root
exec "${CLI_SCRIPT}" "$@"
fi
else
echo "[ERROR] No CLI_SCRIPT in in docker environment defined"
exit 1
fi
52 changes: 20 additions & 32 deletions src/opt/docker/bin/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,47 +1,35 @@
#!/usr/bin/env bash

if [[ -z "$CONTAINER_UID" ]]; then
export CONTAINER_UID=$APPLICATION_UID
export CONTAINER_UID=1000
fi

set -o pipefail # trace ERR through pipes
set -o errtrace # trace ERR through 'time command' and other functions
set -o nounset ## set -u : exit the script if you try to use an uninitialised variable
set -o errexit ## set -e : exit the script if any statement returns a non-true return value
set -o pipefail # trace ERR through pipes
set -o errtrace # trace ERR through 'time command' and other functions
set -o nounset ## set -u : exit the script if you try to use an uninitialised variable
set -o errexit ## set -e : exit the script if any statement returns a non-true return value

# auto elevate privileges (if container is not started as root)
if [[ "$UID" -ne 0 ]]; then
export CONTAINER_UID="$UID"
exec gosu root "$0" "$@"
fi

# remove suid bit on gosu
# chmod -s /sbin/gosu

trap 'echo sigterm ; exit' SIGTERM
trap 'echo sigkill ; exit' SIGKILL

# sanitize input and set task
TASK="$(echo $1| sed 's/[^-_a-zA-Z0-9]*//g')"

source /opt/docker/bin/config.sh

. /opt/docker/bin/config.sh
createDockerStdoutStderr

if [[ "$UID" -eq 0 ]]; then
# Only run provision if user is root

if [ "$TASK" == "supervisord" -o "$TASK" == "noop" ]; then
# Visible provisioning
runProvisionEntrypoint
else
# Hidden provisioning
runProvisionEntrypoint > /dev/null
fi
# sanitize input and set task
TASK="$(echo $1 | sed 's/[^-_a-zA-Z0-9]*//g')"

if [ "$TASK" == "supervisord" ] || [ "$TASK" == "noop" ]; then
# visible provisioning
runProvisionEntrypoint
trap 'runTeardownEntrypoint' SIGTERM
runEntrypoints "$@" &
wait $!
runTeardownEntrypoint
else
# hidden provisioning
runProvisionEntrypoint > /dev/null
runEntrypoints "$@"
fi

#############################
## COMMAND
#############################

runEntrypoints "$@"
4 changes: 4 additions & 0 deletions src/opt/docker/provision/entrypoint.d/05-gosu.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash

# remove suid bit
chmod -s /sbin/gosu
4 changes: 4 additions & 0 deletions src/opt/docker/provision/entrypoint.d/teardown/05-gosu.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash

# add suid bit
chmod +s /sbin/gosu

0 comments on commit 46fac91

Please sign in to comment.