phpmyadmin / docker

Docker container for phpMyAdmin
https://hub.docker.com/_/phpmyadmin
GNU General Public License v3.0
673 stars 456 forks source link

Run container as a non-privileged user #187

Open bittner opened 6 years ago

bittner commented 6 years ago

We need to deploy phpMyAdmin on OpenShift, and this means we cannot perform privileged operations that require root permissions.

chown requires elevated privileges

Unfortunately, this image performs chown operations in the entrypoint script, which makes it impossible to run the image with a non-privileged user. You can verify this easily with a local docker run, e.g.

$ docker run --rm -u 1001 phpmyadmin:latest
/run.sh: line 7: can't create /etc/phpmyadmin/config.secret.inc.php: Permission denied
touch: /etc/phpmyadmin/config.user.inc.php: Permission denied
mkdir: can't create directory '/var/nginx/': Permission denied
chown: /sessions: Operation not permitted
chown: /var/nginx/client_body_temp: No such file or directory
mkdir: can't create directory '/var/run/php/': Permission denied
chown: /var/run/php/: No such file or directory
touch: /var/log/php-fpm.log: Permission denied
chown: /var/log/php-fpm.log: No such file or directory
Error: could not read config file /etc/supervisord.conf
For help, use /usr/bin/supervisord -h

Can we try to fix this, and place a PR? Would you accept such a change?

See also

ibennetch commented 6 years ago

Hi @bittner and thanks for starting this discussion.

In short, yes we would welcome contributions in this area. Our Docker package was set up in a way that got it working and hasn't gotten a whole lot of attention since then, so there are definitely things that could be improved.

I think your suggestion has a high chance of being merged, and any other ideas you have for improving the Docker implementation.

bittner commented 6 years ago

I've looked at the setup a bit. I feel you make your lives unnecessarily complicated with the choice of Nginx. With Apache you have a single service already, no need for a Supervisord setup. The performance penalty is not really significant, IMO.

Is there a reason for this choice?

Would you be happy to simplify the setup and switch back to Apache?

nijel commented 6 years ago

Recommended PHP setup for Apache is anyway using fcgi + php-fpm, so whats the difference?

bittner commented 6 years ago

I don't mean to offend anyone, it's just about maintainability. The second most popular Docker image for phpMyAdmin has a far simpler setup (see its Dockerfile). What is the reason you have a much more elaborate setup? Isn't this more difficult to manage?

It certainly is more difficult for us to convert to a setup that is compatible with OpenShift. :confused:

nijel commented 6 years ago

Yes it has simpler setup - for example it does not verify signature of downloaded tarball. Our setup also used to be simpler when we used prebuilt PHP instead of building it see https://github.com/phpmyadmin/docker/pull/144.

Anyway I don't have strong opinion on whether to use nginx or Apache.

The originally reported issue is generic to many docker containers and is not at all related to nginx or Apache usage. If you run PHP as root inside of the container (what the Apache container AFAIK does), you don't need any chown, but you loose some security. On the other way this is only approach to allow running whole container as different user. I don't have definite answer, but I certainly don't want to trade off security of most users (who don't care about it) for limited set of users who will run docker under different user. The reason for chown is that unprivileged user in container needs write access for session data or file uploads.

bittner commented 6 years ago

We decided to contribute the necessary changes to the nazarpc/phpmyadmin Docker image.

Please, don't be offended. It's really just that it would have taken us much, much longer to get the issue settled with your current setup. Supervisord is reported to be notoriously difficult (if not impossible) to run with a non-privileged user. Thank you for your understanding!

Maybe you can figure out how to get your image to run on Kubernetes-powered container platforms looking at the implementation details (and the README) of the project we contributed to. Keep up the good work! :+1:

nijel commented 6 years ago

Reopening as the issue is still there, it has not disappeared by fixing it in different repository ;-).

Sispheor commented 6 years ago

Just tested the image nazarpc/phpmyadmin and it works perfectly on Openshift. Hope this will be back-ported in this repo soon.

williamdes commented 4 years ago

@Sispheor can someone let us know if it is fixed ? or open a PR ?

v2saude commented 4 years ago

I got the following issue with that img on OpenShift:

AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 10.130.6.146. Set the 'ServerName' directive globally to suppress this message (13)Permission denied: AH00072: make_sock: could not bind to address [::]:80 (13)Permission denied: AH00072: make_sock: could not bind to address 0.0.0.0:80 no listening sockets available, shutting down AH00015: Unable to open logs

