]> git.immae.eu Git - github/shaarli/Shaarli.git/blame_incremental - doc/md/Server-configuration.md
Merge pull request #1361 from Lucas-C/patch-1
[github/shaarli/Shaarli.git] / doc / md / Server-configuration.md
... / ...
CommitLineData
1
2- [Prerequisites](#prerequisistes)
3- [Apache](#apache)
4- [Nginx](#nginx)
5- [Proxies](#proxies)
6- [See also](#see-also)
7
8## Prerequisites
9### Shaarli
10
11- A web server and PHP interpreter module/service have been installed.
12- You have write access to the Shaarli installation directory.
13- The correct read/write permissions have been granted to the web server user and group.
14- Your PHP interpreter is compatible with supported PHP versions:
15
16Version | Status | Shaarli compatibility
17:---:|:---:|:---:
187.2 | Supported | Yes
197.1 | Supported | Yes
207.0 | EOL: 2018-12-03 | Yes (up to Shaarli 0.10.x)
215.6 | EOL: 2018-12-31 | Yes (up to Shaarli 0.10.x)
225.5 | EOL: 2016-07-10 | Yes
235.4 | EOL: 2015-09-14 | Yes (up to Shaarli 0.8.x)
245.3 | EOL: 2014-08-14 | Yes (up to Shaarli 0.8.x)
25
26- The following PHP extensions are installed on the server:
27
28Extension | Required? | Usage
29---|:---:|---
30[`openssl`](http://php.net/manual/en/book.openssl.php) | All | OpenSSL, HTTPS
31[`php-mbstring`](http://php.net/manual/en/book.mbstring.php) | CentOS, Fedora, RHEL, Windows, some hosting providers | multibyte (Unicode) string support
32[`php-gd`](http://php.net/manual/en/book.image.php) | optional | required to use thumbnails
33[`php-intl`](http://php.net/manual/en/book.intl.php) | optional | localized text sorting (e.g. `e->รจ->f`)
34[`php-curl`](http://php.net/manual/en/book.curl.php) | optional | using cURL for fetching webpages and thumbnails in a more robust way
35[`php-gettext`](http://php.net/manual/en/book.gettext.php) | optional | Use the translation system in gettext mode (faster)
36
37--------------------------------------------------------------------------------
38
39### SSL/TLS configuration
40
41To setup HTTPS / SSL on your webserver (recommended), you must generate a public/private **key pair** and a **certificate**, and install, configure and activate the appropriate **webserver SSL extension**.
42
43#### Let's Encrypt
44
45[Let's Encrypt](https://en.wikipedia.org/wiki/Let%27s_Encrypt) is a certificate authority that provides free TLS/X.509 certificates via an automated process.
46
47 * Install `certbot` using the appropriate method described on https://certbot.eff.org/.
48
49Location of the `certbot` program and template configuration files may vary depending on which installation method was used. Change the file paths below accordingly. Here is an easy way to create a signed certificate using `certbot`, it assumes `certbot` was installed through APT on a Debian-based distribution:
50
51 * Stop the apache2/nginx service.
52 * Run `certbot --agree-tos --standalone --preferred-challenges tls-sni --email "youremail@example.com" --domain yourdomain.example.com`
53 * For the Apache webserver, copy `/usr/lib/python2.7/dist-packages/certbot_apache/options-ssl-apache.conf` to `/etc/letsencrypt/options-ssl-apache.conf` (paths may vary depending on installation method)
54 * For Nginx: TODO
55 * Setup your webserver as described below
56 * Restart the apache2/nginx service.
57
58#### Self-signed certificates
59
60If you don't want to request a certificate from Let's Encrypt, or are unable to (for example, webserver on a LAN, or domain name not registered in the public DNS system), you can generate a self-signed certificate. This certificate will trigger security warnings in web browsers, unless you add it to the browser's SSL store manually.
61
62* Apache: run `make-ssl-cert generate-default-snakeoil --force-overwrite`
63* Nginx: TODO
64
65--------------------------------------------------------------------------------
66
67## Apache
68
69Here is a basic configuration example for the Apache web server with `mod_php`.
70
71In `/etc/apache2/sites-available/shaarli.conf`:
72
73```apache
74<VirtualHost *:443>
75 ServerName shaarli.my-domain.org
76 DocumentRoot /absolute/path/to/shaarli/
77
78 # Logging
79 # Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
80 LogLevel warn
81 ErrorLog /var/log/apache2/shaarli-error.log
82 CustomLog /var/log/apache2/shaarli-access.log combined
83
84 # Let's Encrypt SSL configuration (recommended)
85 SSLEngine on
86 SSLCertificateFile /etc/letsencrypt/live/yourdomain.example.com/fullchain.pem
87 SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.example.com/privkey.pem
88 Include /etc/letsencrypt/options-ssl-apache.conf
89
90 # Self-signed SSL cert configuration
91 #SSLEngine on
92 #SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
93 #SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
94
95 # Optional, log PHP errors, useful for debugging
96 #php_flag log_errors on
97 #php_flag display_errors on
98 #php_value error_reporting 2147483647
99 #php_value error_log /var/log/apache2/shaarli-php-error.log
100
101 <Directory /absolute/path/to/shaarli/>
102 #Required for .htaccess support
103 AllowOverride All
104 Order allow,deny
105 Allow from all
106
107 Options Indexes FollowSymLinks MultiViews #TODO is Indexes/Multiviews required?
108
109 # Optional - required for playvideos plugin
110 #Header set Content-Security-Policy "script-src 'self' 'unsafe-inline' https://www.youtube.com https://s.ytimg.com 'unsafe-eval'"
111 </Directory>
112
113</VirtualHost>
114```
115
116Enable this configuration with `sudo a2ensite shaarli`
117
118_Note: If you use Apache 2.2 or lower, you need [mod_version](https://httpd.apache.org/docs/current/mod/mod_version.html) to be installed and enabled._
119
120_Note: Apache module `mod_rewrite` must be enabled to use the REST API._
121
122
123## Nginx
124
125Here is a basic configuration example for the Nginx web server, using the [php-fpm](http://php-fpm.org) PHP FastCGI Process Manager, and Nginx's [FastCGI](https://en.wikipedia.org/wiki/FastCGI) module.
126
127<!--- TODO refactor everything below this point --->
128
129### Common setup
130Once Nginx and PHP-FPM are installed, we need to ensure:
131
132- Nginx and PHP-FPM are running using the _same user and group_
133- both these user and group have
134 - `read` permissions for Shaarli resources
135 - `execute` permissions for Shaarli directories _AND_ their parent directories
136
137On a production server:
138
139- `user:group` will likely be `http:http`, `www:www` or `www-data:www-data`
140- files will be located under `/var/www`, `/var/http` or `/usr/share/nginx`
141
142On a development server:
143
144- files may be located in a user's home directory
145- in this case, make sure both Nginx and PHP-FPM are running as the local user/group!
146
147For all following configuration examples, this user/group pair will be used:
148
149- `user:group = john:users`,
150
151which corresponds to the following service configuration:
152
153```ini
154; /etc/php/php-fpm.conf
155user = john
156group = users
157
158[...]
159listen.owner = john
160listen.group = users
161```
162
163```nginx
164# /etc/nginx/nginx.conf
165user john users;
166
167http {
168 [...]
169}
170```
171
172### (Optional) Increase the maximum file upload size
173Some bookmark dumps generated by web browsers can be _huge_ due to the presence of Base64-encoded images and favicons, as well as extra verbosity when nesting links in (sub-)folders.
174
175To increase upload size, you will need to modify both nginx and PHP configuration:
176
177```nginx
178# /etc/nginx/nginx.conf
179
180http {
181 [...]
182
183 client_max_body_size 10m;
184
185 [...]
186}
187```
188
189```ini
190# /etc/php5/fpm/php.ini
191
192[...]
193post_max_size = 10M
194[...]
195upload_max_filesize = 10M
196```
197
198### Minimal
199_WARNING: Use for development only!_
200
201```nginx
202user john users;
203worker_processes 1;
204events {
205 worker_connections 1024;
206}
207
208http {
209 include mime.types;
210 default_type application/octet-stream;
211 keepalive_timeout 20;
212
213 index index.html index.php;
214
215 server {
216 listen 80;
217 server_name localhost;
218 root /home/john/web;
219
220 access_log /var/log/nginx/access.log;
221 error_log /var/log/nginx/error.log;
222
223 location /shaarli/ {
224 try_files $uri /shaarli/index.php$is_args$args;
225 access_log /var/log/nginx/shaarli.access.log;
226 error_log /var/log/nginx/shaarli.error.log;
227 }
228
229 location ~ (index)\.php$ {
230 try_files $uri =404;
231 fastcgi_split_path_info ^(.+\.php)(/.+)$;
232 fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
233 fastcgi_index index.php;
234 include fastcgi.conf;
235 }
236 }
237}
238```
239
240### Modular
241The previous setup is sufficient for development purposes, but has several major caveats:
242
243- every content that does not match the PHP rule will be sent to client browsers:
244 - dotfiles - in our case, `.htaccess`
245 - temporary files, e.g. Vim or Emacs files: `index.php~`
246- asset / static resource caching is not optimized
247- if serving several PHP sites, there will be a lot of duplication: `location /shaarli/`, `location /mysite/`, etc.
248
249To solve this, we will split Nginx configuration in several parts, that will be included when needed:
250
251```nginx
252# /etc/nginx/deny.conf
253location ~ /\. {
254 # deny access to dotfiles
255 access_log off;
256 log_not_found off;
257 deny all;
258}
259
260location ~ ~$ {
261 # deny access to temp editor files, e.g. "script.php~"
262 access_log off;
263 log_not_found off;
264 deny all;
265}
266```
267
268```nginx
269# /etc/nginx/php.conf
270location ~ (index)\.php$ {
271 # Slim - split URL path into (script_filename, path_info)
272 try_files $uri =404;
273 fastcgi_split_path_info ^(.+\.php)(/.+)$;
274
275 # filter and proxy PHP requests to PHP-FPM
276 fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
277 fastcgi_index index.php;
278 include fastcgi.conf;
279}
280
281location ~ \.php$ {
282 # deny access to all other PHP scripts
283 deny all;
284}
285```
286
287```nginx
288# /etc/nginx/static_assets.conf
289location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
290 expires max;
291 add_header Pragma public;
292 add_header Cache-Control "public, must-revalidate, proxy-revalidate";
293}
294```
295
296```nginx
297# /etc/nginx/nginx.conf
298[...]
299
300http {
301 [...]
302
303 root /home/john/web;
304 access_log /var/log/nginx/access.log;
305 error_log /var/log/nginx/error.log;
306
307 server {
308 # virtual host for a first domain
309 listen 80;
310 server_name my.first.domain.org;
311
312 location /shaarli/ {
313 # Slim - rewrite URLs
314 try_files $uri /shaarli/index.php$is_args$args;
315
316 access_log /var/log/nginx/shaarli.access.log;
317 error_log /var/log/nginx/shaarli.error.log;
318 }
319
320 location = /shaarli/favicon.ico {
321 # serve the Shaarli favicon from its custom location
322 alias /var/www/shaarli/images/favicon.ico;
323 }
324
325 include deny.conf;
326 include static_assets.conf;
327 include php.conf;
328 }
329
330 server {
331 # virtual host for a second domain
332 listen 80;
333 server_name second.domain.com;
334
335 location /minigal/ {
336 access_log /var/log/nginx/minigal.access.log;
337 error_log /var/log/nginx/minigal.error.log;
338 }
339
340 include deny.conf;
341 include static_assets.conf;
342 include php.conf;
343 }
344}
345```
346
347### Redirect HTTP to HTTPS
348Assuming you have generated a (self-signed) key and certificate, and they are
349located under `/home/john/ssl/localhost.{key,crt}`, it is pretty straightforward
350to set an HTTP (:80) to HTTPS (:443) redirection to force SSL/TLS usage.
351
352```nginx
353# /etc/nginx/nginx.conf
354[...]
355
356http {
357 [...]
358
359 index index.html index.php;
360
361 root /home/john/web;
362 access_log /var/log/nginx/access.log;
363 error_log /var/log/nginx/error.log;
364
365 server {
366 listen 80;
367 server_name localhost;
368
369 return 301 https://localhost$request_uri;
370 }
371
372 server {
373 listen 443 ssl;
374 server_name localhost;
375
376 ssl_certificate /home/john/ssl/localhost.crt;
377 ssl_certificate_key /home/john/ssl/localhost.key;
378
379 location /shaarli/ {
380 # Slim - rewrite URLs
381 try_files $uri /index.php$is_args$args;
382
383 access_log /var/log/nginx/shaarli.access.log;
384 error_log /var/log/nginx/shaarli.error.log;
385 }
386
387 location = /shaarli/favicon.ico {
388 # serve the Shaarli favicon from its custom location
389 alias /var/www/shaarli/images/favicon.ico;
390 }
391
392 include deny.conf;
393 include static_assets.conf;
394 include php.conf;
395 }
396}
397```
398
399## Proxies
400
401If Shaarli is served behind a proxy (i.e. there is a proxy server between clients and the web server hosting Shaarli), please refer to the proxy server documentation for proper configuration. In particular, you have to ensure that the following server variables are properly set:
402
403- `X-Forwarded-Proto`
404- `X-Forwarded-Host`
405- `X-Forwarded-For`
406
407In you [Shaarli configuration](Shaarli-configuration) `data/config.json.php`, add the public IP of your proxy under `security.trusted_proxies`.
408
409See also [proxy-related](https://github.com/shaarli/Shaarli/issues?utf8=%E2%9C%93&q=label%3Aproxy+) issues.
410
411## Robots and crawlers
412
413Shaarli disallows indexing and crawling of your local documentation pages by search engines, using `<meta name="robots">` HTML tags.
414Your Shaarli instance and other pages you host may still be indexed by various robots on the public Internet.
415You may want to setup a robots.txt file or other crawler control mechanism on your server.
416See [[1]](https://en.wikipedia.org/wiki/Robots_exclusion_standard), [[2]](https://support.google.com/webmasters/answer/6062608?hl=en) and [[3]](https://developers.google.com/search/reference/robots_meta_tag)
417
418## See also
419
420 * [Server security](Server-security.md)
421
422#### Webservers
423
424- [Apache/PHP - error log per VirtualHost](http://stackoverflow.com/q/176) (StackOverflow)
425- [Apache - PHP: php_value vs php_admin_value and the use of php_flag explained](https://ma.ttias.be/php-php_value-vs-php_admin_value-and-the-use-of-php_flag-explained/)
426- [Server-side TLS (Apache)](https://wiki.mozilla.org/Security/Server_Side_TLS#Apache) (Mozilla)
427- [Nginx Beginner's guide](http://nginx.org/en/docs/beginners_guide.html)
428- [Nginx ngx_http_fastcgi_module](http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html)
429- [Nginx Pitfalls](http://wiki.nginx.org/Pitfalls)
430- [Nginx PHP configuration examples](http://kbeezie.com/nginx-configuration-examples/) (Karl Blessing)
431- [Server-side TLS (Nginx)](https://wiki.mozilla.org/Security/Server_Side_TLS#Nginx) (Mozilla)
432- [How to Create Self-Signed SSL Certificates with OpenSSL](http://www.xenocafe.com/tutorials/linux/centos/openssl/self_signed_certificates/index.php)
433- [How do I create my own Certificate Authority?](https://workaround.org/certificate-authority)
434
435#### PHP
436
437- [Travis configuration](https://github.com/shaarli/Shaarli/blob/master/.travis.yml)
438- [PHP: Supported versions](http://php.net/supported-versions.php)
439- [PHP: Unsupported versions](http://php.net/eol.php) _(EOL - End Of Life)_
440- [PHP 7 Changelog](http://php.net/ChangeLog-7.php)
441- [PHP 5 Changelog](http://php.net/ChangeLog-5.php)
442- [PHP: Bugs](https://bugs.php.net/)