tomcat
tomcat copied to clipboard
Consider providing a "hardened" tomcat
Please considering providing a docker image that would be ready for production use.
Guides https://tomcat.apache.org/tomcat-7.0-doc/security-howto.html https://www.owasp.org/index.php/Securing_tomcat
Also related to using the native library https://github.com/docker-library/tomcat/issues/7
See also the switch to run tomcat as root in 6f1c628fa92feea8b28e98e56a990500f2326936 and the discussion in #3
Would the tomee image be similar to what you are looking for? (https://github.com/docker-library/official-images/pull/889, via: https://github.com/tomitribe/docker-tomee)
EE stands for Enterprise Edition IIRC which mostly means that a lot more stuff is bundled into it.
My concern is more related to operational security and part of the bigger "whose docker images can we trust" question.
Until these security issues are addressed we can't reasonably put this container into production unaltered. And if we can't use the official container in production, then what is the point really? There needs to be better oversight on the security issues. #6 should never have been merged.
I am currently copying the dockerfile because of this, I don't know that I would call not running a daemon as root "hardening", when I think hardened I tend to think of tools like SELinux, this is just a security vulnerability.
Any news on this? It's a serious concern I think, not only the container needs to run as root, but there's no user switch to run tomcat, so it runs as root too. I don't this is acceptable for an official image. Thanks
With user namespaces this is less of an issue than it has been in the past. You can map "container root" to be any specific user id on your docker host (see blog and docs). That said, we are considering adding similar improvements as https://github.com/docker-library/rabbitmq/pull/60 to make docker run -d --user 1000 tomcat work.
(and things like SELinux, AppArmor, and seccomp filtering happen at the Docker level when you run the container through various runtime flags, so they don't apply directly at the image level)
@yosifkit I noticed the same was merged for MariaDB (potentially breaking docker-entrypoint-initdb.d scripts that depend on root.)
But why do it this way? Are there calls for arbitrary user support (I don't have a need for it)? Don't we just want plug-and-play containers that are secure by default?
most official images run on non-root users; it's a bit weird that this official image by default doesn't
i've extended the base image according to some of the OWASP remarks:
FROM library/tomcat:8.0.36-jre8-alpine
RUN rm -R $CATALINA_HOME/webapps/* && \
addgroup -g 900 tomcat && adduser -h $CATALINA_HOME -u 900 -G tomcat -s /bin/bash -D tomcat && \
chown -R tomcat:tomcat $CATALINA_HOME && \
chmod 400 $CATALINA_HOME/conf/* && \
chmod -R 300 $CATALINA_HOME/logs && \
chmod -R 600 $CATALINA_HOME/temp
ADD *.war $CATALINA_HOME/webapps/ROOT.war
USER tomcat
@tubbynl you also need to add the following:
RUN chmod -R 550 $CATALINA_HOME
RUN chmod -R 550 $CATALINA_HOME/webapps/
and then chown to give root:tomcat ownership on the tomcat folder recursively + give tomcat:tomcat ownership on the /conf /logs and /work subfolders recursively.
Otherwise, an eventually vulnerable application running on tomcat may be able to run "rm -rf" on the webapps folder or on other tomcat folders. For more accurate details and examples, see my pull request.
Or even worse: modifying some files. It will take some time before someone notices that the index.jsp file is now redirecting users to some porn site...
The reason for official images to not run as root is based on the purpose of the image. Images that are a service like mysql and postgres run as a specific user since we know ports and file system usage ahead of time. Images that are for running a users code like django, golang, python, node, tomcat, etc, run as root since users often mount their own code in and we cannot guarantee that user 999 in the container, for example, would have access to whatever they mount. In order to provide "plug-and-play" images, we run as root. A user is free to do their own image FROM tomcat that sets a different user and adds correct permissions for their files; I had also mentioned that we contemplated making an entrypoint that chowns and drops to a non-root user, but that messes with users' bind-mounted files.
When I try what is suggested by @tubbynl above, I have this issue : https://github.com/docker/docker/issues/30285 I've tried to switch to overlay2 but I have the same result. I've tried to group "useradd" and "chown" in the same "RUN" but same result. (I have to say some guy with Archlinux distrib and a very recent kernel (~4.8) didnt get this strange behavior, and with devicemapper I don't reproduce it as well).
Could you please give me some light ?
I was very disappointed to discover this image running tomcat as root by default. I recognize the reasons for doing it mentioned by @yosifkit , but I would argue those are bad reasons. How many people are going to pull this image, and because it's the docker official image, assume it's good to go and drop it on the public internet. And just because that isn't good practice doesn't mean it doesn't happen.
This is a bit like using Windows as an administrator user. It might be "easier," but it's a very bad idea.
IMO - This should be put back to the tomcat user and if someone's code won't load then they can fix it instead of running a web server as root out of the box because it's "easier."
I do agree with @lpkirby, it’s especially dangerous because it’s “official”. In it’s current state it’s better to not have it.
People will also always want to run it without the managment app (redeployment inside the container makes no sense)
Also it will always run with a single war (single responsibility).
So i think that streamlining this image to docker best practices will also make it more secure by default.
And extending the image and setting correct ownership really adds a lot of extra size
Quick example to create an image that allows running as any user:
FROM tomcat:9-jre8
# roughly a chmod 777, but don't add executable to regular files
RUN chmod -R go+rwX "$CATALINA_HOME"
# warning that this will probably not work on aufs
Then it can be run with an arbitrary user id:
$ docker build -t tomtest .
$ docker run -d --user 1000:1000 tomtest
There is a slight size increase compared to the regular:
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat 9.0-jre8 bb29c066aba8 9 days ago 557MB
tomtest latest 4e462cc4624f 3 minutes ago 572MB
We could save the size by just adding the permissive permissions in the image and allowing the container to just work when run as an arbitrary user as we have done in other images like https://github.com/docker-library/rabbitmq/pull/60 (and the other PRs linked there). Would this be a useful change?
This issue seems to have been hijacked by one element: running as root. I suggest that argument be moved to another issue.
The original issue was to provide a "hardened" flavor of the tomcat image. There are several things to do, such as removing the docs and examples folders, that can easily be done. Some ideas have been captured by non-official images, such as unidata/tomcat-docker.
All default webapps are being removed by default in https://github.com/docker-library/tomcat/pull/181.
Regarding running it as non-root, here is a Dockerfile that we use:
FROM tomcat:9.0-jdk11-adoptopenjdk-hotspot
RUN addgroup --system --gid 1000 tomcat \
&& adduser --system --uid 1000 --gid 1000 tomcat \
&& chown -R tomcat $CATALINA_HOME
USER tomcat
I do understand that there might be a reason to have this image run as root by default, because there might be usecases where this is just enough. My suggestion would be to just add some bit of documentation on this topic to the page on Dockerhub, as a kind of official recommendation.
If your application doesn't require a specific user named in /etc/passwd, something like the following is also sufficient:
FROM tomcat:xxx
USER 1000:1000
(I did my testing with --user 1000:1000 on docker run.)
We definitely should add a blurb to the image description about that, probably similar to the "Arbitrary user" nodes on several other images.