Using Mongrel Pound

Version 3 (James Turnbull, 09/21/2010 05:07 pm)

1 1
# Using Mongrel with Pound
2 1
3 1
STILL INCOMPLETE
4 1
5 1
Alternatively, see: [[Using Mongrel]] and [[Using Mongrel Nginx]]
6 1
7 1
This solution freshly baked by James Turnbull, Jeff McCune, and
8 1
Nigel Kersten.
9 1
10 1
Date: 2007-11-15
11 1
12 1
## Why choose Pound
13 1
14 1
-   Pound is very small and fast.
15 1
-   Pound gives you fine-grained control of your SSL setup and
16 1
    client authorization.
17 1
-   Pound is probably easier and faster to setup than Apache.
18 1
-   For very-large-installations (3,000+ clients), pound **may**
19 1
    (confirmation needed) scale better than mod\_proxy\_balancer.
20 1
-   Pound is able to do sessions based on IP.
21 1
-   Pound checks Certificate Revocation Lists
22 1
23 1
## Why NOT Choose Pound
24 1
25 1
-   With older versions of Mongrel, you may need to patch pound or
26 1
    upgrade Mongrel. (See issue 2 below, regarding multi-line request
27 1
    headers.)
28 1
29 1
## Overview
30 1
31 1
Out of the box, we encountered a number of issues getting Pound to
32 1
proxy puppetd requests to mongrel and ultimately puppetmasterd.
33 1
34 1
1.  Pound formats the x.509 subject string differently than Apache
35 1
    does. Puppetmasterd uses the x.509 subject as the client name for
36 1
    authorization purposes.
37 1
2.  Pound adds a multi-line X-SSL-Certificate header, containing
38 1
    the PEM encoded certificate of the client. Mongrel does not accept
39 1
    multi-line HTTP headers.
40 1
3.  The header Pound uses for the x.509 Subject is X-SSL-Subject,
41 1
    while Apache uses X-Client-DN.
42 1
4.  Pound requires it's server SSL certificates in a particular
43 1
    format and order.
44 1
5.  Pound is pretty aggressive about short timeouts on the client
45 1
    and back-end connections.
46 1
47 3 James Turnbull
Issues 1 and 2 may require small patches to puppet and pound, as
48 3 James Turnbull
documented in #906.
49 1
50 1
Issue 3 requires puppetmasterd be configured with the option
51 1
**ssl\_client\_header=HTTP\_X\_SSL\_SUBJECT** to work with Pound.
52 1
53 1
Issue 4 requires the PEM certificate and key files to be
54 1
concatenated into a single file.
55 1
56 1
Issue 5 simply requires adjusting timeout values in the pound
57 1
configuration file.
58 1
59 1
## Setting up Pound
60 1
61 1
### Pound SSL Certificates
62 1
63 1
Pound needs a PEM file containing the SSL Private Key, the signed
64 1
x.509 certificate, and any certificates in the chain of trust.
65 1
66 1
Note: Order IS IMPORTANT. Pound requires that it "walk" the chain
67 1
from the top of the PEM file to the Bottom, so the root trusted
68 1
authority should be at the end of the file, and the server's
69 1
certificate should be at the "top" of the PEM file.
70 1
71 1
To create this file of key, server cert, and CA certificate we
72 1
concatenate together our existing Puppet certificates. Here we
73 1
assume your certificates are stored in /etc/puppet/ssl.
74 1
75 1
    $ cat /etc/puppet/ssl/private_keys/host_key.pem >> \
76 1
      /etc/puppet/ssl/pound/host_key_and_cert_chain.pem
77 1
    
78 1
    $ cat /etc/puppet/ssl/certs/host_cert.pem >> \
79 1
      /etc/puppet/ssl/pound/host_key_and_cert_chain.pem
80 1
    
81 1
    $ cat /etc/puppet/ssl/ca/ca_crt.pem >> \
82 1
      /etc/puppet/ssl/pound/host_key_and_cert_chain.pem
