Skip to content

Commit

Permalink
Version 0.6.0
Browse files Browse the repository at this point in the history
  • Loading branch information
felipecrs committed Oct 3, 2023
1 parent fb6f9bc commit 9b6fb88
Show file tree
Hide file tree
Showing 8 changed files with 259 additions and 99 deletions.
9 changes: 9 additions & 0 deletions .shellcheckrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
enable=add-default-case
enable=avoid-nullary-conditions
enable=check-extra-masked-returns
enable=check-set-e-suppressed
enable=check-unassigned-uppercase
enable=deprecate-which
enable=quote-safe-variables
enable=require-double-brackets
enable=require-variable-braces
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## 0.6.0

- Cleanup and refactor code a little bit, enable all ShellCheck optional checks and fix them.
- Handle a situation where the host user is named `docker` and both the host user's group and the Docker daemon's group are named `docker`.
- Add support for a `FIXDOCKERGID_DEBUG` environment variable to enable debug logs.
- Skip `fixdockergid` and `fixuid` if the container is started as `root`.
- Optimize the code a little bit by relying on `install.sh` to have created the `docker` group.
- Use dind to run tests, so that we can test with different host scenarios.
- Add a check to ensure the container user's group is not named `docker`. This would otherwise cause the `fixuid` to change its GID and potentially break permissions to access the Docker daemon's socket.

## Older versions

