diff --git a/.github/workflows/build_test_deploy.yml b/.github/workflows/build_test_deploy.yml index 3b5dafc3..4d10e4ca 100644 --- a/.github/workflows/build_test_deploy.yml +++ b/.github/workflows/build_test_deploy.yml @@ -126,7 +126,7 @@ jobs: password: ${{ secrets.Docker_Password }} - name: Helper to convert docker org to lowercase id: string - uses: ASzc/change-string-case-action@v2 + uses: ASzc/change-string-case-action@v5 with: string: ${{ github.repository_owner }} - name: Build all docker images @@ -182,7 +182,7 @@ jobs: password: ${{ secrets.Docker_Password }} - name: Helper to convert docker org to lowercase id: string - uses: ASzc/change-string-case-action@v2 + uses: ASzc/change-string-case-action@v5 with: string: ${{ github.repository_owner }} - name: Build all docker images @@ -244,7 +244,7 @@ jobs: password: ${{ secrets.Docker_Password }} - name: Helper to convert docker org to lowercase id: string - uses: ASzc/change-string-case-action@v2 + uses: ASzc/change-string-case-action@v5 with: string: ${{ github.repository_owner }} - name: Build all docker images @@ -307,7 +307,7 @@ jobs: password: ${{ secrets.Docker_Password }} - name: Helper to convert docker org to lowercase id: string - uses: ASzc/change-string-case-action@v2 + uses: ASzc/change-string-case-action@v5 with: string: ${{ github.repository_owner }} - name: Build all docker images @@ -370,7 +370,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Helper to convert docker org to lowercase id: string - uses: ASzc/change-string-case-action@v2 + uses: ASzc/change-string-case-action@v5 with: string: ${{ github.repository_owner }} - name: Install python packages @@ -416,7 +416,7 @@ jobs: password: ${{ secrets.Docker_Password }} - name: Helper to convert docker org to lowercase id: string - uses: ASzc/change-string-case-action@v2 + uses: ASzc/change-string-case-action@v5 with: string: ${{ github.repository_owner }} - name: Push image to Docker @@ -461,7 +461,7 @@ jobs: password: ${{ secrets.Docker_Password }} - name: Helper to convert docker org to lowercase id: string - uses: ASzc/change-string-case-action@v2 + uses: ASzc/change-string-case-action@v5 with: string: ${{ github.repository_owner }} - name: Push image to Docker diff --git a/core/admin/start.py b/core/admin/start.py index 3cb5c422..e2163398 100755 --- a/core/admin/start.py +++ b/core/admin/start.py @@ -2,8 +2,15 @@ import os import logging as log +from pwd import getpwnam import sys +os.system("chown mailu:mailu -R /dkim") +os.system("find /data | grep -v /fetchmail | xargs -n1 chown mailu:mailu") +mailu_id = getpwnam('mailu') +os.setgid(mailu_id.pw_gid) +os.setuid(mailu_id.pw_uid) + log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "INFO")) os.system("flask mailu advertise") diff --git a/core/base/Dockerfile b/core/base/Dockerfile index 25c8bd81..20e8b055 100644 --- a/core/base/Dockerfile +++ b/core/base/Dockerfile @@ -1,7 +1,7 @@ # syntax=docker/dockerfile-upstream:1.4.3 # base system image (intermediate) -ARG DISTRO=alpine:3.16.2 +ARG DISTRO=alpine:3.16.3 FROM $DISTRO as system ENV TZ=Etc/UTC LANG=C.UTF-8 @@ -12,7 +12,7 @@ ARG MAILU_GID=1000 RUN set -euxo pipefail \ ; addgroup -Sg ${MAILU_GID} mailu \ ; adduser -Sg ${MAILU_UID} -G mailu -h /app -g "mailu app" -s /bin/bash mailu \ - ; apk add --no-cache bash ca-certificates curl python3 tzdata \ + ; apk add --no-cache bash ca-certificates curl python3 tzdata libcap \ ; machine="$(uname -m)" \ ; ! [[ "${machine}" == x86_64 ]] \ || apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing hardened-malloc @@ -71,6 +71,7 @@ RUN set -euxo pipefail \ FROM system COPY --from=build /app/venv/ /app/venv/ +RUN setcap 'cap_net_bind_service=+ep' /app/venv/bin/gunicorn ENV VIRTUAL_ENV=/app/venv ENV PATH="${VIRTUAL_ENV}/bin:${PATH}" diff --git a/core/none/Dockerfile b/core/none/Dockerfile index f06cc31c..d605cb07 100644 --- a/core/none/Dockerfile +++ b/core/none/Dockerfile @@ -10,5 +10,5 @@ RUN echo $VERSION >/version HEALTHCHECK CMD true -USER app +USER mailu CMD ["/bin/bash", "-c", "sleep infinity"] diff --git a/core/rspamd/start.py b/core/rspamd/start.py index 537d996d..37de1df9 100755 --- a/core/rspamd/start.py +++ b/core/rspamd/start.py @@ -33,4 +33,7 @@ while True: log.warning("Admin is not up just yet, retrying in 1 second") # Run rspamd -os.execv("/usr/sbin/rspamd", ["rspamd", "-i", "-f"]) +os.system("mkdir -m 755 -p /run/rspamd") +os.system("chown rspamd:rspamd /run/rspamd") +os.system("find /var/lib/rspamd | grep -v /filter | xargs -n1 chown rspamd:rspamd") +os.execv("/usr/sbin/rspamd", ["rspamd", "-f", "-u", "rspamd", "-g", "rspamd"]) diff --git a/setup/Dockerfile b/setup/Dockerfile index 85e5f55b..a410871d 100644 --- a/setup/Dockerfile +++ b/setup/Dockerfile @@ -1,24 +1,21 @@ -ARG DISTRO=alpine:3.14.5 -FROM $DISTRO -ARG VERSION -ENV TZ Etc/UTC +# syntax=docker/dockerfile-upstream:1.4.3 + +# setup image +FROM base + +ARG VERSION=local LABEL version=$VERSION - -RUN mkdir -p /app -WORKDIR /app - -COPY requirements.txt requirements.txt -RUN apk add --no-cache curl python3 py3-pip \ - && pip3 install -r requirements.txt - -COPY server.py ./server.py -COPY main.py ./main.py COPY flavors /data/flavors COPY templates /data/templates COPY static ./static +COPY server.py ./server.py +COPY main.py ./main.py + +RUN echo $VERSION >> /version EXPOSE 80/tcp +HEALTHCHECK --start-period=350s CMD curl -skfLo /dev/null http://localhost/ +USER mailu CMD gunicorn -w 4 -b :80 --access-logfile - --error-logfile - --preload main:app -RUN echo $VERSION >> /version diff --git a/setup/requirements.txt b/setup/requirements.txt deleted file mode 100644 index b6f9f713..00000000 --- a/setup/requirements.txt +++ /dev/null @@ -1,12 +0,0 @@ -Flask==1.0.2 -Flask-Bootstrap==3.3.7.1 -gunicorn==19.9.0 -redis==3.2.1 -Jinja2==3.0.3 -MarkupSafe==2.1.0 -Werkzeug==2.0.3 -click==8.0.3 -dominate==2.6.0 -itsdangerous==2.0.1 -redis==3.2.1 -visitor==0.1.3 diff --git a/tests/build.hcl b/tests/build.hcl index fd546ae4..d657cbb7 100644 --- a/tests/build.hcl +++ b/tests/build.hcl @@ -106,6 +106,9 @@ target "docs" { target "setup" { inherits = ["defaults"] context = "setup/" + contexts = { + base = "target:base" + } tags = tag("setup") } diff --git a/tests/compose/filters/02_email_antispam.sh b/tests/compose/filters/02_email_antispam.sh new file mode 100755 index 00000000..ac2653a3 --- /dev/null +++ b/tests/compose/filters/02_email_antispam.sh @@ -0,0 +1,7 @@ +# GTUBE should be blocked, see https://rspamd.com/doc/gtube_patterns.html +python3 tests/email_test.py "XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X" +if [ $? -eq 25 ]; then + exit 0 +else + exit 1 +fi diff --git a/towncrier/newsfragments/2539.misc b/towncrier/newsfragments/2539.misc new file mode 100644 index 00000000..10e3954e --- /dev/null +++ b/towncrier/newsfragments/2539.misc @@ -0,0 +1 @@ +Upgrade to Alpine 3.16.3; Make setup, admin and rspamd run without root privs. Please ensure that your folder overrides/rspamd is owned by 1000:1000