Cette page va nous montrer comment mettre en place un serveur LAMP + Nextcloud sous Debian 9 / Ubuntu 16.04 & 18.04 avec NGINX.
Nextcloud est une plate-forme de partage de fichiers et de communication open source, auto-hébergée accédez et synchronisez vos fichiers, vos contacts, vos calendriers et communiquez et collaborez depuis tous vos appareils. Vous décidez de ce qui se passe avec vos données, où elles se trouvent et qui peuvent y accéder !
Sommaine
- Prérequis
- Installation du serveur LAMP
- Création de la BDD
- Installation de Nextcloud
- Création du vHost NGINX
- Configuration de Nextcloud
- Renouvellement des certificats
- Mise à jour automatique de Nextcloud
- Mise à jour manuel de Nextcloud
Prérequis
Avoir un nom de domaine avec les enregistrements DNS pointant sur votre serveur
Installation du serveur LAMP
La première étape est de se connecter au serveur puis de mettre à jour celui-ci
apt-get update && apt-get upgrade
On passe ensuite à l'installation de la base de donnée avec MariaDB
apt-get install mariadb-server
mysql_secure_installation
Au lancement de la seconde commande une série de questions vous sera posé :
- Set root password ? Pour définir un mot de passe à l'utilisateur root pour la connexion à MariaDB
- Remove anonymous user ? Par défaut, une installation de MariaDB a un utilisateur anonyme, ce qui permet à n'importe qui pour se connecter à MariaDB sans avoir besoin de crée un compte d'utilisateur. Le mieux est donc d'entrée "Y"
- Disallow root login remotely ? Si vous souhaitez désactiver l'accès à distance sur MariaDB pour l'utilisateur root
- Remove test database and access to it ? Par défaut une base de test ou n'importe qui peut accéder est créer par MariaDB le mieux est de la supprimer en tapant "Y"
- Reload privilege tables now? Pour recharger les privilèges de MariaDB
On passe ensuite à l'installation de NGINX et des modules PHP nécessaire pour Nextcloud, certains modules comme curl ou intl sont facultatifs mais recommandé car ils permettent soit d'améliorer les performances soit ils sont nécessaires pour certaines fonctionnalités.
Si vous installez un nouveau plugin sur Nextcloud il faudra vérifier que celui-ci ne requiert pas de modules PHP supplémentaire par exemple php-ldap pour utiliser la connexion à Nextcloud avec authentification via LDAP
apt-get install nginx
apt-get install php-cli php-json php-curl php-imap php-gd php-mysql php-xml php-zip php-intl php-imagick php-mbstring php-fpm php-apcu
Pour des raisons de sécurité il est recommandé de désactiver l’envoi d’informations telles que le numéro de version de votre Nginx. Pour cela, décommentez la directive "server_tokens off" en ouvrant le fichier "/etc/nginx/nginx.conf"
[...]
server_tokens off;
[...]
Création de la base de données
On passe à la création de la base de données en se connectant a MariaDB
mysql -u root -p
Le mot de passe est celui que vous avez entré à la configuration de MariaDB plus tôt. On crée la base Nextcloud
CREATE DATABASE nextcloud;
Si vous voulez utiliser des caractères UTF8 de 4 octets comme des emojis sur votre serveur, la base de données doit être créée avec le jeu de caractères utf8mb4 comme ceci :
CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
On crée ensuite l'utilisateur et on lui applique les droits sur la base de données :
CREATE USER "nextcloud"@"localhost";
SET password FOR "nextcloud"@"localhost" = password('mon_password');
GRANT ALL PRIVILEGES ON nextcloud.* TO "nextcloud"@"localhost" IDENTIFIED BY "mon_password";
FLUSH PRIVILEGES;
EXIT
Installation de Nextcloud
On va maintenant télécharger la dernière archive de nextcloud
cd /var/www
wget https://download.nextcloud.com/server/releases/latest.tar.bz2
On peut télécharger le SHA256 afin de vérifier l'intégrité de l'archive
wget https://download.nextcloud.com/server/releases/latest.tar.bz2.sha256
sha256sum -c latest.tar.bz2.sha256 < latest.tar.bz2
La commande doit alors retourner un "OK"
On décompresse l'archive et on la supprime
tar -xvf latest.tar.bz2
rm latest.tar.bz2*
Dans la documentation de Nextcloud il est recommandé de placer le dossier contenant les data dans un autre répertoire (Il est recommandé de placer le dossier en dehors du Web Root donc /var/www), nous allons juste simplement créer un autre dossier pour notre part dans /var/www
cd /var/www
mkdir nextcloud_data
Si vous optez pour un upgrade manuel de Nextcloud plus tard il est préférable de renommer votre dossier nextcloud en y ajoutant son numéro de version puis de créer un lien symbolique.
mv nextcloud nextcloud_{VersionNextcloud}
ln -s /var/www/nextcloud_{VersionNextcloud} /var/www/nextcloud
On applique les bon droits aux dossiers
chown -R www-data:www-data nextcloud_{version}
find nextcloud_{version}/ -type d -exec chmod 750 {} \;
find nextcloud_{version}/ -type f -exec chmod 640 {} \;
chown -R www-data:www-data nextcloud_data
Grâce à cette technique, cas d'upgrade manuel il ne sera pas nécessaire de modifier les vHosts créer de plus de manière générale la maintenance de Nextcloud est simplifié
Création du vHost NGINX
Dans les étapes suivantes il faudra remplacer {domaine}.tld par votre nom de domaine.
On va créer le vHost pour Nextcloud en crée un fichier dans le dossier /etc/nginx/sites-available. Dans ce vHost on va utiliser HTTP2 et limiter le SSL au TLS1.2.
nano /etc/nginx/sites-available
upstream php-handler {
server unix:/run/php/php7.2-fpm.sock;
}
#------------------------------------------------------------------------
# REDIRECTION HTTPS
#
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name {domaine}.tld;
return 301 https://{domaine}.tld$request_uri;
}
#------------------------------------------------------------------------
# BLOCK SERVEUR HTTPS
#
server {
listen 443 ssl http2;
server_name {domaine}.tld;
root /var/www/nextcloud;
index index.php index.html index.htm;
#------------------------------------------------------------------------
# SECURITY
add_header Content-Security-Policy "default-src 'self' https://*.gstatic.com https://*.googleapis.com data: 'unsafe-inline' 'unsafe-eval'; report-uri https://report-uri.io/report/monurl";
add_header Content-Security-Policy-Report-Only "default-src 'self' https://*.gravatar.com https://*.gstatic.com https://*.googleapis.com https://ssl.google-analytics.com https://s-static.ak.facebook.com https://www.google-analytics.com data: 'unsafe-inline' 'unsafe-eval'";;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
#------------------------------------------------------------------------
# SSL
#
ssl_certificate /etc/letsencrypt/live/{domaine}.tld/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{domaine}.tld/privkey.pem;
ssl_protocols TLSv1.2;
ssl_dhparam /etc/nginx/ssl/dhparam4.pem;
ssl_ecdh_curve secp384r1;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256";
# ssl optimizations
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/{domaine}.tld/chain.pem;
resolver 80.67.169.12 80.67.169.40 valid=300s;
resolver_timeout 15s;
#------------------------------------------------------------------------
# LOCATION SECURITY
#
# On interdit les dotfiles
location ~ /\. { deny all; }
#------------------------------------------------------------------------
# LOCATION NEXTCLOUD
#
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location = /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
# set max upload size
client_max_body_size 512M;
fastcgi_buffers 64 4K;
# Enable gzip but do not remove ETag headers
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
location / {
rewrite ^ /index.php$uri;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
deny all;
}
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+)\.php(?:$|/) {
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ ^/(?:updater|ocs-provider)(?:$|/) {
try_files $uri/ =404;
index index.php;
}
# Adding the cache control header for js and css files
# Make sure it is BELOW the PHP block
location ~ \.(?:css|js|woff|svg|gif)$ {
try_files $uri /index.php$uri$is_args$args;
add_header Cache-Control "public, max-age=15778463";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
access_log off;
}
location ~ \.(?:png|html|ttf|ico|jpg|jpeg)$ {
try_files $uri /index.php$uri$is_args$args;
access_log off;
}
}
Vous pouvez remplacer les {domaines}.tld avec la commande suivante :
sed -i -e "s/cloud.votre-domaine.fr/{domaine}.tld/g" /etc/nginx/sites-available/nextcloud
On n'oublie pas de créer le lien symbolique
ln -s /etc/nginx/sites-available/nextcloud /etc/nginx/sites-enabled/
Il faudra ensuite créer les certificats SSL et créer une clé d'échange diffie-hellman, pour ce faire on va utiliser certbot pour nous créer des certificats SSL let's encrypt, les commandes suivantes sont effectuées sous Debian 9, vous pouvez trouver les commandes pour votre OS sur le site de certbot : https://certbot.eff.org/ en sélectionnant "NGINX" et votre OS
apt-get install python-certbot-nginx -t stretch-backports
On génère ensuite le certificat pour votre domaine, il faudra d'abord stopper NGINX
service nginx stop
certbot certonly --standalone -d cloud.{domaine}.fr
On génère ensuite la clé diffie-hellman, celà peut prendre du temps !
mkdir /etc/nginx/ssl
openssl dhparam -out /etc/nginx/ssl/dhparam4.pem 4096
chmod 600 /etc/nginx/ssl/dhparam4.pem
Notre configuration devrait être OK on peut le vérifier avec la commande suivante
nginx -t
Si tout est ok on peut redémarrer NGINX et PHP-FPM
service nginx start
service php7.2-fpm restart
Avec cette configuration vous obtiendrez un jolie A+ sur le site de SSL Labs
Configuration de Nextcloud
En vous rendant sur votre domaine cloud.{domaine}.fr vous devriez voir la page d'installation de Nextcloud, il vous faudra créer un compte administrateur, modifier le répertoire des datas en mettant celui que vous avez crée précédemment, pour ma part /var/www/nextcloud_data, ensuite entrer les informations relatives à la base de données puis cliquer sur "Terminer l'installation" !
Votre instance Nextcloud est maintenant en place.
On modifie la config globale de PHP pour coller aux requierements de Nextcloud en modifiant le fichier /etc/php/7.2/fpm/pool.d/www.conf
clear_env = no
Et on décommente et on modifie les lignes suivantes dans le fichier /etc/php/7.2/fpm/php.ini
opcache.enable=1
opcache.enable_cli=1
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.memory_consumption=128
opcache.save_comments=1
opcache.revalidate_freq=1
On va effectuer quelques réglages en modifiant le fichier de configuration de Nextcloud pour activer l'anti-bruteforce et le cache local
L'anti-bruteforce de Nextcloud ne banni pas d'IP, il rend seulement les tentatives de connexion de plus en plus lente
nano /var/www/nextcloud/config/config.php
Ajouter les lignes suivantes avant la dernière parenthèse
'installed' => true,
'logtimezone' => 'Europe/Paris',
'logfile' => '/var/www/data/nextcloud.log',
'loglevel' => 2,
'log_authfailip' => true,
'auth.bruteforce.protection.enabled' => true,
'memcache.local' => '\OC\Memcache\APCu',
Renouvellement des certificats
Pour renouveler vos certificats on utilisera un script exécuté par une tâche cron tous les X temps.
Donc dans votre contab :
sudo crontab -e
Placer y ceci à la fin :
30 2 * * 1 /usr/local/bin/letsencrypt-auto renew 1>/dev/null 2>&1
Ce qui exécutera notre script placé dans /usr/local/bin tous les 7 jours à 2h30 du matin
Ensuite on créer un fichier pour notre script sudo vim /usr/local/bin/letsencrypt-auto
Et on y met le contenu suivant :
#!/bin/bash
if [ $# -lt 1 ]
then
echo "Syntax error: $0 renew"
exit 1
fi
do_renew() {
SERVICE_HTTP=""
SERVICE_HTTP=$(systemctl is-active nginx)
if [ "${SERVICE_HTTP}" = "active" ]
then
systemctl stop nginx
sleep 2
fi
certbot renew --dry-run
certbot renew
SERVICE_HTTP=""
SERVICE_HTTP=$(systemctl is-active nginx)
if [ "${SERVICE_HTTP}" != "active" ]
then
systemctl start nginx
sleep 2
fi
}
case "$1" in
renew)
do_renew
;;
*)
echo "Usage: $0 {renew}"
exit 2
;;
esac
Voila votre installation de Nextcloud est maintenant terminé :)
Mise à jour automatique de Nextcloud
Pour mettre automatiquement à jour votre Nextcloud il vous suffira de cliquer sur votre profil puis de sélectionner Paramètres > Paramètres de base puis en bas de la page si une mise à jour est disponible vous pourrez cliquer sur le bouton pour effectuer la mise à jour.
Mise à jour manuel de Nextcloud
Avant de mettre à jour manuellement notre serveur Nextcloud il faut mettre celui-ci en maintenance avec la commande suivante
sudo -u www-data php occ maintenance:mode --on
Puis on effectue un backup de la base de données
mysqldump --single-transaction -h 127.0.0.1 -u root -p[password] [db_name] > nextcloud-sqlbkp_`date +"%Y%m%d"`.bak
On arrête le serveur web
service nginx stop
On se place dans notre répertoire web et on télécharge la dernière archive de Nextcloud, on renomme l'archive et on recrée le lien symbolique
cd /var/www
rm -R nextcloud
wget https://download.nextcloud.com/server/releases/latest.tar.bz2
wget https://download.nextcloud.com/server/releases/latest.tar.bz2.sha256
sha256sum -c latest.tar.bz2.sha256 < latest.tar.bz2
tar -xvf latest.tar.bz2
rm latest.tar.bz2*
mv nextcloud nextcloud_{version}
ln -s /var/www/nextcloud_{VersionNextcloud} /var/www/nextcloud
On récupère l'ancien fichier de configuration
cp /var/www/nextcloud_{old_version}/configs/config.php /var/www/nextcloud_{new_version}/configs
Si vous avez installé des plugins sur votre instance nextcloud il faudra les copiers du dossier /apps de votre ancienne instance nextcloud dans la nouvelle, ne copier que les plugins qui ne sont pas dans la nouvelle instance
On modifie les droits du dossier
chown -R www-data:www-data nextcloud_{version}
find nextcloud_{version}/ -type d -exec chmod 750 {} \;
find nextcloud_{version}/ -type f -exec chmod 640 {} \;
On redémarre le serveur web
service nginx start
Et on lance l'upgrade en ligne de commande de Nextcloud
sudo -u www-data php occ upgrade
La mise à jour manuel de Nextcloud est terminé