]> git.immae.eu Git - github/shaarli/Shaarli.git/blame - doc/md/Server-configuration.md
fix markdown syntax
[github/shaarli/Shaarli.git] / doc / md / Server-configuration.md
CommitLineData
91a21c27 1# Server configuration
992af0b9 2
992af0b9 3
992af0b9 4
91a21c27 5## Requirements
6
7### Operating system and web server
8
9Shaarli can be hosted on dedicated/virtual servers, or shared hosting. The smallest DigitalOcean VPS (Droplet with 1 CPU, 1 GiB RAM and 25 GiB SSD) costs about $5/month and will run any Shaarli installation without problems.
10
11You need write access to the Shaarli installation directory - you should have received instructions from your hosting provider on how to connect to the server using SSH (or FTP for shared hosts).
12
13Examples in this documentation are given for [Debian](https://www.debian.org/), a GNU/Linux distribution widely used in server environments. Please adapt them to your specific Linux distribution.
14
15### Network and domain name
16
17Try to host the server in a region that is geographically close to your users.
18
a32e6665 19A **domain name** ([DNS record](https://opensource.com/article/17/4/introduction-domain-name-system-dns)) pointing to the server's public IP address is required to obtain a SSL/TLS certificate and setup HTTPS to secure client traffic to your Shaarli instance.
91a21c27 20
6384447d 21You can obtain a domain name from a [registrar](https://en.wikipedia.org/wiki/Domain_name_registrar) ([1](https://www.ovh.co.uk/domains), [2](https://www.gandi.net/en/domain)), or from free subdomain providers ([1](https://freedns.afraid.org/)). If you don't have a domain name, please set up a private domain name ([FQDN](ttps://en.wikipedia.org/wiki/Fully_qualified_domain_name)) in your clients' [hosts files](https://en.wikipedia.org/wiki/Hosts_(file)) to access the server (direct access by IP address can result in unexpected behavior).
91a21c27 22
23
24### PHP
25
26Supported PHP versions:
43ad7c8e 27
bdfb967c 28Version | Status | Shaarli compatibility
29:---:|:---:|:---:
307.2 | Supported | Yes
317.1 | Supported | Yes
899d0411 327.0 | EOL: 2018-12-03 | Yes (up to Shaarli 0.10.x)
7062ef4d 335.6 | EOL: 2018-12-31 | Yes (up to Shaarli 0.10.x)
bdfb967c 345.5 | EOL: 2016-07-10 | Yes
355.4 | EOL: 2015-09-14 | Yes (up to Shaarli 0.8.x)
365.3 | EOL: 2014-08-14 | Yes (up to Shaarli 0.8.x)
5409ade2 37
91a21c27 38Required PHP extensions:
43ad7c8e 39
bdfb967c 40Extension | Required? | Usage
41---|:---:|---
42[`openssl`](http://php.net/manual/en/book.openssl.php) | All | OpenSSL, HTTPS
3575fe5b 43[`php-json`](http://php.net/manual/en/book.json.php) | required | configuration parsing
bdfb967c 44[`php-mbstring`](http://php.net/manual/en/book.mbstring.php) | CentOS, Fedora, RHEL, Windows, some hosting providers | multibyte (Unicode) string support
787faa42 45[`php-gd`](http://php.net/manual/en/book.image.php) | optional | required to use thumbnails
bdfb967c 46[`php-intl`](http://php.net/manual/en/book.intl.php) | optional | localized text sorting (e.g. `e->รจ->f`)
47[`php-curl`](http://php.net/manual/en/book.curl.php) | optional | using cURL for fetching webpages and thumbnails in a more robust way
48[`php-gettext`](http://php.net/manual/en/book.gettext.php) | optional | Use the translation system in gettext mode (faster)
992af0b9 49
91a21c27 50Some [plugins](Plugins.md) may require additional configuration.
51
52
53## SSL/TLS (HTTPS)
992af0b9 54
91a21c27 55We recommend setting up [HTTPS](https://en.wikipedia.org/wiki/HTTPS) on your webserver for secure communication between clients and the server.
43ad7c8e 56
91a21c27 57For public-facing web servers this can be done using free SSL/TLS certificates from [Let's Encrypt](https://en.wikipedia.org/wiki/Let's_Encrypt), a non-profit certificate authority provididing free certificates.
992af0b9 58
91a21c27 59 - [How to secure Apache with Let's Encrypt](https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-debian-10)
60 - [How to secure Nginx with Let's Encrypt](https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-debian-10)
61 - [How To Use Certbot Standalone Mode to Retrieve Let's Encrypt SSL Certificates](https://www.digitalocean.com/community/tutorials/how-to-use-certbot-standalone-mode-to-retrieve-let-s-encrypt-ssl-certificates-on-debian-10).
992af0b9 62
91a21c27 63In short:
992af0b9 64
91a21c27 65```bash
66# install certbot
67sudo apt install certbot
bdfb967c 68
91a21c27 69# stop your webserver if you already have one running
70# certbot in standalone mode needs to bind to port 80 (only needed on initial generation)
71sudo systemctl stop apache2
72sudo systemctl stop nginx
bdfb967c 73
91a21c27 74# generate initial certificates - Let's Encrypt ACME servers must be able to access your server!
75# (DNS records must be correctly pointing to it, firewall/NAT on port 80/443 must be open)
76sudo certbot certonly --standalone --noninteractive --agree-tos --email "admin@shaarli.mydomain.org" -d shaarli.mydomain.org
77# this will generate a private key and certificate at /etc/letsencrypt/live/shaarli.mydomain.org/{privkey,fullchain}.pem
bdfb967c 78
91a21c27 79# restart the web server
80sudo systemctl start apache2
81sudo systemctl start nginx
82```
83
84If you don't want to rely on a certificate authority, or the server can only be accessed from your own network, you can also generate self-signed certificates. Not that this will generate security warnings in web browsers/clients trying to access Shaarli:
85
86- [How To Create a Self-Signed SSL Certificate for Apache](https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-apache-on-debian-10)
87- [How To Create a Self-Signed SSL Certificate for Nginx](https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-nginx-on-debian-10)
bdfb967c 88
89--------------------------------------------------------------------------------
90
91a21c27 91## Examples
92
93The following examples assume a Debian-based operating system is installed. On other distributions you may have to adapt details such as package installation procedures, configuration file locations, and webserver username/group (`www-data` or `httpd` are common values).
94
95In these examples we assume the document root for your web server/virtualhost is at `/var/www/shaarli.mydomain.org/`:
96
97```bash
98sudo mkdir -p /var/www/shaarli.mydomain.org/
99```
100
101You can install Shaarli at the root of your virtualhost, or in a subdirectory as well. See [Directory structure](Directory-structure)
102
bdfb967c 103
91a21c27 104### Apache
bdfb967c 105
91a21c27 106```bash
107# Install apache + mod_php and PHP modules
108sudo apt update
109sudo apt install apache2 libapache2-mod-php php-json php-mbstring php-gd php-intl php-curl php-gettext
110
111# Edit the virtualhost configuration file with your favorite editor
112sudo nano /etc/apache2/sites-available/shaarli.mydomain.org.conf
113```
992af0b9 114
992af0b9 115```apache
91a21c27 116<VirtualHost *:80>
117 ServerName shaarli.mydomain.org
118 DocumentRoot /var/www/shaarli.mydomain.org/
119
120 # Log level. Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
121 LogLevel warn
122 # Log file locations
123 ErrorLog /var/log/apache2/error.log
124 CustomLog /var/log/apache2/access.log combined
125
126 # Redirect HTTP requests to HTTPS
127 RewriteEngine on
128 RewriteRule ^.well-known/acme-challenge/ - [L]
129 # except for Let's Encrypt ACME challenge requests
130 RewriteCond %{HTTP_HOST} =shaarli.mydomain.org
131 RewriteRule ^ https://shaarli.mydomain.org%{REQUEST_URI} [END,NE,R=permanent]
132</VirtualHost>
133
bdfb967c 134<VirtualHost *:443>
91a21c27 135 ServerName shaarli.mydomain.org
136 DocumentRoot /var/www/shaarli.mydomain.org/
992af0b9 137
91a21c27 138 # Log level. Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
992af0b9 139 LogLevel warn
91a21c27 140 # Log file locations
141 ErrorLog /var/log/apache2/error.log
142 CustomLog /var/log/apache2/access.log combined
992af0b9 143
91a21c27 144 # SSL/TLS configuration (for Let's Encrypt certificates)
bdfb967c 145 SSLEngine on
91a21c27 146 SSLCertificateFile /etc/letsencrypt/live/shaarli.mydomain.org/fullchain.pem
147 SSLCertificateKeyFile /etc/letsencrypt/live/shaarli.mydomain.org/privkey.pem
bdfb967c 148 Include /etc/letsencrypt/options-ssl-apache.conf
992af0b9 149
91a21c27 150 # SSL/TLS configuration (for self-signed certificates)
bdfb967c 151 #SSLEngine on
152 #SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
153 #SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
992af0b9 154
bdfb967c 155 # Optional, log PHP errors, useful for debugging
156 #php_flag log_errors on
157 #php_flag display_errors on
158 #php_value error_reporting 2147483647
159 #php_value error_log /var/log/apache2/shaarli-php-error.log
992af0b9 160
91a21c27 161 <Directory /var/www/shaarli.mydomain.org/>
162 # Required for .htaccess support
992af0b9 163 AllowOverride All
992af0b9 164 Order allow,deny
bdfb967c 165 Allow from all
bdfb967c 166 </Directory>
992af0b9 167
91a21c27 168 <LocationMatch "/\.">
169 # Prevent accessing dotfiles
170 RedirectMatch 404 ".*"
171 </LocationMatch>
3cc8c898 172
91a21c27 173 <LocationMatch "\.(?:ico|css|js|gif|jpe?g|png)$">
174 # allow client-side caching of static files
175 Header set Cache-Control "max-age=2628000, public, must-revalidate, proxy-revalidate"
176 </LocationMatch>
3cc8c898 177
91a21c27 178 # serve the Shaarli favicon from its custom location
179 Alias favicon.ico /var/www/shaarli.mydomain.org/images/favicon.ico
992af0b9 180
91a21c27 181</VirtualHost>
182```
43ad7c8e 183
91a21c27 184```bash
185# Enable the virtualhost
186sudo a2ensite shaarli
992af0b9 187
91a21c27 188# mod_ssl must be enabled to use TLS/SSL certificates
189# https://httpd.apache.org/docs/current/mod/mod_ssl.html
190sudo a2enmod ssl
992af0b9 191
91a21c27 192# mod_rewrite must be enabled to use the REST API
193# https://httpd.apache.org/docs/current/mod/mod_rewrite.html
194sudo a2enmod rewrite
43ad7c8e 195
91a21c27 196# mod_version must only be enabled if you use Apache 2.2 or lower
197# https://httpd.apache.org/docs/current/mod/mod_version.html
198# sudo a2enmod version
992af0b9 199
91a21c27 200# restart the apache service
201systemctl restart apache
202```
43ad7c8e 203
91a21c27 204See [How to install the Apache web server](https://www.digitalocean.com/community/tutorials/how-to-install-the-apache-web-server-on-debian-10) for a complete guide.
992af0b9 205
91a21c27 206### Nginx
43ad7c8e 207
91a21c27 208Guide on setting up the Nginx web server: [How to install the Nginx web server](https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-debian-10)
992af0b9 209
91a21c27 210You will also need to install the [PHP-FPM](http://php-fpm.org) interpreter as detailed [here](https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mariadb-php-lemp-stack-on-debian-10#step-3-%E2%80%94-installing-php-for-processing). Nginx and PHP-FPM must be running using the same user and group, here we assume the user/group to be `www-data:www-data` but this may vary depending on your Linux distribution.
43ad7c8e 211
992af0b9 212
91a21c27 213```bash
214# install nginx and php-fpm
215sudo apt update
216sudo apt install nginx php-fpm
992af0b9 217
91a21c27 218# Edit the virtualhost configuration file with your favorite editor
219sudo nano /etc/nginx/sites-available/shaarli.mydomain.org
992af0b9
V
220```
221
222```nginx
91a21c27 223server {
224 listen 80;
225 server_name shaarli.mydomain.org;
992af0b9 226
91a21c27 227 # redirect all plain HTTP requests to HTTPS
228 return 301 https://shaarli.mydomain.org$request_uri;
992af0b9 229}
992af0b9 230
91a21c27 231server {
232 listen 443 ssl;
233 server_name shaarli.mydomain.org;
234 root /var/www/shaarli.mydomain.org;
3cc8c898 235
91a21c27 236 # log file locations
237 # combined log format prepends the virtualhost/domain name to log entries
238 access_log /var/log/nginx/access.log combined;
239 error_log /var/log/nginx/error.log;
3cc8c898 240
91a21c27 241 # paths to private key and certificates for SSL/TLS
242 ssl_certificate /etc/ssl/shaarli.mydomain.org.crt;
243 ssl_certificate_key /etc/ssl/private/shaarli.mydomain.org.key;
992af0b9 244
91a21c27 245 # increase the maximum file upload size if needed: by default nginx limits file upload to 1MB (413 Entity Too Large error)
246 client_max_body_size 100m;
992af0b9 247
91a21c27 248 # relative path to shaarli from the root of the webserver
249 location / {
250 # default index file when no file URI is requested
251 index index.php;
252 try_files $uri /index.php$is_args$args;
992af0b9 253 }
992af0b9 254
91a21c27 255 location ~ (index)\.php$ {
256 try_files $uri =404;
257 # slim API - split URL path into (script_filename, path_info)
258 fastcgi_split_path_info ^(.+\.php)(/.+)$;
259 # pass PHP requests to PHP-FPM
260 fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
261 fastcgi_index index.php;
262 include fastcgi.conf;
263 }
43ad7c8e 264
91a21c27 265 location ~ \.php$ {
266 # deny access to all other PHP scripts
267 # disable this if you host other PHP applications on the same virtualhost
268 deny all;
269 }
992af0b9 270
91a21c27 271 location ~ /\. {
272 # deny access to dotfiles
273 deny all;
274 }
992af0b9 275
91a21c27 276 location ~ ~$ {
277 # deny access to temp editor files, e.g. "script.php~"
278 deny all;
279 }
992af0b9 280
91a21c27 281 location = /favicon.ico {
282 # serve the Shaarli favicon from its custom location
283 alias /var/www/shaarli/images/favicon.ico;
284 }
992af0b9 285
91a21c27 286 # allow client-side caching of static files
287 location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
288 expires max;
289 add_header Cache-Control "public, must-revalidate, proxy-revalidate";
290 # HTTP 1.0 compatibility
291 add_header Pragma public;
292 }
f8b936e7 293
f8b936e7 294}
992af0b9
V
295```
296
91a21c27 297```bash
298# enable the configuration/virtualhost
299sudo ln -s /etc/nginx/sites-available/shaarli.mydomain.org /etc/nginx/sites-enabled/shaarli.mydomain.org
300# reload nginx configuration
301sudo systemctl reload nginx
992af0b9
V
302```
303
992af0b9 304
91a21c27 305## Reverse proxies
992af0b9 306
91a21c27 307If Shaarli is hosted on a server behind a [reverse proxy](https://en.wikipedia.org/wiki/Reverse_proxy) (i.e. there is a proxy server between clients and the web server hosting Shaarli), configure it accordingly. See [Reverse proxy](Reverse-proxy.md) configuration.
b230bf20 308
992af0b9 309
3cc8c898 310
91a21c27 311## Allow import of large browser bookmarks export
992af0b9 312
91a21c27 313Web browser bookmark exports can be large due to the presence of base64-encoded images and favicons/long subfolder names. Edit the PHP configuration file.
992af0b9 314
91a21c27 315- Apache: `/etc/php/<PHP_VERSION>/apache2/php.ini`
316- Nginx + PHP-FPM: `/etc/php/<PHP_VERSION>/fpm/php.ini` (in addition to `client_max_body_size` in the [Nginx configuration](#nginx))
992af0b9 317
91a21c27 318```ini
53ed6d7d 319[...]
91a21c27 320# (optional) increase the maximum file upload size:
321post_max_size = 100M
322[...]
323# (optional) increase the maximum file upload size:
324upload_max_filesize = 100M
325```
992af0b9 326
91a21c27 327To verify PHP settings currently set on the server, create a `phpinfo.php` in your webserver's document root
992af0b9 328
91a21c27 329```bash
330# example
331echo '<?php phpinfo(); ?>' | sudo tee /var/www/shaarli.mydomain.org/phpinfo.php
332#give read-only access to this file to the webserver user
333sudo chown www-data:root /var/www/shaarli.mydomain.org/phpinfo.php
334sudo chmod 0400 /var/www/shaarli.mydomain.org/phpinfo.php
335```
992af0b9 336
91a21c27 337Access the file from a web browser (eg. <https://shaarli.mydomain.org/phpinfo.php> and look at the _Loaded Configuration File_ and _Scan this dir for additional .ini files_ entries
992af0b9 338
91a21c27 339It is recommended to remove the `phpinfo.php` when no longer needed as it publicly discloses details about your webserver configuration.
992af0b9 340
b230bf20 341
91a21c27 342## Robots and crawlers
992af0b9 343
91a21c27 344To opt-out of indexing your Shaarli instance by search engines, create a `robots.txt` file at the root of your virtualhost:
3cc8c898 345
91a21c27 346```
347User-agent: *
348Disallow: /
992af0b9 349```
bdfb967c 350
91a21c27 351By default Shaarli already disallows indexing of your local copy of the documentation by default, using `<meta name="robots">` HTML tags. Your Shaarli instance may still be indexed by various robots on the public Internet, that do not respect this header or the robots standard.
bdfb967c 352
91a21c27 353- [Robots exclusion standard](https://en.wikipedia.org/wiki/Robots_exclusion_standard)
354- [Introduction to robots.txt](https://support.google.com/webmasters/answer/6062608?hl=en)
355- [Robots meta tag, data-nosnippet, and X-Robots-Tag specifications](https://developers.google.com/search/reference/robots_meta_tag)
356- [About robots.txt](http://www.robotstxt.org)
357- [About the robots META tag](https://www.robotstxt.org/meta.html)
bdfb967c 358
b49a04f7 359
91a21c27 360## Fail2ban
bdfb967c 361
91a21c27 362[fail2ban](http://www.fail2ban.org/wiki/index.php/Main_Page) is an intrusion prevention framework that reads server (Apache, SSH, etc.) and uses `iptables` profiles to block brute-force attempts. You need to create a filter to detect shaarli login failures in logs, and a jail configuation to configure the behavior when failed login attempts are detected:
6c44d604 363
91a21c27 364```ini
365# /etc/fail2ban/filter.d/shaarli-auth.conf
366[INCLUDES]
367before = common.conf
368[Definition]
369failregex = \s-\s<HOST>\s-\sLogin failed for user.*$
370ignoreregex =
371```
bdfb967c 372
91a21c27 373```ini
374# /etc/fail2ban/jail.local
375[shaarli-auth]
376enabled = true
377port = https,http
378filter = shaarli-auth
379logpath = /var/www/shaarli.mydomain.org/data/log.txt
380# allow 3 login attempts per IP address
381# (over a period specified by findtime = in /etc/fail2ban/jail.conf)
382maxretry = 3
383# permanently ban the IP address after reaching the limit
384bantime = -1
385```
bdfb967c 386
91a21c27 387#### References
bdfb967c 388
91a21c27 389- [Apache/PHP - error log per VirtualHost - StackOverflow](http://stackoverflow.com/q/176)
bdfb967c 390- [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/)
91a21c27 391- [Server-side TLS (Apache) - Mozilla](https://wiki.mozilla.org/Security/Server_Side_TLS#Apache)
bdfb967c 392- [Nginx Beginner's guide](http://nginx.org/en/docs/beginners_guide.html)
393- [Nginx ngx_http_fastcgi_module](http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html)
394- [Nginx Pitfalls](http://wiki.nginx.org/Pitfalls)
91a21c27 395- [Nginx PHP configuration examples - Karl Blessing](http://kbeezie.com/nginx-configuration-examples/)
396- [Apache 2.4 documentation](https://httpd.apache.org/docs/2.4/)
397- [Apache mod_proxy](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html)
398- [Apache Reverse Proxy Request Headers](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#x-headers)
399- [HAProxy documentation](https://cbonte.github.io/haproxy-dconv/)
400- [Nginx documentation](https://nginx.org/en/docs/)
401- [`X-Forwarded-Proto`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto)
402- [`X-Forwarded-Host`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host)
403- [`X-Forwarded-For`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)
404- [Server-side TLS (Nginx) - Mozilla](https://wiki.mozilla.org/Security/Server_Side_TLS#Nginx)
bdfb967c 405- [How to Create Self-Signed SSL Certificates with OpenSSL](http://www.xenocafe.com/tutorials/linux/centos/openssl/self_signed_certificates/index.php)
406- [How do I create my own Certificate Authority?](https://workaround.org/certificate-authority)
bdfb967c 407- [Travis configuration](https://github.com/shaarli/Shaarli/blob/master/.travis.yml)
408- [PHP: Supported versions](http://php.net/supported-versions.php)
91a21c27 409- [PHP: Unsupported versions (EOL/End-of-life)](http://php.net/eol.php)
bdfb967c 410- [PHP 7 Changelog](http://php.net/ChangeLog-7.php)
411- [PHP 5 Changelog](http://php.net/ChangeLog-5.php)
412- [PHP: Bugs](https://bugs.php.net/)
91a21c27 413- [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security)
414- Hosting providers: [DigitalOcean](https://www.digitalocean.com/) ([1](https://www.digitalocean.com/docs/droplets/overview/), [2](https://www.digitalocean.com/pricing/), [3](https://www.digitalocean.com/docs/droplets/how-to/create/), [How to Add SSH Keys to Droplets](https://www.digitalocean.com/docs/droplets/how-to/add-ssh-keys/), [4](https://www.digitalocean.com/community/tutorials/initial-server-setup-with-debian-8), [5](https://www.digitalocean.com/community/tutorials/an-introduction-to-securing-your-linux-vps)), [Gandi](https://www.gandi.net/en), [OVH](https://www.ovh.co.uk/), [RackSpace](https://www.rackspace.com/), etc.
415
416