lucee / lucee-dockerfiles

Official Lucee Dockerfiles for Docker Hub build images
https://hub.docker.com/u/lucee/
MIT License
85 stars 50 forks source link

Tomcat process runs as ROOT within container #46

Open goochjj opened 6 years ago

goochjj commented 6 years ago

nginx is properly configured to drop privileges and run as www-data

The generic tomcat images do NOT create a tomcat service account. It's relatively trivial to create your own, and run as that user, but the default Docker Community images don't provide it.

While containers do have some levels of isolation it's best practice to NOT run internet accessible services as root, whether they're in a container or not.

mattblaha commented 6 years ago

Though not entirely a solution to this issue, I run this image as a non root user with namespaces like this:

https://docs.docker.com/engine/security/userns-remap/#about-remapping-and-subordinate-user-and-group-ids

It works well.

justincarter commented 4 years ago

Tomcat official base image doesn't have non-root option currently (still?) but there's one suggested workaround in this issue comment; https://github.com/docker-library/tomcat/issues/68#issuecomment-311745802

I'm not sure if that's a commonly accepted practice or whether it's still valid.

If there's interest in a Lucee non-root image that works out of the box then perhaps we could provide an alternative tag for it at least. The main downside is working with volumes, some users may experience permission issues with files when the UID/GID changes/doesn't match.

justincarter commented 4 years ago

Also if anyone has working examples that they've implemented and would like to share that could be a good starting point.

goochjj commented 4 years ago

My build process doesn't use these Dockerfiles, nor do I use the tomcat image from Docker, because I need to use different JVMs with tomcat on various different child images - I use Corretto 8, Zulu 7 and Oracle 8, and eventually I'll need to do things with 11, so I have my own copy of the tomcat Dockerfile.

I put tomcat in /opt/tomcat instead of /usr/local.... And I provision a tomcat user:

useradd -c "tomcat" -M -G www-data tomcat

mkdir -p /opt/tomcat/.java/.userPrefs
chown -R tomcat:tomcat /opt/tomcat/.java
chown -R root:tomcat /opt/tomcat/
chown -R tomcat:tomcat /opt/tomcat/logs
chown -R tomcat:tomcat /opt/tomcat/temp
chown -R tomcat:tomcat /opt/tomcat/work
chown -R root:www-data /opt/tomcat/webapps/ROOT/
chown -R root:tomcat /opt/tomcat/webapps/ROOT/WEB-INF/
chmod -R u+rwX,g+rX-w,o-rwx /opt/tomcat

#Create and set perms on Catalina
mkdir /opt/tomcat/conf/Catalina
chown -R tomcat:tomcat /opt/tomcat/conf/Catalina

tomcat:tomcat for things the daemon needs to write to. root:tomcat for things the daemon needs to read, but not write.

Later, I run the tomcat daemon using runit:

!/bin/sh -e

cd /opt/tomcat

Tomcat script handles open files, and limiting -d is a bad idea

exec chpst -u tomcat:tomcat:www-data -c 0 -- /opt/tomcat/bin/catalina.sh run

Running catalina with "run" versus "start" keeps it in the foreground. chpst is making it run as tomcat, with the www-data supplemental group.

This should be completely possible without runit by, for example, using "USER tomcat" in the dockerfile, and setting the CMD to ["/opt/tomcat/bin/catalina.sh", "run" ] (or using an entrypoint that does that)

justincarter commented 4 years ago

Thanks Joe that's super helpful, much appreciated :D I'll take a look in the coming weeks to see how I might be able to integrate this or at least offer it as an alternative.

jamie-pate commented 4 years ago

My Dockerfile change to work around this. (I have a www-data-docker group for writable image directories etc)

# add tomcat user to supervisord.conf
# grep fails the command if the line isn't found.

RUN grep -q '\[program:lucee\]'  /etc/supervisor/conf.d/supervisord.conf && \
  sed -i '/^\[program:lucee\]$/a user=tomcat' /etc/supervisor/conf.d/supervisord.conf

# add the external docker group
RUN set -x && \
    groupadd -g $DATA_GID www-data-docker && \
    groupadd tomcat && \
    usermod www-data -aG www-data-docker

# set tomcat to run as a non-root user
# root:tomcat -> /usr/local/tomcat/webapps/ROOT/WEB-INF ?
# tomcat:tomcat   /usr/local/tomcat/.java ?
# root:www-data-docker  /var/www/WEB-INF  ?

RUN set -x && \
  useradd -c "tomcat" -M -g www-data-docker tomcat && \
  usermod -G tomcat tomcat && \
  chown -R root:tomcat /usr/local/tomcat/ /opt/lucee/ && \
  chown -R tomcat:tomcat \
    /usr/local/tomcat/logs \
    /usr/local/tomcat/temp \
    /usr/local/tomcat \
    /usr/local/tomcat/conf/Catalina \
    /opt/lucee/web/ \
    /opt/lucee/server/ \
    && \
  chmod -R u+rwX,g+rX-w,o-rwx /usr/local/tomcat
# ensure that tomcat doesn't screw up and re-create the lucee-server directory inside tomcat
RUN touch /usr/local/tomcat/lucee-server && chmod u-rw,g-rw,o-rw /usr/local/tomcat/lucee-server
tomchiverton commented 6 months ago

Well, that looks easy - we should do this ?

Does it effect accessing files file a volume (docker run -v /home/me/stuff/:/var/www) ?

jamiejackson commented 6 months ago

There are ramifications for host volumes (see this, for instance: https://github.com/docker-solr/docker-solr/issues/118#issuecomment-301525608). I'm not saying it shouldn't be done, but IIRC, it does introduce complications.

As long as we're on the subject, I got an assist from an OpenShift developer a while back when I was trying to lobby the Solr image developers for changes to its image. It still might be relevant if the Lucee Docker project is considering changes to user/permissions. https://github.com/docker-solr/docker-solr/issues/126#issuecomment-353490427