Informatique

La réplication quand on est auto hébergé

Tuesday, 20 October 2015
|
Écrit par
Grégory Soutadé

On ne le répétera jamais assez : avoir un serveur chez soi, c'est cool. On est réellement maître de ses données, de ce qu'on publie, de ce qu'on héberge, etc. Mais, parce qu'il y a toujours un mais, cela ne va pas sans contraintes. La première étant le débit montant. Avec une offre fibre, ce n'en est plus un (l'ADSL suffit si les fichiers ne sont pas trop gros). La seconde est l'administration. C'est une réalité, même s'il y a beaucoup de choses pour nous faciliter la vie (des paquets tout faits dans votre distribution préférée, voire une distribution dédiée). La dernière étant la disponibilité/réplication.

Disponibilité et réplication sont des notions inter dépendantes : pour avoir la première, il faut qu'en cas de panne, un autre serveur puisse prendre le relais. Donc, il y a nécessité de faire de la réplication (distante de préférence) et d'avoir un mécanisme qui permet de basculer automatiquement de l'un à l'autre. C'est le point que nous allons aborder aujourd'hui.

Pour faire de la réplication, il n'y a pas de miracles : il faut deux serveurs physiques avec (au moins) deux disques durs indépendants. Pour ma part, j'ai, d'un côté mon nouveau joujou "Déméter" (Cubox i2ex) en serveur principal (maître), et de l'autre, mon vieux Sheevaplug ("Cybelle"). Il faut ajouter à cela, un parent, un ami ou un collègue qui accepte d'héberger l'esclave.

Si la procédure est valable (et même cruciale pour un serveur), s'en est de même pour nos données personnelles en tant que particulier. Les inondations qui ont touchés la Côte d'Azur n'en sont que le triste exemple. J'habite au troisième étage ? Les canalisations du quatrième peuvent exploser, un incendie peut se déclarer, je peux être victime d'un vol. Donc dupliquez, dupliquez, dupliquez !

OpenVPN

La première étape est de configurer un tunnel OpenVPN entre les deux machines. Outre l'aspect sécurité d'un tunnel chiffré, OpenVPN est surtout très utile pour communiquer via une adresse (privée virtuelle) unique. On s'abstrait ainsi des problèmes de changement d'adresse IP, de résolution de nom.

Dans notre cas, on reporte la responsabilité de la création du tunnel sur l'esclave qui doit connaître l'IP publique du serveur maître.

Il faut ensuite mettre en place une configuration quasi similaire sur le maître et l'esclave, ce qui nécessite des petits réglages pas toujours évidents (surtout la gestion des différences).

Réplication

En ce qui concerne la réplication à proprement parler, il faudra appliquer différentes méthodes selon le service cible.

Pour un serveur web, des fichiers, des mails, on utilisera rsync.

rsync -auz root@cybelle:/var/mail /var

Pour une base de données, on s'appuiera sur le modèle maître-esclave de MySQL (dans mon cas)/PostgreSql/MariaDB...

Astuce : j'utilise une authentification SSH par clé pour l'utilisateur root sur l'esclave, valable uniquement à travers le tunnel OpenVPN.

On peut ainsi configurer un cron afin que tout soit automatique :

#!/bin/bash

HOST=soutade.fr

function cybelle_not_here()
{
    echo "Cybelle not here" | mail -s "Error" root@$HOST
    exit 0
}

# OpenVPN tunnel conectivity check
ping -c 1 cybelle >/dev/null || cybelle_not_here

# Get emails from Cybelle
rsync -auz root@cybelle:/var/mail /var
# Delete retrieved emails on Cybelle
ssh root@cybelle 'find /var/mail -name "*cybelle*" -delete'

# Push local data
rsync -auz /var/www root@cybelle:/var
rsync -auz /var/projects root@cybelle:/var
rsync -auz /home/soutade/www root@cybelle:/home/soutade

Cybelle est référencée dans /etc/hosts via son adresse privée OpenVPN.

Attention toutefois : même avec une sauvegarde distante, il est NÉCESSAIRE d'en faire une locale. Encore mieux, si elle est réalisée sur un disque chiffré. On notera que lors de la réplication (quotidienne), je lance une commande directement sur l'esclave (pour effacer les mails dans le cas présent).