Please see the [commits history](https://github.com/felipecrs/fixdockergid/commits/v0.5.0/) for older versions.
33 changes: 30 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# syntax=docker/dockerfile:1.2

ARG USERNAME="rootless"

# Compiles _fixdockergid.sh with the suid bit set
FROM buildpack-deps:focal AS build

Expand All @@ -23,11 +25,11 @@ FROM scratch AS bin
COPY --from=build /workspace/_fixdockergid /


# Main image
FROM ubuntu:focal AS main
# Contains non-root user and docker-cli
FROM ubuntu:focal AS docker-cli

# Create non-root user
ARG USERNAME="rootless"
ARG USERNAME
ARG USER_UID=1000
ARG USER_GID=$USER_UID

Expand All @@ -44,6 +46,10 @@ RUN apt-get update \
# Clean up \
&& rm -rf /var/lib/apt/lists/*


# Main image
FROM docker-cli AS main

COPY --from=bin / /usr/local/share/fixdockergid/
RUN --mount=source=install.sh,target=/tmp/install.sh \
/tmp/install.sh
Expand All @@ -69,5 +75,26 @@ RUN if [ -n "${HOST_DOCKER_GID}" ]; then groupadd -g "${HOST_DOCKER_GID}" hostdo
USER rootless


FROM docker-cli AS dind

ARG USERNAME

# Install Docker
RUN apt-get update \
&& apt-get install -y --no-install-recommends docker-ce containerd.io docker-buildx-plugin sudo \
# Clean up \
&& rm -rf /var/lib/apt/lists/* \
# Add user to sudoers \
&& echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" | tee "/etc/sudoers.d/${USERNAME}" \
# Add user to docker group \
&& usermod -aG docker "${USERNAME}"

VOLUME ["/var/lib/docker"]

CMD ["sudo", "dockerd"]

USER "${USERNAME}"


# Set default target
FROM main
Binary file modified _fixdockergid
Binary file not shown.
59 changes: 36 additions & 23 deletions _fixdockergid.sh
Original file line number Diff line number Diff line change
@@ -1,40 +1,53 @@
#!/bin/sh

set -eu

if [ "${FIXDOCKERGID_DEBUG:-}" = "true" ]; then
set -x
fi

error() {
echo "$*" >&2
exit 1
}

set -eu

DOCKER_SOCK='/var/run/docker.sock'
CONFIG_YML='/etc/fixuid/config.yml'
fixuid_config='/etc/fixuid/config.yml'

if [ ! -f $CONFIG_YML ]; then
error "File does not exist: $CONFIG_YML. Did you configure fixuid properly?"
if [ ! -f "${fixuid_config}" ]; then
error "File does not exist: ${fixuid_config}. Did you configure fixuid properly?"
fi

if [ "$(id -u)" != 0 ]; then
current_uid="$(id -u)"
if [ "${current_uid}" != 0 ]; then
error "Not running as root. Did you configure the suid bit properly?"
fi
unset current_uid

if [ -S $DOCKER_SOCK ]; then
DOCKER_GID="$(stat -c "%g" $DOCKER_SOCK)"
if [ ! "$(getent group "$DOCKER_GID")" ]; then
if [ "$(getent group docker)" ]; then
groupmod -g "$DOCKER_GID" docker
else
groupadd -g "$DOCKER_GID" docker
fi
docker_sock='/var/run/docker.sock'
if [ -S "${docker_sock}" ]; then
docker_gid="$(stat -c "%g" "${docker_sock}")"

fixuid_group_name="$(awk '/group:/ {print $2}' "${fixuid_config}")"
if [ "${fixuid_group_name}" = "docker" ]; then
error "The fixuid group name cannot be 'docker'."
fi
DOCKER_GROUP=$(getent group "$DOCKER_GID" | cut -d: -f1)
# Make sure the docker group name is docker, so --group-add=docker always works
if [ "$DOCKER_GROUP" != docker ]; then
if [ "$(getent group docker)" ]; then
groupdel docker

if getent group "${docker_gid}" >/dev/null; then
# A group with the docker GID already exists

# Check if it is named docker
docker_gid_group_name="$(getent group "${docker_gid}" | cut -d: -f1)"
if [ "${docker_gid_group_name}" != "docker" ]; then
# In this case we make the group named docker be an alias of such group.
groupmod -o -g "${docker_gid}" docker
fi
groupmod -n docker "$DOCKER_GROUP"
unset docker_gid_group_name
else
# There is no group with docker GID does not already exist, so we fix the
# group named docker to have the proper docker GID.
groupmod -g "${docker_gid}" docker
fi
USER="$(awk '/user:/ {print $2}' $CONFIG_YML)"
usermod -a -G docker "$USER"

fixuid_user_name="$(awk '/user:/ {print $2}' "${fixuid_config}")"
usermod -a -G docker "${fixuid_user_name}"
fi
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

set -euxo pipefail

DOCKER_BUILDKIT=1 docker build --target=bin --platform=amd64 -o . .
docker buildx build --target=bin --platform=amd64 -o . .
83 changes: 48 additions & 35 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,80 +7,93 @@ error() {

set -eu

if [ "$(id -u)" != 0 ]; then
current_uid="$(id -u)"
if [ "${current_uid}" != 0 ]; then
error "This script must be run as root."
fi
unset current_uid

if [ ! "$(command -v curl)" ] && [ ! "$(command -v wget)" ]; then
if ! command -v curl >/dev/null && ! command -v wget >/dev/null; then
error "This script needs curl or wget installed."
fi

fixdockergid_dir=/usr/local/share/fixdockergid
mkdir -p $fixdockergid_dir
cd $fixdockergid_dir
mkdir -p "${fixdockergid_dir}"
cd "${fixdockergid_dir}"
_fixdockergid_filename='_fixdockergid'
if [ -f "$_fixdockergid_filename" ]; then
if [ -f "${_fixdockergid_filename}" ]; then
# Used when building fixdockergid's Dockerfile
echo "Using existing $fixdockergid_dir/$_fixdockergid_filename"
echo "Using existing ${fixdockergid_dir}/${_fixdockergid_filename}"
else
if [ -z "${FIXDOCKERGID_COMMIT+x}" ]; then
if [ -z "${FIXDOCKERGID_COMMIT:-}" ]; then
error "The FIXDOCKERGID_COMMIT environment variable must be set."
fi
echo "Downloading $_fixdockergid_filename to $fixdockergid_dir/$_fixdockergid_filename"
_fixdockergid_url="https://raw.githubusercontent.com/felipecrs/fixdockergid/$FIXDOCKERGID_COMMIT/_fixdockergid"
if [ "$(command -v curl)" ]; then
curl -fsSL -o $_fixdockergid_filename "$_fixdockergid_url"
echo "Downloading ${_fixdockergid_filename} to ${fixdockergid_dir}/${_fixdockergid_filename}"
_fixdockergid_url="https://raw.githubusercontent.com/felipecrs/fixdockergid/${FIXDOCKERGID_COMMIT}/_fixdockergid"
if command -v curl >/dev/null; then
curl -fsSL -o "${_fixdockergid_filename}" "${_fixdockergid_url}"
else
wget -q -O $_fixdockergid_filename "$_fixdockergid_url"
wget -q -O "${_fixdockergid_filename}" "${_fixdockergid_url}"
fi
fi
chown root:root $_fixdockergid_filename
chmod 4755 $_fixdockergid_filename
chown root:root "${_fixdockergid_filename}"
chmod 4755 "${_fixdockergid_filename}"

## Install fixuid
if [ ! "$(command -v fixuid)" ]; then
if [ -z "${USERNAME+x}" ]; then
if ! command -v fixuid >/dev/null; then
if [ -z "${USERNAME:-}" ]; then
error "The USERNAME environment variable must be set."
fi
fixuid_version='0.6.0'
echo "Installing fixuid v$fixuid_version"
fixuid_url="https://github.com/boxboat/fixuid/releases/download/v$fixuid_version/fixuid-$fixuid_version-linux-amd64.tar.gz"
echo "Installing fixuid v${fixuid_version}"
fixuid_url="https://github.com/boxboat/fixuid/releases/download/v${fixuid_version}/fixuid-${fixuid_version}-linux-amd64.tar.gz"
fixuid_filename='fixuid.tar.gz'
if [ "$(command -v curl)" ]; then
curl -fsSL -o $fixuid_filename $fixuid_url
if command -v curl >/dev/null; then
curl -fsSL -o "${fixuid_filename}" "${fixuid_url}"
else
wget -q -O $fixuid_filename $fixuid_url
wget -q -O "${fixuid_filename}" "${fixuid_url}"
fi
fixuid_dir='/usr/local/bin'
tar -C $fixuid_dir -xzf $fixuid_filename
rm -f $fixuid_filename
fixuid_binary="$fixuid_dir/fixuid"
chown root:root $fixuid_binary
chmod 4755 $fixuid_binary
tar -C "${fixuid_dir}" -xzf "${fixuid_filename}"
rm -f "${fixuid_filename}"
fixuid_binary="${fixuid_dir}/fixuid"
chown root:root "${fixuid_binary}"
chmod 4755 "${fixuid_binary}"
mkdir -p /etc/fixuid
printf "%s\n" "user: $USERNAME" "group: $USERNAME" >/etc/fixuid/config.yml
printf "%s\n" "user: ${USERNAME}" "group: ${USERNAME}" >/etc/fixuid/config.yml
fi

fixdockergid_binary='/usr/local/bin/fixdockergid'
echo "Installing fixdockergid to $fixdockergid_binary"
tee $fixdockergid_binary >/dev/null \
echo "Installing fixdockergid to ${fixdockergid_binary}"
tee "${fixdockergid_binary}" >/dev/null \
<<EOF
#!/bin/sh
set -eu
'$fixdockergid_dir/$_fixdockergid_filename'
if [ "\${FIXDOCKERGID_DEBUG:-}" = "true" ]; then
set -x
fi
# Skip if running as root
current_uid="\$(id -u)"
if [ "\${current_uid}" = 0 ]; then
exec "\$@"
fi
unset current_uid
'${fixdockergid_dir}/${_fixdockergid_filename}'
exec fixuid -q -- "\$@"
EOF
chmod +x $fixdockergid_binary
chmod +x "${fixdockergid_binary}"

echo "Ensuring docker group exists"
if [ ! "$(getent group docker)" ]; then
groupadd --system docker
if ! getent group docker >/dev/null; then
groupadd -r docker
fi

echo "Ensuring $USERNAME is part of docker group"
usermod -a -G docker "$USERNAME"
echo "Ensuring ${USERNAME} is part of docker group"
usermod -a -G docker "${USERNAME}"

echo "fixdockergid installation done."
Loading

0 comments on commit 9b6fb88

Please sign in to comment.