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