DNS Failover

Maintenant que nous avons deux serveurs configurés sur deux sites distants, on peut commencer les choses sérieuses : la défaillance d'un des deux (surtout le maître). La solution proposée ici est une solution de pauvre et n'est pas recommandée pour un usage professionnel.

Nous allons discuter du DNS Failover (basculement DNS). L'idée est, qu'en cas de défaillance du serveur principal (maître), l'entrée DNS (NB: qui gère la correspondance nom de domaine/IP) soit mise à jour vers le serveur de secours (esclave). Cette solution (de pauvre) a deux inconvénients majeurs qui sont :

  • La mise à jour des serveurs DNS primaires est de l'ordre d'une demi-heure
  • Les entrées DNS peuvent être encore dans le cache du client (donc non rafraîchies)

Dans l'idéal, il aurait fallu avoir de l'IP failover, c'est-à-dire qu'un serveur frontal se charge de rediriger le trafic vers la bonne destination (celle qui est encore en vie). Mais cela nécessite des infrastructures beaucoup trop onéreuses pour les petits particuliers que nous sommes.

Pour la mise en pratique, j'ai modifié le script de mise à jour de DNS de Gandi afin qu'il retourne 34 quand une entrée vient d'être modifiée (détection d'un changement d'IP). Il affiche désormais sur la sortie standard l'ancienne et la nouvelle IP.

Sur l'esclave, un script est exécuté toutes les dix minutes. Il est chargé de vérifier que le maître est toujours vivant. Si ce n'est pas le cas, il change l'entrée DNS vers son IP actuelle (il réalise le basculement) :

#!/bin/bash

HOST=soutade.fr
MASTER_ADDRESS="10.8.0.1"

ping -c 4 checkip.dyndns.com 2>/dev/null || exit 0 # No internet connexion at all                                                          
ping -c 4 $MASTER_ADDRESS 2>/dev/null && exit 0 # Master is up, ouf !                                                                      
python /home/soutade/gandi.py || exit 0
echo `date` | mail -s "Fallback server (cybelle) activated" root@$HOST

Sur le maître, un autre script est exécuté toutes les dix minutes également :

#!/bin/bash

HOST=soutade.fr

vals=`python /home/soutade/gandi.py`
if [ $? -eq 34 ] ; then
    old_ip=`echo $vals | cut -d' ' -f9`
    new_ip=`echo $vals | cut -d' ' -f5`
    ssh -oStrictHostKeyChecking=no root@${old_ip} "sed -i -e 's/^remote .*$/remote ${new_ip}/g' /etc/openvpn/cybelle.conf ; service openvp\
n restart"
    echo `date` | mail -s "Master server (demeter) activated" root@$HOST
fi

Si le changement d'IP est effectif (changement d'IP au niveau FAI ou redémarrage du serveur), on va modifier la configuration OpenVPN de l'esclave avec notre nouvelle IP et relancer le service.

Un petit dessin pour bien visualiser les différentes situations :

Infrastructure dans le cas normal

Et en cas de défaillance du maître :

Basculement en cas de défaillance du maître

Dénote 0.1

Monday, 28 September 2015
|
Écrit par
Grégory Soutadé

Capture d'écran Dénote

Après le blog, on est à la limite du tutorial de base Django : une application de gestion de notes. D'ailleurs, un blog et un gestionnaire de note sont très proches au niveau structure du code et fonctionnalités.

Pourtant, c'est une application qui me manquait cruellement : Écrire des petites notes, pouvoir les stocker/organiser et y accéder de partout. Je n'ai pas trouvé ailleurs sur le web une appli open source en Python/PHP facilement installable chez soi.

Pourquoi ne pas utiliser le téléphone me direz-vous ? Et bien, quand on veut juste copier-coller un lien d'Internet, ajouter deux/trois commentaires pour y retourner plus tard, c'est bien plus pratique de le faire sur son PC. Je n'ai pas non plus envie d'être restreint aux seuls marque-pages.

Qu'en est-il de pastebin ? Je vous avais vanté les mérites de ce petit logiciel de copier-coller communautaire. Il faut reconnaître qu'il est bien pratique pour s'échanger des bouts de code (ou autre) pendant une courte durée. Mais, dès qu'ils s'agit de garder et d'organiser ses "pastes", et bien on atteint très vite ses limites.

