docker-php icon indicating copy to clipboard operation
docker-php copied to clipboard

Running processes as root helps attackers

Open szepeviktor opened this issue 4 years ago • 15 comments

Please consider avoiding root (UID 0) and system users (UID 1-999) e.g. www-data. Least privileges come with normal users.

szepeviktor avatar May 28 '21 02:05 szepeviktor

I totally agree and this is on my radar.

I am hoping this will be fixed in #15.

The only problem I had was if I set it to www-data in this image, then later on I want to add a PHP package (like php-redis or something), I was running into errors that www-data did not have permissions to install.

I will definitely be revisiting this because its one of the bigger worries I had about this set up.

jaydrogers avatar May 28 '21 16:05 jaydrogers

Please be aware that www-data is a "system user" having higher privileges than normal users. See UID-s in the top comment.

szepeviktor avatar May 28 '21 16:05 szepeviktor

then later on I want to add a PHP package

Setting user in a Docker image should be the last step.

I hope you do not intent to install packages in a running container!

szepeviktor avatar May 28 '21 17:05 szepeviktor

I hope you do not intent to install packages in a running container!

No, this would be like this...

Problem

  • If I set a USER 12345 to run the serversideup/php:8.0-fpm-nginx as, how would down stream docker images add their project dependencies?

For example

(I think I tried this earlier)

On a downstream docker project, I might want a new Dockerfile that depends off of the base image from ServerSideUp:

FROM serversideup/php:8.0-fpm-nginx

RUN apt update && apt install php-redis

☝️ If I have USER 12345 (telling the container to run as UID 12345 from the parent image), this will fail because USER 12345 cannot install php-redis.

Thoughts?

jaydrogers avatar May 28 '21 17:05 jaydrogers

how would down stream docker images add their project dependencies?

USER 0
MANAGE DEPS
USER 12345

Done!

szepeviktor avatar May 28 '21 17:05 szepeviktor

I will definitely give this a whirl, thanks!!

jaydrogers avatar May 28 '21 17:05 jaydrogers

Here is an update on this:

Problem

  • When I use S6 Overlay, I cannot get logging to work on the php-fpm image

Screen Shot 2021-06-22 at 5 25 58 PM

How to recreate the problem

1. Copy my Dockerfile

####################################################
# Server Side Up -  PHP 7.4 / FPM image 
#####################################################

FROM serversideup/php:beta-7.4-cli

LABEL maintainer="Jay Rogers (@jaydrogers)"

# Set default PHP environment variables

ENV PHP_DATE_TIMEZONE="UTC" \
    PHP_DISPLAY_ERRORS=On \
    PHP_ERROR_REPORTING="E_ALL & ~E_DEPRECATED & ~E_STRICT" \
    PHP_MEMORY_LIMIT="256M" \
    PHP_MAX_EXECUTION_TIME="99" \
    PHP_POST_MAX_SIZE="100M" \
    PHP_UPLOAD_MAX_FILE_SIZE="100M" \
    PHP_POOL_NAME="www" \
    PHP_PM_CONTROL=dynamic \
    PHP_PM_MAX_CHILDREN="20" \
    PHP_PM_START_SERVERS="2" \
    PHP_PM_MIN_SPARE_SERVERS="1" \
    PHP_PM_MAX_SPARE_SERVERS="3"

# Install FPM
RUN apt-get update \
    && apt-get -y --no-install-recommends install \
        php7.4-fpm \
        && echo "Allow pool name to be set via env, default it to 'www'..." \
    && sed -i -e 's/\[www\]/\[$\{PHP_POOL_NAME\}]/g' /etc/php/7.4/fpm/pool.d/www.conf \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*

# Apply PHP configuration file
# COPY etc/php/fpm/pool.d/y-override-php-defaults.conf /etc/php/7.4/fpm/pool.d/y-override-php-defaults.conf

CMD ["/usr/sbin/php-fpm7.4", "-O" ]

# Open up fcgi port
EXPOSE 9000

2. Build my Dockerfile locally Run this from the folder where you placed the Dockerfile:

docker build --pull . -t localhost/php:7.4-fpm

3. Run the local image Run the

docker run -it --rm --name fpm localhost/php:7.4-fpm

Important note:

  1. The Dockerfile above depends on the beta image (serversideup/php:beta-7.4-cli), which is built from this file https://github.com/serversideup/docker-php/blob/dev/php/7.4/cli/Dockerfile
  2. The CLI image is based off of serversideup/docker-baseimage-s6-overlay-ubuntu:20.04, which is located in this new repo https://github.com/serversideup/docker-baseimage-s6-overlay-ubuntu/blob/main/Dockerfile

Things that concern me

I don't even know if this is possible to run as a "non-root" user due to how PHP-FPM is structured. I'm pretty sure PHP-FPM needs root in order to start its processes.

Other repos that are running PHP as "root"

These very talented groups are also not running things as an unprivileged user:

  1. bitnami/php-fpm
  2. linuxserver/docker-nextcloud (great example of a PHP app running on S6 Overlay... they aren't PHP-FPM though...)

What I think I might have to do

My gut feeling is telling be that I will:

  • Need to continue to run the container as root
  • Use the configurations of NGINX & PHP-FPM to select the proper user (my 9999 user)

Calling in help

@szepeviktor: Are you aware of any examples of projects running PHP as an unprivileged user?

jaydrogers avatar Jun 22 '21 22:06 jaydrogers

Hello! It is highly popular to give a sh*t about what is(is going on) inside a container. People do not have time to follow CVE-s. So there's such a thing as breaking out of a container.

Actually it is a novice mistake to run something as root - no matter whether inside a container or not.

S6 Overlay needs to run as root but it does not mean that PHP-FPM needs too. PHP-FPM opens a socket file and a TCP socket, starts threads, creates a PID file - what is the problem here?

szepeviktor avatar Jun 22 '21 23:06 szepeviktor

Are you aware of any examples of projects running PHP as an unprivileged user?

I think PHP-FPM operates this way

kép

The master process runs as root, workers run as a normal user.

szepeviktor avatar Jun 22 '21 23:06 szepeviktor

Thanks for chiming in!

You confirmed my assumptions. I will need to remove the extra arguments on this line:

https://github.com/serversideup/docker-php/blob/718f31077fab37d27648120e81963a42fea7be83/php/7.4/cli/Dockerfile#L51

If I leave those lines in there above, PHP-FPM will not be able to start correctly because its trying to start the master process as webuser (userid 9999).

Instead, I will have root start the masterprocess, which will then use the PHP-FPM config to start the children as webuser (userid 9999).

Does that sound like a good approach?

jaydrogers avatar Jun 22 '21 23:06 jaydrogers

BTW Debian uses https://github.com/krallin/tini

szepeviktor avatar Jun 22 '21 23:06 szepeviktor

Does that sound like a good approach?

At first glace yes. Staring a lot at htop may tell you much more.

szepeviktor avatar Jun 22 '21 23:06 szepeviktor

php-fpm.conf could have daemonize = no and I think PHP-FPM could run as non-privileged user if you don't set user and group in pool config.

szepeviktor avatar Jun 22 '21 23:06 szepeviktor

php-fpm.conf could have daemonize = no

Thanks! I have this set already.

and I think PHP-FPM could run as non-privileged user if you don't set user and group in pool config.

Interesting! I will play around with this. Thanks!!

jaydrogers avatar Jun 22 '21 23:06 jaydrogers

It is open-source. You can spend weeks with it!

szepeviktor avatar Jun 22 '21 23:06 szepeviktor