Installer Nextcloud sur son Raspberry

Table des Matières

Il y a quelques temps j’avais évoqué ici mon acquisition d’un raspberry pi 3 pour me faire un petit serveur @home. Depuis le début j’utilisai la distribution DietPi, basée sur Raspbian avec pleins d’améliorations et des logiciels pré-configurés installables en quelques clics. Le serveur tournait parfaitement, sans avoir besoin de bidouiller la bête. Mais c’est lors d’un banal renouvellement de certificats letsencrypt que les ennuis ont commencé.

L’outils Dietpi-Letsencrypt m’indiqua qu’aucun serveur web n’était configuré sur la machine. J’essaie de passer de Lighttpd à Nginx, toujours le même message d’erreur. Une réinstallation n’a rien changé alors il a fallu tourner la page, revenir à du Raspbian pure pour tout faire comme un grand à la main, mieux comprendre les rouages. Voici donc les quelques notes prises pendant cette aventure.

Installer Raspbian

Raspbian est la distribution officielle pour les Raspberry, elle est basée sur Debian et apporte toute la stabilité dont la distribution mère tire sa renommée.

Pour télécharger la distribution il faut se rendre sur le site officiel de la fondation Raspberry, on y trouve alors deux images :

La première image est plus lourde et offre une interface graphique légère, la deuxième quant à elle, est plus légère et s’oriente donc logiquement vers une base pour un serveur.

Une fois l’image téléchargée, libre à chacun de la copier sur la carte SD avec son outil préféré. DD fait très bien le boulot par exemple.

Boot headless

Nous voulons donc créer un serveur headless, sans écran. Cela veut dire qu’il va falloir passer par une connexion ssh pour avoir accès à Raspbian en ligne de commande.

Par défaut Raspbian n’active pas ssh, cela depuis novembre 2016 et l’affaire des attaques DDOS à travers des objets connectés. Il faut donc l’activer à la main une fois l’installation automatique faite.
Pour ne pas avoir à brancher un écran au Raspberry afin d’activer SSH, une astuce existe. Il suffit de créer un fichier nommé ssh dans le dossier /boot pour activer le service à la première connexion. Le fichier peut rester vide, seul sa présence compte.

Il est également possible de configurer une connexion wifi au premier démarrage en éditant le fichier /etc/wpa/supplicant/wpa/supplicant.conf :

network={
    ssid="NomduRéseauWIFI"
    psk="motdepasswifi"
}

Il est également possible de modifier le port de connexion ssh en éditant le fichier /etc/ssh/sshd_config. Ainsi le serveur se verra un peu plus protégé des attaques automatiques sur le port 22.

Serveur Web et Base de Données

Raspbian est maintenant installée, il va falloir s’occuper du serveur web. Pour cela je suis parti sur un combo Nginx/MariaDB, les deux logiciels ont une très bonne réputation et la documentation est abondante.

Nginx + MariaDB :

Commençons par mettre à jour son OS puis installer les logiciels :

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install nginx mariadb-server mariadb-client

Lors de l’installation de MariaDB un mot de passe vous sera demandé pour se connecter avec l’utilisateur root à la base de données.

Configuration de MariaDB

Le logiciel de contrôle de base de données est maintenant installé. Il va falloir le configurer pour permettre à Nextcloud d’écrire dessus.

Pour sécuriser d’avantage sa base SQL il est possible de lancer la commande mysql_secure_installation.

Création de la base mysql

Pour se connecter à la base nous utilisons la commande suivante : mysql -u root -p, le mot de passe crée lors de l’installation de MariaDB sera alors demandé.

Nous allons maintenant créer la base de données pour Nextcloud, configurer l’utilisateur qui pourra s’y connecter et gérer la base de données.

## Création de la base de données
create database nextcloud;

## Création de l'utilisateur
CREATE USER "nextclouduser"@"localhost" ;

## Définition d'un mot de passe
SET password FOR "nextclouduser"@"localhost" = password('mot_de_passe_pour_nextcloud') ;

## Attribution des privilèges pour la base
GRANT ALL ON nextcloud.* TO "nextclouduser"@"localhost" ;

## Néttoyer les privilèges
flush privileges;

## Quitter MySQL
exit;

Nginx et Php

Maintenant que Nginx est installé et que la base de données est crée nous allons installer PHP et divers modules nécessaires au bon fonctionnement de Nextcloud.

