Un blog RGPD compliant


Enfin j'espère

Chez Shaft Inc, votre vie privée est au centre de nos préoccupations. Afin d'être transparents sur les données que nous traitons, nous vous présentons une nouvelle version de nos conditions d'utilisation, entrants en vigueur le 25 mai 2018...

Ce type d'amphigouri pullule sur nombre de sites et services Web en cette journée d'entrée en vigueur du Règlement général sur la protection des données personnelles (le fameux RGPD). Étant mine de rien, administrateur de ce site, je me retrouve donc responsable des données que vous pouvez y laisser. L'occasion de voir donc ce que j'en fait (spoiler : rien) et comment je les sécurise (puisque la plus grosse menace, à ne jamais négliger, est la compromission de la machine par un tiers et la copie frauduleuse des données qu'elle contient)

Logs

Le serveur Web affichant cette belle page est un Apache, configuré de manière a priori normale niveau log :

<VirtualHost *:443>
		...
		CustomLog ${APACHE_LOG_DIR}/access.log combined

J'ai donc des logs de cette forme sur le port 443 :

		2001:db8::2505:2018 - - [25/May/2018:15:44:21 +0000] "GET / HTTP/2.0" 200 13377 "https://example.org/shaft-inc-trop-fort" "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0"

Sur le port 80, le log est quasiment identique (il n'y a a priori que des robots discutant avec le port 80, HTTPS n'étant pas une option)

		www.shaftinc.fr:80 2001:db8::2505:2018 - - [25/May/2018:15:44:21 +0000] "GET / HTTP/1.1" 308 234 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0"

Votre IP peut également se retrouver dans le log d'erreur, si vous tentez de faire des bêtises :

		[Sun May 20 19:42:00.138363 2018] [authz_core:error] [pid 8255:tid 150448084659000] [client 2001:db8::2505:2018:51584] AH01630: client denied by server configuration: /chemin/blog/index.html

À moins d'utiliser le User-Agent d'un bot que j'ai identifié comme non désirable, peu de chances de tomber sur ce cas.

À l'occasion, typiquement lorsque j'introduis de la nouveauté dans la configuration TLS du serveur (pas de changement prévu avant l'arrivée de TLS 1.3 je pense), il m'arrive d'ajouter un autre log, configuré comme suit :

CustomLog ${APACHE_LOG_DIR}/tls.log "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

Log qui a la particularité de donner des détails sur les protocoles de chiffrement utilisés (ça me fut bien pratique pour me décider à couper définitivement TLS 1.0 et dégager des suites de chiffrements sans remords) :

		[25/May/2018:15:44:21 +0000] 2001:db8::2505:2018  TLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 "GET / HTTP/2.0" 13377

Les seules données personnelles que vous laissez sont donc votre adresse IP, la page consultée ici bas, et éventuellement le référent (referrer) si vous venez d'un autre site. C'est à la fois peu et énorme. J'ai donc pour politique de ne garder ces données au maximum 2 semaines (je suis ce que fait la Quadrature du Net avec son instance Mastodon par exemple). L'effacement se fait à la rotation des logs, configurées comme-ci avec logrotate :

/var/log/apache2/*.log {
			weekly
			missingok
			rotate 1
			notifempty
				create 640 root adm
			sharedscripts
			postrotate
				if /etc/init.d/apache2 status > /dev/null ; then \
					/etc/init.d/apache2 reload > /dev/null; \
				fi;
			endscript
			prerotate
				if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
						run-parts /etc/logrotate.d/httpd-prerotate; \
				fi; \
			endscript
		}

Une instance Nextcloud est également hébergée sur ce site et quelques fichiers sont accessibles librement, notamment depuis d'autres articles de blogs (ici par exemple). La politique de log, définie dans config.php, de cette instance est la suivante :

'log_type' => 'owncloud',
		'logdateformat' => 'd-M-Y H:i:s O',
		'logfile' => '/var/log/nextcloud.log',
		'loglevel' => 2,
		'log_authfailip' => true,

Le niveau 2 correspondant au log d'avertissement (WARN) selon la documentation, donc votre IP n'est pas logguée ici si vous tentez de télécharger un fichier librement accessible. Le seul cas où cela peut arriver est normalement, encore une fois, en faisant une bêtise et en spammant l'authentification sur la page d'accueil de Nextcloud.

Parmi les autres logs pouvant contenir votre adresse IP, les logs Fail2ban. A moins de faire des bêtises, peu de chances de s'y retrouver. Les logs Nextcloud et Fail2ban sont conservés selon la même politique que pour Apache.

Enfin dernier log pouvant révéler une visite ici, le pare-feu. A raison de 5 entrées maximum par minute, les paquets jetés par iptables sont inscrits dans un fichier. Les données étant conservées une semaine.

Il reste entendu qu'un malveillant s'emparant du disque dur du serveur peut tenter une récupération de données effacées et donc des logs normalement supprimés.

Base de données

Le gros morceau, c'est la galerie Photos tournant sous Piwigo. Il y a derrière une base de données et cette dernière contient notamment par défaut deux tables, history et sessions, pouvant être problématique. sessions contient les id de session contenus dans les cookies envoyés par Piwigo aux visiteurs ainsi que quelques données (qui ne sont pas systématiquement les mêmes, la plus explicite que j'ai pu trouver est la taille de la fenêtre du navigateur. Ceci dit l'id de session reste problématique car si ce serveur et votre PC sont compromis, un lien peut être établi. history contient quand à elle notamment l'IP des visiteurs et les pages visitées :

MariaDB [piwigo]> SELECT * FROM piwi_history LIMIT 10;
+-------+------------+----------+---------+-----------------+--------------+-------------+---------+----------+------------+------------+-----------+-------------+
| id    | date       | time     | user_id | IP              | section      | category_id | tag_ids | image_id | summarized | image_type | format_id | auth_key_id |
+-------+------------+----------+---------+-----------------+--------------+-------------+---------+----------+------------+------------+-----------+-------------+
| 17315 | 2018-05-24 | 22:47:18 |       2 | 2001:db8:2505:1 | categories   |        NULL | NULL    |     NULL | false      | NULL       |      NULL |        NULL |
| 17316 | 2018-05-24 | 22:47:21 |       2 | 2001:db8:2505:1 | categories   |           4 | NULL    |     NULL | false      | NULL       |      NULL |        NULL |
| 17317 | 2018-05-24 | 22:47:23 |       2 | 2001:db8:2505:1 | categories   |           4 | NULL    |      385 | false      | picture    |      NULL |        NULL |
| 17318 | 2018-05-24 | 22:56:26 |       2 | 2001:db8:2505:1 | categories   |        NULL | NULL    |     NULL | false      | NULL       |      NULL |        NULL |
| 17319 | 2018-05-24 | 22:56:28 |       2 | 2001:db8:2505:1 | most_visited |        NULL | NULL    |     NULL | false      | NULL       |      NULL |        NULL |
| 17320 | 2018-05-24 | 22:56:31 |       2 | 2001:db8:2505:1 | most_visited |        NULL | NULL    |     1019 | false      | picture    |      NULL |        NULL |
| 17321 | 2018-05-24 | 22:56:36 |       2 | 192.0.2.128     | most_visited |        NULL | NULL    |     NULL | false      | NULL       |      NULL |        NULL |
| 17322 | 2018-05-24 | 22:56:37 |       2 | 192.0.2.128     | most_visited |        NULL | NULL    |      627 | false      | picture    |      NULL |        NULL |
| 17323 | 2018-05-24 | 22:56:38 |       2 | 192.0.2.128     | most_visited |        NULL | NULL    |     NULL | false      | NULL       |      NULL |        NULL |
| 17324 | 2018-05-24 | 22:56:40 |       2 | 192.0.2.128     | most_visited |        NULL | NULL    |      952 | false      | picture    |      NULL |        NULL |
+-------+------------+----------+---------+-----------------+--------------+-------------+---------+----------+------------+------------+-----------+-------------+

Le user_id correspond à l'utilisateur Guest. À noter que si vous utilisez IPv6, la nullité de MySQL et MariaDB (qui ne proposent toujours pas de types spécifiques pour manier les IPs) et le manque de sérieux des dévs de Piwigo vous protègent en partie, l'IP étant pour eux une chaine de caractères de longueur 15 au maximum :

CREATE TABLE `piwi_history` (
		...
			`IP` VARCHAR(15) NOT NULL DEFAULT '',

Bref, trêve de péroraisons : ces données sont inutiles (voir redondantes avec les logs), je ne les conserve qu'une journée. Une purge des tables est possible via la console d'administration de Piwigo, mais ce n'est pas la panacée. Par conséquent, tous les jours à 06:20, la table est purgée via un événement SQL :

CREATE EVENT `purge_piwi`
			ON SCHEDULE
				EVERY 1 DAY STARTS '2018-05-20 06:20:00'
			ON COMPLETION PRESERVE
			ENABLE
			COMMENT 'Purge quotidienne de la base Piwigo'
			DO BEGIN
				TRUNCATE piwi_history;
				TRUNCATE piwi_sessions;
			END

(avant le 20 mai, je conservais 2 semaines de données comme pour les logs mais à la réflexion cela est inutile)

La base est dumpée tous les jours à 06h29 et envoyée en tant que backup sur une autre machine. Là, ce dump est monté dans ce qu'on pourrait appeler une base miroir. Afin d'éviter les soucis entre l'heure de la suppression des données (06h20) et celle du dump (06h29 modulo les tâches en cours à cet instant), l'événement est répété sur la base miroir à 06h45.

Pour Nextcloud, point de requêtes en base de données à faire : pas de tables contenant l'historique des visiteurs et pas non plus, a priori, de table avec les cookies de session. Étant le seul utilisateur enregistré de l'instance, si les données personnelles qui y sont stockées se retrouvent dans la nature, c'est à moi-même que je devrais m'en prendre. Une petite remarque cependant si vous administrez une instance et que cette dernière possède quelques utilisateurs : par défaut l'application Activity, qui permet entre autre choses d'envoyer des notifications aux membres en cas de partages de fichiers, répertoires..., est activée et elle conserve en base des données personnelles (du type tel utilisateur a téléversé/effacé/partagé un fichier, ce genre de chose). Il est possible de configurer Nextcloud pour faire une purge de cette table. Dans le fichier config.php, ajouter :

'activity_expire_days' => 7,

(ou moins si vous voulez garder les données moins d'une semaine)

Cookies et autres joyeusetés

On l'a vu, Piwigo laisse un cookie de session sur votre machine. Ils y en a typiquement 4 (mais peut-être plus). Le premier nommé pwg_display_thumbnail qui vaut en général no_thumbnail_display, cap qui indique la taille de la fenêtre du navigateur et pwg_id du type a42d0riyyleetv5p33keujrgpd. Ils sont normalement valides jusqu'à la fin de votre session.

Nextcloud va lui déposer 4 cookies : le premier dont le nom (et le contenu) sont un identificateur technique, le deuxième nommé oc_sessionPassphrase est dont la valeur est une longue phrase de passe. Ces deux là sont censés expirer à la fin de la session. Les deux derniers nc_sameSiteCookielax et nc_sameSiteCookiestrict valent tous les deux true et expirent en 2101 (!). Dans tous les cas, pensez à configurer votre navigateur pour effacer ces petits gâteaux à sa fermeture.

Enfin, comme précisé sur la page À Propos :

Les seules requêtes externes que ce site fera sont la récupération de tuiles OpenStreetMap sur la partie Photos et rien d'autre. Voir la politique d'OSM concernant la vie privée. Si elle vous semble insupportable, bloquez toutes requêtes vers *.tile.openstreetmap.org avec une extension telle que Privacy Badger ou uMatrix. À noter que ce site utilise désormais l'entête Referrer-Policy de manière à ne pas envoyer d'entête referer vers d'autres sites (valeur : same-origin). Attention, la chose est récente et seul un navigateur compatible (Firefox l'est à partir de la version 52) sera en mesure de l'utiliser.

Je pense avoir fait le tour des données personnelles vous appartenant qui sont collectées en ces lieux et la manière dont je les gère. Cette politique me semble être raisonnable dans le compromis à faire entre rétention nécessaire de données pour les tâches d'administration et respect de la vie privée. Si ça ne vous semble pas le cas, on peut en discuter sur Mastodon ou autour d'une bière à l'occasion 🙂.