Flylib.com

Books Software

 
 
 

Recipe 13.6. Configuring Pound with SSL Support


Recipe 13.6. Configuring Pound with SSL Support

Problem

You want to secure HTTP traffic to and from your Rails application using Secure Sockets Layer (SSL). Specifically, you want to use SSL with a cluster of Mongrel servers.

Solution

Use Pound to handle HTTPS requests , decrypting and passing them back to your Mongrel cluster as plain HTTP.

For Pound to handle HTTPS requests, you have configure it with SSL support at build-time. Do this by passing the --with-ssl option to configure , supplying the location of your OpenSSL header files (e.g., /usr/include/openssl ).

$

cd /usr/local/src/Pound-2.0

$

./configure --with-ssl=/usr/include/openssl

$

make

$

sudo make install


To verify that Pound has been built and configured successfully, you can always run:

$

pound -v -c

30/Jul/2006 22:22:10 -0700: starting... Config file /usr/local/etc/pound.cfg is OK

Now, edit the Pound configuration file, adding a ListenHTTPS directive. Within that directive, specify port 443 and the location of your SSL certificate (e.g., /usr/local/etc/openssl/site-cert.pem ).

/etc/pound/pound.cfg :

User "www-data" Group "www-data" LogLevel 3 Alive 30 ListenHTTPS Address 69.12.146.109

Port 443 Cert "/usr/local/etc/openssl/site-cert.pem"


HeadRemove "X-Forwarded-Proto"

AddHeader "X-Forwarded-Proto: https" End Service BackEnd Address 127.0.0.1 Port 3303 End BackEnd Address 127.0.0.1 Port 3304 End Session Type BASIC TTL 300 End End

After restarting Pound, you should be able to visit your Rails application over SSL with URLs beginning with https:// .

Discussion

The listener in the solution's configuration adds a header named "X-Forwarded-Proto" that indicates the original request was via HTTPS. Without this, there is no way for your Rails application to know if requests are being encrypted or not. Especially if you are processing highly sensitive information, such as credit card numbers , your actions need to be able to confirm that they are not sending and receiving this data in plain text, over the network.

By adding the "X-Forwarded-Proto: https" header to requests being passed to the Mongrel servers, you can use the Request#ssl? method to test for SSL. For example, the following call in one of your views will confirm that Pound is communicating with external clients via HTTPS:

ssl? <%= request.ssl? %>

See Also

  • The Pound home page, http://www.apsis.ch/pound



Recipe 13.7. Simple Load Balancing with Pen

Problem

You want to set up simple load balancing to a cluster of backend web servers such as Mongrel. Although Pound configuration is not very complicated, you'd like something that's even simpler to get up and running.

Solution

Pen is a very lightweight software load balancer that you typically run as a single command, with all configuration passed as arguments to this command. To demonstrate a simple setup in which Pound distributes requests between two Mongrel servers, start the Mongrel cluster with:

$

sudo mongrel_rails cluster::start

Starting 2 Mongrel servers...

Then, verify that the Mongrel processes are listening on the ports that you configured in your mongrel_cluster.yml with the lsof command:

$

sudo lsof -i -P  grep mongrel

mongrel_r 11567  mongrel    3u  IPv4  17648       TCP *:4000 (LISTEN)
mongrel_r 11570  mongrel    3u  IPv4  17654       TCP *:4001 (LISTEN)

Start Pen listening on port 80:

$

sudo pen -l pen.log 80 localhost:4000 localhost:4001


The -l option tells Pen to log to the specified file, pen.log . Following that is the port that Pen is to listening on, 80 in this case. Finally, each server in the cluster is listed with the hostname and port number. By default, the pen command starts Pen as a background process. To verify that it's running, use ps :

$

sudo ps -ef  grep pen

root     11671     1  0 13:40 ?  00:00:00 pen -l pen.log 80
  localhost:4000 localhost:4001

To verify that Pen is listening on the port you specified, use lsof and grep for "pen" :

$

sudo lsof -i -P  grep pen

pen       11671     root    3u  IPv4  17973       TCP *:80 (LISTEN)

Discussion

As you can see, Pen doesn't take much in the way of configuration files to get running. This might be very appealing if your situation is relatively simple. As of Version 0.17.1, SSL support for Pen is considered experimental. You can configure SSL support by building Pen with the --with-experimental-only-ssl option.

By default, Pen uses a load balancing algorithm that keeps track of clients and tries to send them back to the server they used last. This allows your application to preserve session information for each connecting client. If your application doesn't use sessions, you can tell Pen to use a round- robin load balancing algorithm instead by passing the -r option.

One issue that might be problematic , depending on your application, is that Rails sees requests as originating from the IP address of the web server that serves the request. So when you're running Pen, your Rails application will see requests coming from 127.0.0.1 (which is running the Pen instance), instead of the IP address from which the incoming request came. You can verify this by placing the following line in one of your views:

<p>request.remote_ip: <%=

request.remote_ip

%></p>

If you do find that Pen will meet the needs of your application, there are some supporting tools you should investigate. These are the commands and their function:



penctl

Connects to the optional control socket on a Pen load balancer. It reads commands from the command line, performs minimal syntax checking and sends them to Pen. Replies, if any, are printed on stdout .



penlogd

Receives log entries from Pen and from each of the balanced web servers, consolidates the entries by replacing the source addresses in each entry with the "real" client address, and writes the result to stdout or to the file given on the command line.



penlog

Reads web server log entries from stdin and sends them using UDP to penlogd .

See Also

  • The Pen web site, http://siag.nu/pen

  • Section 13.4"