Voilà donc "Dénote" en version 0.1. Ses fonctionnalités sont :

  • Ajout/suppression de note
  • Syntaxe markdown (avec support de la coloration de code)
  • Catégories

Que du très classique, avec un design simple, mais qui colle assez bien à l'application (de mon point de vue). J'ai eu la joie de réaliser tout le design (c'est quand même mieux que gPass), et, pour être honnête, je le trouve plutôt sympa.

Comme d'habitude les sources sont disponibles sur ma forge sous licence GPLv3. Il existe une instance ouverte (soumise à création de compte (un minimum d'info est demandé)) est disponible ici, c'est celle que j'utilise.

De mon point de vue, il manque encore la recherche ainsi que (éventuellement) un système de note publique/privée (actuellement tout est privé).

À défaut d'être révolutionnaire, cette petite m'a permis de remonter les soucis de conflit lorsque l'on fait tourner deux applications Django dans une même instance Apache.

Bitcoin en interne

Thursday, 20 August 2015
|
Écrit par
Grégory Soutadé

Tout le monde connaît le Bitcoin, au moins de nom. Un truc obscure, monnaie virtuelle qui fonctionne en réseau, ou quelque chose comme ça...

Le Bitcoin en tant que monnaie virtuelle a beau être volatile, on ne peut s'empêcher de penser que son taux a fait fois 10 000 en quelques années (création en février 2009), et, peut-être regretter de ne pas s'y être intéressé avant.

Pour cet article, je laisserai de côté les questions morales de son utilisation, souvent liées à des activités frauduleuses.

Récemment, j'ai organisé une collecte de fond auprès des collègues de travail. En plus des traditionnels liquides, chèques, virements bancaires et Paypal, j'ai aussi proposé en l'air le Bitcoin.

J'ai donc cherché des outils pour manipuler cette devise et suit tombé sur Electrum. il s'agit d'un client (SPV) très complet qui a deux avantages majeurs :

  • Le portefeuille est en local
  • Il a une interface en ligne de commandes

C'est en voyant des termes barbares (UTXO, merkel root...), que j'ai commencé à me demander "Comment fonctionne réellement le Bitcoin ?". Je suis alors tombé sur le site bitcoin.org qui propose énormément de ressources sur cette crypto monnaie, et tout particulièrement la section "développeur" (en anglais uniquement) vraiment très bien expliquée. Je vais essayer de résumer les concepts clés à travers cet article. Tous les schémas proviennent de la page développeurs.

Bitcoin en interne

En plongeant des les détails techniques, on se rend compte que le Bitcoin est bien plus qu'une monnaie virtuelle. Nous avons affaire à un véritable système de transactions ! D'un point de vue théorique et mathématique, le système est très pur (extrêmement bien conçu). Pour autant, il n'y a rien de vraiment "neuf", mais c'est un assemblage très élégant de concepts modernes.

Comme je l'ai dit plus haut, le système Bitcoin est avant tout un système de transactions. On ne possède pas directement des bictoins, mais le droit d'utiliser le montant d'une transaction précédente. Comme illustré ci-dessous :

Propagation des transactions

Dans le schéma ci-dessus, il est question de satoshis, pour être au clair :

  • 1.0 = 1 bitcoin (BTC)
  • 1/100 (0.01) BTC = 1 bitcent (cBTC)
  • 1/1000 (0.001) BTC = 1 millibitcoin (mBTC)
  • 1/100000 (0.000001) BTC = 1 microbitcoin (uBTC, “bits”)
  • 1/10000000 (0.00000001) = 1 satoshi

1 Satoshi est donc un dix millionième bitcoin, c'est l'unité minimale.

L'utilisateur a donc à disposition des Unspent Transaction Outputs (UTXO). C'est-à-dire, des sorties de transactions non dépensées, donc non utilisées par des entrées de transactions suivantes.

Lors de la création d'une nouvelle transaction, il faut indiquer le(s) numéro(s) de(s) la sortie(s) précédente(s).

La phobie du concepteur (et des utilisateurs) étant la double dépense (double spent) : qu'un utilisateur dépense deux fois sa monnaie. C'est particulièrement vrai par le fait que les transactions ne sont intégrées au réseau de façon sûre qu'à partir de 10 minutes, avec la validation d'au moins un nœud (transaction valide à 75%). C'est l'effet P2P.

