Using Mongrel

Version 1 (Anonymous, 03/13/2010 08:02 pm)

1 1
# Using Mongrel with Apache
2 1
3 1
Alternatively, see: [[Using Mongrel On Debian]] [[Using Mongrel On
4 1
Enterprise Linux]] [[Using Mongrel Pound]] [[Using Mongrel Nginx]]
5 1
[[Using Passenger]]
6 1
7 1
Puppet daemons default to using WEBrick for http serving, but
8 1
puppetmasterd can be used with Mongrel instead. This requires
9 1
setting up a web proxy in front of Mongrel to handle the SSL
10 1
connections, and then you can start as many puppetmasterd instances
11 1
as you need. Note that Puppet uses Mongrel differently than most --
12 1
usually, you would have a mongrel\_cluster command that managed
13 1
multiple Mongrel instances. I planned to implement it this way, but
14 1
it ended up being easier in the short term to stick with
15 1
puppetmasterd. Please contact me (Luke) if you want to work on
16 1
getting mongrel\_cluster to work with Puppet, as it could be used
17 1
to manage multiple Mongrel instances at once.
18 1
19 1
See the following diagram which shows how it works:
20 1
[http://reductivelabs.com/trac/puppet/attachment/wiki/UsingMongrel/puppetmaster-mongrel.png](http://reductivelabs.com/trac/puppet/attachment/wiki/UsingMongrel/puppetmaster-mongrel.png)
21 1
22 1
Version 0.23.1 or higher of puppetmasterd is required. (Earlier
23 1
versions couldn't do certificate signing because they didn't
24 1
support the X-Client-Verify header.)
25 1
26 1
This document only describes setting up Apache as a proxy in front
27 1
of Mongrel. Any other http proxy should work, as long as it
28 1
supports validating client certificates.
29 1
30 1
# Why You'd Do This
31 1
32 1
Mongrel scales much better than WEBrick, at least partially because
33 1
it allows you to run multiple processes serving the same pool of
34 1
clients on the same host. WEBrick only uses Ruby's threading, which
35 1
does not scale beyond one processor, and it appears that WEBrick
36 1
starts dropping connections beyond about 2 concurrent connections.
37 1
38 1
If you're getting connection-reset or End-of-file errors, you
39 1
should try Mongrel. As more people try it and it proves to be
40 1
stable, it will eventually become the preferred serving platform
41 1
for the master.
42 1
43 1
# Known Issues
44 1
45 1
The Puppet file server (and other parts of puppet?) will not see
46 1
connections coming from the puppet client but from the reverse
47 1
proxy (ie. Apache). FileServingConfiguration (Security section)
48 1
gives more detail.
49 1
50 1
There is a problem with Apache and the certificate revocation list
51 1
(CRL) as generated by the puppet CA. If you encounter this problem,
52 1
you are likely to see lines like this in your error log:
53 1
54 1
[Mon Nov 10 08:47:20 2008] [warn] Invalid signature on CRL
55 1
56 1
[Mon Nov 10 08:47:20 2008] [error] Certificate Verification: Error
57 1
(8): CRL signature failure
58 1
59 1
Puppet will also complain:
60 1
61 1
err: Could not retrieve catalog: Certificates were not trusted:
62 1
tlsv1 alert decrypt error
63 1
64 1
Yet everything looks good in your puppet.conf.
65 1
66 1
If so, comment out the line containing !SSLCARevocationFile from
67 1
your apache config.
68 1
69 1
# Apache Configuration
70 1
71 1
Here is a complete apache configuration, intended for use only with
72 1
puppet:
73 1
74 1
    # Jeff McCune <mccune@math.ohio-state.edu>
75 1
    # 2007-09-14
76 1
    #
77 1
    # Minimal Apache Configuration for Apache+Mongrel+Puppetmaster
78 1
    #
79 1
    #  Host System Setup and Configuration:
80 1
    #  - Add puppet/puppet user/group
81 1
    #  - Use the following configuration file.
82 1
    #  - /Library/Puppet/Generated/Server is owned by puppet/puppet
83 1
    #
84 1
    #  - If you have a system which doens't provide Apache 2.2.X packages:
85 1
    #    Apache may be built with:
86 1
    #
87 1
    #    ./configure --enable-so \
88 1
    #       --enable-ssl=shared --enable-proxy=shared --enable-proxy_http=shared \
89 1
    #       --enable-proxy_balancer=shared --enable-headers=shared \
90 1
    #       --enable-authz_host=shared --enable-log_config=shared \
91 1
    #       --prefix=/Library/Puppet/Resources/httpd-2.2.4
92 1
    #
93 1
    # - Finally, start the SSL proxy with:
94 1
    #   /Library/Puppet/Resources/httpd-2.2.4/bin/httpd -f \
95 1
    #   /Library/Puppet/Versioned/Server/cluster-orange/httpd/puppetmasterd.conf
96 1
    
97 1
    Listen 8140
98 1
    PidFile /Library/Puppet/Generated/Server/balancer.pid
99 1
    User puppet
100 1
    Group puppet
101 1
    
102 1
    LoadModule proxy_module modules/mod_proxy.so
103 1
    LoadModule proxy_http_module modules/mod_proxy_http.so
104 1
    LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
105 1
    LoadModule headers_module modules/mod_headers.so
106 1
    LoadModule ssl_module modules/mod_ssl.so
107 1
    LoadModule authz_host_module modules/mod_authz_host.so
108 1
    LoadModule log_config_module modules/mod_log_config.so
109 1
    
110 1
    <Directory />
111 1
        Options FollowSymLinks
112 1
        AllowOverride None
113 1
        Order deny,allow
114 1
        Deny from all
115 1
    </Directory>
116 1
    
117 1
    <Proxy balancer://puppetmaster>
118 1
      BalancerMember http://127.0.0.1:18140 keepalive=on max=2 retry=30
119 1
      BalancerMember http://127.0.0.1:18141 keepalive=on max=2 retry=30
120 1
    </Proxy>
121 1
    
122 1
    <VirtualHost *:8140>
123 1
        SSLEngine on
124 1
        SSLCipherSuite SSLv2:-LOW:-EXPORT:RC4+RSA
125 1
        SSLCertificateFile      /Library/Puppet/Generated/Server/SSL/host_cert.pem
126 1
        SSLCertificateKeyFile   /Library/Puppet/Generated/Server/SSL/host_key.pem
127 1
        SSLCertificateChainFile /Library/Puppet/Generated/Server/SSL/ca/ca_crt.pem
128 1
        SSLCACertificateFile    /Library/Puppet/Generated/Server/SSL/ca/ca_crt.pem
129 1
        SSLCARevocationFile     /Library/Puppet/Generated/Server/SSL/ca/ca_crl.pem
130 1
        SSLVerifyClient optional
131 1
        SSLVerifyDepth  1
132 1
        SSLOptions +StdEnvVars
133 1
    
134 1
        # The following client headers allow the same configuration to work with Pound.
135 1
        RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e
136 1
        RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e
137 1
        RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e
138 1
    
139 1
        <Location />
140 1
            SetHandler balancer-manager
141 1
            Order allow,deny
142 1
            Allow from all
143 1
        </Location>
144 1
    
145 1
        ProxyPass / balancer://puppetmaster:8140/ timeout=180
146 1
        ProxyPassReverse / balancer://puppetmaster:8140/
147 1
        ProxyPreserveHost on
148 1
        SetEnv force-proxy-request-1.0 1
149 1
        SetEnv proxy-nokeepalive 1
150 1
    
151 1
        ErrorLog  /Library/Puppet/Generated/Server/balancer_error.log
152 1
        CustomLog /Library/Puppet/Generated/Server/balancer_access.log combined
153 1
        CustomLog /Library/Puppet/Generated/Server/balancer_ssl_request.log \
154 1
                      "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
155 1
    </VirtualHost>
156 1
157 1
Note that you'll have to customize it to match the name of your
158 1
puppet server. Note also the cluster member declarations -- this is
159 1
where you tell Apache how to contact the Mongrel instances -- you
160 1
need a separate line for every instance, and (of course) each
161 1
instance needs to be started on a separate port.
162 1
163 1
This configuration starts Apache on Puppet's normal server port, so
164 1
clients do not need to be reconfigured.
165 1
166 1
# Another Apache configuration
167 1
168 1
Here's another happy apache configuration, without all the OSXey
169 1
stuff ('''Note:''' You still need to load the apache modules from
170 1
the configuration above. Except for ''log\_config'' which seems to
171 1
be OS X specific):
172 1
173 1
    Listen 8140
174 1
    
175 1
    ProxyRequests Off
176 1
    
177 1
    <Proxy balancer://puppetmaster>
178 1
        BalancerMember http://127.0.0.1:18140
179 1
    </Proxy>
180 1
    
181 1
    <VirtualHost *:8140>
182 1
        SSLEngine on
183 1
        SSLCipherSuite SSLv2:-LOW:-EXPORT:RC4+RSA
184 1
        SSLCertificateFile /etc/puppet/ssl/certs/backup4.foo.com.pem
185 1
        SSLCertificateKeyFile /etc/puppet/ssl/private_keys/backup4.foo.com.pem
186 1
        SSLCertificateChainFile /etc/puppet/ssl/ca/ca_crt.pem
187 1
        SSLCACertificateFile /etc/puppet/ssl/ca/ca_crt.pem
188 1
        SSLCARevocationFile /etc/puppet/ssl/ca/ca_crl.pem
189 1
        SSLVerifyClient optional
190 1
        SSLVerifyDepth  1
191 1
        SSLOptions +StdEnvVars
192 1
    
193 1
        RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e
194 1
        RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e
195 1
    
196 1
        <Location />
197 1
           SetHandler balancer-manager
198 1
           Order allow,deny
199 1
           Allow from all
200 1
        </Location>
201 1
    
202 1
        ProxyPass / balancer://puppetmaster:8140/
203 1
        ProxyPassReverse / balancer://puppetmaster:8140/
204 1
        ProxyPreserveHost on
205 1
    
206 1
    </VirtualHost>
207 1
208 1
# Configuring Puppet
209 1
210 1
The only change to Puppet is that you need to start puppetmasterd
211 1
with --servertype mongrel and choose a separate masterport for each
212 1
instance. You will also need to specify a separate pidfile for each
213 1
instance.
214 1
215 1
The attached example init script for RedHat systems, or this helper
216 1
script might be useful:
217 1
218 1
    #!/bin/bash
219 1
    #
220 1
    # Start a Puppet Master Server instance.
221 1
    EZPUPPET_CONFDIR="${EZPUPPET_CONFDIR:=${EZPUPPET_BASE:=/Library/Puppet}/Versioned/Server/${EZPUPPET_SERVER:=cluster-orange}/puppet}"
222 1
    
223 1
    if ! [[ "$1" -gt 0 ]]; then
224 1
      echo "ERROR: You must provide a port to run this puppet master on."
225 1
      echo "Start at 18140 and increment upward."
226 1
      echo "  The apache load balancer is configured to talk to these servers"
227 1
      echo "  so the port numbers are NOT arbitrary."
228 1
      exit 1
229 1
    fi
230 1
    
231 1
    MASTERPORT="$1"
232 1
    shift
233 1
    
234 1
    puppetmasterd \
235 1
      --confdir="${EZPUPPET_CONFDIR}" \
236 1
      --pidfile=${EZPUPPET_BASE}/Generated/Server/var/run/puppetmaster."${MASTERPORT}".pid \
237 1
      --servertype=mongrel \
238 1
      --masterport="${MASTERPORT}" \
239 1
      $*
240 1
241 1
As mentioned earlier, this would be easier if it were done with
242 1
mongrel\_start, but it will take a significant amount of work to
243 1
get all of Puppet's existing code working in that framework, and
244 1
I'm unlikely to do it except as part of contract development.
245 1
Clearly, patches that provided this would be accepted.
246 1
247 1
'''NOTE''': The current (as of at least 0.24.6)
248 1
/etc/init.d/puppetmaster script on RedHat and compatible systems
249 1
already supports multiple mongrel instances in a similar way to
250 1
above. Simply specify your Mongrel instance ports in
251 1
/etc/sysconfig/puppetmaster in BASH array format as per the
252 1
following example:
253 1
254 1
    PUPPETMASTER_PORTS=([0]=18140 [1]=18141 [2]=18142 [3]=18143 [4]=18144)
255 1
256 1
# Generating Certificates
257 1
258 1
In version 0.23.2 I found that puppetmasterd would not generate
259 1
certificates when started using Mongrel. I worked around the
260 1
problem by using puppetca to generate the certificates as part of
261 1
the install process, like this:
262 1
263 1
    puppetca --generate <DOMAIN>