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