Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I am setting up a Debian server to serve Java web applications. I have done quite a bit of research for several weeks now. Tomcat's web site says it is better to use stand alone Tomcat for speed if you are not clustering. However, I have seen many people suggest that using Apache + Tomcat gives you better security and protection against attacks.

Please assume that the process will be running on port 80 as an unprivileged user. I would assume that if you are running a firewall in front the server, Tomcat should be fine. If, however, you just want to run an exposed web server using Linux firewall, what is the best option?

Or maybe someone can recommend another open source web server. I am trying to keep the solution as light as possible as these webapps will be running in containers.

All opinions welcome and valued.

share|improve this question

3 Answers 3

From my own experience, It's wise to keep something in front of Tomcat to shield it a bit from the outside world. If you run tomcat with the Tomcat-native extension, IO are very fast and Tomcat will behave very well.

Also Tomcat can run on port 80 without running in root by using jsvc which is, if not provided with your distro, very simple to build and use.

However keeping a simple Web frontend just in case is also useful: because this frontend can give you the small touch of flexibility you'll never have with Tomcat (gzip on the fly, rewrite rules, handle more than one tomcat on the same IP:Port using simple virtualhost and proxy mapping,... )

Apache2 can be this frontend using mod_proxy + AJP. AJP handles headers and source IP forwarding to the Tomcat and you'll never be much happier when you'll have to add RewriteRules on your domain because Apache provides that in a very simple way.

However, AJP is very slow to pick the webapp status change and having to wait 30 seconds when your webapp restarts to see it available again on the internet is VERY frustrating. There are also some not so nice issues in latest AJP + Tomcat combination leading to empty pages and broken content type (can be fixed though, but by giving up the tomcat-native enhancements...).

The simple HTTP Mod_proxy can also be used, but by not being a real proxy (Apache changes the Host: header, source IP becomes proxy address,...) is something I don't really like.

Other nice alternatives include:

  • HAProxy: Very smart and simple proxy, very good at handling load, quite simple to configure, rock solid and a real HTTP Proxy, can forward the source IP via the usual X-Forwarded-For Header. I use this in production and I'm very happy about that. It can scale up to thousands of live connection while restricting the number of active connections to your backend and has many nice features built-in. However, it is probably not fit to make something much more clever than HTTP routing (like RewriteRules for example).

  • Nginx: I've heard this server do actually support AJP. Being lighter than Apache and more full-featured than HAProxy, I'll probably try this today if I had the opportunity.

Conclusion

  • If you have some time for testing, try Nginx,
  • If you prefer having a simple and solid frontend, go for HAProxy,
  • If you prefer the "traditionnal" route, go for Apache2+AJP,
  • If you think Tomcat will be strong enough and will provide you all the features you need, use jsvc and put Tomcat on port 80
share|improve this answer
    
Thank you for the thorough answer. I will have to investigate Nginx. I had kind of decided on using lighttpd for its small footprint to front Tomcat or Winstone, but Nginx lloks very interesting with its mail modules as well. I have seen HAProxy, but figured if I used a webserver with webdav, I will have more container choices. Thanks! –  TonyZ Apr 5 '10 at 13:48
    
lighttpd has a reputation for leaking like a sieve. I believe Nginx is better. –  Draemon Jun 24 '10 at 21:14

The problem that I've run into with both Tomcat and Glassfish on UNIX is that (because they are Java applications I suppose) they cannot bind to port 80 and then drop root privileges. Running these types of things as root isn't a best practice, so that leaves two options:

(1) Run the application server as a regular user bound to a high port (say 8080) and use something like an iptables rule to redirect port 80 traffic to port 8080. I've done this with some Glassfish servers on Linux and it worked very well.

(2) Run the application server as a regular user behind Apache. Apache can bind to port 80, drop privileges and then proxy the requests on to your application server on a high port.

I prefer the latter, but mostly because I have worked with Apache for a long time and find it convenient to configure and manage. So if you know Apache well use it, you'll be happy you did when you need to rewrite some URLs on the fly or tune expiration headers. On the other hand if you have no Apache experience (or in this case since you need things to be as lightweight as possible) it might be easier to stick to just Tomcat and use iptables.

share|improve this answer
    
Thanks. I am on Debian, so I can use authbind. I do not have a lot of Apache experience, but I was looking for the most efficient, smallest solution. I know Jetty would probably do the job, but I need webdav as well which can be accomplished with any of the above combinations. However, these will be public servers and some have said Apache can reduce your attack surface. In the past, I have used Sun Web Server, but it is really overkill for a single app. –  TonyZ Apr 1 '10 at 0:59
    
@TonyZ: I didn't have much luck using authbind (or privbind) with GlassFish serverfault.com/questions/124537/… –  Chris Lercher Apr 1 '10 at 11:29

Following on from @deutsch's answer, Tomcat does NOT have to run as root on UNIX. If you install it from a package, e.g. the tomcat6 RPM for Fedora / CentOS / Red Hat, it will run as user tomcat with a restricted set of privileges.

Having said that, I agree with @Deutsch's last paragraph; use Apache as a front end to Tomcat unless you're under a very restrictive deadline to get deployed. Even if you're not that familiar with it yet, it's easy to get a basic deployment going with mod_proxy in front of Tomcat, and you will almost certainly benefit from the increased flixibility and security down the line.

share|improve this answer
    
Thank you for the answer. –  TonyZ Apr 2 '10 at 11:12
    
If you install Tomcat from an official tarball, run it as a non-root user, and manually change its port to 80 it is unable to bind to it as one would expect. This is also true for the Debian packages that I expect the OP is using. Is there something special about the RPMs you mention? Perhaps they are utilizing Linux capabilities? I am curious. –  Deutsch Apr 2 '10 at 18:03
1  
@Deutsch, I'm not sure of the answer to your question as I haven't tried manually changing the Tomcat port to 80; if I want to run on port 80 I always put an Apache proxy in front of Tomcat. –  gareth_bowles Apr 2 '10 at 19:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.