williamdes commented 4 years ago

@v2saude could you post your configuration ?

williamdes commented 4 years ago

After some tricks I managed to make it run:


  pmatestvol:
    image: phpmyadmin/phpmyadmin:latest
    container_name: pmatestvol
    dns_search: williamdes.local
    hostname: pmatest.williamdes.local
    domainname: williamdes.local
    restart: on-failure:2
    mem_limit: 100m
    user: 1000:1000
    networks:
      williamdeslocal:
        aliases:
          - pmatest.williamdes.local
    env_file:
      - ./pma.env
    sysctls:
      - net.ipv4.ip_unprivileged_port_start=0
    volumes:
      - pmavol:/var/www/html
      - ./phpmyadmin-upload-limit.ini:/usr/local/etc/php/conf.d/phpmyadmin-upload-limit.ini
      - ./config.secret.inc.php:/etc/phpmyadmin/config.secret.inc.php
      - ./config.user.inc.php:/etc/phpmyadmin/config.user.inc.php:ro
    ports:
      - "600:80"
chiqui3d commented 3 years ago

And why not use a port other than 80 in Apache, i.e. a port greater than 1024 so that it can run as a non-root user, and then we redirect the port as we are currently doing.

0Styless commented 2 years ago

Is there anything new to this? We definitely want to run this container as nonRoot, especially in combination with Kyverno-Policies in k8s.

As @chiqui3d mentioned, it would be a good first step to use another port than 80 (greater than 1024) in Apache.

devinmatte commented 2 years ago

Any update on this? Just want to be able to run the app on a port other than 80 like requested in #340 to allow running on Openshift

williamdes commented 2 years ago

Any update on this? Just want to be able to run the app on a port other than 80 like requested in #340 to allow running on Openshift

Next phpMyAdmin version will have the new env to change the Apache port 🎉 Deployed on https://hub.docker.com/_/phpmyadmin ! 🚀 That said I am not sure how this will work out for non root users because the files are still owner by root

Anyone has ideas on how to solve this without rebuilding the image ?

erfantkerfan commented 1 year ago

+1

williamdes commented 1 year ago

Hi @erfantkerfan Can you try and report what's not working so it can be fixed?

erfantkerfan commented 1 year ago

Hi @erfantkerfan Can you try and report what's not working so it can be fixed?

running phpmyadmin/phpmyadmin image with user nobody doesn't work (I'm not mounting any files), In my case, I'm using docker swarm but there is no difference between a simple docker run with how I'm running it. PS. Don't mind the PMA_ABSOLUTE_URI I'm running it behind an Nginx reverse proxy. I think this is the exact thing I tried to do, the URL became available but gave me some error about it not being able to read the config file and I couldn't log in. I hope it helps.

version: "3.7"

services:
  phpmyadmin_web:
    image: phpmyadmin/phpmyadmin:latest
    ports:
      - "80:80"
    extra_hosts:
      - mydb:host-gateway
    user: nobody
    environment:
      - PMA_HOST=mydb
      - PMA_ABSOLUTE_URI=https://someweburi.com/pma
    deploy:
      replicas: 1
ebeltramo96 commented 1 year ago

hello, is there any update on this topic?

williamdes commented 1 year ago

Hello Unfortunately not, 8 am sorry about that But that's definitely on my infinite todo list Any pull request to try to fix this would be very welcome

obel1x commented 10 months ago

i lately installed docker rootless as written in https://docs.docker.com/engine/security/rootless/ using some created user named docker.

Problem: phpMyAdmin will show Fatal error: Uncaught Error: Failed opening required '/etc/phpmyadmin/config.secret.inc.php' (include_path='.:/usr/local/lib/php') in /etc/phpmyadmin/config.inc.php:3 Stack trace: #0 /var/www/html/show_config_errors.php(43): include() #1 {main} thrown in /etc/phpmyadmin/config.inc.php on line 3

And won't connect at login.

Cause: The Permissions of /etc/phpmyadmin/config.secret.inc.php are wrong by default in that case:

root@e85f80f22781:/etc/phpmyadmin# ls -l
total 16
-rw-rw-r-- 1 root root 5336 Dec 19 23:52 config.inc.php
-rw-rw---- 1 root root   68 Dec 28 15:36 config.secret.inc.php
-rw-r--r-- 1 root root  352 Dec 28 15:20 config.user.inc.php

