Secure Tomcat
Securing Tomcat Installation
This article will help you to make your existing Tomcat installation more secure.
Disable all unnecessary connectors
By default tomcat listens on several ports and it is possible to connect to the tomcat instance from the network. We will limit connectivity only from loopback interface (localhost only) and only through AJP connector. This is bare minimum server.xml that will do the job done:
<Server> <GlobalNamingResources> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> </GlobalNamingResources> <Service name="Catalina"> <Connector port="8009" protocol="AJP/1.3" address="127.0.0.1" /> <Engine name="Catalina" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase" /> <Host name="localhost" appBase="webapps" /> </Engine> </Service> </Server>
Now tomcat listens only on TCP port localhost:8009, can't be more secure from network point of view. It's also useless, since no one can connect to it from the outside. We need to provide a proxy agent who will listens on HTTP (TCP port 80) and HTTPS (TCP port 443) sockets, route requests to tomcat, get responses and send them back to the requester. We will use apache server to accomplish the task.
Installing apache server
We will use httpd version 2.2.11 (latest at this moment) since it has all required components (ssl, ajp) in the source tree.
- Download source code
- Extract it into current directory
gunzip -c < httpd-2.2.11.tar.gz | tar xf -
- Sanitize the environment
unset LD_LIBRARY_PATH
- Run configure script
- We will install apache server into /usr/local/apache. Here we assume OpenSSL kit is installed in /usr/local/ssl and ZLib library is installed as a system library. If not, --with-z and --with-ssl options need to be adjusted accordingly
cd httpd-2.2.11 ./configure --prefix=/usr/local/apache --with-included-apr --enable-ssl --enable-mods-shared=all \ --with-ssl=/usr/local/ssl --enable-proxy --enable-proxy-ajp
- Build and install apache
make && make install
Create SSL certificate for HTTPS connections
- Generate SSL key server.key
cd /usr/local/apache/conf touch server.key chmod 600 server.key openssl genrsa -out server.key 2048
- Create openssl config file server-ssl.config, here we assume server name is vvc.homeunix.net. Update all the fields appropriately
[ req ] default_bits = 2048 distinguished_name = req_dn default_md = sha1 req_extensions = cert_type prompt = no [ req_dn ] # country (2 letter code) C=US # State or Province Name (full name) ST=Virginia # Locality Name (eg. city) L=Leesburg # Organization (eg. company) O=VVC # Organizational Unit Name (eg. section) OU=Apache server # Common Name (*.example.com is also possible) CN=vvc.homeunix.net # E-mail contact emailAddress=vvc@chepkov.com [ cert_type ] keyUsage=digitalSignature,keyEncipherment extendedKeyUsage=serverAuth subjectAltName=DNS:vvc.homeunix.net
- Generate certificate request server.req
openssl req -new -key server.key -out server.req -config server-ssl.config
- Obtain server certificate. Save it in server.crt
Create apache configuration
Here is the bare minimum httpd.conf that should provide you with all the functions outlined before
ServerRoot "/usr/local/apache" Listen 80 Listen 443 LoadModule authz_host_module modules/mod_authz_host.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_ajp_module modules/mod_proxy_ajp.so LoadModule ssl_module modules/mod_ssl.so LoadModule mime_module modules/mod_mime.so LoadModule dir_module modules/mod_dir.so LoadModule log_config_module modules/mod_log_config.so User www Group www ServerAdmin vvc@chepkov.com DocumentRoot "/usr/local/apache/htdocs" <Directory /> Options FollowSymLinks AllowOverride None Order deny,allow Deny from all </Directory> LogLevel warn LogFormat "%h %l %u %t \"%r\" %>s %b" common CustomLog logs/access_log common ErrorLog logs/error_log DefaultType text/plain TypesConfig conf/mime.types # A client will get this message in case tomcat server is down ErrorDocument 503 "The server is under maintenance" SSLRandomSeed startup builtin SSLRandomSeed connect builtin ProxyPass / ajp://localhost:8009/ SSLPassPhraseDialog builtin SSLSessionCache "shmcb:logs/ssl_scache(512000)" SSLSessionCacheTimeout 300 SSLMutex "file:logs/ssl_mutex" <VirtualHost _default_:443> SSLEngine on SSLCipherSuite HIGH:!SSLv2:!ADH SSLProtocol all -SSLv2 SSLCertificateFile conf/server.crt SSLCertificateKeyFile conf/server.key BrowserMatch ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0 </VirtualHost>
Start apache server
/usr/local/apache/bin/apachectl start
That's all.