Using Mongrel Nginx

Version 5 (Peter Meier, 08/18/2010 12:31 pm)

1 1
# Using Mongrel with nginx
2 1
3 1
Alternatively, see: [[Using Mongrel]] and [[Using Mongrel Pound]]
4 1
5 1
This solution freshly baked by Jeff McCune.
6 1
7 1
Date: 2007-11-27
8 1
9 1
## References
10 1
11 1
-   [English Language nginx Wiki](http://wiki.codemongers.com/Main)
12 1
13 1
## Why choose nginx
14 1
15 1
-   Performance: nginx is very small and fast. Many claim it's
16 1
    faster than Pound.
17 1
-   Logging, Debugging: nginx appears to be "cleaner" than Pound.
18 1
-   Flexibility: nginx handles SSL client verification at the
19 1
    application layer, rather than terminating the SSL connection.
20 1
-   You don't have to patch pound if you don't want to upgrade
21 1
    Mongrel.
22 1
-   You don't have to upgrade Mongrel if you don't want to patch
23 1
    Pound.
24 1
-   nginx works "out of the box"
25 1
-   Despite russian documentation, the configuration syntax is
26 1
    intuitive.
27 1
28 1
## Why NOT choose nginx
29 1
30 1
-   I see no way to configure a certificate revocation list. If you
31 1
    need revocation, consider Pound or Apache for your SSL proxy.
32 1
33 1
## Overview
34 1
35 1
This sample configuration is based off nginx-0.5.33.
36 1
37 1
The back end puppet servers are configuration-compatible with the
38 1
[[Using Mongrel Pound]] documentation. That is, you must configure
39 1
ssl\_client\_header = HTTP\_X\_SSL\_SUBJECT and take note of ticket
40 1
[#906](http://projects.reductivelabs.com/issues/906).
41 1
42 1
## Sample Configuration
43 1
44 1
This configuration appears to be working well for about 300 clients
45 1
in production:
46 1
47 1
    user  daemon daemon;
48 1
    worker_processes  4;
49 1
    
50 1
    error_log       /var/log/nginx-puppet.log notice;
51 1
    pid             /var/run/nginx-puppet.pid;
52 1
    
53 1
    events {
54 1
        worker_connections  1024;
55 1
    }
56 1
    
57 1
    http {
58 1
        # include /etc/mime.types;
59 1
        default_type  application/octet-stream;
60 1
    
61 1
        # no sendfile on OSX uncomment 
62 1
        #this if your on linux or bsd
63 1
        sendfile        on;
64 1
        tcp_nopush      on;
65 1
        
66 1
        # Look at TLB size in /proc/cpuinfo (Linux) for the 4k pagesize
67 1
        large_client_header_buffers     16      4k;
68 1
        proxy_buffers                   128     4k;
69 1
    
70 1
        # if you adjust this setting to something higher
71 1
        # you should as well update the proxy_read_timeout 
72 1
        # in the server config part (see below)
73 1
        # Otherwise nginx will rerequest a manifest compile.
74 1
        keepalive_timeout  65;
75 1
        tcp_nodelay        on;
76 1
    
77 1
        ssl                     on;
78 1
        ssl_certificate         /Library/Puppet/Generated/Server/SSL/host_cert.pem;
79 1
        ssl_certificate_key     /Library/Puppet/Generated/Server/SSL/host_key.pem;
80 1
        ssl_client_certificate  /Library/Puppet/Generated/Server/SSL/ca/ca_crt.pem;
81 1
        ssl_ciphers             SSLv2:-LOW:-EXPORT:RC4+RSA;
82 1
        ssl_session_cache       shared:SSL:8m;
83 1
        ssl_session_timeout     5m;
84 1
    
85 1
        upstream puppet-production {
86 1
            server 127.0.0.1:18140;
87 1
            server 127.0.0.1:18141;
88 1
            server 127.0.0.1:18142;
89 1
            server 127.0.0.1:18143;
90 1
        }
91 1
    
92 1
        upstream puppet-test1 {
93 1
            server 127.0.0.1:28140;
94 1
        }
95 1
    
96 1
        upstream puppet-test2 {
97 1
            server 127.0.0.1:38140;
98 1
        }
99 1
    
100 1
        upstream puppet-test3 {
101 1
            server 127.0.0.1:48140;    
102 1
        }
103 1
    
104 1
        server {
105 1
            listen                  8140;
106 1
            ssl_verify_client       on;
107 1
            root                    /var/empty;
108 1
            access_log              /var/log/nginx/access-8140.log;
109 1
            rewrite_log             /var/log/nginx/rewrite-8140.log;
110 1
    
111 1
            # Variables
112 1
            # $ssl_cipher returns the line of those utilized it is cipher for established SSL-connection
113 1
            # $ssl_client_serial returns the series number of client certificate for established SSL-connection
114 1
            # $ssl_client_s_dn returns line subject DN of client certificate for established SSL-connection
115 1
            # $ssl_client_i_dn returns line issuer DN of client certificate for established SSL-connection
116 1
            # $ssl_protocol returns the protocol of established SSL-connection
117 1
    
118 1
            location / {
119 1
                proxy_pass          http://puppet-production;
120 1
                proxy_redirect      off;
121 1
                proxy_set_header    Host             $host;
122 1
                proxy_set_header    X-Real-IP        $remote_addr;
123 1
                proxy_set_header    X-Forwarded-For  $proxy_add_x_forwarded_for;
124 1
                proxy_set_header    X-Client-Verify  SUCCESS;
125 3 Jim Blomo
                proxy_set_header    X-Client-DN      $ssl_client_s_dn;
126 1
                proxy_set_header    X-SSL-Subject    $ssl_client_s_dn;
127 1
                proxy_set_header    X-SSL-Issuer     $ssl_client_i_dn;
128 1
                proxy_read_timeout  65;
129 1
            }
130 1
        }
131 1
    
132 1
        server {
133 1
            listen                  8141;
134 1
            ssl_verify_client       off;
135 1
            root                    /var/empty;
136 1
            access_log              /var/log/nginx/access-8141.log;
137 1
            rewrite_log             /var/log/nginx/rewrite-8141.log;
138 1
    
139 1
            location / {
140 1
                proxy_pass  http://puppet-production;
141 1
                proxy_redirect     off;
142 1
                proxy_set_header   Host             $host;
143 1
                proxy_set_header   X-Real-IP        $remote_addr;
144 1
                proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
145 1
                proxy_set_header   X-Client-Verify  FAILURE;
146 3 Jim Blomo
                proxy_set_header   X-Client-DN      $ssl_client_s_dn;
147 1
                proxy_set_header   X-SSL-Subject    $ssl_client_s_dn;
148 1
                proxy_set_header   X-SSL-Issuer     $ssl_client_i_dn;
149 1
                proxy_read_timeout  65;
150 1
            }
151 1
        }
152 1
    
153 1
        server {
154 1
            listen                  8150;
155 1
            ssl_verify_client       on;
156 1
            root                    /var/empty;
157 1
            access_log              /var/log/nginx/access-8150.log;
158 1
            rewrite_log             /var/log/nginx/rewrite-8150.log;
159 1
    
160 1
            location / {
161 1
                proxy_pass  http://puppet-test1;
162 1
                proxy_redirect     off;
163 1
                proxy_set_header   Host             $host;
164 1
                proxy_set_header   X-Real-IP        $remote_addr;
165 1
                proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
166 1
                proxy_set_header   X-Client-Verify  SUCCESS;
167 3 Jim Blomo
                proxy_set_header   X-Client-DN      $ssl_client_s_dn;
168 1
                proxy_set_header   X-SSL-Subject    $ssl_client_s_dn;
169 1
                proxy_set_header   X-SSL-Issuer     $ssl_client_i_dn;
170 1
                proxy_read_timeout  65;
171 1
            }
172 1
        }
173 1
    
174 1
        server {
175 1
            listen                  8160;
176 1
            ssl_verify_client       on;
177 1
            root                    /var/empty;
178 1
            access_log              /var/log/nginx/access-8160.log;
179 1
            rewrite_log             /var/log/nginx/rewrite-8160.log;
180 1
    
181 1
            location / {
182 1
                proxy_pass  http://puppet-test2;
183 1
                proxy_redirect     off;
184 1
                proxy_set_header   Host             $host;
185 1
                proxy_set_header   X-Real-IP        $remote_addr;
186 1
                proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
187 1
                proxy_set_header   X-Client-Verify  SUCCESS;
188 3 Jim Blomo
                proxy_set_header   X-Client-DN      $ssl_client_s_dn;
189 1
                proxy_set_header   X-SSL-Subject    $ssl_client_s_dn;
190 1
                proxy_set_header   X-SSL-Issuer     $ssl_client_i_dn;
191 1
                proxy_read_timeout  65;
192 1
            }
193 1
        }
194 1
    
195 1
        server {
196 1
            listen                  8170;
197 1
            ssl_verify_client       on;
198 1
            root                    /var/empty;
199 1
            access_log              /var/log/nginx/access-8170.log;
200 1
            rewrite_log             /var/log/nginx/rewrite-8170.log;
201 1
    
202 1
            location / {
203 1
                proxy_pass  http://puppet-test3;
204 1
                proxy_redirect     off;
205 1
                proxy_set_header   Host             $host;
206 1
                proxy_set_header   X-Real-IP        $remote_addr;
207 1
                proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
208 1
                proxy_set_header   X-Client-Verify  SUCCESS;
209 3 Jim Blomo
                proxy_set_header   X-Client-DN      $ssl_client_s_dn;
210 1
                proxy_set_header   X-SSL-Subject    $ssl_client_s_dn;
211 1
                proxy_set_header   X-SSL-Issuer     $ssl_client_i_dn;
212 1
                proxy_read_timeout  65;
213 1
            }
214 1
        }
215 1
    
216 1
    }
217 1
218 1
## Certificate Signing
219 1
220 1
-   You will need to add **--ca\_port 8141** to your first puppetd
221 1
    run in order to have the puppetmaster sign your certificate.
222 1
223 1
## Nginx > 0.8.7
224 1
225 1
Since Nginx 0.8.7 or any 0.7 version with the patches from:
226 4 Peter Meier
[http://www.masterzen.fr/2009/07/21/new-ssl-features-for-nginx/](http://www.masterzen.fr/2009/07/21/new-ssl-features-for-nginx/) (Note: not all 0.7 version need these patches, from a certain version on they are integrated upstream)
227 1
Nginx supports out of the box
228 1
229 1
\* Optional client verification, like apache \* CRL certificate
230 1
verification
231 1
232 1
Thus for those versions, the configuration becomes much simpler,
233 1
and you don't need to instruct your clients to use another port
234 1
(--ca\_port is not needed anymore):
235 1
236 1
    ...
237 1
    upstream puppet-production {
238 1
      server 127.0.0.1:18140;
239 1
      server 127.0.0.1:18141;
240 1
    }
241 1
    
242 1
    server {
243 1
      listen 8140;
244 1
    
245 1
      ssl                     on;
246 1
      ssl_session_timeout     5m;
247 1
      ssl_certificate         /var/lib/puppet/ssl/certs/puppetmaster.pem;
248 1
      ssl_certificate_key     /var/lib/puppet/ssl/private_keys/puppetmaster.pem;
249 1
      ssl_client_certificate  /var/lib/puppet/ssl/ca/ca_crt.pem;
250 1
    
251 1
      # choose any ciphers
252 1
      ssl_ciphers             SSLv2:-LOW:-EXPORT:RC4+RSA;
253 1
    
254 1
      # allow authenticated and client without certs
255 1
      ssl_verify_client       optional;
256 1
    
257 1
      # obey to the Puppet CRL
258 1
      ssl_crl /var/lib/puppet/ssl/ca/ca_crl.pem;
259 1
    
260 1
      root                    /var/tmp;
261 1
    
262 1
      location / {
263 1
        proxy_pass              http://puppet-production;
264 1
        proxy_redirect         off;
265 1
        proxy_set_header    Host             $host;
266 1
        proxy_set_header    X-Real-IP        $remote_addr;
267 1
        proxy_set_header    X-Forwarded-For  $proxy_add_x_forwarded_for;
268 1
        proxy_set_header    X-Client-Verify  $ssl_client_verify;
269 3 Jim Blomo
        proxy_set_header    X-Client-DN      $ssl_client_s_dn;
270 1
        proxy_set_header    X-SSL-Subject    $ssl_client_s_dn;
271 1
        proxy_set_header    X-SSL-Issuer     $ssl_client_i_dn;
272 1
        proxy_read_timeout  65;
273 1
      }
274 4 Peter Meier
    }
275 4 Peter Meier
    ...
276 4 Peter Meier
277 4 Peter Meier
## Fair Proxy Balancer
278 4 Peter Meier
279 4 Peter Meier
There is a module for nginx available that improves how requests are balanced to the backend mongrel servers: [http://www.brainspl.at/articles/2007/11/09/a-fair-proxy-balancer-for-nginx-and-mongrel](http://www.brainspl.at/articles/2007/11/09/a-fair-proxy-balancer-for-nginx-and-mongrel). Integrating and activating this module for your nginx can improve performance of puppet runs further. The reason is that some puppet requests are very long living such as the compile requests. As the mongrel instance is busy during that time compiling your catalog it won't serve any other requests and they are stuck in nginx's queue until this request is finished. If you have 4 mongrel instances running and one is currently busy compiling a huge catalog every 4th request from another client that is for example asking for file metadata will be stuck at the mongrel instance compiling the catalog. This will slowdown the puppet runs on the second client.
280 4 Peter Meier
281 4 Peter Meier
The fair proxy balancer will keep track which of your mongrel instances are busy and will direct new requests to other mongrel instances, which are probably free.
282 4 Peter Meier
283 4 Peter Meier
All you need to do is to compile nginx with this module and setup your proxy balancer like that:
284 4 Peter Meier
285 4 Peter Meier
    ...
286 4 Peter Meier
    upstream puppet-production {
287 5 Peter Meier
      fair;
288 4 Peter Meier
      server 127.0.0.1:18140;
289 4 Peter Meier
      server 127.0.0.1:18141;
290 1
    }
291 1
    ...