mriedmann / humhub-docker

Alpine-based PHP-FPM and NGINX HumHub docker-container
MIT License
95 stars 77 forks source link

draft: feat: Run as non-root by default to allow easier deployment on the restricted environments like OpenShift, Kubernetes and any corporate (or just secure) environments where root privileges are not allowed #308

Open blackandred opened 1 year ago

blackandred commented 1 year ago

Hi,

The container does not necessarily start as root and then switches permissions to nginx user. I simplified it by starting everything as nginx from the beginning. Additionally I reduced the end image size and memory usage (~20 MB less) by migrating from supervisord to multirun which is a container-native init process, that does not depend on Python.

Benefits:

I was testing it initially with docker-compose, I will test also on Kubernetes and will then "undraft" the PR. I'm creating the PR at this moment to know what do you think about such a big change.

blackandred commented 1 year ago

This may probably resolve issues like https://github.com/mriedmann/humhub-docker/issues/194, because no any process will be running with other privileges than the application, so there will be no chance of accidentially creating a file as root.

blackandred commented 1 year ago

After some more testing I see volume mount points are having non-deterministic permissions, sometimes I get nginx:nginx and other times (more often) I get 101:nginx (why 101?).

Here is my testing script:

HUMHUB_VERSION=1.13.0

build-prod:
    docker build . --target humhub_nginx --build-arg HUMHUB_VERSION=${HUMHUB_VERSION} -t docker.io/mriedmann/humhub:stable-nginx
    docker build . --target humhub_phponly --build-arg HUMHUB_VERSION=${HUMHUB_VERSION} -t docker.io/mriedmann/humhub:stable-phponly

rm-prod:
    docker-compose -f docker-compose.prod.yml rm -s -v -f
    docker volume rm -f humhub-docker_assets humhub-docker_modules humhub-docker_mysql humhub-docker_themes humhub-docker_uploads

run-prod: build-prod rm-prod
    docker-compose -f docker-compose.prod.yml up

build-aio:
    docker build . --target humhub_allinone --build-arg HUMHUB_VERSION=${HUMHUB_VERSION} -t docker.io/mriedmann/humhub:latest
make run-prod
ArchBlood commented 1 year ago

After some more testing I see volume mount points are having non-deterministic permissions, sometimes I get nginx:nginx and other times (more often) I get 101:nginx (why 101?).

Here is my testing script:

HUMHUB_VERSION=1.13.0

build-prod:
  docker build . --target humhub_nginx --build-arg HUMHUB_VERSION=${HUMHUB_VERSION} -t docker.io/mriedmann/humhub:stable-nginx
  docker build . --target humhub_phponly --build-arg HUMHUB_VERSION=${HUMHUB_VERSION} -t docker.io/mriedmann/humhub:stable-phponly

rm-prod:
  docker-compose -f docker-compose.prod.yml rm -s -v -f
  docker volume rm -f humhub-docker_assets humhub-docker_modules humhub-docker_mysql humhub-docker_themes humhub-docker_uploads

run-prod: build-prod rm-prod
  docker-compose -f docker-compose.prod.yml up

build-aio:
  docker build . --target humhub_allinone --build-arg HUMHUB_VERSION=${HUMHUB_VERSION} -t docker.io/mriedmann/humhub:latest
make run-prod

Is it running on a reverse proxy?

blackandred commented 1 year ago

Yes, I'm testing the variant with separate nginx and php-fpm if you are asking abut this.

ArchBlood commented 1 year ago

Yes, I'm testing the variant with separate nginx and php-fpm if you are asking abut this.

Are there any noticeable differences in the logs between ngnix:nginx and 101:nginx after each run?

From my understanding of HumHub itself, it can be picky with reverse proxies. 🤔

blackandred commented 1 year ago

Yeah, with nginx:nginx it starts. With 101:nginx the installation fails for assets directory.

blackandred commented 1 year ago

On all-in-one variant it looks pretty fine I see, at least in docker-compose, I will have to check on Kubernetes on CRI-O.

$ docker volume ls
DRIVER    VOLUME NAME
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

Startup logs

humhub_1  | /docker-entrypoint.sh: Creating database...
humhub_1  | /docker-entrypoint.sh: Installing...
humhub_1  | total 776
humhub_1  | drwxr-xr-x    1 nginx    nginx         4096 Mar  3 05:56 .
humhub_1  | drwxr-xr-x    1 root     root          4096 Mar  3 05:56 ..
humhub_1  | -rw-rw-r--    1 nginx    nginx          413 Dec 21 16:01 .codeclimate.yml
humhub_1  | -rw-rw-r--    1 nginx    nginx         1588 Dec 21 16:01 .htaccess.dist
humhub_1  | -rw-rw-r--    1 nginx    nginx          312 Dec 21 16:01 .php_cs.dist
humhub_1  | -rw-rw-r--    1 nginx    nginx       123496 Dec 21 16:01 CHANGELOG.md
humhub_1  | -rw-rw-r--    1 nginx    nginx         1889 Dec 21 16:01 CONTRIBUTING.md
humhub_1  | -rw-rw-r--    1 nginx    nginx         5973 Dec 21 16:01 Gruntfile.js
humhub_1  | -rw-rw-r--    1 nginx    nginx          328 Dec 21 16:01 LICENSE
humhub_1  | -rw-rw-r--    1 nginx    nginx        34524 Dec 21 16:01 LICENSE.AGPL-3.0-or-later
humhub_1  | -rw-rw-r--    1 nginx    nginx          832 Dec 21 16:01 README.md
humhub_1  | -rw-rw-r--    1 nginx    nginx          240 Dec 21 16:01 SECURITY.md
humhub_1  | drwxrwxr-x    2 nginx    users         4096 Mar  4 08:02 assets
humhub_1  | -rw-rw-r--    1 nginx    nginx         5253 Mar  2 21:46 composer.json
humhub_1  | -rw-rw-r--    1 nginx    nginx       420847 Dec 21 16:01 composer.lock
humhub_1  | -rw-rw-r--    1 nginx    nginx         1331 Dec 21 16:01 index-test.php
humhub_1  | -rw-rw-r--    1 nginx    nginx          876 Dec 21 16:01 index.php
humhub_1  | -rw-rw-r--    1 nginx    nginx       102926 Mar  2 21:46 package-lock.json
humhub_1  | -rw-rw-r--    1 nginx    nginx          433 Mar  2 21:46 package.json
humhub_1  | drwxr-xr-x    1 nginx    nginx         4096 Mar  2 21:17 protected
humhub_1  | -rw-rw-r--    1 nginx    nginx           23 Dec 21 16:01 robots.txt
humhub_1  | drwxrwxr-x    9 nginx    nginx         4096 Mar  2 21:45 static
humhub_1  | drwxrwxr-x    1 nginx    nginx         4096 Mar  2 21:45 themes
humhub_1  | drwxrwxr-x    4 nginx    users         4096 Mar  4 08:02 uploads

