Can Tomcat be started as a user other than root under Unix?

Alex Chaffee

Yes, you can run Tomcat as a user other than root. This is recommended, to forestall security holes. (Currently, there are no known problems with running Tomcat as root, but there may be a bug we haven't discovered yet. Also, if you are hosting others' webapps, you don't want a rogue webapp to run Runtime.exec("rm -rf /") or something equally hideous.)

Here is a shell script that starts Tomcat as user "nobody". Under Linux, you may place it in /etc/rc.d/init.d/tomcat and use chkconfig to enable it as a startup/shutdown sequence. Make sure to replace the variable settings with those appropriate to your system.

#!/bin/sh
# Tomcat daemon start/stop script.

mode=$1

export TOMCAT_HOME=/usr/local/tomcat
export JAVA_HOME=/usr/java/jdk1.3

case "$mode" in
  'start')
    # Start daemon
    su -c "$TOMCAT_HOME/bin/tomcat.sh $mode" nobody
    ;;

  'stop')
    # Stop daemon. We use a signal here to avoid having to know the
    # root password.
	$TOMCAT_HOME/bin/tomcat.sh $mode
    ;;

  *)
    # usage
    echo "usage: $0 start|stop"
    exit 1
    ;;
esac

The only problem is that unless you're root, you can't open a socket listening to port 80. This is not a problem if you're running behind a Web server, but if you're running standalone, it means that Tomcat can't respond to "regular" URL requests.

There are plans to add the ability for Tomcat to switch to user root just long enough to open the ServerSocket, then switch back to the regular user.

Until then, here is a workaround. The following Perl script reads HHTP requests from port 80 and responds with an HTTP Redirect response that redirects the clients to port 8080. Unfortunately, this confuses some clients and proxies, so it's not an ideal situation. Install the following as /usr/local/bin/redirector:

#!/usr/bin/perl

$redirect = $ARGV[0];
if ($redirect eq "") {
	$redirect = "http://www.purpletech.com:8080";
}

$line = <STDIN>;
chomp($line);
if ($line =~ /^GET/) {

    $loop = 1;
    while ($loop) {
	$header = <STDIN>;
	chomp($header);
	if ($header =~ /^s*$/) {
	    $loop = 0;
	}
    }
    
    ($uri) = $line =~ /^GET (.*) HTTP/1.*$/;
    if ($uri ne "") {
	print "HTTP/1.0 302 Found
";
	print "Content-type: text/html
";
	print "Location: ${redirect}${uri}
";
	print "
";
	print "<head><title>Document moved</title></head>
";
	print "<body><h1>Document moved</h1>
";
	print "This document has moved <a href='${redirect}${uri}'>here</a>.<p>
";
	print "</body>";
	exit(0);
    }
}

print "HTTP/1.0 404 Not Found
";
print "Content-type: text/html
";
print "
";
print "<head><title>Document not found</title></head>
";
print "<body><h1>Document not found</h1>
";
print "This document is not available right now [line='$line' uri='$uri']
";
print "</body>";
exit(0);
You may install this using inetd or xinetd. For example, to redirect requests to the site http://www.purpletech.com, add the following line to /etc/inetd.conf:
http stream tcp nowait nobody /usr/local/bin/redirector http://www.purpletech.com:8080
(Does anyone know how to do this with xinetd?)
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

About | Sitemap | Contact