I have been running my puppetmaster using the embedded WEBrick server for a while. I decided it was time to migrate to something a little more robust - namely Apache and Passenger. I loosely followed the documentation available on the Puppet site, although that covers Passenger 3.0.x and I’m using 4.0.x, and the supplied Apache configuration does not work. There were also a few other changes I had to make along the way to suit my configuration requirements. My puppetmaster is running CentOS 6.4.
First off, as much as it pained me, I had to turn off SELinux. I did run through iterations of:
|
1 2 |
# grep httpd /var/log/audit/audit.log | audit2allow -M passenger # semodule -i passenger.pp |
but the automatically generated policy was very unwieldy. The server is in a secure VLAN with a thorough lockdown applied anyway, so until I find time to write a custom SELinux policy for this:
|
1 2 3 |
# setenforce permissive # vi /etc/selinux/config SELINUX=permissive |
I then verified my current state - I’m running the standard puppetmaster (version 3.2.1) from the Puppet yum repos, and iptables is configured appropriately for port 8140/tcp, etc. Everything is operating as expected prior to the migration:
|
1 2 3 4 5 6 7 8 9 |
# chkconfig --list puppetmaster puppetmaster 0:off 1:off 2:on 3:on 4:on 5:on 6:off # ps -ef | grep '[p]uppet' puppet 1437 1 0 Jun13 ? 00:20:48 /usr/bin/ruby /usr/bin/puppet master # puppet master --version 3.2.1 # iptables -L -n | grep 8140 ACCEPT tcp -- 192.168.122.0/24 0.0.0.0/0 state NEW tcp dpt:8140 ACCEPT tcp -- 192.168.123.0/24 0.0.0.0/0 state NEW tcp dpt:8140 |
The first step is to install all prerequisite packages and their dependencies:
|
1 2 |
# yum install -y httpd httpd-devel mod_ssl ruby-devel rubygems gcc # yum install -y openssl-devel curl-devel gcc-c++ zlib-devel make |
Next, install the rack and passenger gems, and their dependencies:
|
1 |
# gem install rack passenger |
Now, run through the apache2 module build utility that comes with Passenger. This is a TUI application that will verify that all prerequisites are met prior to building the module. Once it has completed the build, it’ll give you the appropriate directives (LoadModule, PassengerRoot and PassengerDefaultRuby) you need to add into your Apache configuration.
|
1 |
# passenger-install-apache2-module |
The Puppet documentation has the Rack application running out of /usr/share … which to me is a terrible thing. I decided I’d like mine to run out of /var/lib/puppet/rack instead. Create the appropriate directories, and copy in the config.ru file. Ensure permissions are correct:
|
1 2 3 4 |
# mkdir -p /var/lib/puppet/rack/puppetmasterd # mkdir /var/lib/puppet/rack/puppetmasterd/{public,tmp} # cp /usr/share/puppet/ext/rack/files/config.ru /var/lib/puppet/rack/puppetmasterd # chown -R puppet /var/lib/puppet/rack |
Because Apache will need to access these directories, add an ACL (presuming your filesystem supports them) to /var/lib/puppet for your webserver user (in my case, apache):
|
1 2 3 4 5 6 7 8 9 10 11 |
# setfacl -m u:apache:rx /var/lib/puppet # getfacl /var/lib/puppet getfacl: Removing leading '/' from absolute path names # file: var/lib/puppet # owner: puppet # group: puppet user::rwx user:apache:r-x group::r-x mask::r-x other::--- |
Now, create your Apache VirtualHost configuration. Two of the directives provided in the Puppet document (PassengerUseGlobalQueue and RackAutoDetect) are no longer required, and if you use passenger as the module name you’ll find that the symbol is undefined - for Passenger 4.0.x you need passenger_module in your LoadModule directive.
I created this file at /etc/httpd/conf.d/00-default-vhost-puppetmaster.conf. You will need to modify the paths to your certificates as pertinent to your configuration. You may also need to adjust some of the other values according to your setup:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# Default VirtualHost - for Puppetmaster on Passenger # Load the passenger module LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-4.0.5/libout/apache2/mod_passenger.so # Define the passenger root directory PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-4.0.5 # Specify the path to the default ruby interpreter PassengerDefaultRuby /usr/bin/ruby # Turn passenger high performance settings on PassengerHighPerformance On # Set this to ~1.5 times the number of CPU cores on master system PassengerMaxPoolSize 2 # Recycle master processes after they service 1000 requests PassengerMaxRequests 1000 # Stop processes if they sit idle for 10 minutes PassengerPoolIdleTime 600 # Set up the apache virtual host Listen 8140 <VirtualHost *:8140> SSLEngine On # Only allow high security cryptography. Alter if needed for compatibility. SSLProtocol All -SSLv2 SSLCipherSuite HIGH:!ADH:RC4+RSA:-MEDIUM:-LOW:-EXP SSLCertificateFile /var/lib/puppet/ssl/certs/sun.local.pem SSLCertificateKeyFile /var/lib/puppet/ssl/private_keys/sun.local.pem SSLCertificateChainFile /var/lib/puppet/ssl/ca/ca_crt.pem SSLCACertificateFile /var/lib/puppet/ssl/ca/ca_crt.pem SSLCARevocationFile /var/lib/puppet/ssl/ca/ca_crl.pem SSLVerifyClient optional SSLVerifyDepth 1 SSLOptions +StdEnvVars +ExportCertData # These request headers are used to pass the client certificate # authentication information on to the puppet master process RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e DocumentRoot /var/lib/puppet/rack/puppetmasterd/public <Directory /var/lib/puppet/rack/puppetmasterd> Options None AllowOverride None Order allow,deny allow from all </Directory> </VirtualHost> |
Now, stop the existing WEBrick implementation:
|
1 |
# service puppetmaster stop |
And, all things being well, start Apache without errors:
|
1 |
# service httpd start |
Initiate a few puppet runs from your clients, and check that all is well:
|
1 |
# puppet agent --test |
If so, disable the original implementation and enable the new via chkconfig, and you’re done!
|
1 2 |
# chkconfig httpd on # chkconfig puppetmaster off |
You can view the status of passenger at any time with the passenger-status command:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
# passenger-status ----------- General information ----------- Max pool size : 2 Processes : 1 Requests in top-level queue : 0 ----------- Application groups ----------- /var/lib/puppet/rack/puppetmasterd#default: App root: /var/lib/puppet/rack/puppetmasterd Requests in queue: 0 * PID: 8423 Sessions: 0 Processed: 10 Uptime: 9s CPU: 5% Memory : 68M Last used: 2s ago |