Pour éviter la double dépense, le réseau doit donc s'assurer que les sorties ne sont utilisées qu'une seule fois.

L'ensemble des transactions sont conservées à vie dans la "blockchain", une sorte de grand livre des comptes. On peut ainsi vérifier TOUTES les transactions depuis le bloc (genesis block).

Aperçu de la Blockchain

Cette blockchain est maintenue via un réseau pair à pair (peer-to-peer/P2P, comme bittorent) dans lequel des serveurs vérifient et insèrent les transactions. Mais, pour avoir le droit d'insérer des transactions, il faut fournir une preuve de travail. Preuve qui peut aussi rapporter des bitcoins (c'est le minage/mining) aussi appelée coinbase (transaction de base qui permet de créer des bitcoins).

La preuve de travail est simple : L'entête fait 80 octets, avec notamment 4 octets de libre. Pour avoir le droit d'insérer la transaction, il faut trouver une combinaison telle que le résultat de la fonction de hashage sha256 de l'entête soit inférieure à une valeur décidée par le réseau. Cette valeur est mise à jour tous les 2016 blocs. Pour schématiser :

SHA256(header) <= 00000000XXXXXXXXXXXXXXXXXXXXXXX.

Il est prévu que l'insertion de 2016 blocs dure environ deux semaines. Si ce n'est pas le cas, la difficulté pour insérer les blocs est augmentée ou diminuée consensuellement.

Si un attaquant veut modifier une transaction, il doit détenir 51% de la puissance de calcul du réseau afin de la faire accepter aux autres pairs.

Qui dit travail, dit récompense. Les serveurs qui insèrent vos transactions dans la blockchain s'assurent de la validité de celles-ci. En échange, l'utilisateur paie des frais de transaction (fees). Ces frais sont variables d'un serveur à l'autre, le minimum étant 10 000 satoshis. Au final, ce système peut rapporter pas mal aux serveurs en place.

On notera l'utilisation d'un arbre de Merkle pour la partie données. Le principe est le suivant : La valeur du niveau n est la valeur du hash de ses descendants de niveau n+1, jusqu'à la racine (merkle root).

La partie de données peut contenir de une à n transactions (groupées par bloc/block). Empaqueter un ensemble de transactions permet de mutualiser l'entête, donc de réduire le travail à fournir.

Description d'une transaction

Mais, si on regarde d'encore plus près, on se rend compte à quel point le Bitcoin est un système fascinant. En effet, une transaction est composée d'un index (pour l'identifier dans un bloc de la blockchain), d'un locktime, des indexes des transactions d'entrée et d'un script !

Le langage utilisé est un dérivé du Forth, un langage de programmation à pile. Il détermine les conditions pour lesquelles la transaction est valide. Le montant est la somme de toutes les entrées et peut être divisé en plusieurs sorties.

Le script lui-même contient les clés publiques, les signatures et demande (le plus souvent) à ce que 1 à n signatures soient présentent et valides. Ce script doit être approuvé par le receveur.

La durée de verrouillage (locktime) est la durée durant laquelle la transaction ne peut être intégrée à la blockchain. Si l'émetteur change d'avis avant la durée du lock, il peut envoyer une transaction d'annulation (qui utilisent les mêmes entrées et donc rend caduque la transaction précédente qui n'a pas encore été insérée, quitte à se retourner ses propres bitcoins).

Côté signature, Bitcoin utilise les courbes elliptiques 256 bits ainsi que du SHA256. Les données (notamment les clés) étant présentées en base 58 pour être "plus" facilement lisibles.

Dans le cas où le montant des entrées (inputs) est supérieur à celui des sorties (outputs), la différence est encaissée par le serveur au titre de frais de transaction. Si le montant total des entrées (indivisible) est largement supérieur à que l'on souhaite dépenser, on va ajouter une transaction supplémentaire vers notre propre portefeuille pour encaisser le surplus. L'adresse de réception est dans ce cas dénommée adresse de "change" (change address).

Cas d'utilisation

La souplesse du système (malléabilité des transactions/transaction malleability) amène à plusieurs cas d'utilisations.

