Introduction
Phusion Passenger allows running Ruby web applications such as puppetmaster inside Apache or nginx web servers. It is also known as mod_passenger, mod_rails or mod_rack, especially when discussed in conjunction with the Apache webserver.
By default puppetmasterd runs inside a Webrick web server. However, Webrick is mostly intended for Ruby web application development and is not suitable for production use, especially when there are more than a few puppetd clients connecting to the puppetmasterd.
There is an official Puppet Wiki page describing how to run Puppetmaster using Phusion Passenger, Unfortunately information there is spotty and confusing due to several different ways you can install and configure Puppet, Passenger and Apache on a variety of platforms. This article aims at describing the steps needed to configure puppetmaster to run inside mod_passenger container hosted by Apache. This has been achieved with minimal changes to the default Debian puppetmaster setup. This process works with Debian Lenny and Squeeze.
It is also possible to setup a completely independent puppetmaster/passenger environment outside Debian packaging system. This has some benefits but is outside the scope of this article.
Installing software
On Debian Lenny need to use packages from the Lenny backports repository, as Phusion Passenger does not even work with the very old puppet version (0.24.5) that's available from stock Debian Lenny repositories. Instruction for configuring your system to use the backports repository can be found from here here. On Debian Squeeze you don't need to use the backports repository.
Note that by default (without apt-pinning) aptitude only upgrades minimum amount of packages to newer (backported) versions. While this is generally a good idea, in this case mixing backported with non-backported packages can cause strange, hard to debug issues with some puppet client versions. To avoid this make sure that all dependencies of the above packages - and their dependencies' dependencies - are fetched from the backports repository. The easiest way to do this is to use aptitude and individually select the backport packages, even when not necessary to keep the Debian packaging system happy.
On both Lenny and Squeeze you need to install puppet, puppetmaster and libapache2-mod-passenger packages.
Generating puppetmaster's certificates and keys
If you have not launched puppetmaster (with Webrick) before on the puppetmaster server, do it before starting configuring mod_passenger. This first run generates all the certificates and keys which are required.
Configuring puppetmaster to use mod_passenger
Configuration overview
There are several things one has to configure to run puppetmaster inside mod_passenger:
- configure puppetmasterd properly
- create a proper rack environment for puppetmaster
- add a proper startup file (config.ru) to the rack environment
- configure Apache to use mod_passenger
add a new ?VirtualHost definition that uses mod_passenger
Configuring puppetmasterd
Debian stores puppet configuration in /etc/puppet/puppet.conf. This file will contain all puppet-related configuration details. If you're lucky, you only need to add these two entries in to the [puppetmasterd] section:
ssl_client_header = SSL_CLIENT_S_DN ssl_client_verify_header = SSL_CLIENT_VERIFY
Below is a sample configuration file which works with mod_passenger:
[main] logdir=/var/log/puppet vardir=/var/lib/puppet ssldir=/var/lib/puppet/ssl rundir=/var/run/puppet factpath=$vardir/lib/facter pluginsync=true [production] # Here we define the default environment ("production"). # It seems that without this section 0.25.4 clients bail out. modulepath=/etc/puppet/modules templatedir=/var/lib/puppet/templates manifest=/etc/puppet/manifests/site.pp [puppetmasterd] # Stored configuration support. storeconfigs = true dbadapter = sqlite3 dblocation = /var/lib/puppet/storeconfigs.sqlite # Client state database migration. dbmigrate = true # Use this to get lots of stuff into /var/log/puppet/rails.log #rails_loglevel = debug # Passenger (a.k.a. mod_rails) needs these ssl_client_header = SSL_CLIENT_S_DN ssl_client_verify_header = SSL_CLIENT_VERIFY
Setting up the rack environment
Phusion Passenger uses Rack to run Ruby on Rails web applications. In practice this means that we need to create a valid Rack environment for puppetmaster. The least intrusive way to do this is to create a rack directory into /var/lib/puppet. It should contain the following entries:
/var/lib/puppet/rack: main directory
/var/lib/puppet/rack/public: the root webapp directory for puppet
/var/lib/puppet/rack/public/puppet: a link pointing to /usr/lib/ruby/1.8/puppet; alternatively a directory containing puppet sources
/var/lib/puppet/rack/config.ru: the rack webapp startup file; see below for details
The file config.ru is not installed with Debian's puppet packages, so we need to fetch it separately. Note that you need a version of config.ru matching your puppet version. This file is probably easiest to fetch using the Puppet Git tree web interface. Here are a few direct links:
config.ru for puppetmaster 0.25.4 (Lenny + backports)
config.ru for puppetmaster 2.6.2 (Squeeze)
Once you've fetched config.ru make sure all of the above files and directories are owned by "puppet:puppet". This is especially important in case of config.ru, as mod_passenger will run as the user who owns that file.
Enabling Apache modules
The next step is to enable mod_ssl and mod_passenger. The standard "Debian way" is to use a2enmod like this:
a2enmod ssl a2enmod passenger
Adding Apache VirtualHost definition for puppetmaster
The last step is to add a ?VirtualHost definition for Apache. Below is an example of virtualhost definition:
# You probably want to tune the settings below # Unlike some webapps puppetmaster can use # Passenger's high-performance mode PassengerHighPerformance on PassengerMaxPoolSize 12 PassengerPoolIdleTime 1500 # PassengerMaxRequests 1000 PassengerStatThrottleRate 120 RackAutoDetect On RailsAutoDetect On # Uncomment to limit interfaces on which puppetmaster responds to requests # Listen 192.168.1.254:8140 Listen 8140 <VirtualHost *:8140> SSLEngine on SSLProtocol -ALL +SSLv3 +TLSv1 SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:-LOW:-SSLv2:-EXP SSLCertificateFile /var/lib/puppet/ssl/certs/<replace-with-puppetmaster-fqdn>.pem SSLCertificateKeyFile /var/lib/puppet/ssl/private_keys/<replace-with-puppetmaster-fqdn>.pem SSLCertificateChainFile /var/lib/puppet/ssl/ca/ca_crt.pem SSLCACertificateFile /var/lib/puppet/ssl/ca/ca_crt.pem # If Apache complains about invalid signatures on the CRL, you can try disabling # CRL checking by commenting the next line, but this is not recommended. SSLCARevocationFile /var/lib/puppet/ssl/ca/ca_crl.pem SSLVerifyClient optional SSLVerifyDepth 1 SSLOptions +StdEnvVars #RackBaseURI / DocumentRoot /var/lib/puppet/rack/public/ <Directory /var/lib/puppet/rack/public/> Options None AllowOverride None Order allow,deny allow from all # We are told that this is required for correct operation Options -MultiViews </Directory> </VirtualHost>
Make sure to change the SSLCertificateFile and SSLCertificateKeyFile entries to match your system.
Testing and debugging
Once you've configured everything restart Apache and check that it's listening for connections on port 8140:
$ /etc/init.d/apache2 restart Restarting web server: apache2 ... waiting . $ netstat -an|grep LISTEN|grep 8140 tcp6 0 0 :::8140 :::* LISTEN
Also make sure that firewall is not blocking access to port 8140, e.g. with
$ iptables -L -v
Next test that puppet clients can connect to master and fetch their catalogs. If not (which is likely), check out the relevant log files:
/var/log/apache2/error.log (on puppetmaster): contains errors from the puppetmaster
/var/log/apache2/other_vhosts_access.log (on puppetmaster): contains puppetmaster access logs
/var/log/daemon.log (on puppet clients): contains errors from puppet clients
Passenger web interface itself is very useful for debugging Puppetmaster startup problems. Simply point your browser to the puppetmaster URL, e.g. https://<your-puppet-master-server>:8140 and check what it says.
Integrating puppet-dashboard into Passenger
On Debian Squeeze you can install puppet-dashboard Debian package available here. For the most part you can follow setup instructions given here regarding reports directory setup and database generation/migration. If you've configured Puppet+Passenger as described above, the following ?VirtualHost definition should work:
# Uncomment to limit the interface dashboard listens on #Listen 192.168.1.254:8141 Listen 8141 <VirtualHost *:8141> DocumentRoot /usr/share/puppet-dashboard/public/ <Directory /usr/share/puppet-dashboard/public/> Options None AllowOverride AuthConfig Order allow,deny allow from all </Directory> ErrorLog /var/log/apache2/dashboard.example.com_error.log LogLevel warn CustomLog /var/log/apache2/dashboard.example.com_access.log combined ServerSignature On </VirtualHost>
Potential caveats
Running puppetmaster as user other than puppet
Running puppetmaster as non-puppet user (e.g. www-data) is not recommended, as it effectively forces you to create a completely separate puppetmaster + passenger environment outside Debian packaging system or heavy modifications to permissions of default puppet directories. Also, running puppetd on the puppetmaster server is problematic: every time puppetd runs it changes owner of certificate files (by default located in /var/lib/puppet/ssl) to puppet. This means that the puppetmasterd (which is not running as puppet user) can't read those files anymore. External nodes obviously don't trigger this error.