From e2873ffce795432bc21e0b50856ec0d6b1f1e8b2 Mon Sep 17 00:00:00 2001 From: Stefan Allius <122395479+s-allius@users.noreply.github.com> Date: Wed, 22 Nov 2023 21:57:42 +0100 Subject: [PATCH] Hardening (#30) * set build-argument for environment * hardening remove dangerous commands * add hardening scripts for base and final image --- CHANGELOG.md | 1 + app/Dockerfile | 16 +++++++++++----- app/build.sh | 6 +++--- app/entrypoint.sh | 4 +++- app/hardening_base.sh | 19 +++++++++++++++++++ app/hardening_final.sh | 22 ++++++++++++++++++++++ 6 files changed, 59 insertions(+), 9 deletions(-) create mode 100644 app/hardening_base.sh create mode 100644 app/hardening_final.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index ddb5eca..332984c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- hardening remove dangerous commands from busybox - add OTA start message counter - add message handler for over the air updates - add unit tests for ota messages diff --git a/app/Dockerfile b/app/Dockerfile index 1409601..6b796c1 100644 --- a/app/Dockerfile +++ b/app/Dockerfile @@ -7,8 +7,11 @@ ARG GID=1000 FROM python:3.12-alpine AS base USER root +COPY --chmod=0700 ./hardening_base.sh . RUN apk upgrade --no-cache && \ - apk add --no-cache su-exec + apk add --no-cache su-exec && \ + ./hardening_base.sh && \ + rm ./hardening_base.sh # # second stage for building wheels packages @@ -29,29 +32,32 @@ ARG VERSION ARG UID ARG GID ARG LOG_LVL +ARG environment ENV VERSION=$VERSION ENV SERVICE_NAME=$SERVICE_NAME ENV UID=$UID ENV GID=$GID ENV LOG_LVL=$LOG_LVL +ENV HOME=/home/$SERVICE_NAME # set the working directory in the container WORKDIR /home/$SERVICE_NAME -# update PATH environment variable -ENV HOME=/home/$SERVICE_NAME - VOLUME ["/home/$SERVICE_NAME/log", "/home/$SERVICE_NAME/config"] # install the requirements from the wheels packages from the builder stage # and unistall python packages and alpine package manger to reduce attack surface COPY --from=builder /root/wheels /root/wheels +COPY --chmod=0700 ./hardening_final.sh . RUN python -m pip install --no-cache --no-index /root/wheels/* && \ rm -rf /root/wheels && \ python -m pip uninstall --yes setuptools wheel pip && \ - apk --purge del apk-tools + apk --purge del apk-tools && \ + ./hardening_final.sh && \ + rm ./hardening_final.sh + # copy the content of the local src and config directory to the working directory COPY --chmod=0700 entrypoint.sh /root/entrypoint.sh diff --git a/app/build.sh b/app/build.sh index 85905ee..87cc79f 100755 --- a/app/build.sh +++ b/app/build.sh @@ -22,11 +22,11 @@ fi echo version: $VERSION build-date: $BUILD_DATE image: $IMAGE if [[ $1 == dev ]];then -docker build --build-arg "VERSION=${VERSION}" --build-arg "LOG_LVL=DEBUG" --label "org.label-schema.build-date=${BUILD_DATE}" --label "org.opencontainers.image.version=${VERSION}" -t ${IMAGE}:latest app +docker build --build-arg "VERSION=${VERSION}" --build-arg environment=dev --build-arg "LOG_LVL=DEBUG" --label "org.label-schema.build-date=${BUILD_DATE}" --label "org.opencontainers.image.version=${VERSION}" -t ${IMAGE}:latest app elif [[ $1 == rc ]];then -docker build --build-arg "VERSION=${VERSION}" --label "org.label-schema.build-date=${BUILD_DATE}" --label "org.opencontainers.image.version=${VERSION}" -t ${IMAGE}:latest app +docker build --build-arg "VERSION=${VERSION}" --build-arg environment=production --label "org.label-schema.build-date=${BUILD_DATE}" --label "org.opencontainers.image.version=${VERSION}" -t ${IMAGE}:latest app elif [[ $1 == rel ]];then -docker build --no-cache --build-arg "VERSION=${VERSION}" --label "org.label-schema.build-date=${BUILD_DATE}" --label "org.opencontainers.image.version=${VERSION}" -t ${IMAGE}:latest -t ${IMAGE}:${MAJOR} -t ${IMAGE}:${VERSION} app +docker build --no-cache --build-arg "VERSION=${VERSION}" --build-arg environment=production --label "org.label-schema.build-date=${BUILD_DATE}" --label "org.opencontainers.image.version=${VERSION}" -t ${IMAGE}:latest -t ${IMAGE}:${MAJOR} -t ${IMAGE}:${VERSION} app docker push ghcr.io/s-allius/tsun-gen3-proxy:latest docker push ghcr.io/s-allius/tsun-gen3-proxy:${MAJOR} docker push ghcr.io/s-allius/tsun-gen3-proxy:${VERSION} diff --git a/app/entrypoint.sh b/app/entrypoint.sh index 87148ce..7698d41 100644 --- a/app/entrypoint.sh +++ b/app/entrypoint.sh @@ -11,10 +11,12 @@ if [ "$user" = '0' ]; then mkdir -p /home/$SERVICE_NAME/log /home/$SERVICE_NAME/config if ! id $SERVICE_NAME &> /dev/null; then + echo "# create user" addgroup --gid $GID $SERVICE_NAME 2> /dev/null adduser -G $SERVICE_NAME -s /bin/false -D -H -g "" -u $UID $SERVICE_NAME + chown -R $SERVICE_NAME:$SERVICE_NAME /home/$SERVICE_NAME || true + rm -fr /usr/sbin/addgroup /usr/sbin/adduser /bin/chown fi - chown -R $SERVICE_NAME:$SERVICE_NAME /home/$SERVICE_NAME || true echo "######################################################" echo "#" diff --git a/app/hardening_base.sh b/app/hardening_base.sh new file mode 100644 index 0000000..c377337 --- /dev/null +++ b/app/hardening_base.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +rm -fr /var/spool/cron +rm -fr /etc/crontabs +rm -fr /etc/periodic + +# Remove every user and group but root +sed -i -r '/^(root)/!d' /etc/group +sed -i -r '/^(root)/!d' /etc/passwd + +# Remove init scripts since we do not use them. +rm -fr /etc/inittab + +# Remove kernel tunables since we do not need them. +rm -fr /etc/sysctl* +rm -fr /etc/modprobe.d + +# Remove fstab since we do not need it. +rm -f /etc/fstab diff --git a/app/hardening_final.sh b/app/hardening_final.sh new file mode 100644 index 0000000..c6896bb --- /dev/null +++ b/app/hardening_final.sh @@ -0,0 +1,22 @@ +#!/bin/sh +# For production images delete all uneeded admin commands and remove dangerous commands. +# addgroup, adduser and chmod will be removed in entrypoint.sh during first start +# su-exec will be needed for ever restart of the cotainer +if [ "$environment" = "production" ] ; then \ + find /sbin /usr/sbin ! -type d \ + -a ! -name addgroup \ + -a ! -name adduser \ + -a ! -name nologin \ + -a ! -name su-exec \ + -delete; \ + find /bin /usr/bin -xdev \( \ + -name chgrp -o \ + -name chmod -o \ + -name hexdump -o \ + -name ln -o \ + -name od -o \ + -name strings -o \ + -name su -o \ + -name wget -o \ + \) -delete \ +; fi