(...)

humhub_1  | Validating: User Module - ContentContainer (1 entries)
humhub_1  | Validating: User Module - Users (1 entries)
humhub_1  | Validating: User Module - Password (1 entries)
humhub_1  | Validating: User Module - Profile (1 entries)
humhub_1  | Validating: User Module - Mentioning (0 entries)
humhub_1  | Validating: User Module - Follow (0 entries)
humhub_1  | Validating: User Module - Content container (1 entries)
humhub_1  | 
humhub_1  | *** All integrity checks done
humhub_1  | 
humhub_1  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/60-nginx-config.sh
humhub_1  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/70-nginx-allowedips.sh
humhub_1  | Setting HUMHUB_REVERSEPROXY_WHITELIST
humhub_1  | Added 127.0.0.1 to Reverseproxy Whitelist
humhub_1  | /docker-entrypoint.sh: Configuration complete; ready for start up
humhub_1  | /docker-entrypoint.sh: Entrypoint finished! Launching ...
humhub_1  | crond: crond (busybox 1.34.1) started, log level 8
humhub_1  | 2023/03/04 08:03:27 [notice] 72#72: using the "epoll" event method
humhub_1  | 2023/03/04 08:03:27 [notice] 72#72: nginx/1.20.2
humhub_1  | 2023/03/04 08:03:27 [notice] 72#72: OS: Linux [redacted]
humhub_1  | 2023/03/04 08:03:27 [notice] 72#72: getrlimit(RLIMIT_NOFILE): 1024:1024
humhub_1  | 2023/03/04 08:03:27 [notice] 72#72: start worker processes
humhub_1  | 2023/03/04 08:03:27 [notice] 72#72: start worker process 73
humhub_1  | [04-Mar-2023 08:03:28] NOTICE: [pool www] 'user' directive is ignored when FPM is not running as root
humhub_1  | [04-Mar-2023 08:03:28] NOTICE: [pool www] 'group' directive is ignored when FPM is not running as root
humhub_1  | [04-Mar-2023 08:03:28] NOTICE: fpm is running, pid 69
humhub_1  | [04-Mar-2023 08:03:28] NOTICE: ready to handle connections
humhub_1  | - -  04/Mar/2023:08:03:56 +0000 "GET /ping" 200
$ curl localhost:8080 -L -s  |grep HumHub|grep "<title>"
    <title>Login - HumHub</title>
mriedmann commented 1 year ago

Hi! Thank you both so much for your work. I will try to have a look asap and comment/approve it.

blackandred commented 1 year ago

I marked is as draft so it is not an asap, take your time. I will play with it little bit more and will let you know as I don't want to break somebody's instance with this change 😃

blackandred commented 1 year ago

I started making a Helm Chart (https://github.com/riotkit-org/k8s-humhub) at first I will support root image, then I will experiment with non-root after I will get the root image working enough stable.

mriedmann commented 8 months ago

I would really like to see this change and the helm chart come to (more) life, but I have no time to finish it. Is anyone interested in helping with this? Is there even a need for it? Please Emoji-Vote if you would be interested in using this, thx.

chroniclesofdave commented 7 months ago

I would really like to see this change and the helm chart come to (more) life, but I have no time to finish it. Is anyone interested in helping with this? Is there even a need for it? Please Emoji-Vote if you would be interested in using this, thx.

I'm going to be honest, I have no idea what you are doing with the code, but I use the docker container in truecharts with truenas scale, and I love it. If sorry you have no time, but if I could upvote it a million times I would. I'm having an issue with my deployment because of supervisord troubles and if this would fix those, it would light up my world.

mriedmann commented 6 months ago

I had another look and I will try to get this going. I am still no big fan of multirun but reducing the size and complexity and getting a non-root container is a big improvement. I hope I can get to it over the weekend.

blackandred commented 6 months ago

Wow, sorry for abadoning the topic. I "slept" for almost a year. My instance still works on a feature branch, damn it 😁 Happy to see that somebody took over it.

blackandred commented 6 months ago

I must at least finish the Helm Chart :)

blackandred commented 6 months ago

Regarding the non-root container - I feel there could be some pitfalls on container startup, like chmod/chown or cache wipe, let's check it more strictly.

ArchBlood commented 6 months ago

Regarding the non-root container - I feel there could be some pitfalls on container startup, like chmod/chown or cache wipe, let's check it more strictly.

I've also considered this as well for my own Dockerfile, currently this is how I've implemented it; https://github.com/GreenMeteor/humhub-docker/pull/23