21 November 2005

Rails with Apache MPM worker


The existing instructions for Typo on FreeBSD presume that you’re running lighttpd and Apache httpd with mod_proxy. This is unnecessary and, generally speaking, more complicated than what most people need. It turns out you can serve your Rails app, legacy PHP pages and static content just fine with just one webserver installed. This can also help save memory (my own motivation), by running PHP as a FastCGI process rather than embedding it in every Apache MPM prefork process.

It seems like many users aren’t aware that there is any option beside MPM prefork for Apache httpd. Starting with Apache httpd 2 you can choose different multi-processing models. One of these is MPM worker, which keeps not only multiple processes, but also uses several threads to handle requests.

Threads complicate matters with things that are not typically thread-safe like mod_php, mod_perl, and many other programming language Apache modules. Luckily FastCGI can move this work outside of the httpd process where it can be handled outside of these threading concerns.

Before I wander into the exact details of configuring this setup, a word about performance: Super. MPM worker does a fabulous job serving static and dynamic content quickly. In addition, memory consumption is much easier to control since the FastCGI processes associated with each language or Rails application can be independently controlled and tuned to the traffic they’re seeing.

Installing the Pieces

I put the following into my /etc/make.conf to make sure the components are built correctly:


WITH_APACHE2=YES
WITH_MPM=worker
WITH_KQUEUE_SUPPORT=YES
WITH_FASTCGI=YES

Next, the correct ports have to be built. The packages are listed below along with their origin (that is, where to find them in the FreeBSD ports collection). Building the things below with the options above will be different on other systems.


































Package Origin
apache-worker-2.0.54_4 www/apache2
rubygem-rails-0.13.1 www/rubygems-rails
mod_fastcgi-2.4.2 www/mod_fastcgi
ruby18-fcgi-0.8.6 www/ruby-fcgi
ruby18-sqlite-2.2.3 databases/ruby-sqlite
ruby18-postgres-0.7.1_2 databases/ruby-postgres
ruby18-mysql-2.6 databases/ruby-mysql

You only need the database package relevant to the database you want to be using; which one you should not use is a rant for another day, today I’m going to use sqlite. There may be newer versions of these packages available by the time you read this.

For this example, we’ll unzip/untar the latest typo release into /usr/local/www/data.

Configuring the components

First, I’m going to get the Typo install configured. This is simply building the database with sudo -u www sqlite db/typo.sqlite.db < db/schema.sqlite.sql and then changing my config/database.yml to contain:


login: &login
adapter: sqlite
dbfile: db/typo.sqlite.db

development:
<<: *login

test:
<<: *login

production:
<<: *login

A quick run with script/server will indicate if things are working correctly with the Rails application. I had to comment out a line in config/environment.rb to get it to run (and have filed a bug about it).

I also check at this point if public/dispatch.fcgi will run correctly from within Apache httpd. Generally the PATH used by Apache httpd will not include the ruby executable, so I change the /usr/bin/env ruby at the top of public/dispatch.fcgi to /usr/local/bin/ruby.

Now I’ll configure Apache httpd. The default values for MPM worker are quite reasonable, so I’ll leave them alone. You’ll find them near the text <IfModule worker.c> along with a comment about what the settings do.

Setting ServerName is usually a good idea right about now. Remember that this needs to be a real name that points at this server.

In order for Apache to use the FastCGI module, it’ll need to know that I want it to be loaded. At the end of all the lines that start with LoadModule we’ll want to add the FastCGI module with:

LoadModule fastcgi_module libexec/apache2/mod_fastcgi.so

Next, move the DocumentRoot into Rails application by changing it to "/usr/local/www/data/typo/public"

Lastly, after the line with DocumentRoot I add lines specific to the FastCGI configuration and the permissions we want:


<IfModule mod_fastcgi.c>
FastCgiIpcDir /tmp/fcgi_ipc/
FastCgiServer /usr/local/www/data/typo/public/dispatch.fcgi -idle-timeout 120 -initial-env RAILS_ENV=production -processes 2
FastCgiConfig -idle-timeout 120 -initial-env RAILS_ENV=production -restart
AddHandler fastcgi-script fcgi fcgi fpl
</IfModule>

<Directory "/usr/local/www/data/typo/public">
AllowOverride All
Options ExecCGI
</Directory>

The critical line in there is the FastCgiServer line that Scott Laird has written about in some detail on his blog.

And we’re off…

Now I just run apachectl start as root and I’m up and running.


16 November 2005

GPGMail Patch


Just a quick follow up with the patch to the source to produce the mailbundle in the last entry.

The patch is here.

The detached signature is here.

This software is subject to the following license.


13 November 2005

GPGMail.mailbundle With SHA{256,384,512}


By adding 6 lines to the code of GPGMail, I’ve allowed it to send messages with some (perhaps) less compromised hashing algorithms. Generally an algorithm called SHA-1 is used to generate a condensed representation or “hash” of the text PGP/GPG messages for signing purposes. The SHA-1 algorithm is subject to an attack described by Chinese researchers that allows another text that generates the same hash (called a “collision”) to be found in 269 steps rather than the 280 steps that the original design specified. This attack makes finding a collision several orders of magnitude faster.

Collisions are hazardous in that a powerful adversary (usually named Mallory) could take a note you signed that said “I like cashews” and generate a new note with some variation of “I agree to sell my home to Mallory for $15.–” With plaintext messages this is a lot harder because generally one must add random garbage to the end of the message, but with files that do (or could) have a lot of unused junk data in them such as Microsoft Word this is a lot easier. Many prominent figures in the cryptographic community have weighed in on the need to move away from SHA-1.

GPGMail.mailbundle right now only allows SHA-1, MD5 (subject to its own collision attacks), and RIPEMD-160. Adding a few lines of code allows users like me to send messages also with SHA-256, SHA-384, and SHA-512. A zip of this updated mailbundle is attached for existing GPGMail users. It depends on all the same sorts of things that the usual GPGMail depends on, check the GPGMail web page for details. You also have to make a configuration change and generate an RSA signing key in order to use the newer algorithms:


  • Add the line digest-algo sha512 to .gnupg/gpg.conf (or sha256 or sha384 if you prefer)

  • Generate an RSA signing subkey by running gpg --edit-key your@email.addr

    • addkey

    • Enter your password at the prompt

    • Pick the number for RSA (sign only) and finish the configuration of your key


It’s not time to panic and run away from SHA-1, but now is the time to migrate away from it if possible. People who are picky about standards will note that using these new algorithms is not strictly allowed by the OpenPGP RFC. There are revisions floating within the IETF to fix this, but standards processes move a lot like glaciers.

The patched mail bundle is downloadable here along with a signature.