tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Pier Fumagalli <>
Subject Re: chroot tomcat
Date Mon, 17 Jun 2002 23:26:50 GMT
"Jason Corley" <> wrote:

> Pier,
> Sorry for emailing you personally but I wasn't sure this is tomcat-dev
> appropriate.  Someone on tomcat-users is asking about chroot and tomcat, and
> I've seen you mention in the past that you have this set up.  I don't know how
> frequently (or even if) you read tomcat-users, so I thought I'd pass along the
> note that at least a few people are curious to know how you set that up
> (myself included).  Again, sorry for bugging you offline.
> Thanks,
> Jason

Don't worry... It's not easy... Basically, you need to set up a small
environment to run a chrooted JVM...

I found a little hack, though: with ldd you can start tracking down what
libraries your JVM requires, and you copy them straight into your chroot
environment /lib directory, right? Do it recursively, so that you won't miss
any of them, then, just use this little bugger:

#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <pwd.h>

int main(int argc, char *argv[]) {
    struct passwd *user=NULL;
    char **args=NULL;
    int x;

    if (argc<4) {
        fprintf(stderr, "Usage: %s [user] [chroot] [command]

    if ((user=getpwnam(argv[1]))==NULL) {
        fprintf(stderr, "%s cannot retrieve user \"%s\"

    if (chroot(argv[2])!=0) {
        fprintf(stderr, "%s cannot chroot to \"%s\"\n",argv[0],argv[2]);

    if (setgroups(1,&user->pw_gid)!=0) {
        fprintf(stderr, "%s cannot set groups id\n", argv[0]);

    if (setgid(user->pw_gid)!=0) {
        fprintf(stderr, "%s cannot set effective group id\n", argv[0]);

    if (setegid(user->pw_gid)!=0) {
        fprintf(stderr, "%s cannot set real group id\n", argv[0]);

    if (setuid(user->pw_uid)!=0) {
        fprintf(stderr, "%s cannot set effective user id\n", argv[0]);

    if (seteuid(user->pw_uid)!=0) {
        fprintf(stderr, "%s cannot set real user id\n", argv[0]);

    args=(char **)malloc((argc-2)*sizeof(char *));
    for (x=3; x<argc; x++) args[x-3]=argv[x];

    execvp(argv[3], args);
    fprintf(stderr, "%s: %s: %s\n", argv[0], argv[3], strerror(errno));

Marvel of marvels, you compile it statically (I called it "safexec") run it
as root (DO NOT INSTALL IT SUID ROOT OR YOU WILL DIE) and all it does is:

1) retrieve the user information from the real /etc
2) chroot the environment
3) switch userid and groupid
4) execute a process...

To launch tomcat, I usually copy /sbin/sh (the static shell) in my chrooted
environment, install the VM in there, and install tomcat: a layout might
look like:


In Lib I put the libraries required by the VM, in java I install the JVM, in
tomcat the default tomcat distribution and in /bin the statically linked sh
and the above little program compiled static as well...

And then (magic):

[root@myhost] ~ # exec env - \
    CATALINA_HOME=/tomcat \
    CATALINA_BASE=/tomcat \
    JAVA_HOME=/java \
    safexec \
        nobody $CHROOT /bin/sh -c "exec /tomcat/bin/ start"

And you get a nice chrooted tomcat 4.0 running as nobody, without too much
hassle! :)

It works on Solaris (you might have to tweak it for Linux, I don't use that
"thing" and neither should you! :) There might be some errors in what I've
written, my chrooted JVMs are all behind a firewall I can't access from
here, but, you'll figure a way! :) :) :)

Oh, btw, we use it not only for Tomcat, but for quite a big set of Java
engines (ServletExec, Orion...).

    Pier (Ccing tomcat-user/dev for the records)

[Perl] combines all the worst aspects of C and Lisp:  a billion of different
sublanguages in  one monolithic executable.  It combines the power of C with
the readability of PostScript. [Jamie Zawinski - DNA Lounge - San Francisco]

To unsubscribe, e-mail:   <>
For additional commands, e-mail: <>

View raw message