Le cas le plus classique est la transaction simple : le script contient la clé publique de l'émetteur, sa signature et demande la vérification de ces deux éléments.

Là où ça devient drôle, c'est dans le cas de signatures multiples.

Le contrat "d'escrow" par exemple. Il s'agit d'un type de contrat qui implique deux acteurs et un arbitre. Pour qu'il soit valide, il faut deux signatures. En cas de conflit, les deux acteurs se tournent vers l'arbitre. Celui-ci propose une solution (remboursement à hauteur de X%) et émet une transaction qui doit être signée par au moins un des deux acteurs (en plus de sa propre signature).

Autre exemple qui implique un verrouillage : le micro paiement à la tâche. Bob veut payer 100 satoshis à Alice (correspondant à 100% de ses objectifs). Il crée alors deux transactions. La première contient les 100 satoshis à destination d'Alice et la seconde utilise la sortie de la première (le compte d'Alice) et retourne les satoshis à Bob avec une durée de verrouillage de 24h. Ell aura comme numéro de séquence 1.

En fin de journée, Alice fait signer à Bob un "bon" (bond) comme quoi elle n'a réalisée que 70% du travail. Elle va donc créer une transaction qui va rembourser Bob de 30 satoshis (en utilisant la sortie de la première transaction) avec un numéro de séquence > 1. Une fois signée par Bob, elle pourra l'envoyer au réseau (broadcast). Il faudra bien sûr l'envoyer avant la réalisation de la seconde transaction (plus le temps de traitement). Si tout se passe bien, la second transaction (numéro de séquence 1) ne sera plus valide.

Entre temps, Alice peut envoyer à Bob plusieurs bons (en incrémentant le numéro de séquence), sans les émettre sur le réseau. C'est un exemple de transaction "privées" (non émise).

Dernier exemple : pour brouiller les pistes quant au traçage des bitcoins, plusieurs personnes peuvent créer une transaction à signature multiple dans laquelle ils vont provisionner à valeur égale une certaine somme. La sortie sera mélangée et redistribuée à chacun d'entre eux (à parts égales). C'est ce qu'on appelle le CoinJoin.

Anonymité du Bitcoin

Contrairement à ce que l'on pense, le Bitcoin n'est pas anonyme, puisque toutes les transactions sont enregistrées à vie dans la blockchain. Du coup, si on arrive à associer une adresse à une personne, on a accès à toutes ses transactions. Pour pallier à cela, il est recommandé d'utiliser une adresse publique différente lors de chaque transaction.

Gestion des clés

Dérivation de la clé maître

Le portefeuille (wallet) qui stocke les Bitcoin contient une clé maître générée à partir d'une graine (seed). La clé maître génère elle-même n sous clés (publiques et privées). Les propriétés des courbes elliptiques permettant, en effet, de tout dériver à partir de la graine (Il est donc important de bien la protéger !).

Ceux qui ne comprennent pas la notion de clé publique/privée pourront jeter un œil sur l'articule Wikipedia consacré à la cryptographie asymétrique. Globalement, la clé privée permet de signer une transaction et sa correspondante publique permet de vérifier la signature. On diffuse la publique et on garde secrètement la privée.

La valeur du porte-monnaie sera donc celle de la somme de toutes les transactions de sortie non dépensées (UTXO) de toutes les sous-clé publiques.

Sécurité du Bitcoin

Bitcoin est utilisée comme monnaie virtuelle, on n'en voit jamais la couleur. Finalement, ce n'est pas si différent de nos comptes bancaires directement crédités par l'employeur et débités via des cartes bancaires. Néanmoins, après le casse du siècle sur le site Mt. Gox où des centaines de milliers de bitcoins ont disparus, on peut se poser la question de la sécurité.

Il existe plein de services sur Internet qui disent tout gérer pour vous. Votre portefeuille se retrouve en ligne, et on y accède via un compte. Si le serveur se fait pirater, tout est perdu !

La solution originale est d'exécuter sur sa machine les utilitaires bitcoin et bitcoind afin de gérer à 100% son installation (et accessoirement se passer de frais de transactions). Un peu lourd quand on connaît la taille actuelle de la blockchain (plus de 37GB)...