But apache is running as www-data user:

root@e85f80f22781:/etc/phpmyadmin# ps xua | grep apache
root         1  0.0  0.1 223500 32612 ?        Ss   15:36   0:00 apache2 -DFOREGROUND
www-data    22  0.0  0.0 224196 30980 ?        S    15:36   0:00 apache2 -DFOREGROUND
www-data    23  0.0  0.0 224244 29696 ?        S    15:36   0:00 apache2 -DFOREGROUND

This is due to default umask and facls on the docker- user- directory, not allowing "others" to read docker- contents (on the host). The docker-entrypoint.sh which creates the file will inherit the permissions of the host while not specifying them.

Solved by: Changing the group of that file in docker-entrypoint.sh works: chgrp www-data /etc/phpmyadmin/config.secret.inc.php

This is more safe, than changing the permissions while they would also get change on the host i guess.

Would it be possible to add that line to the file? I'll leave a quick push here if you like.

williamdes commented 7 months ago

Hello all,

I pushed some work to mitigate some of the current rootless issues. See: https://github.com/phpmyadmin/docker/commit/6d69b7796b970039b725ec8937433eb68148f5f9 and https://github.com/phpmyadmin/docker/commit/2335c3151b93ea6a4cf8779c4c90cb21572b6c50

The custom INI file and the web files are now owned+group by www-data.

I added a test for this https://github.com/phpmyadmin/docker/commit/6a687794c6c5857e37866de5c39eba50a7bc82ca#diff-56ee0291fa09d6cff1f37f773112f9ad35f117812b37abcd39b90ce057da1143R25

Now to run rootless Debian you need to use:

    # www-data:www-data in Debian (https://stackoverflow.com/a/69290889/5155484)
    user: 33:33

@obel1x do you think https://github.com/phpmyadmin/docker/pull/432 is still needed ?

One item left is the APACHE_PORT ENV but I am not that confident about widening permissions on the /etc/apache2/sites-enabled/000-default.conf and /etc/apache2/ports.conf files.

ℹ️ This is not released yet

obel1x commented 7 months ago

Hello @williamdes,

The custom INI file and the web files are now owned+group by www-data. Well i admit i do not spend much time investigating the code, but generally as from the security p.o.v... sorry to say, but this - i think - is a very very bad idea, until there is a strong need for giving the phpmyadmin/apache write permissions to the files. If there is no reason for phpmyadmin writing to the files (are there really any for the custom ini, which is inserted for additional settings from the host-side?), please do not make them owned by www-data and if you make them group accessable, then remove write permissions until they are needed for functionality.

If the is any security leak either in php( ,fpm?), in phpmyadmin or in apache, you could easyly change all contents of all those files, giving some attacker an easy way to capture that service completely. When setting up services without docker, i always have all files that apache is allowed to access owned by root and give the apache read access by group only (or by acl). That way, writing to the files won't be allowed for the service even if the code may be breached. This is following the important "principle of least privilege" - https://www.okta.com/identity-101/minimum-access-policy/ Maybe you can find other ways to solve those issues? I would really appreciate this.

@obel1x do you think #432 is still needed ? Yes - as written in https://github.com/phpmyadmin/docker/pull/432#discussion_r1468866482 i explained that the File is intentionally owned by root which is highly needed for security.

I admit, it is a pitty that docker is not able to manage groups the persistent way that linux does and that umask is not supported until now, but as long as thats the fact, docker implementations need to work around and still be secure.

williamdes commented 2 months ago

If the is any security leak either in php( ,fpm?), in phpmyadmin or in apache, you could easyly change all contents of all those files, giving some attacker an easy way to capture that service completely. When setting up services without docker, i always have all files that apache is allowed to access owned by root and give the apache read access by group only (or by acl). That way, writing to the files won't be allowed for the service even if the code may be breached. This is following the important "principle of least privilege" - https://www.okta.com/identity-101/minimum-access-policy/ Maybe you can find other ways to solve those issues? I would really appreciate this.

I agree that this was not a great idea and indeed there is an escalation risk I reverted this part with 0109a4fbdd4144fa3585260527d200818ac76eaf

Now that #432 is merged, do you think we are rootless ready (minimum) ? That said, for now ENVs do not work anymore for rootless. Like it was before my commit. See CI failure: https://github.com/phpmyadmin/docker/actions/runs/10476943894/job/29016974520#step:6:249