83 1
84 1
### Pound Configuration
85 1
86 1
Please note that for those following along in the Apache
87 1
configuration, client SSL verification is optional there, as Apache
88 1
can set the X-Client-Verify header dynamically depending on the
89 1
success or failure of the SSL verification.
90 1
91 1
In pound, we don't have dynamic variable expansion, so we instead
92 1
configure two listener ports 8140 and 8140. 8140 requires a valid,
93 1
verified certificate as it will ALWAYS set X-Client-Verify: SUCCESS
94 1
to proxied connections. 8140 does not set the X-Client-Verify
95 1
header.
96 1
97 1
    ##################################################
98 1
    # pound.cfg for use with mongrel => puppetmasterd
99 1
    #
100 1
    # Jeff McCune <jeff@northstarlabs.net>
101 1
    #
102 1
    
103 1
    User            "puppet"
104 1
    Group           "puppet"
105 1
    
106 1
    ## Set log level
107 1
    LogLevel        2
108 1
    
109 1
    ## Fork to the background
110 1
    Daemon 1
111 1
    
112 1
    ## Check back-end mongrel servers every 30 seconds.
113 1
    Alive           30
114 1
    
115 1
    # Client timeout in seconds.  Pound will kill the connection if it does
116 1
    # not receive any data after this many seconds.
117 1
    Client 300
118 1
    
119 1
    # How long should Pound wait for a response from the back-end (in seconds).
120 1
    TimeOut 180
121 1
    
122 1
    # Authenticated clients connect to port 8140
123 1
    ListenHTTPS
124 1
      Address 0.0.0.0
125 1
      Port    8140
126 1
    
127 1
      # THIS IS VERY IMPORTANT.  Without it, clients may forge
128 1
      # the X-Client-Verify: SUCCESS header.
129 1
      # I believe this is correct, but have not verified it.
130 1
      HeadRemove "X-SSL-.*"
131 1
      HeadRemove "X-Client-Verify.*"
132 1
    
133 1
      ####    Pound's SSL certificate, key file, and CA chain of trust.
134 1
      Cert    "/etc/puppet/ssl/pound/host_key_and_cert_chain.pem"
135 1
    
136 1
      # This is the list of CA's we ultimately trust.
137 1
      # If a certificate's chain of trust is ROOTED with a CA in this list,
138 1
      # The client connection is authorized.
139 1
      VerifyList "/etc/puppet/ssl/ca/ca_crt.pem"
140 1
    
141 1
      # This is the list of CA's we will permit to exist in the CHAIN
142 1
      # from client certificate to ROOT CA's listed in VerifyList.
143 1
      # This list is sent to the client, so they may pick the correct
144 1
      # certificate to submit.
145 1
      CAlist "/etc/puppet/ssl/ca/ca_crt.pem"
146 1
    
147 1
      ## THIS IS WHERE ALL YOUR SECURITY STEMS FROM.  TAKE CARE!
148 1
      # ClientCert 0|1|2|3 depth
149 1
      #   0 - don't ask (default),
150 1
      #   1 - ask,
151 1
      #   2 - demand, and require valid chain to a root CA listed in VerifyList
152 1
      #   3 - demand (I think) but do not verify
153 1
      #   depth is the depth of verification for a client certificate (up to 9).
154 1
      ClientCert 2 4
155 1
    
156 1
      # Revocation is important.
157 1
      CRLlist    "/etc/puppet/ssl/ca/ca_crl.pem"
158 1
    
159 1
      # Pound, by default is too strict with SSL ciphers.
160 1
      Ciphers    "SSLv2:-LOW:-EXPORT:RC4+RSA"
161 1
    
162 1
      # If all of the above SSL stuff checks out...  Then
163 1
      # NOTE: I believe there is a bug in Pound where only one
164 1
      # header may be added.
165 1
      AddHeader "X-Client-Verify: SUCCESS"
166 1
    