sudo apt-get install php5-curl php5-gd php5-tidy php5-mysql php5-intl php5-mcrypt php5-imagick php-xml-parser`php5-fpm

Pour paramétrer nginx pour inclure php5-fpm dans la configuration et donc pouvoir utiliser Nextcloud il faudra inclure le code suivant dans la configuration nginx. On y reviendra plus tard.

include fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTPS on;
#Avoid sending the security headers twice
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;

La commande nginx -t permet de contrôler vos fichiers de configuration Nginx et de relever les erreurs de syntaxe qui pourraient nuire au bon fonctionnement du serveur. C’est donc une commande à utiliser sans modération !

Certbot

Pour obtenir un certificat SSL pour notre serveur et ainsi assurer une connexion chiffrée avec le navigateur ou le client il est maintenant possible d’utiliser Certbot aka Letsencrypt pour générer le dit certificat localement. L’outil est notamment développé par l’EFF et Mozilla.

Il est important d’avoir au préalable un nom de domaine pour votre serveur. Il est possible d’en acheter un auprès de fournisseurs tels OVH ou Gandhi. Ou alors il est également possible de passer par un service de DNS Dynamique (DDNS) comme [no-ip](https://www.noip.com), ce dernier a d’ailleurs un outil disponible qui s’installe sur Raspbian et qui connecte automatiquement votre serveur avec votre nom de domaine noip crée.

Récupérer Certbot

le root nginx de base se situe dans /var/www/html, j’ai choisi /var/www pour une meilleure gestion de mes différents services sur mon serveur.

Dans un premier temps nous devons récupérer certbot et le rendre exécutable :

wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto

Il faut alors modifier le fichier de configuration Nginx /etc/nginx/sites/available/default/ pour y insérer la localisation .well-known qui est utilisé par l’ACME Challenge pour vous délivrer un certificat.

sudo nano /etc/nginx/sites-available/default

### Rajouter les lignes suivantes à celle du bloc Serveur SSL
        location ~ /.well-known {
                allow all;
        }

Une fois cela fait nous allons redémarrer Nginx : service nginx reload

Maintenant on envoie Certbot au charbon avec ./path/to/certbot-auto certonly --webroot -w /var/www -d votresite.com

Si tout c’est bien passé les certificats sont créés, on peut rapidement voir le résultat en allant fouiller dans les repertoires de certbot :
ls -l /etc/letsencrypt/live/your_domain_name

Il faudra penser à ajouter le nom de domaine du serveur dans le fichier de configuration Nginx

Ajout des certificats à Nginx

Nous devons éditer le fichier de configuration d’Nginx pour ajouter l’URL de notre serveur ainsi que les lignes suivantes pour pointer vers les certificats créés par Certbot.

Pour faciliter la gestion des différents paramètres dans le fichier default Nginx nous allons utiliser des snippets. Ce qui va permettre de séparer les différents paramètres dans des fichiers distincts, que l’on pourra plus rapidement éditer par la suite.

sudo nano /etc/nginx/snippets/ssl-letsencrypt.conf

# Ajouter le certificat SSL
ssl_certificate /etc/letsencrypt/live/nodenixbox.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/nodenixbox.com/privkey.pem;/

Amélioration du niveau SSL

Les certificats générés de base par Certbot sont bons mais, il est possible de les rendre encore plus fort :

# Générer un Strong Diffie-Hellman Group
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Le fichier crée (/etc/ssl/certs/dhparam.pem) sera utilisé par la suite pour le serveur.

Cypher et Android

Lors de ma première connexion du client Nextcloud Android avec mon instance je rencontrais une erreur qui indiquait que la connexion était impossible, un rapide tour sur le web indiqua qu’il fallait utiliser le cypher ECDHE-RSA-AES128-SHA pour que la synchronisation fonctionne correctement.

Nous allons de nouveau utiliser un snippets pour incorporer les paramètres ssl pour le serveur : Les paramètres sont issus de la documentation officielle Nextcloud et du site cipherli.st.

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-RSA-AES128-SHA";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Disable preloading HSTS for now.  You can use the commented out header line that includes
# the "preload" directive if you understand the implications.
#add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header Cache-Control "public, max-age=7200";
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options "SAMEORIGIN";
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;

ssl_dhparam /etc/ssl/certs/dhparam.pem;

Nextcloud

Installation

L’installation est assez simple par la suite, il suffit de récupérer l’archive de la dernière version stable, de décompresser l’archive et de balancer le dossier dans /var/www:

wget https://download.nextcloud.com/server/releases/latest.tar.bz2
tar xfvj latest.tar.bz2
sudo mv nextcloud /var/www

Créer un dossier data

Pour que Nextcloud fonctionne correctement il faut absolument créer un dossier data avec les permissions qui vont bien.

sudo mkdir -p /var/www/nextcloud/data
sudo chown www-data:www-data /var/www/nextcloud/data
sudo chmod 750 /var/www/nextcloud/data

Permissions

cd /var/www/nextcloud
sudo chown www-data:www-data config apps

Pour vérifier que les permissions sont bien strictes la doc officielle de Nextcloud met à disposition un petit script bash pour cela.

Ensuite il ne reste plus qu’à se rendre sur l’URL adressedevotrepi/nextcloud pour démarrer l’installation

Nextcloud et Nginx

Maintenant nous allons paramétrer nginx pour inclure le dossier Nextcloud au serveur et ainsi arriver à la fin du périple et pouvoir par la suite utiliser Nextcloud sur notre serveur.

Il suffit d’éditer le fichier de configuration default et d’y indiquer :

#################
### Nextcloud ###
#################
     location ~ /.well-known {
        allow all;
    }

    # The following 2 rules are only needed for the user_webfinger app.
    # Uncomment it if you're planning to use this app.
    # rewrite ^/.well-known/host-meta /nextcloud/public.php?service=host-meta
    # last;
    #rewrite ^/.well-known/host-meta.json
    # /nextcloud/public.php?service=host-meta-json last;

    location = /.well-known/carddav {
      return 301 $scheme://$host/nextcloud/remote.php/dav;
    }
    location = /.well-known/caldav {
      return 301 $scheme://$host/nextcloud/remote.php/dav;
    }

    location /.well-known/acme-challenge { }
    
    location ^~ /nextcloud {

        # set max upload size
        client_max_body_size 512M;
        fastcgi_buffers 64 4K;

        # Disable gzip to avoid the removal of the ETag header
        gzip off;

        # Uncomment if your server is build with the ngx_pagespeed module
        # This module is currently not supported.
        #pagespeed off;

        error_page 403 /nextcloud/core/templates/403.php;
        error_page 404 /nextcloud/core/templates/404.php;

        location /nextcloud {
            rewrite ^ /nextcloud/index.php$uri;
        }

        location ~ ^/nextcloud/(?:build|tests|config|lib|3rdparty|templates|data)/ {
            deny all;
        }
        location ~ ^/nextcloud/(?:\.|autotest|occ|issue|indie|db_|console) {
            deny all;
        }

        location ~ ^/nextcloud/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {
            include fastcgi_params;
            fastcgi_split_path_info ^(.+\.php)(/.*)$;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_param HTTPS on;
            #Avoid sending the security headers twice
            fastcgi_param modHeadersAvailable true;
            fastcgi_param front_controller_active true;
            fastcgi_pass php-handler;
            fastcgi_intercept_errors on;
        }

        location ~ ^/nextcloud/(?: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 /nextcloud/index.php$uri$is_args$args;
            add_header Cache-Control "public, max-age=7200";
            # Add headers to serve security related headers  (It is intended
            # to have those duplicated to the ones above)
            # Before enabling Strict-Transport-Security headers please read
            # into this topic first.
            # add_header Strict-Transport-Security "max-age=15768000;
            # includeSubDomains; preload;";
            add_header X-Content-Type-Options nosniff;
            add_header X-Frame-Options "SAMEORIGIN";
            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;
            # Optional: Don't log access to assets
            access_log off;
        }

        location ~* \.(?:png|html|ttf|ico|jpg|jpeg)$ {
            try_files $uri /nextcloud/index.php$uri$is_args$args;
            # Optional: Don't log access to other assets
            access_log off;
        }
    }

Peaufinage et Sécurité

Sécuriser son dossier data

Il est recommandé de placer son dossier data en dehors de la racine du serveur web pour éviter toute intrusion. Comme je ne suis pas un mec qui réfléchit de base je n’ai pas fait la manipulation avant l’installation mais bien après.

sudo mkdir /var/nextcloud
sudo mv -v /var/www/nextcloud/data /var/nextcloud/data

Puis il faut éditer le fichier config.php de Nextcloud et modifier la ligne 'datadirectory' => '/var/www/nextcloud/data', pour y modifier le chemin vers le dossier data.

Il est d’ailleurs possible de faire la manip’ avant l’installation de Nextcloud pour n’avoir qu’à sélectionner le dossier data sécurisé lors de l’installation. C’est tout aussi pratique.

Getenv

Lors de mon installation Nextcloud indiqua que la fonction Getenv de PHP n’était pas trouvable. Il faut alors décommenter la ligne PHP : ;env[PATH] = /usr/local/bin:/usr/bin:/bin dans le fichier /etc/php5/fpm/pool.d/www.conf

Memcache

Nextcloud me renvoyait également une erreur au sujet de Memcache. Un tour sur la doc et la solution est trouvée.

# Installer un Memcache
sudo apt-get install php5-apcu

# Ajouter le memcache à nextcloud
sudo nano nextcloud/config/config.php
'memcache.local' => '\OC\Memcache\APCu', # à ajouter #

Maintenant tout est bon pour faire tourner Nextcloud sans erreur, nous n’avons plus qu’à redémarrer les services php5-fpm et nginx et tada.

Nous pouvons maintenant profiter de la dernière version stable de Nextcloud sur un petit serveur @Home où seul votre connexion internet sera une limite.

Billets en liens :