Home > Articles > Operating Systems, Server > Linux/UNIX/Open Source

Using the Nginx Web Server as a Reverse Proxy: Multiple SSL Sites with a Single IP Address

  • Print
  • + Share This
  • 💬 Discuss
Programming expert Jesse Smith shows how to set up the Nginx web server to improve web hosting performance and host multiple SSL sites using a single IP address.

Overview

Nginx (pronounced Engine X, or EX for short) is a Linux-based web server that now powers at least 6% of the world's web servers. It has gained popularity for its numerous features, including Server Naming Indication (SNI), which allows you to host multiple SSL websites on a single IP address. This feature saves the expense of extra IP addresses, SSL certs, and network interface cards. Another attractive quality is that the server is very fast—faster than Apache—as it doesn't create a new thread for each user request. Instead, EX synchronizes requests by using a limited amount of threads. It seems to work well even with high-volume traffic. The only downside is that if many users are downloading very large files at the same time, the server will slow considerably as new requests are being blocked until the pending requests finish.

EX has many similarities to the Apache web server, including the ability to add and remove modules. Unlike Apache, though, EX includes a powerful scripting language that includes conditional logic, making it powerful when doing advanced configuration directives that tell the web server how to behave. EX also can act as a reverse proxy for your existing network infrastructure if you aren't ready to get rid of your Apache and/or Tomcat servers. Try replacing your existing proxy with EX, and you should notice an improvement.

Installing EX

This article will show you how to install, configure, and run the EX web server using SNI and GeoIP (IP-to-location services), so that the server can create country zones in which only certain countries can access the server with a simple IF condition. The main reason for zone blocking is to prevent server spamming and denial-of-service attacks. You'll also learn how to configure the server as a reverse proxy.

How you install EX depends on the requirements of your business. Many modules can be configured for EX. In our example, the preconfiguration of EX should load several modules, including support for SNI and IP-to-location, but first we need to load some external libraries to make those modules work.

The Perl Compatible Regular Expression (PCRE) library is required for compiling EX (this example is for CentOS):

yum install pcre pcre-devel

The zlib library provides developers with compression algorithms. It's required for the use of gzip compression in various modules of Nginx.

yum install zlib zlib-devel

Next, we need to load the Maxmind IP-to-location database to support the GeoIP module. This database allows the server to map incoming requests to a location based on the request's IP number. The gz file also contains the C library needed by the module.

cd usr/local/src
wget http://geolite.maxmind.com/download/geoip/api/c/GeoIP.tar.gz
tar zxf GeoIP.tar.gz

cd GeoIP-1.4.8
./configure --prefix=/usr/local/geoip

make
make install

Once that's installed, we need to tell EX where to find the core library. If EX is unaware of the library's location, the server won't start, so this step is important. The ldconfig command creates the necessary links and cache to the most recent shared libraries found in the directories specified on the command line, in the file /etc/ld.so.conf, and in the trusted directories (/lib and /usr/lib). Edit the ld.so.conf to link the GeoIP library:

vim etc/ld.so.conf

Add the following line at the top:

/usr/local/geoip/lib/

Run the ldconfig command to link the library:

ldconfig

Now it's time to download EX:

wget http://nginx.org/download/nginx-1.3.7.tar.gz
tar zxf nginx-1.3.7.tar.gz

The following modules are enabled to support SSL, SNI, GeoIP, Real-IP, and so on when preparing the installation configuration:

usr/local/src/nginx-1.3.7 ./configure
--user=nginx
--group=nginx
--with-http_ssl_module
--with-http_realip_module
--with-openssl="/usr/local/src/openssl-1.0.0i/"
--with-openssl-opt="enable-tlsext"
--with-http_secure_link_module
--with-http_random_index_module
--with-http_geoip_module
--with-ld-opt="-Wl,-R,$HOME/apps/GeoIP/lib -L
$HOME/apps/GeoIP/lib"

Finally, install EX with the make command.

make
make install

The user and group switches tell the server to use the specified user/group when running processes. It's important to apply permissions to any necessary folders for the user with regard to getting access to external libraries.

The SSL module provides SSL services, including SNI support. The real-ip module tells the server to acquire the real IP address from the request header data.