L'alternative qui a été développée est un gestionnaire de portefeuille qui utilise le Simplified Payment Verification (SPV) ou encore Vérification Simple des Paiements. Electrum fait partie de ceux-ci. Cette alternative offre l'avantage d'avoir un portefeuille en local sur la machine, mais d'utiliser un serveur distant pour l'insertion des transactions. Il ne va télécharger que quelques morceaux de la blockchain lorsqu'il devra vérifier une transaction. Reste éventuellement le problème de la synchronisation entre plusieurs périphériques (ordinateurs, tablettes, smartphones...)

Le Bitcoin ayant un équivalent (volatile) en euros, il est important de bien stocker le portefeuille, de le dupliquer, et même de le chiffrer (même si la graine est sensée déjà l'être).

Conclusion

Le système Bitcoin est un projet extrêmement bien pensé et a sûrement été réfléchi et mûri pendant des années avant d'apparaître sur la toile. Sa conception est un véritable travail de chercheur !

Malgré ses 6 ans d'âge, l'engouement reste assez limité, clairement dû à la volatilité du cours. Et même s'il a fait des petits, ses concurrents tels que litecoin, peercoin, dogecoin... restent très méconnus et beaucoup moins utilisés.

La qualité de bitcoin.org est le reflet d'une communauté très active qui essaie de promouvoir l'utilisation de sa crypto monnaie. Un exemple de ce dynamisme est l'utilisation d'URL simplifiée bitcoin:// pour réaliser des transactions ou encore l'utilisation des Codes QR.

Le Bitcoin est-il une autre bulle qui explosera ? À voir. Le traçage de plus en plus systématique et important de la population l'amènera peut être à détrôner un jour le système bancaire classique...

LUKS on Cubox (imx6 platform)

Sunday, 09 August 2015
|
Écrit par
Grégory Soutadé

Now I have a Cubox (i2ex), I wanted to encrypt my backup disks. I followed this excellent tutorial. The cipher recommendation is aes-xts-plain64. So, I created formated disk, encrypt it, copy data from my computer and connect it to the Cubox.

But, I get this error :

cryptsetup --type luks open /dev/sda1 backup
Enter passphrase for /dev/sda1: 
No key available with this passphrase.

I tried a couple of times, use a keyfile. Nothing worked !! It made me crazy. After a bunch of search, I found that the current kernel in the Debian image from Igor Pečovnik is 3.14.14 and has issues with NEON AES implementation.

I cannot blacklist the module as it's builtin. The solution is to build a new module from the latest 3.14.49 kernel (maintained by Greg Kroah-Hartman). Ouf ! I increased cra_priority to be sure to use the new implementation.

Instructions

In the Cubox :

  • Install kernel headers (already here in the image)
  • Download the latest 3.14 kernel from kernel.org
  • Decompress it
  • Apply this patch
  • Compile
  • Install
  • Reboot

Commands :

patch -p1 < crypto.patch
cd linux-3.14.49/arch/arm/crypto/
make
sudo make install
sudo echo aes-arm-bs >> /etc/modules
reboot

If you just want to test :

insmod aes-arm-bs.ko

Precompiled version

A precompiled version is available here. To manually install it :

sudo cp aes-arm-bs.ko /lib/modules/3.14.14-cubox-i/extra/
sudo depmod
sudo echo aes-arm-bs >> /etc/modules

Or just

sudo make install
sudo echo aes-arm-bs >> /etc/modules

IWLA 0.2

Thursday, 16 July 2015
|
Écrit par
Grégory Soutadé

Capture d'écran IWLA

Deuxième version d'IWLA, le clone d'AWSTATSl'analyseur de log web écrit en Python.

Qu'est ce qu'on trouve dans cette version ? Et bien ... tout. Cette version arrive au niveau d'AWSTATS en ce qui concerne mon usage, et même le dépasse !

Quelques fonctions non présentes dans AWSTATS :

  • (Meilleure) Détection des robots
  • Affichage des différences entre deux analyses
  • Ajout facile des ses propres moteurs de recherche
  • Traçage d'IP
  • Détection de lecteur de flux RSS
  • Support des fichiers de log compressés

Pour le reste, on retrouve toutes les briques de bases. Mon seul regret est de n'avoir pas encore mis en place les tests automatiques.