OpenClinica User Manual/UsingAReverseProxy

=Using a secure reverse proxy for OpenClinica=

Introduction
Out-of-the-box OpenClinica is served by Apache Tomcat, while this works nicely, we can get a performance boost if we add a "reverse proxy" to the equation. A reverse proxy server will take weight off the shoulders of the Tomcat server. It can send static files like CSS, javascript and images without bothering Tomcat about it. Tomcat only needs to serve the dynamic study content i.e. the generated pages with our study data. Furthermore, a reverse proxy allows us to send compressed responses, or tell the client that a file is not going to change for a long while, and thus that the already downloaded file can be used instead of downloading it again from the server. These modifications reduce bandwidth use. The reserve proxy can also be used for SSL encryption, again taking away workload from Tomcat.

The main body of this page is a tutorial using Nginx (pronounce: Engine X). Not only is Nginx very fast, more importantly it is very easy to install and configure. Nginx is open sourced under the "2-clause BSD license".

Nginx is only in Beta on Windows
Whilst Nginx has release versions for Linux/BSD, it is only in Beta on Windows operating systems (see the nginx for Windows page). Alternative Windows proxy software include Apache HTTP Server (detailed below) and SQUID.

Another option - don't use a proxy but set up Tomcat for compression and SSL encryption
If you just want your pages to be encrypted and compressed, but don't need the caching effects of a reverse proxy such as Nginx, Tomcat can be set up for SSL encryption by following the SSL Configuration HOW-TO, and Compression can also be set up in Tomcat. This thread suggests setting up Tomcat for SSL encryption and compression, rather than using a proxy as when configured optimally, OpenClinica is primarily limited by the performance of Postgres' caching (see page on Performance).

Prerequisites:
First use your package manager (apt-get, yum) to check if the following libraries are installed on your system. Also make sure the development files are available for these libraries, these have the postfix '-dev' or '-devel' depending on your system.
 * zlib library (for gzip module)
 * pcre library (for rewrite module)
 * openssl library (for ssl support)

RedHat/CentOS example: Debian/Ubuntu example:

Because we are going to compile the source code the development tools and development libraries for your system need to be installed.

RedHat/CentOS example:

Debian/Ubuntu example:

Download and install Nginx
Download the stable source from http://wiki.nginx.org/Install#Source_Releases. At the time of writing the version is: 1.0.5. After downloading unpack Nginx. Configure Nginx with ssl support and gzip compression. Build it. Here are the steps:

If all went well Nginx is now installed in /usr/local/nginx/.

RedHat/CentOS
Get the init script for RedHat/CentOS here: http://wiki.nginx.org/RedHatNginxInitScript We need to modify this file slightly to get it working with our installation. Change: nginx="/usr/sbin/nginx" to: nginx="/usr/local/nginx/sbin/nginx" Change: NGINX_CONF_FILE="/etc/nginx/nginx.conf" to: NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"

Debian/Ubuntu
Get the init script from: http://wiki.nginx.org/Nginx-init-ubuntu Change: DAEMON=/usr/local/sbin/nginx to DAEMON=/usr/local/nginx/sbin/nginx

When you have modified the file to your needs copy the init script `nginx` to /etc/init.d/. Make sure it starts automatically by running these commands:

Check if everything is working well by starting the server. Before you start the server make sure no other webserver is using port 80. When you browse to http://localhost, you should see the message `Welcome to Nginx`.

Secure connection
We want to create a secure connection to our study system. If you do not have a security certificate already, create one using this excellent guide on creating a self-signed certificate: http://www.akadia.com/services/ssh_test_certificate.html. Follow this guide up to step 4. Let's say your security files are called `my-server.crt` and `my-server.key`. Create a directory called ssl in /usr/local/. Copy the two files to the folder /usr/local/ssl/. You will see these file names again in the configuration file. Now we can configure Nginx.

Configure Nginx
The main configuration file can be found in /usr/local/nginx/conf/nginx.conf

Here is an example configuration file that gives us compression, encryption, expiry headers and a proxy to our OpenClinica installation. Read the comments in the file for explanation. Copy this to your nginx.conf file. Be aware that OpenClinica was installed as a webapp with the name `studies`. That is why you will find urls like http://localhost:8080/studies in the configuration file. This confiruration also hardcodes the location of the "includes" and "images" directories as local directories.

Nginx configuration file
After we have made change to the configuration file we must restart nginx, like this: Try the new configuration by going to http://localhost/studies/.

Proxy for more than one OpenClinica installation
The part that is responsible for passing requests to OpenClinica is: location /studies { proxy_pass http://127.0.0.1:8080/studies; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } If you have more than one OpenClinica installed, you can still have one access point but as many back-ends as you need. Consider for example this configuration: location /study_1 { proxy_pass http://127.0.0.1:8080/OpenClinica_1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /study_2 { proxy_pass http://192.168.1.100:8080/OpenClinica_2; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /study_3 { proxy_pass http://192.168.1.101:8080/OpenClinica_3; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } In this configuration one Nginx server is a proxy for three OpenClinica servers, these can be real or virtual servers. As you can see the first one is running on the same machine as the Nginx server. The other two are servers in the local domain.

Restricting access
Most of the time data will only be entered from a limited number of known locations. We can instruct Nginx to only allow access to our server from those locations based on their public IP addresses. All other IP address are blocked. Have a look at this snippet: Connections from unauthorized IP addresses will get a 403 error. We can catch this error and send a more meaningful message to the client. To do so create a file called 403.html in the folder /usr/local/nginx/html/. Add something like this to the file: Add the next line to the http section of the Nginx configuration file. error_page 403 http://my-server.org/403.html; Now unauthorized clients will get an informative message when they try to access our study system.

Configuring OpenClinica
Ensure that OpenClinica's sysURL setting (in the file OpenClinica/WEB-INF/classes/datainfo.properties) is set to the public URL of the system, e.g.

This ensures that URLs in system emails and some internal messages correctly point to the proxy, rather than anywhere else.

See the difference
When you install and run the Firefox extension YSlow, you can see the improvement of the reverse proxy over the standard OpenClinica installation. Use port 8080 to bypass the proxy. Here is an example of the Notes & Discrepancies page from OC 3.0.4.1: Before optimization: After optimization: Explanation: on the left we see the anatomy of the page. To load this page, the browser sends no less than 76 requests to the server. These requests result in a total download size of 462.7k. If we add gzip compression the size is reduced to 162.6K. The first time we contact the OpenClinica server all static content like images, javascripts and css files are cached on the client machine. On the right side we see the effect of caching: the amount of data downloaded from the server is greatly reduced. The 'expires max' tells the browser that it should not check the server for a new version of a file for a long time. That is why we only hit the server twice in the optimized situation. This is a major improvement, especially in situations where bandwidth is limited and latency is high. In this case the number of requests can even be reduced to one, because we have not set 'expires max' for the favicon file.

Setting up Apache HTTP Server as a reverse proxy
A similar result can be achieved by using Apache HTTP Server as a reverse proxy. Note that the configuration below doesn't yet include SSL:

Conclusion
Installing and configuring a reverse proxy is not very difficult. With a reverse proxy in place we let Tomcat do what it does best: serve dynamic content. The reverse proxy takes care of all other requests, SSL, content compression and caching on the client. We have seen that the optimizations reduce bandwidth use and the number of requests send to the server. This adds to the responsiveness of the application, in particular on networks that have high latency and low bandwidth.