Back

Running dotCMS Behind Reverse-proxy Web Server

Description

This document explains how to set up dotCMS to run behind a reverse proxy web server. There are a multitude of reason why you might want to do this: enhanced security, special URL handling, etc… A frontend web server provides far more flexible configuration options than Tomcat is capable of. In this example, we are running a web server (nginx) in front of the dotCMS process on each clustered dotCMS application server. We have a hardware load-balancer distribution connections and offloading SSL in front of both dotCMS servers.

The first step is to create two Tomcat Connectors to accept the proxied connections: one for unencrypted http connections, and another for encrypted https connections. These are configured in the $dotCMShome/conf/server.xml

 

The http connector is fairly straightforward:

<!-- Proxied non-secure connector -->


<Connector port="8080" URIEncoding="UTF-8"


address="127.0.0.1"


maxThreads="75" minSpareThreads="25" maxSpareThreads="50"


enableLookups="false" redirectPort="443" acceptCount="100"


debug="0" connectionTimeout="20000"


disableUploadTimeout="true" proxyPort="80"


/>

 

The port you choose to run the connector on does not have to be the same as the example shown (but must be different than other Connectors on the same interface). However, you must make sure that your frontend web server and your Tomcat Connector are configured consistently with regard to the port they use to communicate.

 

The important parameter to include is the “proxyPort”. This tells Tomcat the original port that the client’s request was sent to, and is used to build links and redirects.

 

If your web server or load-balancer is located on the same server as the dotCMS application, you may want to also use the “address” attribute to bind Tomcat only to the localhost address. This will reduce the application’s surface area, and enhance security.

 

The proxied https connector has a few more parameters needed to function correctly:

 

<!-- Proxied secure connector -->


<Connector port="8081" URIEncoding="UTF-8"


address="127.0.0.1"


maxThreads="75" minSpareThreads="25" maxSpareThreads="50"


enableLookups="false" redirectPort="443" acceptCount="100"


debug="0" connectionTimeout="20000"


disableUploadTimeout="true" secure="true"


proxyPort="443" scheme="https"


/>

 

Again, the “port” parameter can be changed, but must be different from the non-secure Connector and must be configured to match in your frontend web server.

 

In order for Tomcat to recognize that requests to this Connector are considered “secure” (and to enforce security constraints), you must set the “secure” parameter to “true”. With the secure Connector, you must set the “scheme” to “https”, as well as the “proxyPort” in order for link and redirect construction to work properly.

 

As in the non-secure Connector, you may also bind the Connector to only the localhost interface using the “address” parameter if your server configuration supports this.

 

After you have configured the two proxied Tomcat Connectors, you will probably want to disable the default http Connector so that you may bind your web server to port 80:

<!--


<Connector port="80" URIEncoding="UTF-8"


maxThreads="75" minSpareThreads="25" maxSpareThreads="50"


enableLookups="false" redirectPort="443" acceptCount="100"


debug="0" connectionTimeout="20000"


disableUploadTimeout="true" />


-->


 

 

After you have set up your Tomcat Connectors appropriately, you will need to stop and restart dotCMS for the changes to take effect. Be sure to review logs/dotcms.log to ensure that the Connectors start up correctly:

 

INFO http11.Http11Protocol: Initializing Coyote HTTP/1.1 on http-127.0.0.1-8080


INFO http11.Http11Protocol: Initializing Coyote HTTP/1.1 on http-127.0.0.1-8081


 

 

The second step to setting up a reverse-proxied dotCMS instance is to configure your frontend web server. One option for the frontend server is a lightweight web server like nginx (http://nginx.net/). Nginx has a very solid reputation for being high-performance, as well as very secure. It is used by many of the Internet’s highest-volume web sites.

 

A simple nginx configuration for a reverse proxy would like something like this (/etc/nginx/nginx.conf):

 

http {


include mime.types;


default_type application/octet-stream;


 


# HTTP server


server {


listen 80;


server_name www.myschool.edu;


 


location / {


proxy_pass http://localhost:8080;


proxy_set_header Host dotcms.com;


proxy_set_header X-Real-IP $remote_addr;


proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;


}


}


 


# HTTPS server


# We are running this behind an ssl load-balancer, hence the non-ssl config


server {


listen 81;


server_name www.myschool.edu;


 


# If you are terminating SSL connections directly on the web server


# you might have configuration like this:


#listen 443;


#ssl on;


#ssl_certificate /etc/ssl/certs/www.myschool.edu/server.crt;


#ssl_certificate_key /etc/ssl/certs/www.myschool.edu/server.key;


 


location / {


proxy_pass http://localhost:8081;


proxy_set_header Host dotcms.com;


proxy_set_header X-Real-IP $remote_addr;


proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;


}


}


}

 

Of course, this could also be done using Apache web server and the mod_proxy module. The mod_proxy configuration directives might look similar to this (ssl example):

 

LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so


LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so


LoadModule proxy_connect_module /usr/lib/apache2/modules/mod_proxy_connect.so


 


SSLProxyEngine on


ProxyRequests Off


ProxyVia On


<Proxy *>


Order deny,allow


Allow from all


</Proxy>


 


ProxyPass / http://localhost:8081/


ProxyPassReverse / https://localhost:8081/

 

 

 

Code

see above