apache-frontend: add possibility to individually provide state to frontends
[slapos.git] / software / apache-frontend / README.apache_frontend.txt
1 apache_frontend
2 ===============
3
4 Frontend system using Apache, allowing to rewrite and proxy URLs like
5 myinstance.myfrontenddomainname.com to real IP/URL of myinstance.
6
7 apache_frontend works using the master instance / slave instance design.
8 It means that a single main instance of Apache will be used to act as frontend
9 for many slaves.
10
11 Software type
12 =============
13
14 Apache frontend is available in 3 software types:
15   * default : The standard way to use the apache frontend configuring everything with a few given parameters
16   * custom-personal : This software type allow each slave to edit its apache configuration file
17   * custom-group : This software type use a template given as a parameter on master instance to generate apache configuration for all slaves
18   * replicate : This software type is set to replicate any kind of apache
19
20 About replicate frontend
21 ========================
22
23 Slaves of the root instance (type "replicate") are sent as a parameter to requested frontends which will process them. The only difference is that they will then return the « would-be published information » to the root instance instead of publishing it. The root instance will then do a synthesis and publish the information to its slaves. The replicate instance only use 4 type of parameters for itself and will transmit the rest to requested frontends.
24 These parameters are :
25   * "-frontend-type" : the type to deploy frontends with. (default to 2)
26   * "-frontend-quantity" : The quantity of frontends to request (default to "default")
27   * "-frontend-i-state": The state of frontend i
28   * "-sla-i-foo" : where "i" is the number of the concerned frontend (between 1 and "-frontend-quantity") and "foo" a sla parameter.
29 ex:
30 <parameter id="-frontend-quantity">3</parameter>
31 <parameter id="-frontend-type">custom-personal</parameter>
32 <parameter id="-frontend-2-state">stopped</parameter>
33 <parameter id="-sla-3-computer_guid">COMP-1234</parameter>
34 will request the third frontend on COMP-1234. All frontends will be of software type "custom-personal". The second frontend will be requested with the state stopped
35
36 Note: the way slaves are transformed to a parameter avoid modifying more than 3 lines in the frontend logic.
37 Important NOTE: The way you ask for slave to a replicate frontend is the same as the one you would use for the software given in "-frontend-quantity". Do not forget to use "replicate" for software type. XXXXX So far it is not possible to do a simple request on a replicate frontend if you do not know the software_guid or other sla-parameter of the master instance. In fact we do not know yet the software type of the "requested" frontends. TO BE IMPLEMENTED
38
39 How to deploy a frontend server
40 ===============================
41
42 This is to deploy an entire frontend server with a public IPv4.
43 If you want to use an already deployed frontend to make your service available
44 via ipv4, switch to the "Example" parts.
45
46 First, you will need to request a "master" instance of Apache Frontend with:
47   * A "domain" parameter where the frontend will be available
48   * A "public-ipv4" parameter to state which public IPv4 will be used
49
50 like::
51   <?xml version='1.0' encoding='utf-8'?>
52   <instance>
53    <parameter id="domain">moulefrite.org</parameter>
54    <parameter id="public-ipv4">xxx.xxx.xxx.xxx</parameter>
55   </instance>
56
57 Then, it is possible to request many slave instances
58 (currently only from slapconsole, UI doesn't work yet)
59 of Apache Frontend, like::
60   instance = request(
61     software_release=apache_frontend,
62     partition_reference='frontend2',
63     shared=True,
64     partition_parameter_kw={"url":"https://[1:2:3:4]:1234/someresource"}
65   )
66 Those slave instances will be redirected to the "master" instance,
67 and you will see on the "master" instance the associated RewriteRules of
68 all slave instances.
69
70 Finally, the slave instance will be accessible from:
71 https://someidentifier.moulefrite.org.
72
73 About SSL
74 =========
75 Default and custom-personal software type can handle specific ssl for one slave instance.
76 IMPORTANT: One apache can not serve more than One specific SSL VirtualHost and be compatible with obsolete browser (i.e.: IE8). See http://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI
77
78 #How to have custom configuration in frontend server
79 #===================================================
80 #
81 #In your instance directory, you, as sysadmin, can directly edit two
82 #configuration files that won't be overwritten by SlapOS to customize your
83 #instance:
84 #
85 # * $PARTITION_PATH/srv/srv/apache-conf.d/apache_frontend.custom.conf
86 # * $PARTITION_PATH/srv/srv/apache-conf.d/apache_frontend.virtualhost.custom.conf
87 #
88 #The first one is included in the end of the main apache configuration file.
89 #The second one is included in the virtualhost of the main apache configuration file.
90 #
91 #SlapOS will jsut create those two files for you, then completely forget them.
92 #
93 #Note: make sure that the UNIX user of the instance has read access to those
94 #files if you edit them.
95
96 Instance Parameters
97 ===================
98
99 Master Instance Parameters
100 --------------------------
101
102 domain
103 ~~~~~~
104 name of the domain to be used (example: mydomain.com). Subdomains of this
105 domain will be used for the slave instances (example:
106 instance12345.mydomain.com). It is then recommended to add a wildcard in DNS
107 for the subdomains of the chosen domain like::
108   *.mydomain.com. IN A 123.123.123.123
109 Using the IP given by the Master Instance.
110 "domain" is a mandatory Parameter.
111
112 public-ipv4
113 ~~~~~~~~~~~
114 Public ipv4 of the frontend (the one Apache will be indirectly listening to)
115
116 port
117 ~~~~
118 Port used by Apache. Optional parameter, defaults to 4443.
119
120 plain_http_port
121 ~~~~~~~~~~~~~~~
122 Port used by apache to serve plain http (only used to redirect to https).
123 Optional parameter, defaults to 8080.
124
125 ip-read-limit
126 ~~~~~~~~~~~~~
127 Use to set IPReadLimit Parameter for antiloris.
128 Optional parameter, defaults to 10.
129
130 apache_custom_http (custom-group)
131 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
132 Jinja template for apache virtualhost http configuration. It will be used by all slaves
133
134 apache_custom_https (custom-group)
135 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
136 Jinja template for apache virtualhost https configuration. It will be used by all slaves
137
138
139 Slave Instance Parameters (default)
140 -----------------------------------
141
142 url
143 ~~~
144 url of backend to use.
145 "url" is a mandatory parameter.
146 Example: http://mybackend.com/myresource
147
148 enable_cache
149 ~~~~~
150 Specify if slave instance should use a squid to connect to backend.
151 Possible values: "true", "false".
152 "enable_cache" is an optional parameter. Defaults to "false".
153 Example: true
154
155 type
156 ~~~~
157 Specify if slave instance will redirect to a zope backend. If specified, Apache
158 RewriteRule will use Zope's Virtual Host Daemon.
159 Possible values: "zope", "default".
160 "type" is an optional parameter. Defaults to "default".
161 Example: zope
162
163 domain (former custom_domain)
164 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
165 Domain name to use as frontend. The frontend will be accessible from this domain.
166 "domain" is an optional parameter. Defaults to
167 [instancereference].[masterdomain].
168 Example: www.mycustomdomain.com
169
170 https-only
171 ~~~~~~~~~~
172 Specify if website should be accessed using https only. If so, the frontend
173 will redirect the user to https if accessed from http.
174 Possible values: "true", "false".
175 "https-only" is an optional parameter. Defaults to "false".
176 Example: true
177
178 path
179 ~~~~
180 Only used if type is "zope".
181
182 Will append the specified path to the "VirtualHostRoot" of the zope's
183 VirtualHostMonster.
184
185 "path" is an optional parameter, ignored if not specified.
186 Example of value: "/erp5/web_site_module/hosting/"
187
188 Slave Instance Parameters (custom-personal)
189 -------------------------------------------
190
191 apache_custom_https
192 ~~~~~~~~~~~~~~~~~~~
193 Raw apache configuration in python template format (i.e. write "%%" for one "%") for the slave listening to the https port. Its content will be templatified in order to access functionalities such as cache access, ssl certificates... The list is available above.
194 NOTE: If you want to use the cache, use the apache option "ProxyPreserveHost On"
195
196 apache_custom_http
197 ~~~~~~~~~~~~~~~~~~
198 Raw apache configuration in python template format (i.e. write "%%" for one "%") for the slave listening to the http port. Its content will be templatified in order to access functionalities such as cache access, ssl certificates... The list is available above
199 NOTE: If you want to use the cache, use the apache option "ProxyPreserveHost On"
200
201 url
202 ~~~
203 Necesarry to activate cache. url of backend to use.
204 "url" is an optional parameter.
205 Example: http://mybackend.com/myresource
206
207 domain
208 ~~~~~~
209 Necesarry to activate cache. The frontend will be accessible from this domain.
210 "domain" is an optional parameter.
211 Example: www.mycustomdomain.com
212
213 enable_cache
214 ~~~~~~~~~~~~
215 Necesarry to activate cache.
216 "enable_cache" is an optional parameter.
217
218 ssl_key, ssl_crt, ssl_ca_crt, ssl_crs
219 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
220 SSL certificates of the slave.
221 They are optional.
222
223 Functionalities for apache configuration:
224 In the slave apache configuration you can use parameters that will be replaced during instanciation. They should be entered as python templates parameters ex:" %(parameter)s"
225   * cache_access : url of the cache. Should replace backend url in configuration to use the cache
226   * error_log : path of the slave error log in order to log in a deferenciated file.
227   * error_log : path of the slave access log in order to log in a deferenciated file.
228   * ssl_key, ssl_crt, ssl_ca_crt, ssl_crs : path of the certificates given in slave instance parameters
229
230 Slave Instance Parameters (custom-group)
231 ----------------------------------------
232
233 url
234 ~~~
235 Necesarry to activate cache. url of backend to use.
236 "url" is an optional parameter.
237 Example: http://mybackend.com/myresource
238
239 domain
240 ~~~~~~
241 Domain name to use as frontend. The frontend will be accessible from this domain.
242 "domain" is an optional parameter necessary to activate cache. Defaults to
243 [instancereference].[masterdomain].
244 Example: www.mycustomdomain.com
245
246 The rest of the parameters are defined by templates given to the master and accessible by the slave_parameter dict in it.
247
248
249 Examples
250 ========
251
252 Here are some example of how to make your SlapOS service available through
253 an already deployed frontend.
254
255 Simple Example (default)
256 ------------------------
257
258 Request slave frontend instance so that https://[1:2:3:4:5:6:7:8]:1234 will be
259 redirected and accessible from the proxy::
260   instance = request(
261     software_release=apache_frontend,
262     software_type="RootSoftwareInstance",
263     partition_reference='my frontend',
264     shared=True,
265     partition_parameter_kw={
266         "url":"https://[1:2:3:4:5:6:7:8]:1234",
267     }
268   )
269
270
271 Zope Example (default)
272 ----------------------
273
274 Request slave frontend instance using a Zope backend so that
275 https://[1:2:3:4:5:6:7:8]:1234 will be redirected and accessible from the
276 proxy::
277   instance = request(
278     software_release=apache_frontend,
279     software_type="RootSoftwareInstance",
280     partition_reference='my frontend',
281     shared=True,
282     partition_parameter_kw={
283         "url":"https://[1:2:3:4:5:6:7:8]:1234",
284         "type":"zope",
285     }
286   )
287
288
289 Advanced example (default)
290 --------------------------
291
292 Request slave frontend instance using a Zope backend, with Varnish activated,
293 listening to a custom domain and redirecting to /erp5/ so that
294 https://[1:2:3:4:5:6:7:8]:1234/erp5/ will be redirected and accessible from
295 the proxy::
296   instance = request(
297     software_release=apache_frontend,
298     software_type="RootSoftwareInstance",
299     partition_reference='my frontend',
300     shared=True,
301     partition_parameter_kw={
302         "url":"https://[1:2:3:4:5:6:7:8]:1234",
303         "enable_cache":"true",
304         "type":"zope",
305         "path":"/erp5",
306         "domain":"mycustomdomain.com",
307     }
308   )
309
310 Simple Example (custom-personal)
311 --------------------------------
312
313 Request slave frontend instance so that https://[1:2:3:4:5:6:7:8]:1234 will be
314   instance = request(
315     software_release=apache_frontend,
316     software_type="RootSoftwareInstance",
317     partition_reference='my frontend',
318     shared=True,
319     software_type="custom-personal",
320     partition_parameter_kw={
321         "url":"https://[1:2:3:4:5:6:7:8]:1234",
322
323         "apache_custom_https":'
324   ServerName www.example.org
325   ServerAlias example.org
326   ServerAdmin geronimo@example.org
327   SSLEngine on
328   SSLProxyEngine on
329   # Rewrite part
330   ProxyVia On
331   ProxyPreserveHost On
332   ProxyTimeout 600
333   RewriteEngine On
334   RewriteRule ^/(.*) https://[1:2:3:4:5:6:7:8]:1234/$1 [L,P]',
335
336         "apache_custom_http":'
337   ServerName www.example.org
338   ServerAlias www.example.org
339   ServerAlias example.org
340   ServerAdmin geronimo@example.org
341   SSLProxyEngine on
342   # Rewrite part
343   ProxyVia On
344   ProxyPreserveHost On
345   ProxyTimeout 600
346   RewriteEngine On
347   # Remove "Secure" from cookies, as backend may be https
348   Header edit Set-Cookie "(?i)^(.+);secure$" "$1"
349   # Not using HTTPS? Ask that guy over there.
350   # Dummy redirection to https. Note: will work only if https listens
351   # on standard port (443).
352   RewriteRule ^/(.*) https://[1:2:3:4:5:6:7:8]:1234/$1 [L,P],
353     }
354   )
355
356 Simple Cache Example (custom-personal)
357 --------------------------------
358
359 Request slave frontend instance so that https://[1:2:3:4:5:6:7:8]:1234 will be
360   instance = request(
361     software_release=apache_frontend,
362     software_type="RootSoftwareInstance",
363     partition_reference='my frontend',
364     shared=True,
365     software_type="custom-personal",
366     partition_parameter_kw={
367         "url":"https://[1:2:3:4:5:6:7:8]:1234",
368         "domain": "www.example.org",
369         "enable_cache": "True",
370
371         "apache_custom_https":'
372   ServerName www.example.org
373   ServerAlias www.example.org
374   ServerAlias example.org
375   ServerAdmin geronimo@example.org
376   SSLEngine on
377   SSLProxyEngine on
378   # Rewrite part
379   ProxyVia On
380   ProxyPreserveHost On
381   ProxyTimeout 600
382   RewriteEngine On
383   RewriteRule ^/(.*) %(cache_access)s/$1 [L,P]',
384
385         "apache_custom_http":'
386   ServerName www.example.org
387   ServerAlias www.example.org
388   ServerAlias example.org
389   ServerAdmin geronimo@example.org
390   SSLProxyEngine on
391   # Rewrite part
392   ProxyVia On
393   ProxyPreserveHost On
394   ProxyTimeout 600
395   RewriteEngine On
396
397   # Remove "Secure" from cookies, as backend may be https
398   Header edit Set-Cookie "(?i)^(.+);secure$" "$1"
399
400   # Not using HTTPS? Ask that guy over there.
401   # Dummy redirection to https. Note: will work only if https listens
402   # on standard port (443).
403   RewriteRule ^/(.*) %(cache_access)s/$1 [L,P],
404     }
405   )
406
407
408 Advanced example (custom-personal)
409 ----------------------------------
410
411 Request slave frontend instance using custom apache configuration, willing to use cache and ssl certificates.
412 listening to a custom domain and redirecting to /erp5/ so that
413 https://[1:2:3:4:5:6:7:8]:1234/erp5/ will be redirected and accessible from
414 the proxy::
415   instance = request(
416     software_release=apache_frontend,
417     software_type="RootSoftwareInstance",
418     partition_reference='my frontend',
419     shared=True,
420     software_type="custom-personal",
421     partition_parameter_kw={
422         "url":"https://[1:2:3:4:5:6:7:8]:1234",
423         "enable_cache":"true",
424         "type":"zope",
425         "path":"/erp5",
426         "domain":"example.org",
427
428         "apache_custom_https":'
429   ServerName www.example.org
430   ServerAlias www.example.org
431   ServerAdmin example.org
432   SSLEngine on
433   SSLProxyEngine on
434   SSLProtocol -ALL +SSLv3 +TLSv1
435   SSLHonorCipherOrder On
436   SSLCipherSuite RC4-SHA:HIGH:!ADH
437   # Use personal ssl certificates
438   SSLCertificateFile %(ssl_crt)s
439   SSLCertificateKeyFile %(ssl_key)s
440   SSLCACertificateFile %(ssl_ca_crt)s
441   SSLCertificateChainFile %(ssl_ca_crt)s
442   # Configure personal logs
443   ErrorLog "%(error_log)s"
444   LogLevel info
445   LogFormat "%%h %%l %%{REMOTE_USER}i %%t \"%%r\" %%>s %%b \"%%{Referer}i\" \"%%{User-Agent}i\" %%D" combined
446   CustomLog "%(access_log)s" combined
447   # Rewrite part
448   ProxyVia On
449   ProxyPreserveHost On
450   ProxyTimeout 600
451   RewriteEngine On
452   # Redirect / to /index.html
453   RewriteRule ^/$ /index.html [R=302,L]
454   # Use cache
455   RewriteRule ^/(.*) %(cache_access)s/VirtualHostBase/https/www.example.org:443/erp5/VirtualHostRoot/$1 [L,P]',
456
457     "apache_custom_http":'
458   ServerName www.example.org
459   ServerAlias www.example.org
460   ServerAlias example.org
461   ServerAdmin geronimo@example.org
462   SSLProxyEngine on
463   # Rewrite part
464   ProxyVia On
465   ProxyPreserveHost On
466   ProxyTimeout 600
467   RewriteEngine On
468   # Configure personal logs
469   ErrorLog "%(error_log)s"
470   LogLevel info
471   LogFormat "%%h %%l %%{REMOTE_USER}i %%t \"%%r\" %%>s %%b \"%%{Referer}i\" \"%%{User-Agent}i\" %%D" combined
472   CustomLog "%(access_log)s" combined
473   # Remove "Secure" from cookies, as backend may be https
474   Header edit Set-Cookie "(?i)^(.+);secure$" "$1"
475   # Not using HTTPS? Ask that guy over there.
476   # Dummy redirection to https. Note: will work only if https listens
477   # on standard port (443).
478   RewriteRule ^/(.*)$ https://%%{SERVER_NAME}%%{REQUEST_URI}',
479
480     "ssl_key":"-----BEGIN RSA PRIVATE KEY-----
481 XXXXXXX..........XXXXXXXXXXXXXXX
482 -----END RSA PRIVATE KEY-----",
483     "ssl_crt":'-----BEGIN CERTIFICATE-----
484 XXXXXXXXXXX.............XXXXXXXXXXXXXXXXXXX
485 -----END CERTIFICATE-----',
486     "ssl_ca_crt":'-----BEGIN CERTIFICATE-----
487 XXXXXXXXX...........XXXXXXXXXXXXXXXXX
488 -----END CERTIFICATE-----',
489     "ssl_csr":'-----BEGIN CERTIFICATE REQUEST-----
490 XXXXXXXXXXXXXXX.............XXXXXXXXXXXXXXXXXX
491 -----END CERTIFICATE REQUEST-----',
492     }
493   )
494
495 Notes
496 =====
497
498 It is not possible with slapos to listen to port <= 1024, because process are
499 not run as root.
500
501 Solution 1 (IPv4 only)
502 ----------------------
503
504 It is a good idea then to go on the node where the instance is
505 and set some iptables rules like (if using default ports)::
506
507   iptables -t nat -A PREROUTING -p tcp -d {public_ipv4} --dport 443 -j DNAT --to-destination {listening_ipv4}:4443
508   iptables -t nat -A PREROUTING -p tcp -d {public_ipv4} --dport 80 -j DNAT --to-destination {listening_ipv4}:8080
509
510 Where {public ip} is the public IP of your server, or at least the LAN IP to where your NAT will forward to.
511 {listening ip} is the private ipv4 (like 10.0.34.123) that the instance is using and sending as connection parameter.
512
513 Solution 2 (IPv6 only)
514 ----------------------
515
516 It is also possible to directly allow the service to listen on 80 and 443 ports using the following command:
517
518   setcap 'cap_net_bind_service=+ep' /opt/slapgrid/$APACHE_FRONTEND_SOFTWARE_RELEASE_MD5/parts/apache-2.2/bin/httpd
519
520 Then specify in the instance parameters "port" and "plain_http_port" to be 443 and 80, respectively.