1 Introduction
J’autohéberge un serveur owncloud depuis quelques années maintenant sur un vieux nettop. Et puis owncloud périclite, son fork nextcloud devient la nouvelle référence, les raspberry pi se démocratisent avec un consommation encore plus faible (~5W) que les nettop (~20W), et bien d’autres avantages (taille, bruit, coût).
J’ai donc récemment sauté le pas pour me mettre au goût du jour et comme je suis content du résultat, je partage. J’ai personnellement opté pour le raspberry pi 2B parce qu’il consomme un petit peu moins que le 3 et que je n’avais aucune utilité ni du wifi ni du bluetooth.
Comme je me suis allègrement servi, je rends à César ce qui appartient à César en citant mes sources principales :
- https://soozx.fr/nextcloud11-raspberry/
- https://www.bloguslibrus.fr/post/20170205-installer-nextcloud-sur-son-raspberry/
- https://mespotesgeek.fr/fr/configuration-et-securisation-dun-serveur-linux-debian-partie-1/
Cet article s’adresse à des personnes qui ont un minimum de connaissance de linux.
NB : Dans cet article j’utilise des dénominations du type “myuser” ainsi que des mots de passes d’exemple. Je ne saurais que vous recommander de personnaliser ces dénominations génériques et d’éviter des noms évidents ! Il va de soit que les mots de passes doivent aussi être personnalisés et sécurisés.
2 Préliminaires
2.1 Préparation de la carte SD
Télécharger la distribution raspbian lite (https://www.raspberrypi.org/downloads/raspbian/) et suivre les instructions pour écrire l’image téléchargée sur la carte SD (https://www.raspberrypi.org/documentation/installation/installing-images/README.md).
Après avoir créé un fichier vide nommé ssh
dans la partition boot
de la carte SD pour activer le ssh
au premier démarrage, il faut démonter la carte SD, même si
La vie est trop courte pour retirer le périphérique USB en toute sécurité
et la mettre dans le raspberry pi avant de brancher ce dernier sur le réseau et au secteur.
2.2 Se connecter en SSH
Pour trouver l’IP attribuée par le DHCP au raspberry pi ainsi que adresse MAC, scanner le réseau :
$ sudo nmap -sP 192.168.0.0/24
Starting Nmap 7.40 ( https://nmap.org ) at 2017-03-05 20:57 CET
Nmap scan report for 192.168.0.100
Host is up (0.014s latency).
MAC Address: XX:XX:XX:XX:XX:XX (Raspberry Pi Foundation)
...
Pour cet exemple l’IP est 192.168.0.100
. Se connecter en SSH avec l’utilisateur pi
et le mot de passe raspberry
:
$ ssh pi@192.168.0.100
2.3 Utilitaire de configuration
On commence doucement avec l’utilitaire de configuration développé pour le raspberry pi :
$ sudo raspi-config
qui ouvre une interface semi-graphique dans laquelle on règles les paramètres suivants :
- Choisir
Internationalisation Options
puisChange Locale
.- Sélectionner
fr_FR.UTF-8 UTF-8
puisOK
. - Choisir
fr_FR.UTF-8 UTF-8
.
- Sélectionner
- Choisir
Internationalisation Options
puisChange Timezone
.- Choisir
Europe
, puisParis
.
- Choisir
- Choisir
Advanced Options
puisHostname
.- Taper le nom de la machine,
myserver
dans le cadre de cet exemple.
- Taper le nom de la machine,
- Choisir
Advanced Options
puisMemory Split
.- Taper
16
.
- Taper
- Choisir
Advanced Options
puisSSH
puisyes
. - Choisir
<Finish>
puisyes
pour redémarrer.
Une fois redémarré, on se reconnecte en ssh (le mot de passe est toujours raspberry
) :
pi@raspberrypi:~ $ Connection to 192.168.0.100 closed by remote host.
Connection to 192.168.0.100 closed.
$ ssh pi@192.168.0.100
2.4 Mens sana in corpore sano
Une petite mise à jour le système pour partir sur de bons rails :
$ sudo apt update
$ sudo apt upgrade
$ sudo reboot
Se reconnecter au SSH.
3 Sortez couverts
3.1 Préserver la carte SD
Pour mettre les fichiers temporaires en mémoire vive, on rajoute les deux lignes suivantes dans /etc/fstab
:
tmpfs /tmp tmpfs defaults,noatime,nosuid,size=100m 0 0
tmpfs /var/tmp tmpfs defaults,noatime,nosuid,size=30m 0 0
L’utilitaire log2ram permet de placer les logs en mémoire vive et de ne les sauvegarder que toutes les heures :
$ cd
$ mkdir download
$ cd download
$ sudo apt install git
$ git clone https://github.com/azlux/log2ram.git
$ cd log2ram
$ chmod +x install.sh
$ sudo ./install.sh
Pour indiquer au serveur apache de démarrer après log2ram
, éditer le fichier /etc/systemd/system/log2ram.service
:
Before=syslog.target mysql.service fail2ban.service nginx.service rsyslog.service apache2.service
Vérifier que toutes les modifications ont été prises en compte en vérifiant que vous avez bien les quatre dernières lignes après avoir redémarré :
$ df -h
Sys. de fichiers Taille Utilisé Dispo Uti% Monté sur
/dev/root 15G 1012 M 13G 12% /
devtmpfs 475M 0 475M 0% /dev
tmpfs 479M 0 479M 0% /dev/shm
tmpfs 479M 6,4M 473M 2% /run
tmpfs 5,0M 4,0K 5,0M 1% /run/lock
tmpfs 479M 0 479M 0% /sys/fs/cgroup
tmpfs 30M 0 30M 0% /var/tmp
tmpfs 100M 0 100M 0% /tmp
/dev/mmcblk0p1 63M 21M 43M 34% /boot
log2ram 40M 3,1M 37M 8% /var/log
Pour corriger un bug de raspbian qui envoie des erreurs du fait qu’il n’y a pas de console graphique, éditer le fichier /etc/rsyslog.conf
et commenter les lignes suivantes (à la fin du fichier) :
#daemon.*;mail.*;\
# news.err;\
# *.=debug;*.=info;\
# *.=notice;*.=warn |/dev/xconsole
3.2 Sécuriser le serveur
Ajouter l’utilisateur personnalisé, dans cet exemple sera myuser
, avec les droits sudo
, définir un M0t#2Pass3_Compl1quE!
:
$ sudo useradd -m myuser -G sudo
$ sudo passwd myuser
On peut maintenant se déconnecter de la session de l’utilisateur pi et se reconnecter avec notre utilisateur myuser
fraichement créé :
$ logout
Connection to 192.168.0.10 closed.
$ ssh myuser@192.168.0.100
Et c’est avec un petit plaisir sadique qu’on supprime l’utilisateur par défaut pi
et ses fichiers :
$ sudo deluser --remove-all-files pi
Peaufinons maintenant la configuration du server ssh en éditant le fichier /etc/ssh/sshd_config
et en modifiant les paramètres suivants :
...
# Logging
SyslogFacility AUTH
LogLevel VERBOSE
# Authentication:
LoginGraceTime 20
PermitRootLogin no
StrictModes yes
...
#UseLogin no
MaxStartups 10:30:60
#Banner /etc/issue.net
...
# Add allowed users
AllowUsers myuser
On restreindre le service SSH à l’IPv4 et on redémarre le service ssh en vérifiant son statu :
$ echo 'AddressFamily inet' | sudo tee -a /etc/ssh/sshd_config
$ sudo systemctl restart ssh
$ sudo systemctl status ssh
Pour que notre serveur puisse nous envoyer de gentils petits courriels, nous installons nullmailer
:
$ sudo apt install nullmailer mailutils
Pendant l’installation renseigner le nom de la boite mail (qui doit être une boite mail existante) :
webmaster@mydomain.com
Puis fournir les paramètres SMTP
de la boite mail en question :
smtp.mydomain.com smtp --port=465 --auth-login --user=webmaster@mydomain.com --pass=M0t#2Pass3_2MaB0ate-ma1l --ssl
En cas de problème, ces informations peuvent être modifiées dans les fichiers situés dans le dossier /etc/nullmailer/
.
Appliquer le fix suivant pour corriger le header des emails et le forcer l’expéditeur à webmaster@mydomain.com
et ainsi éviter de se faire bouler par le serveur smtp :
$ sudo mv /usr/sbin/sendmail /usr/sbin/sendmail-bin
$ sudo echo webmaster@mydomain.com > /etc/nullmailer/forced-from
Créer un fichier /usr/sbin/sendmail
dans lequel mettre :
#!/bin/bash
/usr/sbin/sendmail-bin $@ -f `cat /etc/nullmailer/forced-from` </dev/stdin
Que l’on rend exécutable :
$ chmod +x /usr/sbin/sendmail
Pour tester l’envoie de mail :
$ echo "Un mail de test" | mail -s "test nullmailer" destinataire@pourletest.com
L’utilitaire fail2ban
va nous permettre d’ajouter une couche de sécurité au serveur :
$ sudo apt install fail2ban
Éditer la première ligne du fichier /etc/hosts
:
127.0.0.1 localhost localhost.localdomain myserver
Créer un fichier de configuration pour fail2ban
:
$ sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Puis éditer le fichier créé /etc/fail2ban/jail.local
comme suit :
...
ignoreip = 127.0.0.1/8 192.168.0.0/24
...
# "bantime" is the number of seconds that a host is banned.
Bantime = 3600
...
#
# Destination email address used solely for the interpolations in
# jail.{conf,local} configuration files.
destemail = webmaster@mydomain.com
#
# Name of the sender for mta actions
sendername = Fail2Ban
# Email address of the sender
sender = webmaster@mydomain.com
...
# Choose default action. To change, just override value of 'action' with the
# interpolation to the chosen action shortcut (e.g. action_mw, action_mwl, etc) in $
# globally (section [DEFAULT]) or per specific section
action = %(action_mwl)s
...
[ssh]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log maxretry = 3
...
[pam-generic]
enabled = true
filter = pam-generic
port = all
banaction = iptables-allports
port = anyport
logpath = /var/log/auth.log
maxretry = 3
Relancer le service fail2ban
et vérifier que tout c’est bien passé :
$ sudo systemctl restart fail2ban
$ sudo systemctl status fail2ban
3.3 Configurer le réseau
Ci-après, c’est votre box internet que vous devez configurer. Comme il y a autant de cas que de fournisseurs d’accès et d’offres, je vous propose de vous reporter sur ce lien si vous n’arrivez pas à trouver comment faire les actions suivantes.
- Commencez par configurer un bail DHCP pour que l’adresse MAC du raspberry pi (
XX:XX:XX:XX:XX:XX
) – obtenue avec la commandenmap
(souvenez-vous c’était ici) – ait une IP fixe (192.168.0.100
dans ce cas). - Rediriger ensuite les ports entrant
80
(HTTP) et443
(HTTPS) en TCP vers les mêmes ports de l’IP192.168.0.100
. - Rediriger enfin le port entrant de votre choix (
1234
par exemple) en TCP vers le port22
(SSH) de l’IP192.168.0.100
. Ça permet de brouiller un peu – pas beaucoup – les pistes pour un éventuel pirate, la connexion en SSH depuis l’extérieur se faisant avec l’IP de la box que vous pouvez facilement trouver sur ce lien (exemple ou123.456.789.12
) :
$ ssh myuser@123.456.789.12 -p 1234
Maintenant il s’agit de configurer le DNS sur votre nom de domaine. Rajoutez un sous domaine (mycloud
par exemple) qui pointe vers votre box internet :
mycloud.mydomain.com IN A 123.456.789.12
4 Le gros œuvre
4.1 Base de données
Installer le gestionnaire de bases de données mariadb
, définir un m0t-DeuX!p4sse
pour le root
, et appliquer les paramètres sécurisés proposés par la seconde commande (sauf le changement du mot de passe root
car celui que vous venez de définir est évidemment brillamment sécurisé) :
$ sudo apt install mariadb-server
$ sudo mysql_secure_installation
Créer la base de données et l’utilisateur pour nextcloud :
$ mysql -u root -p
Enter password:
...
MariaDB [(none)]> create database myclouddb;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> create user myclouduser@localhost identified by 'S3cUr1tY_firST';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> grant all on myclouddb.* to myclouduser@localhost;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> exit;
Bye
Où la base de donnée pour nextcloud est myclouddb
, l’utilisateur myclouduser
et son mot de passe d’accès S3cUr1tY_firST
.
Décommenter les lignes suivantes du fichier /etc/mysql/conf.d/mariadb.cnf
:
default-character-set = utf8
...
character-set-server = utf8
collation-server = utf8_general_ci
character_set_server = utf8
collation_server = utf8_general_ci
Et redémarrer le service puis vérifier que tout s’est bien passé :
$ sudo systemctl restart mysql
$ sudo systemctl status mysql
4.2 Server web
Pour l’heure votre serveur ne sait toujours pas afficher une page web. Pour y remédier, installer apache
et php
puis relancer le service apache
:
$ sudo apt install apache2 libapache2-mod-php5 php5-json php5-gd php5-mysql php5-curl php5-intl php5-mcrypt php5-imagick php5-apcu
$ sudo systemctl restart apache2
$ sudo systemctl status apache2
Testez que tout est bien installé en créant un fichier de test /var/www/html/info.php
contenant :
<?php
phpinfo();
?>
Puis ouvrir dans votre navigateur successivement les deux liens qui doivent ouvrir la même page :
- http://192.168.0.100/info.php
- http://mycloud.mydomain.com/info.php
Une fois cette vérification faite supprimer le fichier :
$ sudo rm /var/www/html/info.php
Modifier les paramètres suivants du fichier /etc/apache2/conf-available/security.conf
:
ServerTokens Prod
ServerSignature Off
Modifier les paramètres suivants du fichier /etc/php5/apache2/php.ini
:
post_max_size = 20M
upload_max_filesize = 20M
mysql.connect_timeout = 180
allow_url_fopen = Off
Éditer le fichier /etc/apache2/apache2.conf
et ajouter à la fin :
# Cookie HTTP header flag with HTTPOnly & Secure to protect website from XSS attacks
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure
Puis relancer le service apache et vérifier que cela c’est bien passé :
$ sudo systemctl reload apache2
$ sudo systemctl status apache2
4.3 Configurer HTTPS
Installer certbot
et créer un certificat pour le sous-domaine :
$ cd
$ mkdir download
$ cd download
$ wget https://dl.eff.org/certbot-auto
$ chmod a+x certbot-auto
$ ./certbot-auto certonly --webroot -w /var/www/html -d mycloud.mydomain.com
Vérifier que le certificat est créé :
$ sudo ls -l /etc/letsencrypt/live/mycloud.mydomain.com
Ajouter ou modifier les paramètres suivants
dans
/etc/apache2/sites-available/default-ssl.conf
:
ServerName mycloud.myserver.com
SSLCertificateFile /etc/letsencrypt/live/mycloud.myserver.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mycloud.myserver.com/privkey.pem
Puis ouvrir dans votre navigateur le lien pour vérifier que HTTPS fonctionne :
- https://mycloud.mydomain.com/
Désactiver les virtualhost
apache par défaut puis relancer le service :
$ sudo a2dissite 000-default.conf
$ sudo a2dissite default-ssl.conf
$ sudo systemctl reload apache2
$ sudo systemctl daemon-reload
$ sudo systemctl status apache2
4.4 Fichiers Nextcloud
Télécharger les fichiers et vérifier leur intégrité :
$ cd ~/download
$ wget https://download.nextcloud.com/server/releases/latest.zip
$ wget https://download.nextcloud.com/server/releases/latest.zip.sha256
$ sha256sum -c latest.zip.sha256
Si une erreur apparaît lors du checksum, il faudra peut-être renommer le fichier latest.zip
par celui rechercé par latest.zip.sha256
.
Décompresser le zip et mettre les fichiers au bon endroit avec les bons droits :
$ unzip latest.zip
$ sudo cp -r nextcloud /var/www/
$ sudo chown www-data:www-data /var/www/nextcloud/ -R
$ sudo mkdir /var/www/data
$ sudo chown www-data:www-data /var/www/data
4.5 Hôte Apache pour Nextcloud
Modifier le fichier /etc/apache2/apache2.conf
:
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
Créer le fichier /etc/apache2/sites-available/nextcloud.conf
contenant :
# Forward HTTP to HTTPS
<VirtualHost *:80>
ServerName mycloud.mydomain.com
Redirect / https://mycloud.mydomain.com/
</VirtualHost>
# HTTPS config
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName mycloud.mydomain.com
ServerAdmin myuser@localhost
DocumentRoot /var/www/nextcloud
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# SSL Engine Switch:
# Enable/Disable SSL for this virtual host.
SSLEngine on
# A self-signed (letsencrypt) certificate
SSLCertificateFile /etc/letsencrypt/live/mycloud.mydomain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mycloud.mydomain.com/privkey.pem
SSLCipherSuite RC4-SHA:AES128-SHA:HIGH:!aNULL:!MD5
SSLHonorCipherOrder on
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
</IfModule>
# SSL Engine Options
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
# SSL Protocol Adjustments
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
# MSIE 7 and newer should be able to use keepalive
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
</VirtualHost>
</IfModule>
Activer ce nouvel l’hôte virtuel :
$ sudo ln -s /etc/apache2/sites-available/nextcloud.conf /etc/apache2/sites-enabled/nextcloud.conf
$ sudo a2enmod rewrite headers env dir mime
$ sudo a2enmod ssl
$ sudo a2ensite nextcloud
$ sudo systemctl reload apache2
$ sudo systemctl daemon-reload
$ sudo systemctl status apache2
5 Les finitions
5.1 Initialisation de Nextcloud
Avec votre navigateur aller sur : http://mycloud.mydomain.com
.
Vérifiez que vous êtes bien redirigés sur le HTTPS et que la page d’initialisation de nextcloud s’affiche. Configurer comme suit :
- Définissez un compte administrateur (toujours en les personnalisant)
myadminnextcloud
avec unMoT_dE_pAsSe_SeCuRiSe
. - Définir le répertoire des données :
/var/www/data
. - Configurer la base de données définie plus haut.
Cliquer sur Terminer la configuration
, est une fois arrivé sur l’écran de login – ça prend un peu de temps – nextcloud peut commencer à être utilisé. Peaufinez l’installation en modifiant ou ajoutant les paramètres suivants dans le fichier /var/www/nextcloud/config/config.php
:
array (
0 => 'mycloud.mydomain.com',
1 => '192.168.0.100',
),
...
'logfile' => '/var/www/data/nextcloud.log',
'loglevel' => 2,
'log_authfailip' => true,
'memcache.local' => '\OC\Memcache\APCu',
5.2 Configurer Nextcloud
Voici comment j’ai personnellement configuré mon instance nextcloud.
J’ai installé les applications :
- Calenda
- Contacts
- Default encryption module
- Notes
Dans le menu d’administration j’ai modifié les onglets suivants.
5.2.1 Onglet paramètres serveur
Vérifier qu’il n’y a pas d’avertissement sécurité & configuration. Sélectionner cron
pour les tâches cron. Ajouter une tâche cron
pour nextcloud en éditant via la commande :
$ crontab -u www-data -e
Choisir l’éditeur parmi ceux proposés et ajouter les lignes :
# cron job for nextcloud
*/15 * * * * php -f /var/www/nextcloud/cron.php
5.2.2 Onglet chiffrement
Activer le chiffrement.
5.2.3 Onglet paramètres supplémentaires
Utiliser sendmail
pour le mode d’envoie des emails avec l’adresse source : webmaster@mydomain.com
. Envoyer un email pour tester que la configuration fonctionne.
Vérifier la politique de mots de passe et la modifier en fonction de ses souhaits de sécurité.
5.3 Restons up-to-date
Commençons par un petit peu de ménage avant d’installer cron-apt qui va permettre de maintenir le système à jour :
$ sudo apt-get autoremove && sudo apt-get autoclean
$ sudo apt install cron-apt
Éditer le fichier /etc/cron-apt/config
(vide) en ajoutant :
APTCOMMAND=/usr/bin/apt-get
MAILTO="webmaster@mydomain.com"
MAILON="always"
Éditer /etc/cron-apt/action.d/3-download
et supprimer le -d :
autoclean -y
dist-upgrade -y -o APT::Get::Show-Upgraded=true
Éditer /etc/cron.d/cron-apt
et ajouter l’exécution de la tache tous les lundis à 1h du matin :
# Every Monday night at 1 o'clock
0 1 * * 1 test -x /usr/sbin/cron-apt && /usr/sbin/cron-apt
Pour tester l’exécution de la tache :
$ sudo cron-apt
Ensuite on programme une tache cron pour redémarrer le raspberry tous les lundis à 2h du matin et envoyer un mail à chaque démarrage :
$ sudo mkdir /var/log/cron
$ sudo crontab -e
Ajouter au début et à la fin :
MAILTO=webmaster@mydomain.com
...
# Reboot Monday night at 2 o’clock
0 2 * * 1 /sbin/shutdown -r > /var/log/cron/cron-reboot.log
@reboot echo "myserver has just reboot" | mail -s "Reboot" webmaster@mydomain.com
5.4 Tester le serveur
J’ai testé cette installation avec ces outils :
- Mozilla : https://observatory.mozilla.org/ : J’obtiens la note A
- Nextcloud : https://scan.nextcloud.com/ : J’obtiens la note A+
Bonjour,
Merci !!! excellent tuto
Quelques différences dans les fichier de conf avec la version “sketch” mais facile à adapter.
Juste la partie “Certbot” qui n’a pas fonctionné mais on peu palier en allant le faire en ligne directement sur le site “https://certbot.eff.org/”
Super encore merci
Salut ! Super tuto.
Juste une question : quid des débits de synchro ? J’ai une install peu ou proue similaire, et les débits sont affreusement lents. Je soupçonne la ram limitée du rasperry 2b+.
Merci encore
J’ai l’impression que mes débits sont corrects. Je m’en sers essentiellement pour synchroniser mes agenda et contact sur mon téléphone et occasionnellement pour partager des fichiers à mon entourage.
Souvent l’initialisation de la connexion prend un petit peu de temps, mais une fois que le raspberry s’est réveillé, ça passe. C’est probablement dépendant aussi du fournisseur d’accès !
Merci de la réponse. Pour un usage de synchro massif, je suis bien en-dessous de la bande passante de mon réseau, c’est pour ça que je pensais à la ram. J’ai souvent des erreurs quand j’upload pas mal de fichiers un peu volumunieux (quelques centaines de Mo). Pour l’agenda et les contacts, effectivement, ça ne doit pas poser de pb.