167 1
      # Forward the connection back to the Mongrel servers.
168 1
      Service
169 1
        BackEnd
170 1
          Address 127.0.0.1
171 1
          Port    18140
172 1
        End
173 1
        BackEnd
174 1
          Address 127.0.0.1
175 1
          Port    18141
176 1
        End
177 1
        # etc...
178 1
        Session
179 1
          Type IP
180 1
          TTL  300
181 1
        End
182 1
      End
183 1
    End
184 1
    
185 1
    ## Listen on port 8141 for CA signing requests.
186 1
    ListenHTTPS
187 1
      Address    0.0.0.0
188 1
      Port       8141
189 1
      HeadRemove "X-SSL-.*"
190 1
      HeadRemove "X-Client-Verify.*"
191 1
      Cert    "/etc/puppet/ssl/pound/host_key_and_cert_chain.pem"
192 1
      VerifyList "/etc/puppet/ssl/ca/ca_crt.pem"
193 1
      CAlist "/etc/puppet/ssl/ca/ca_crt.pem"
194 1
      ClientCert 3 9
195 1
      CRLlist    "/etc/puppet/ssl/ca/ca_crl.pem"
196 1
      Ciphers    "SSLv2:-LOW:-EXPORT:RC4+RSA"
197 1
      
198 1
      Service
199 1
        BackEnd
200 1
          Address 127.0.0.1
201 1
          Port    18140
202 1
        End
203 1
        BackEnd
204 1
          Address 127.0.0.1
205 1
          Port    18141
206 1
        End
207 1
        Session
208 1
          Type IP
209 1
          TTL  300
210 1
        End
211 1
      End
212 1
    End
213 1
214 1
## Starting Pound
215 1
216 1
Now we can start Pound:
217 1
218 1
    # pound -f /etc/pound/pound.cfg -p /var/run/pound.pid
219 1
220 1
### Debugging Pound
221 1
222 1
Pound logs to syslog - on Debian this defaults to logging to
223 1
/var/log/daemon.log. If you use syslog-ng you can direct your
224 1
logging output elsewhere using a filter like:
225 1
226 1
    destination df_pound { file("/var/log/pound.log"); };
227 1
    filter f_pound { program("pound"); };
228 1
    log {
229 1
            source(s_all);
230 1
            filter(f_pound);
231 1
            destination(df_pound);
232 1
    };
233 1
234 1
## Start puppetmasterd daemons
235 1
236 1
You need to run the puppetmasterd daemon using the Mongrel web
237 1
server and run each instance on the port numbers indicated in our
238 1
BackEnd clauses defined in our pound.cfg. You can use a script like
239 1
this to start each instance:
240 1
241 1
    #!/bin/bash
242 1
    # name: mongrel_puppetmasterd
243 1
    # Start a Puppet Master Server instance.
244 1
    
245 1
    if ! [[ "$1" -gt 0 ]]; then
246 1
    echo "ERROR: You must provide a port to run this puppet master on."
247 1
    echo "Ensure your apache load balancer is configured to talk to these servers"
248 1
    exit 1
249 1
    fi
250 1
    
251 1
    MASTERPORT="$1"
252 1
    shift
253 1
    
254 1
    puppetmasterd \
255 1
    --pidfile=/var/run/puppetmasterd."${MASTERPORT}".pid \
256 1
    --servertype=mongrel \
257 1
    --ssl_client_header=HTTP_X_SSL_SUBJECT \
258 1
    --masterport="${MASTERPORT}" \
259 1
    $*
260 1
261 1
The script is initiated by passing the port number you wish to
262 1
start the puppetmasterd on. To start puppetmasterd daemons for the
263 1
Back End? instances we've defined in our pound.cfg you would:
264 1
265 1
    # mongrel_puppetmasterd 18140
266 1
    # mongrel_puppetmasterd 18141
267 1
268 1
## Test clients
269 1
270 1
Now attempt to test a client connection.