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