After a successful installation, we need to configure the Nginx.conf file. Following is a sample .configuration file, complete with detailed comments. You can use this configuration to start with, as it has been tested and guaranteed to work with EX.

# Sets worker processes across CPUs (4 processors each w/ 4 cores totaling 16 cores)
# Usually 2 processes per core will suffice, as most operating systems at this time only utilize 2 cores per processor.
worker_processes  8;

pid /usr/local/nginx/logs/nginxlocal.pid;

# events module is used to define network-related directives, many of which are for performance
events {
    # number of connections per worker process. 1024 represents 1 core. 4096
    # would take advantage of up to 4 cores. The simultaneous connections to be
    # served could be as high as 16,384.

    worker_connections  4096;

    #scales the server to reduce spawning threads while synchronizing requests across limited available threads.
    use epoll;
}

#http block. Only one block allowed per conf. file
http {

#Uses the IP-to-location database downloaded from Maxmind
#This module is configured to only allow traffic from the US
    geoip_country /usr/share/GeoIP/GeoIP.dat;
    map $geoip_country_code $allowed_country {
        default no;
        US yes;

    }

   #global to all server blocks
   #==========================================================================

           # Set log paths
           #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            error_log  /usr/local/nginx/logs/accesslocal.log;
            access_log  /usr/local/nginx/logs/errorlocal.log;

           # Set data/file types
           #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            include       mime.types;
            default_type  application/octet-stream;
            sendfile        on;
            keepalive_timeout  65;

           # Set proxy specifics and set variables (i.e., remote IP address)
           #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            proxy_redirect     off;

            proxy_set_header   Host             $host;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_max_temp_file_size 0;

            client_max_body_size       10m;
            client_body_buffer_size    128k;

            proxy_connect_timeout      90;
            proxy_send_timeout         90;
            proxy_read_timeout         90;

            proxy_buffer_size          4k;
            proxy_buffers              4 32k;
            proxy_busy_buffers_size    64k;
            proxy_temp_file_write_size 64k;

           # Set SSL specifics
           #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            ssl_session_timeout  5m;

            ssl_protocols  TLSv1; #required by SNI
            ssl_ciphers  HIGH:!aNULL:!MD5;
            ssl_prefer_server_ciphers   on;

            ssl                  on;


    # HTTPS server www.yourfirstdomain.com port 8080
    #------------------------------------------------------------------------
    server {

        listen       10.1.10.136:443 ssl;
        server_name  test.example.com;

    #Set up your cert paths
        ssl_certificate_key  /etc/httpd/ssl/apache/star_example_com.key;
        ssl_certificate   /etc/httpd/ssl/apache/star_example_com.crt;

    #Prevent any access other than to the path specified below
       location / {
             deny all;
        }

        location /testing {

        if ($allowed_country = yes) {
                      proxy_pass   https://127.0.0.1:8080;
        }
        }

    }


    # HTTPS server test2.example.com port 8447
    #------------------------------------------------------------------------
    server {
        listen       10.1.10.136:443 ssl;
        server_name  test2.example.com;

        ssl_certificate      /etc/httpd/ssl/apache/star_example_com.crt;
        ssl_certificate_key  /etc/httpd/ssl/apache/star_example_com.key;

       location / {
             deny all;
        }

        location /testing {


            if ($allowed_country = yes) {
                   proxy_pass         https://127.0.0.1:8447;
             }

        }

    }

}

Notice that we're only using one IP address, two different domains, and the same SSL certificate for both domains. No need for multiple certs and/or domains, thus lowering costs associated with hosting.

This configuration accepts a request on the listening IP and forwards that request to an Apache server listening on the local server. The load on the Apache server has just decreased, and EX is now acting as the reverse proxy.

Running EX

If you want to alternate between running production and test configurations, this command will tell EX which configuration file to use when launching:

/usr/local/nginx/sbin/./nginx -c /usr/local/nginx/conf/nginx.conf

To reload EX, use this command:

nginx -s reload

Summary

By setting up the EX web server, you can use a single IP and one SSL certificate for multiple domains. You've also learned how EX can work in your existing network infrastructure as a reverse proxy, improving the response speed of your web pages, and now you can host multiple domains, each with different SSL certs, using a single IP address.

  • + Share This
  • 🔖 Save To Your Account

Discussions

comments powered by Disqus