lalahop
Categorie: Administration système

À la recherche d’un MUA

Il y a 2 mois, je décidais d'utiliser exclusivement mes serveurs de mails personnels ou ceux d'entités de confiance. Adieu donc les Hotmail, Gmail, FAI, ... Et vous verrez plus loin que mon choix est antérieur au NSA-gate. 😉 Histoire de tout faire en une seule fois, j'ai harmonisé les boîtes mail restantes et notamment le protocole de consultation (IMAP partout) et je me suis intéressé aux différentes manière de trier mes mails. Et, forcement, j'ai décidé de comparer les clients mail (MUA) existants pour voir si un autre MUA conviendrait mieux à mes besoins que Icedove (aka Thunderbird chez Debian). Je vais tenter de résumer tout ça dans ce billet bordelique.

Si vous êtes tombé sur ce billet alors que vous cherchez à mettre en place votre propre serveur mail, je vous redirige vers la partie « Courrier électronique » de wiki.auto-hebergement.fr et vers Postfix tranquille chez Karchnu pour l'installation basique et vers Sécuriser un serveur de mail chez Tetaneutral.net pour les techniques avancées.

Table des matières

FAQ

Avant d'entrer dans le vif du sujet, je vais répondre, de manière publique, aux deux questions que l'on m'a le plus souvent posées :

  • « Comment as-tu réussi la transition si vite et à faire en sorte que les gens ne t'écrivent plus que sur les nouvelles adresses ? ». Je n'ai pas fait la transition en seulement deux petits mois :
    • J'ai prévenu depuis janvier 2013 qu'à partir de juillet 2013, je ne recevrai plus les mails sur les anciennes adresses. Et j'ai été ferme sur le fait que je n'irai pas sur le webmail les lire. M'envoyer un mail aux anciennes adresses, c'est perdu ! Pour le reste, à savoir les mailing-list (liste de discussion) auxquelles je suis abonné et les entreprises/administrations/associations auxquelles j'ai donné mon adresse, j'ai effectué le changement d'adresse sur leur site web dès janvier et cela s'est très bien passé ... sauf pour 2 banques (une personnelle, l'autre pour une association) dans lesquelles il faut prendre un rendez-vous avec un conseiller pour changer une adresse mail ... Oui, en 2013, oui, oui, oui !
    • Entre janvier et juillet, à chaque fois que j'ai reçu un mail sur ce qui allait devenir une ancienne adresse, je répondais au mail, en indiquant, dès le début du mail, qu'il ne fallait plus utiliser cette adresse et en positionnant un en-tête « reply-to » (Réponse à) contenant la nouvelle adresse.

    Bilan : seulement 2 personnes n'ont pas compris et se sont plaintes récemment que je n'ai pas répondu à leurs mails ...

  • « Tu ne perds pas de mails ? ». Quasiment non. J'ai demandé à un maximum de personnes, qui utilisent des fournisseur d'adresses mail bien différents, de tester et il s'avère que le seul fournisseur chez qui mes mails tombent dans le dossier SPAM, c'est le casse-couille de la profession, à savoir, Hotmail ! Cela ne concerne que le premier mail, tant que la personne qui possède l'adresse Hotmail ne vous a jamais répondu ou écrit de sa propre initiative. Non, je ne suivrai pas leur procédure pour me faire autoriser : le mail est normalisé, je n'ai pas à suivre les instructions d'une entreprise particulière pour envoyer des mails ! Je pense avoir mis en place suffisamment de procédés normalisés (SPF, DKIM, reverse v4/v6 corrects, TLS, ...) pour que l'on se doive de me foutre la paix !

Choix d'un MUA

Je cherchais un MUA qui réunit ces quelques critères :

  • Logiciel libre.
  • Un client lourd, pas un webmail.
  • KISS. Je n'ai pas besoin d'avoir un agenda intégré, j'ai déjà un agenda. Je n'ai pas besoin d'avoir un gestionnaire de TODO intégré. Bref, je veux juste du mail.
  • Support de la fonctionnalité IDLE d'IMAP. Cela permet au client d'indiquer au serveur qu'il souhaite être notifié en temps-réel de l'arrivée de nouveaux mails.
  • Stockage des mails au format Maildir. Un mail par fichier par opposition à Mailbox avec lequel un fichier stocke toute une boîte. Maildir est réputé plus efficaces sur un volume moyen de mails. Mais surtout, un mail par fichier permet une sauvegarde impeccable et une restauration facile quand le MUA pète les plombs et dégage un mail ou mélange les en-têtes d'un mail avec le contenu d'un autre ... Si, si, si, ces deux cas me sont déjà arrivés avec Thunderbird. Heureusement, j'avais une sauvegarde mais du coup, les mails n'apparaissent plus dans le client. Pour les relire, il faut que j'ouvre la sauvegarde. Et c'est moyen-moyen.

L'ergonomie est un critère secondaire.

Si l'on exclut les clients mail dont l'implémentation de Maildir est un patch dont on ne sait pas si c'est stable ou non, il reste :

  • Mutt
  • KMail
  • Evolution
  • Icedove (aka Thunderbird)

Voici les avantages et les inconvénients que j'ai trouvé à chaque client.

Mutt :

  • + Je l'utilise déjà mais je souhaite quand même utiliser un autre client en parallèle le temps de finir d'apprendre les combinaisons de touches les plus utiles au quotidien. Histoire d'être efficace et surtout histoire de ne pas faire d'erreurs de manip' du genre « oooops, tiens, cette boite mail était vide avant ? ». 😛
  • + KISS.
  • + Contrairement à tous les autres MUA, l'affichage des nouveaux mails est efficace : ouvrir un dossier et pouf, la sidebar affiche tous les nouveaux messages dans tous les dossiers. Avec Icedove/Evolution, je suis obligé de survoler l'intégralité des dossiers pour voir les nouveautés dans les dossiers.
  • + Léger ... Il ne prend pas 95 % du CPU pendant plusieurs dizaines de secondes pour relever une BAL.
  • + Maildir par défaut (voir dans Mutt/cache/BAL/).
  • - Je suis le seul avec qui Mutt segfault parfois. 🙁

KMail :

  • - Bien que les devs et la doc indiquent que KMail supporte IMAP IDLE, je n'ai pas trouvé ça fonctionnel.
  • - L'ergonomie de l'interface est vraiment, vraiment mauvaise. Pareil pour la mise en place d'un compte ... L'utilisation au quotidien est juste affreuse.

Evolution :

  • - N'est pas KISS : il fait aussi TODO, agenda, ...
  • - Pour voir si j'ai de nouveaux mails dans mes dossiers, je suis obligé de survoler l'intégralité des dossiers pour voir les nouveautés dans les dossiers.
  • + Maildir.
  • - Niveau ergonomie, on n'est pas loin de KMail ... Notamment, quand le texte d'un mail dépasse la fenêtre, impossible de scroller, il faut forcement utiliser l'ascenseur ou les flèches du clavier ...
  • - Il reste quelques petits bugs, par-ci, par-là. Il y a des paramètres (mapping/port d'un serveur par exemple) qui sautent sans raison lors d'un re-démarrage du logiciel donc il faut insister plusieurs fois pour que ça soit bien pris en compte.
  • - Evolution range les mails/paramètres/autre dans pas moins de 4 dossiers dans le home directory. Bon courage pour la sauvegarde ! Au moins Thunderbird et Mutt mettent tout dans un même dossier.

Icedove/Thunderbird :

  • + Le poids des habitudes : je n'ai connu que Thunderbird en client mail graphique donc y renoncer maintenant s'avère difficile.
  • + Quasiment KISS (mail + newsgroups sauf si des extensions sont installées (iceowl pour faire agenda, par exemple).
  • - Pour voir si j'ai de nouveaux mails dans mes dossiers, je suis obligé de survoler l'intégralité des dossiers pour voir les nouveautés dans les dossiers. ÉDIT du 19/09/2013 à 20h05 : Lire les commentaires de JB, le pourquoi du comment y est tout bien expliqué. Solution provisoire : mettre « mail.server.default.check_all_folders_for_new » à « true », solution définitive à long terme : IMAP NOTIFY (RFC 5465). Fin de l'édit
  • - L'implémentation de Maildir est récente, activable via de la bidouille dans les fichiers de configuration. Il y a eu des bugs importants ces derniers temps (déplacement foireux (l'original n'est pas effacé), une mise à la corbeille foireuse) et il en reste encore d'après le bugtracker (même si certains sont plus des PEBKAC que des bugs). Vu qu'elle est expérimentale, cette implémentation peut subire des changements radicaux (ie : les devs peuvent penser « ceux qui l'activent le font en connaissance de cause donc on peut se permettent de casser la compatibilité par la suite, les utilisateurs sont des beta-testeurs, ils s'attendent à perdre éventuellement des mails »).
  • - Lourdeur : 95 % du CPU pendant plusieurs dizaines de secondes pour juste parler IMAP ?! O_O

En fait, je me suis rendu compte que la première partie de la devise de Mutt, « All mail clients suck. », est vraie.

En conséquence, en attendant de savoir manier totalement Mutt pour mes usages quotidiens, j'ai choisi de continuer à utiliser Icedove/Thunderbird sans Maildir. En ce qui concernant les boîtes mail que j'auto-héberge (la majorité), j'ai une sauvegarde issue du serveur donc elle est au format Maildir. Pour les autres, j'ai la sauvegarde du dossier Icedove donc Mailbox mais sauvegarde quand même.

Tri du courrier

Il existe plein de mécanismes différents pour trier et filtrer ses mails.

Chaque MUA permet de le faire avec sa syntaxe précise.

Il est aussi possible d'utiliser des langages côté serveur. Cela permet d'avoir les mêmes règles de tri/filtrage quel que soit le client utilisé (client lourd, webmail, ...) puisque les mails sont triés sur le serveur et non plus par le client. Et c'est portable (si l'on change de MUA, que l'on oublie de sauvegarder sa config, ...). Il existe plein de mécanisme côté serveur : procmail, maildrop, Sieve, ...

Je me sers de Sieve, via Dovecot LDA, sur un de mes serveurs de mail et de procmail sur les 2 autres. Je m'en sers exclusivement pour déplacer un mail dans un dossier en fonction d'un critère : comparaison de l'en-tête « List-Id » pour identifier un mail d'une liste de discussion, comparaison du delimiteur dans l'adresse mail du destinataire pour identifier l'origine, une communauté, un service, ... ou pour supprimer les mails envoyés par des réseaux asociaux.

Pour les avantages et les inconvénients de procmail :

  • + Offre de grandes possibilités ;
  • - La courbe d'apprentissage est raide ;
  • - N'est pas normalisé.
  • - Pour modifier les règles, il faut avoir accès au serveur.

Pour les avantages et les inconvénients de Sieve :

  • + Normalisé. Plusieurs implémentations sont disponibles (Dovecot, Cyrius, ...) ;
  • + Facilité de prise en main / human-readable ;
  • - Moins de possibilités pour les utilisateurs expérimentés et exigeants.
  • + Pour modifier les règles, on peut utiliser Manage Sieve, un protocole dédié. Une extension Thunderbird existe pour cela mais je ne sais pas ce qu'elle vaut : j'ai un shell sur mes serveurs persos, quand même :P.

Utiliser procmail et/ou Sieve

procmail

Pour utiliser procmail avec Postfix, il suffit de rajouter ce qui suit au main.cf :

mailbox_command = /usr/bin/procmail -f- -a $USER -a $EXTENSION

« $EXTENSION » permet de fournir le texte après le délimiteur (exemple : toto dans guigui+toto@) à procmail. Cela permet d'écrire des règles qui matcheront cet élément. Source : Postfix Configuration Parameters - Mailbox command. ÉDIT du 19/09/2013 à 19h35 : Avant de me faire troller, je précise que le délimiteur n'est pas forcement le caractère « + » et qu'il peut être changé. Avec Postfix, il faut voir ça avec la directive de configuration « recipient_delimiter ». Fin de l'édit

Ensuite, il faut rajouter les instructions générales et les recipes (les règles) dans un fichier (.)procmailrc. Il peut se trouver dans /etc/ et il s'appliquera en conséquence à toutes les boîtes mail hébergées sur le système. Il peut se trouver dans le home directory (.procmailrc) d'un utilisateur auquel cas il s'appliquera uniquement à la boîte aux lettres de cet utilisateur. Si les deux existent, procmail exécutera d'abord celui contenu dans /etc/ puis celui contenu dans le home directory. Source : man procmail (« If no rcfiles and no -p have been specified on the command line, procmail will, prior to reading $HOME/.procmailrc, interpret commands from /etc/procmailrc (if present). »).

Du coup, je me sers de /etc/procmail pour indiquer des instructions générales (log, dossier par défaut si le dossier précisé dans une règle n'existe pas, ...) dans /etc/procmailrc. Les règles se trouvent dans mon home directory. Voici, par exemple, le contenu de mon fichier /etc/procmailrc :

SHELL=/bin/false
PATH=/bin:/usr/bin:/usr/local/bin
 
LOGFILE=/var/log/mail/procmail.log
VERBOSE=no
 
DROPPRIVS=yes
 
LOGNAME=$USER
MAILDIR=$HOME/Maildir
DEFAULT=$HOME/Maildir/new
ORGMAIL=$MAILDIR/new

Attention :

  • Sur le web, j'ai déjà vu des procmailrc contenant « DEFAULT=$HOME/Maildir/cur ». Cela me semble être incorrect. Le format Maildir indique que le MTA/MDA place le mail dans tmp durant sa réception puis le déplace dans new dès la réception complète. Seul le MUA déplace le mail dans cur. Or, procmail n'est pas un MUA. Source : Maildir sur Wikipedia.
  • Procmail s'enlève les droits dès qu'il parse l'instruction « DROPPRIVS ». Donc la mettre avant « LOGFILE » empêche procmail de logger (dans /var/log/* j'entends).

Quelques exemples de règles :

DELIM = $2
 
# Les listes de discussion de la FFDN seront rangées dans le dossier FFDN 
:0:
* ^List-Id:.*lists.ffdn.org
$HOME/Maildir/.FFDN/
 
# Tout ce qui arrive sur l'adresse guigui+toto@ va dans le dossier toto
:0:
* DELIM ?? ^^toto^^
$HOME/Maildir/.toto/

## Pour dégager les réseaux asociaux
# LinkedIn - premier mail
:0H:
* ^Subject:.*Check out my profile on LinkedIn.*
/dev/null

# LinkedIn - relances
:OH:
* ^From: .*invitations@linkedin.com
/dev/null

## Fin dégager les réseaux asociaux

Pour apprendre à écrire vos règles procmail, je vous recommande les ressources suivantes :

Sieve avec Dovecot LDA

Pour utiliser Dovecot LDA avec Postfix, il suffit de rajouter ce qui suit au main.cf :

mailbox_command = /usr/lib/dovecot/dovecot-lda -f "$SENDER" -a "$RECIPIENT" -d "$USER"

Il faut également ajouter ce qui suit dans /etc/dovecot/dovecot.conf (ou dans les bons fichiers dans conf.d pour ceux qui veulent faire propre et version 2 compliant) :

protocol lda {
        mail_plugins = sieve
        postmaster_address = postmaster@votredomaine.example
}
 
plugin {
         sieve = ~/.dovecot.sieve
}

Source : The Perfect Server - OpenSUSE 12.2 x86_64 (Apache2, Dovecot, ISPConfig 3 - Page 4.

Ensuite, il ne reste plus qu'à placer les règles dans ~/.dovecot.sieve (qui est le fichier que nous avons indiqué dans la directive « sieve » dans dovecot.conf). Le log s'ajoute directement dans le log général, avec les tentatives de connexions IMAP/POP.

Quelques exemples de règles :

require ["fileinto", "envelope", "subaddress"];
 
# Les listes de discussion de la FFDN seront rangées dans le dossier FFDN 
if anyof (
	header :contains "List-Id" "lists.ffdn.org",   # Si le mail vient de la ML 
	header :contains "Subject" "[FFDN]"            # ou réponse hors-liste (fictif)
) {     
	fileinto "FFDN";
	stop; # Pas la peine de parcourir le reste des règles
}
 
# Tout ce qui arrive sur l'adresse guigui+toto@ va dans le dossier toto
if envelope :detail "to" "toto" {
	fileinto "toto";
	stop;
}

# Pour dégager les réseaux asociaux
if anyof (
       # LinkedIn (premier mail + relances)
       header :is ["Subject"] "Check out my profile on LinkedIn",
       address :is ["From"] "invitations@linkedin.com"
)
{
       discard;
       stop;
}

Pour apprendre à écrire vos règles Sieve, je vous recommande les ressources suivantes :

Trucs & astuces

Icedove/Thunderbird

Si vous utilisez les délimiteurs dans votre adresse mail (exemple : toto+commerçantA@votredomaine.example ou toto+listeDeDiscussionA@votredomaine.example) pour trier votre courrier plus facilement et savoir qui a revendu votre adresse mail, vous pouvez avoir besoin d'envoyer des mails avec comme adresse d'expéditeur, l'adresse complète soit toto+listeDeDiscussionA@votredomaine.example et non pas uniquement toto@votredomaine.example. C'est typiquement le cas pour les listes de dicussions : le gestionnaire de la liste (sympa, mailman, ...) n'acceptera vos mails que s'ils contiennent l'adresse d'expéditeur indiquée lors de votre inscription à la liste.

Evidemment, vous n'allez pas créer autant de compte dans votre MUA que d'adresse mail différente : Thunderbird (comme les autres MUA) permet de lier plusieurs identités à un compte mail. Voir : Multiple identities per e-mail account.

Paramètres des comptes -> Sélectionner le compte concerné -> Gérer les identités -> Ajouter -> saisir juste le nom et l'adresse mail avec le délimiteur -> Ok *3.

Créer des adresses mail temporaires auto-hebergées

Voir : Service d'adresse de redirection temporaire. Je trouve ça excellent !

Le mécanisme d'alias vous permet de créer des adresses temporaires pour votre domaine. Les alias virtuels permettent de créer des alias qui sortent de votre domaine, pour des amis, une petite communauté, ... Il n'est pas nécessaire d'utiliser le script PHP (sauf si vous ouvrez votre service à tout le monde, bien sûr) : il suffit d'ajouter/supprimer des alias.

Mutt

Sous Mutt, impossible de se passer de mutt-sidebar. Sous Debian, c'est le package mutt-patched qu'il faut installer.

Pour vous faire une config Mutt qui ne craint pas trop, je vous recommande ces deux ressources : Desktop in a shell: mutt et Mutt sur le wiki Archlinux.

Pour utiliser plusieurs adresses mail sans les rediriger sur une seule, il suffit d'utiliser les profiles. Je ne sais pas pourquoi je lis à droite et à gauche « hola, c'est compliqué, utilises des alias plutôt » ... Le commutateur « -F » permet de préciser un muttrc différent de ~/.muttrc. Il suffit donc de créer autant de profiles (et donc de fichiers) que de boîtes aux lettres différentes, contenant chacun les informations nécessaires pour utiliser une BAL (paramètres généraux, IMAP, SMTP, ...). Tout en utilisant la directive « source » pour inclure un fichier contenant les directives communes à tous les comptes mail. Il suffit ensuite d'utiliser screen et un alias. Exemple : l'alias « screen-mail » ouvre X onglets et lance un « mutt -F profile-X » dans chaque. On peut aussi utiliser uniquement des alias : Kevin's Mutt Tips and Tricks - Mutt

Auto-hébergement sur OLinuXino

Aujourd'hui, je vous propose un billet sur les ordinateurs monocarte OLinuXino, concurrents (comme d'autres) du Raspberry Pi. On fera une comparaison des deux avant de voir comment on s'auto-héberge sur un OLinuXino.

Je vous conseille la lecture (ou au moins l'ouverture en parallèle) de mon billet sur comment s'auto-héberger avec un Raspberry Pi car je vais faire des parallèles et je tiendrai pour acquis la connaissance de certaines informations.

Je suis désolé pour la mise en forme minable de certaines parties ... On fait ce que l'on peut avec un WordPress. 😉

Table des matières

Quelle alternative libre au RPi ?

Il y a tout un tas d'ordinateurs monocarte concurrents du RPi sur le marché : OLinuXino, Cubieboard, Gooseberry, Hackberry, PandaBoard ... Lequel choisir ?

Tous les constructeurs utilisent plus ou moins les mêmes composants, notamment pour le CPU : les Allwinner AXX (exemples : A13, A20) et TI OMAPXX sont courants. Cela permet d'avoir plus de documentation pour une même erreur puisque l'erreur sera commune à plusieurs modèles d'ordinateurs monocarte. Cela rapproche aussi "les communautés" : j'ai remarqué ce fait entre la communauté autour des CubbieBoard et celle autour des OLinuXino.

Tous les fabricants prétendent faire de l'Open Source et de l'Open Hardware ...

Et tous les ordinateurs monocarte ont des inconvénients éthiques du point de vue de la liberté qu'ils accordent à leurs utilisateurs. Quelques exemples (tirés de : Single-board computers - Free Software Foundation) :

  • le GPU du RPi utilise un blob propriétaire ... et comme c'est lui qui fait l'amorçage du système ... ;
  • le chip WiFi des Cubieboard, Gooseberry et A13-OLinuXino-WIFI utilise un driver/firmware propriétaire ;
  • le GPU des BeagleBoard, OLinuXino, Cubieboard, Gooseberry, Hackberry et PandaBoard utilise un driver/firmware propriétaire. Le driver libre, Lima, n'est pas totalement abouti d'après ce je lis à droite et à gauche ;

Comme c'est bonnet blanc et blanc bonnet entre tous ces ordinateurs, je me suis contenté d'en choisir un parmi ceux :

  • qui ont des morceaux proprios uniquement dans les composants que je n'utilise pas et qui ont un comportement bien connu et attendu (exemple : le GPU sur OLinuXino ; contre-exemple : le GPU sur RPi qui sert aussi à booter le système d'exploitation) ;
  • qui sont distribués depuis la zone euro histoire d'éviter de me taper des conversions monétaires ;
  • qui ont un minimum de documentation potable.

C'est ainsi que j'ai choisi de me prendre un OLinuXino.

Quel OLinuXino choisir ?

Le modèle d'OLinuXino qui se rapproche le plus d'un Raspberry Pi modèle B, c'est l'OLinuXino A10S, le modèle sans la mémoire NAND 4G qui permet de se passer de SD pour booter/utiliser la carte mais dont le bootloader libre ne permet pas de tirer partie. L'OLinuXino A13 est supérieur au RPi en terme de puissance CPU, équivalent en terme de RAM disponible, ... mais ne dispose pas d'un port réseau. Il n'est donc pas comparable au RPi. L'OLinuXino iMX233 dispose d'un port réseau mais n'est pas comparable au RPi en terme de quantité de RAM disponible et de puissance CPU.

L'OLinuXino A10S coûte 54 € (TTC, hors frais de port) contre 37 € (TTC, hors frais de port) pour le RPi modèle B au moment où je l'ai acheté. Aujourd'hui, un RPi modèle B se trouve, dans la même boutique, pour 31 € (TTC, hors frais de port) donc l'écart se creuse mais nous verrons plus loin que la qualité des deux prestations n'est strictement pas équivalente. De même, il ne faut pas oublier que les prix du RPi sont tirés vers le bas à cause de sa popularité (popularité -> ils commandent des volumes plus gros de composants/production -> coûts tirés vers le bas -> gain répercuté sur le prix de vente).

Bien qu'un RPi modèle B soit déjà trop puissant pour faire office de petit serveur (DNS + mail + web + XMPP principalement) pour un ou pas beaucoup d'utilisateurs et que donc un OLinuXino A10S aurait largement suffit à ces usages, je me suis laissé tenté par un OLinuXino A20 à 66 € (TTC, hors frais de port). Un CPU double cœur, 1 GB de RAM, plus de connectique, ... Bref, tout ce qui sert à rien pour l'usage serveur précédemment décrit. 😀 Le surplus de puissance me permettra de monter du monitoring (usage qui à l'air d'être assez vorace sur un RPi), de tester des trucs, ce genre de choses ... Pour 10 € de plus, l'appel de l'usage futur est tentant. 🙂

Coût total d'acquisition

ÉDIT du 13/10/2014 à 19h55 : Ce billet date d'il y a plus d'un an donc les prix sont purement indicatifs toussa. L'OLinuXino A20 voit son coût total d'acquisition diminuer de plus de 13€, la gamme RPi a été renouvelée (RPi modèle B+) et voit son coût total d'acquisition diminuer d'environ 6€. Fin de l'édit

Pour ceux qui veulent se faire une idée du coût total d'acquisition (ie : quand on n'a ni l'adaptateur secteur, ni une carte SD, bref quand on n'a rien sous la main). Tous les prix sont TTC, souvent arrondis au supérieur. Bien sûr, ce qui suit est purement indicatif, vous trouverez peut-être des boutiques moins chères mais je ne rembourse pas deux fois la différence. 😛

RPi (37 €) + adaptateur secteur/USB (7,43 €) + câble USB A vers micro USB B (pour aller de l'adaptateur au RPi) (2,93 €) + une carte SD (environ 10-12 € pour un produit décent) + transport (15-20 € pour un service décent avec assurance) : 75-80 € au total.

OLinuXino A20 (66 €) + transfo électrique (8,31 €) + carte SD (10-12 €) + transport (15-20 €) : 100-105 € au total.

Pour un OLinuXino A10S, le coût total s'élève à 87-92 €.

Pour le RPi, on peut aussi ajouter un boîtier à 7 €. À ma connaissance, il n'existe rien de tel pour les OLinuXino (sauf pour les IMX233). ÉDIT du 13/10/2014 à 19h55 : Taziden me signale que des boîtiers sont en vente pour les OLinuXino A10 LIME et A20. Fin de l'édit

OLinuXino A20 versus Raspberry Pi modèle B

Éthique

  • Le RPi est un projet de la Raspberry Pi Foundation, une association sans but lucratif reconnue comme œuvre de bienfaisance basée en Angleterre. OLinuXino est un produit d'Olimex, une société basée en Bulgarie. J'ai entendu une remarque selon laquelle c'est mieux de s'équiper en RPi plutôt qu'en OLinuXino car cela aide une association reconnue comme œuvre de bienfaisance. Sauf que, pour l'instant, je n'ai pas vu la RPi Foundation effectuer une donation ou un projet humanitaire. Si l'argent reste dans la caisse, ça permet, certes, d'investir, mais où est l'œuvre de bienfaisance ? Simplement fournir un ordinateur monocarte avec de bons morceaux propriétaires dedans ? Obtenir des réductions fiscales ? Bref, ma conscience est tranquille même si j'ai acheté un produit auprès d'une saloperie de société capitaliste qui exploite des Bulgares (et des Chinois -> Allwinner AXX) !
  • OLinuXino, plus libre que RPi ? Vaste question. Voici quelques éléments de réponse :
    • Au niveau des packages installés par défaut, je n'ai rien vu venant de contrib ou de non-free sur l'OLinuXino A20 avec vrms. ÉDIT du 09/08/2014 à 18h25 : Sur la nouvelle image Debian distribuée par Olimex depuis mars 2014, « ULTIMATE A20 Debian 4GB SD-card image release-7 with hardware accelerated video », les packages firmware-ralink et firmware-realtek sont présents. Fin de l'édit

      Sur le RPi, les packages non-free suivants sont installés par défaut : firmware-atheros, firmware-brcm80211, firmware-libertas, firmware-ralink, firmware-realtek. Comme vous le voyez, il s'agit de firmwares pour cartes réseaux WiFi donc si vous n'utilisez pas de dongle WiFi, vous pouvez les désinstaller.

    • Sur le RPi, le GPU est totalement propriétaire. Donc le boot du système, l'affichage 2D/3D et le décodage/encodage vidéo matériel sont faits avec du logiciel sur lequel personne (sauf Broadcom) n'a le contrôle.

      Sur l'OLinuXino, le GPU et le chargement d'un OS depuis la flash interne (pour les modèles qui en sont équipés) sont totalement propriétaires. Donc l'affichage 2D/3D et le décodage/encodage vidéo matériel sont faits avec du logiciel sur lequel personne n'a le contrôle. Lima, le driver libre pour l'affichage 2D/3D ne semble pas être encore prêt pour mesa. Le VPU, un CedarX nécessite lui aussi des blobs propriétaires mais une alternative libre, basée sur du reverse engineering, est en train d'émerger mais reste encore à l'état de PoC bien que sachant déjà décoder le MPEG2 et H264. Notons que le GPU n'est pas responsable du chargement de l'OS donc, pour ceux qui veulent un serveur at home et pas un media center, l'OLinuXino me paraît être plus libre qu'un RPi.

    • Au niveau matériel, la RPi Foundation ne communique pas les schémas ni même les datasheet complètes (et pour cause, Broadcom les distribue uniquement sous NDA). Le RPi n'est donc pas un projet open hardware.

      Olimex semble distribuer l'intégralité des schémas et des datasheet. Voir :

      Olimex distribue tout ça sous licence CC-BY-SA. Les morceaux de code produits par Olimex sont sous GPL. Je vous laisse regarder le dépôt Github par vous même pour le reste des composants et les autres modèles d'OLinuXino.

      Je ne suis pas compétent pour affirmer si c'est de l'open hardware complet ou s'il manque des schémas ou des données techniques. J'émets néanmoins un bémol : on n'a pas les schémas des composants Allwinner (CPU,GPU,VPU). Comment fonctionnent-ils vraiment ? J'ai l'impression que seul le travail d'Olimex est distribué sous licence libre. Est-ce suffisant ?

    • Il est regrettable qu'Olimex utilise des formats de fichiers propriétaires et des services centralisés dans un projet qui se veut le plus ouvert et libre possible. Pour les services centralisés, je parle de Github (qui contient tous les documents importants) et de Google Docs (sur lequel sont stockés certains éléments comme les images Debian/Android des cartes SD). Un dépôt git, ça se met chez soi. Des images bien lourdes, ça se diffuse en torrent. Pour les formats de fichiers propriétaires, je parle principalement des rar disponibles ça et là dans le dépôt git. gzip, lzma, 7z existent ! Je ne jugerai pas l'usage du logiciel propriétaire Eagle vu que je suis un zéro pointé dès que l'on parle de conception de PCB. J'ai fait remonter ces griefs à Olimex. Réponse : « You are right that we still have some files in rar archives but those are files that we have already received as a rar from other sources (Allwinner technology and other manufacturers). In respect to their packaging we have kept the same package. All files modified or created by Olimex LTD are packed in zip archives. ». Ce à quoi je réponds : quid de l'image Debian pour carte SD qui est distribuée en rar via Google Docs ? ÉDIT du 13/09/2013 à 00h35 : « You are correct about the rar. We will try to upload files in 7-zip now on. » Fin de l'édit
    • Le dernier point problématique concerne le noyau fourni dans l'image officielle. Comme l'indique la page consacrée à l'OLinuXino A20 sur le wiki d'Olimex : « Note: Kernel 3.3 is based on Android SDK Kernel and may contain GPL violations which are behind our control, it's not recommended to use it nor to improve/contribute to it for this purpose better use Linux-Sunxi 3.4 kernel which have everything working exept the LCD touchscreen. We work on the TS issue to solve. »

      J'ai essayé de compiler le noyau 3.4. La compilation se passe bien mais le noyau ne boot pas : les fichiers de logs ne sont pas modifiés sur la carte SD. Je n'ai pas d'écran à brancher sur mon OLinuXino ni d'adaptateur série/USB sous la main donc je ne peux pas debugguer plus loin. Apparemment, je ne suis pas le seul à être en échec.

      Pour ceux qui voudraient essayer, je recommande les ressources suivantes :

      ÉDIT du 09/08/2014 à 18h35 : La nouvelle image Debian distribuée par Olimex depuis mars 2014, « ULTIMATE A20 Debian 4GB SD-card image release-7 with hardware accelerated video », contient Linux 3.4.X, version Sunxi, plus basée sur l'Android SDK. \o/ De là à dire qu'il n'y a plus de bouts propriétaires, je ne m'engagerai pas sur ce point car je n'ai pas assez de recul pour juger. Fin de l'édit

Technique

  • Comme je l'ai écrit plus haut, entre un RPi et un OLinuXino, on n'est clairement pas dans le même niveau de prestation :
    • L'OLinuXino est livré dans une boîte en carton alors que le RPi est livré nu.
    • Les OLinuXino A10 et A20 sont équipés d'une horloge matérielle (RTC) ... mais comme il n'y a pas de batterie de base (on peut en acheter une, il y a un port matériel pour la brancher), je n'en vois pas l'intérêt (avoir une plus grande précision ?) : l'horloge se perd en cas de coupure de l'alimentation électrique. Ce point n'est pas gênant dans un usage serveur puisque tout administrateur consciencieux utilise NTP sur ses serveurs.
    • L'OLinuXino possède plusieurs boutons. Certains sont fortement utiles (RESET/PWR) mais le reste est totalement futile à mon avis. En effet, les boutons restants servent dans un contexte de media-center. Or, dans un tel contexte, qui va se bouger le cul pour aller appuyer sur ces boutons ? Télécommande powa.
    • L'OLinuXino utilise des bus séparés pour les ports USB là où le RPi utilise un même bus ce qui peut s'avérer limitant pour certains usages fortement consommateurs en capacité de transfert (webcam (OpenCV par exemple) + disque dur c'est déjà trop) puisqu'elle est partagée entre tous les périphériques de tous les ports. De même, la carte réseau de l'OLinuXino n'est pas greffée sur un contrôleur USB, contrairement à celle du RPi.
    • Pour ceux qui veulent faire de l'électronique et non pas un serveur avec leur OLinuXino (ce qui est quand même la destinée première de ces ordinateurs), ce dernier possède plus d'entrée/sorties que le RPi : sur le RPi, on parle de 17 entrées/sorties (dont 2*i2c et 2*UART) dont 5 sont partagées sur un même bus (source : GNU Linux Magazine France numéro 156). Sur l'OLinuXino A20, on parle de 160 GPIO (répartis sur 3 bus) + 2*UEXT + 1*UART ... Reste à voir combien de GPIO sont exploitables en parallèle.
    • Le reste de la connectique (audio, HDMI, USB, ...) reste quand même bonnet blanc et blanc bonnet entre le RPi et l'OLinuXino, à mon avis.
    • Un boîtier acheté en supplément peut contenir le RPi. À ma connaissance, rien n'est commercialisé ni même prévu pour les OLinuXino, à l'exception de l'iMX233. La boîte en carton de livraison semi-ouverte + une mousse non-conductrice et antistatique (pour le surélever dans la boîte) permet de compenser un peu ce manque ... ÉDIT du 13/10/2014 à 19h55 : Taziden me signale que des boîtiers sont en vente pour les OLinuXino A10 LIME et A20. Fin de l'édit
    • À l'inverse du RPi, l'OLinuXino A20 dispose d'une unique LED allumée en permanence : celle qui indique que la carte est sous-tension. Elle est de couleur rouge donc, à l'inverse des LEDs oranges et vertes du RPi, elle est moins irritante la nuit. Et la LED de l'OLinuXino ne pulse pas, contrairement à celles du RPi qui éclairent la moitié d'une pièce.

      ÉDIT du 09/08/2014 à 18h45 : Avec la nouvelle image Debian distribuée par Olimex depuis mars 2014, « ULTIMATE A20 Debian 4GB SD-card image release-7 with hardware accelerated video », une LED verte discrète clignote à côté de la LED rouge. Ce clignotement est géré par un script custom d'Olimex : /opt/led_blink.sh. Sans ce script, la LED reste allumée en permanence. Si vous voulez l'éteindre en permanence, il faut ajouter ceci dans /etc/rc.local :

      echo 47 > /sys/class/gpio/export
      echo out > /sys/class/gpio/gpio47_ph2/direction
      echo 0 > /sys/class/gpio/gpio47_ph2/value

      Fin de l'édit

  • L'OLinuXino permet des transferts via le réseau plus rapides que le RPi.

    Pour l'envoi d'un fichier de 512 Mo, au contenu issu de /dev/zero, depuis mon RPi vers un desktop, en scp, j'obtiens un débit stable de 3,2 Mo/s.

    Ce n'est pas une limitation de la carte SD qui fournit 25 Mo/s environ en lecture. C'est une limitation du CPU du RPi :

    %Cpu(s): 51,8 us, 30,4 sy,  0,0 ni,  0,0 id,  0,0 wa,  1,3 hi, 16,6 si,  0,0 st
    25420 root    20   0  8912 1340  804 R  88,8  0,3   0:19.20 sshd                                                                  
    25421 root    20   0  2196  720  592 S   5,5  0,1   0:01.23 scp

    En utilisant netcat (« nc -vv -l -p 1234 > test » sur le desktop, « nc -vv <IP> 1234 < test » sur le RPi,), toujours sur TCP, pour transférer le même fichier, j'obtiens 5,6 Mo/s (mesuré avec iftop). Mais, même là, j'ai l'impression que le transfert est limité par la puissance du CPU du RPi :

    %Cpu(s):  4,5 us, 55,5 sy,  0,0 ni,  0,0 id,  0,6 wa,  2,9 hi, 36,5 si,  0,0 st
    25458 root    20   0  2344  724  600 R  89,3  0,1   0:41.71 nc
       36 root    20   0     0    0    0 S   4,5  0,0   3:43.15 mmcqd/0

    Sur mon OLinuXino A20, j'obtiens 5,2 Mo/s avec scp. On est CPU-limited : sshd n'utilise qu'un seul core, le CPU passe encore 40 % de son temps à idler :

    %Cpu(s): 31,5 us, 15,1 sy,  0,0 ni, 40,1 id,  0,0 wa,  0,0 hi, 13,3 si,  0,0 st
    2552 glucas    20   0  7892 1212  664 R  93,3  0,1   0:38.70 sshd
    2553 glucas    20   0  1772  648  520 R   9,3  0,1   0:03.06 scp

    Avec netcat, je ne suis plus limité par le CPU et j'obtiens 11,5 Mo/s.

  • La température de l'OLinuXino A20 est inférieure à celle du RPi. Je n'ai pas de thermomètre qui permettrait de prendre en compte uniquement la chaleur dégagée par l'ordinateur ni de caméra thermique donc c'est du pur ressenti bien subjectif. Peut-être que la plus grande surface de l'OLinuXino permet une dissipation thermique supérieure ...
  • Un RPi équipé de Raspbian utilise ses propres dépôts dont je ne sais pas si je peux avoir confiance (même si plein de miroirs sont hébergés par des gens sérieux, ça ne veut rien dire). J'ai tenté d'utiliser les dépôts Debian traditionnels sur mon RPi, je me suis pris une avalanche d'erreurs (même en désactivant la "branche" « RPi »), j'ai abandonné. Quid des mises à jour de sécurité ? En combien de temps sont-elles distribuées ? Je n'en sais rien, ce n'est pas documenté. Lors de la dernière faille de sécurité dans BIND, la mise à jour est apparue 1 jour plus tard que dans les dépôts Debian traditionnels. Ce délai peut être long dans le cas d'un usage serveur. ÉDIT du 09/08/2014 à 18h55 : Et que penser de ce type de listchanges : « --- Modifications pour openssl (libssl1.0.0 openssl) ---
    openssl (1.0.1e-2+rvt+deb7u11) wheezy-staging; urgency=low

    * Bump version number so it is above previous raspbian versions.
    (the change previously in the raspbian versions is now in Debian). » ? Ça fait quand même 4 DSA sur OpenSSL pour lesquels Raspbian nous assure que nous sommes tranquilles. Fin de l'édit

    L'OLinuXino utilise les dépôts Debian traditionnels pour les mises à jour/installations. Donc la team Debian, Debian-security, ....

    Notons que dans les deux cas, des logiciels sont installés en dehors du mécanisme apt. C'est le cas du noyau, par exemple. Il faudra voir ce que ça donne lorsqu'une faille de sécurité sera découverte sur ces logiciels là. ÉDIT du 23/01/2016 à 18h00 : On peut utiliser le noyau packagé par Debian (à partir de Debian Jessie) afin de bénéficier du suivi de la sécurité réalisée par la team Debian-security. Voir : Installer le noyau packagé par Debian sur une carte OLinuXino (et Raspberry Pi). FIN DE L'ÉDIT

Autre

  • En une semaine, c'est acheté et livré. Et je parle bien de l'intégralité de ma commande. Contrairement au RPi où j'ai attendu plus d'un mois et demi avant de tout recevoir ... Oui, l'adaptateur USB/secteur c'est moins utile sans RPi ... Et RPi + adaptateur, c'est moins utile sans le cable USB/micro USB ... Pourtant, je n'ai pas commandé mon RPi durant leur période de gloire où tout le monde en voulait un.

Les grandes lignes pour transformer son OLinuXino en serveur

J'utilise l'image Debian fournie par Olimex sur leur wiki.

  • Si vous avez acheté la carte SD avec l'image Debian dessus, le /etc/network/interfaces est incorrect : l'interface eth0 ne sera pas montée au boot car la ligne « auto eth0 » est commentée et même si elle ne l'était pas, l'interface est configurée avec un adressage statique en 192.168.0.244/24. Il faut donc changer ça en mettant la SD dans un lecteur de cartes mémoires puis en modifiant /etc/network/interfaces. Rien à signaler sur l'image téléchargée. J'ai fait remonter l'info au support d'Olimex. ÉDIT du 09/08/2014 à 18h55 : C'est un choix assumé : « Note: in the previous Debian releases the Ethernet was auto-detected and initialized during boot BUT this was causing big delays in the start-up of the board if you didn't want to use Ethernet or if there wasn't Ethernet cable connected. » Fin de l'édit
  • Pour faire booter la carte, il n'y a pas de manipulations compliquées, c'est comme avec le RPi : alimentez-la en électricité et ça part tout seul. Après quelques dizaines de secondes, un nmap -sV vous montrera qu'un serveur SSH tourne sur l'OLinuXino. Il suffit donc de s'y connecter : root/olimex.
  • Comme avec le RPi, la première chose à faire est de créer un utilisateur normal puis de changer le mot de passe du compte root pour un mot de passe fort. Puis déposer sa clé publique, modifier la configuration du serveur SSH pour ne pas autoriser les connexions en tant que root (su est là pour l'élévation de privilèges) et pour autoriser uniquement l'authentification par clés, ... Bref, tout ça c'est du classique.
  • Avec l'image « ULTIMATE A20 Debian 4GB SD-card image release-7 with hardware accelerated video », il y a un peu de ménage à faire :
    # Supprimer le compte utilisateur normal Olimex
    userdel olimex
    rm -rf /home/olimex
     
    # Supprimer des dossiers/fichiers vides/inutiles à la racine
    rm -rf /a /sunxi-tools /Desktop
     
    # Supprimer les sunxi-tools inutiles ici
    rm -rf /opt/sunxi-tools
     
    # Si vous ne voulez pas du script pour faire clignoter la LED verte
    rm /opt/led_blink.sh
    sed -i "s=\./opt/led_blink.sh&==" /etc/rc.local
     
    # Root est connecté automatiquement (sans demande de mdp) sur la console série (ttyS0)
    # Exemple : root     ttyS0                     21:56   1680days  0.08s  0.04s -bash
    # Pour désactiver ce comportement :  
    sed -i "s=T0:2345:respawn:/sbin/getty -L -a root ttyS0 115200 linux=#&=" /etc/inittab
  • Il convient de compléter le fichier /etc/apt/sources.list qui est notoirement incomplet : il manque les dépôts debian-security et volatile (renommé stable-updates depuis wheezy).
    # STABLE
    deb ftp://ftp.debian.org/debian/ wheezy main
     
    # STABLE-UPDATES (EX-VOLATILE)
    deb ftp://ftp.debian.org/debian/ wheezy-updates main
     
    # SECURITY
    deb ftp://security.debian.org/debian-security/ wheezy/updates main

    Bien sûr, il faudra faire un apt-get update, as usual.

  • Faire les mises à jour (sauf si l'installation est fraîche, of course) :
    apt-get -y update && apt-get -y upgrade &&  apt-get -y dist-upgrade && apt-get -y autoremove && apt-get -y autoclean
  • Changer (ou pas) d'IO scheduler pour un scheduler plus adapté aux mémoires flash :
    L'intérêt de cette manipulation fait souvent débat de ce que j'ai vu dans les forums. Je vous conseille de tester vous même car cela dépend de la carte SD. Pour moi, le résultat est sans appel :

    Avec le scheduler deadline :

    dd if=/dev/zero of=test bs=1M count=512
    512+0 records in
    512+0 records out
    536870912 bytes (537 MB) copied, 52.2637 s, 10.3 MB/s
     
    rm test
     
    timeout -s2 60 dd if=/dev/zero of=test
    1122023+0 records in
    1122023+0 records out
    574475776 bytes (574 MB) copied, 60.1867 s, 9.5 MB/s

    Avec le scheduler NOOP :

    dd if=/dev/zero of=test bs=1M count=512
    512+0 records in
    512+0 records out
    536870912 bytes (537 MB) copied, 44.4487 s, 12.1 MB/s
     
    rm test
     
    timeout -s2 60 dd if=/dev/zero of=test
    1167132+0 records in
    1167132+0 records out
    597571584 bytes (598 MB) copied, 63.1541 s, 9.5 MB/s

    De plus, j'ai un sentiment d'une meilleure réactivité du système, en cas de fortes lectures/écritures avec le scheduler noop.

    Pour voir le scheduler actif et le changer temporairement (pour modifier, il faut être root, of course) :

    echo noop > /sys/block/mmcblk0/queue/scheduler
    cat /sys/block/mmcblk0/queue/scheduler
    [noop] deadline

    Pour le changer définitivement, il faut créer un fichier « uEnv.txt » à la racine de la première partition de votre carte SD (là où il y a « script.bin » et « uImage ») qui contient :

    extraargs=elevator=noop

    Ce fichier est utilisé par U-boot pour compléter sa variable « bootargs » qui permet de passer des paramètres au noyau (cmdline).

    J'ai trouvé le mécanisme sur la page suivante : linux-sunxi/u-boot-sunxi.

    Normalement, lors du prochain reboot de votre OLinuXino, le scheduler noop sera utilisé et cat /proc/cmdline affichera ceci :

    console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait loglevel=8 panic=10 elevator=noop
  • Changer le fuseau horaire : soit tzselect, soit :
    echo "Europe/Paris" > /etc/timezone 
    cp /usr/share/zoneinfo/Europe/Paris /etc/localtime
  • Configurer les applications pour le français :
    dpkg-reconfigure locales
     
    # Et comme ça ne fonctionne pas ...
    sed -i 's/LANG=en_US.UTF-8/LANG=fr_FR.UTF-8/' /etc/environment
  • Désinstaller l'inutile pour un serveur (gain : environ 550 Mo) :
    apt-get autoremove --purge gnome-* xserver-* desktop-* consolekit hicolor-icon-theme vim-* aspell aspell-en tsconf scratch notification-daemon dictionaries-common lightdm lightdm-gtk-greeter gcc g++ mplayer alsa-base alsa-utils gcc-4.6 gcc-4.6-base dosfstools esound-common wireless-tools wpasupplicant mpg321 mpg123 wdiff patch isc-dhcp-client slim midori consolekit hicolor-icon-theme leafpad vim-* aptitude aptitude-common aspell aspell-en xarchiver wpagui tsconf scratch samba-common nfs-common ppp openbox notification-daemon network-manager netsurf-common mupdf ncdu bluez cifs-utils dictionaries-common dillo dnsmasq-base fbset galculator gksu gpicview lightdm lightdm-gtk-greeter lxappearance lxinput lxpanel lxmenu-data lxpolkit lxrandr lxsession lxsession-edit lxshortcut lxtask lxterminal obex-data-server obexd-client gtk2-engines idle idle3 triggerhappy gcc g++ gdb gdbserver isc-dhcp-client alsa-base alsa-utils wireless-tools wpasupplicant xinit strace xterm blt firmware-* lksctp-tools xkb-data kbd fontconfig-config fonts-freefont-ttf ttf-freefont ttf-dejavu-core libblas3 libatlas3-base alsa-tools apt-listchanges autoconf automake autotools-dev cpio cpuburn cpufrequtils dialog git git-man glmark2-* i2c-tools linux-libc-dev lxde-icon-theme make mesa-* minicom ntfs-3g sshfs tasksel tasksel-data whiptail x11-common x11proto-* xorg-sgml-doctools isc-dhcp-common
  • Installer l'indispensable :
    apt-get install iptables telnet traceroute rsyslog bash-completion tcpdump ethtool dnsutils
  • Installer votre indispensable (screen/tmux, vim/nano/emacs, bash/dash/zsh, ...).
  • Installer vos logiciels serveur et les configurer avec vos réglages habituels. Ces configurations ne changent pas.

    ÉDIT du 09/08/2014 à 20h15 : Avec l'ancienne image fournie par Olimex (Linux 3.3 Android based, avant mars 2014), on obtient les erreurs suivantes lors du lancement de bind9 :

    Aug  8 20:38:19 A20 named[2635]: loading configuration from '/etc/bind/named.conf'
    Aug  8 20:38:19 A20 named[2635]: reading built-in trusted keys from file '/etc/bind/bind.keys'
    Aug  8 20:38:19 A20 named[2635]: using default UDP/IPv4 port range: [1024, 65535]
    Aug  8 20:38:19 A20 named[2635]: using default UDP/IPv6 port range: [1024, 65535]
    Aug  8 20:38:19 A20 named[2635]: net.c:142: unexpected error:
    Aug  8 20:38:19 A20 named[2635]: socket() failed: Permission denied
    Aug  8 20:38:19 A20 named[2635]: net.c:142: unexpected error:
    Aug  8 20:38:19 A20 named[2635]: socket() failed: Permission denied
    Aug  8 20:38:19 A20 named[2635]: no IPv6 interfaces found
    Aug  8 20:38:19 A20 named[2635]: no IPv4 interfaces found
    Aug  8 20:38:19 A20 named[2635]: not listening on any interfaces
    Aug  8 20:38:19 A20 named[2635]: generating session key for dynamic DNS
    Aug  8 20:38:19 A20 named[2635]: sizing zone task pool based on 5 zones
    Aug  8 20:38:19 A20 named[2635]: server.c:2466: unexpected error:
    Aug  8 20:38:19 A20 named[2635]: unable to obtain neither an IPv4 nor an IPv6 dispatch
    Aug  8 20:38:19 A20 named[2635]: loading configuration: unexpected error
    Aug  8 20:38:19 A20 named[2635]: exiting (due to fatal error)

    La solution : « groupadd -g 3003 aid_inet
    usermod -G aid_inet ntp
    usermod -G aid_inet bind
    usermod -G aid_inet mysql

    but this can be done after 1st failed installation attempt.
    Must figure out, can I create those users beforehand?

    Anyway, would it be mossible to remove kernel flag
    CONFIG_ANDROID_PARANOID_NETWORK to solve the issue? »

    Ou, encore plus facile : utiliser la nouvelle image fournie par Olimex depuis mars 2014 et son noyau 3.4 qui n'est plus Android-based.

    Ce paramètre de compilation du noyau affecte d'autres logiciels. Ejabberd :

    Aug  8 20:37:42 A20 epmd: epmd: error opening stream socket
    Aug  8 20:37:43 A20 epmd: epmd: error opening stream socket

    NTPd :

    Aug  8 20:37:41 A20 ntpd[2427]: ./../lib/isc/unix/ifiter_ioctl.c:348: unexpected error:
    Aug  8 20:37:41 A20 ntpd[2427]: making interface scan socket: Permission denied

    Fin de l'édit

Notes :

  • Pas besoin de charger le module ipv6, il est compilé "en dur" dans le noyau, contrairement au RPi.
  • Pour le split de la RAM entre CPU et GPU, je ne sais pas comment cela se passe sur OLinuXino. Je n'ai rien trouvé de convaincant à ce sujet. Pas même dans les fichiers scripts.(bin|fex). Je constate que j'ai 975 Mo de RAM adressables par le système. ÉDIT du 09/08/2014 à 19h15 : La réponse est là : Kernel arguments sur le wiki Linux-sunxi : il faut utiliser les paramètres : « sunxi_ve_mem_reserve=0 sunxi_g2d_mem_reserve=0 sunxi_no_mali_mem_reserve sunxi_fb_mem_reserve=16 ». Ils s'utilisent comme « elevator=noop" que l'on a vu ci-dessus. 😉 Bilan : 986M de RAM adressables par le système. Fin de l'édit

Les problèmes

Un manque de neutralité

Les problèmes liès à mon Fournisseur d'Accès à Internet, qui ne permet pas à ses clients d'installer un serveur et donc d'être vraiment sur Internet, restent évidemment inchangés entre mon RPi et mon OLinuXino. Je vous invite donc à lire la section « Les problèmes » de mon billet sur le RPi pour un usage serveur.

OpenDNSSEC/SoftHSM

SoftHSM ne segfault plus lors de l'initialisation des token mais l'erreur « error parsing RR at line » se manifeste ici aussi.

Un load average toujours supérieur ou égal à 1

Avec l'image Debian (apparemment, cela ne se produit pas avec l'image Android), on constate que la charge système ne cesse de monter dès le boot pour se stabiliser à 1 et ne plus jamais redescendre sous ce seuil quand bien même aucun service n'est lancé ... juste le noyau et les démons de base (log, sshd, ...).

Avec la commande top, on observe que c'est ksoftirqd, processus dédié à la mise en queue des interruptions logicielles (qui sont souvent traitées suite à des interruptions matérielles) lorsqu'il y en a trop, qui est le processus le plus consommateur de CPU. On observe également qu'environ 5 % du temps CPU part dans le traitement d'interruptions logicielles :

%Cpu(s):  0,3 us,  0,9 sy,  0,0 ni, 93,7 id,  0,0 wa,  0,0 hi,  5,1 si,  0,0 st

En regardant dans /proc/interrupts, on constate que deux interruptions se démarquent nettement et que leurs nombres de déclenchements progressent très rapidement (environ 100 par seconde) :

           CPU0       CPU1       
 29:      28685      43852       GIC  arch_timer
 30:          0          0       GIC  arch_timer
 32:          0          0       GIC  axp_mfd
 33:        161          0       GIC  serial
 37:          1          0       GIC  RemoteIR
 39:      14059          0       GIC  sun7i-i2c.0
 40:          0          0       GIC  sun7i-i2c.1
 41:          0          0       GIC  sun7i-i2c.2
 54:       3294          0       GIC  timer0
 56:          0          0       GIC  sunxi-rtc alarm
 59:          0          0       GIC  dma_irq
 64:      33270          0       GIC  sunxi-mmc
 67:          0          0       GIC  sunxi-mmc
 71:          0          0       GIC  ehci_hcd:usb2
 72:          0          0       GIC  ehci_hcd:usb4
 76:     151786          0       GIC  dev_name
 77:          0          0       GIC  dev_name
 79:      75888          0       GIC  dev_name
 80:          0          0       GIC  dev_name
 87:       6823          0       GIC  eth0
 96:          0          0       GIC  ohci_hcd:usb3
 97:          0          0       GIC  ohci_hcd:usb5
IPI0:          0          0  Timer broadcast interrupts
IPI1:      18364      17755  Rescheduling interrupts
IPI2:          0          0  Function call interrupts
IPI3:         23        109  Single function call interrupts
IPI4:          0          0  CPU stop interrupts
IPI5:          0          0  CPU backtrace
Err:          0

Évidemment, les dev' n'ont pas donné un nom représentatif à leurs interruptions, sinon ça serait trop facile.

La solution est détaillée ici : loadavg always >=1.00 on debian sur le forum Olimex. Cette surcharge est générée par port mini-USB (qui peut être utilisé en USB OTG) et par le fait que « The whole USB support is flawed in 3.3. » (et apparemment, le sous-système USB de la version 3.4 provoque d'autres bugs).

Voici comment contourner ce problème (tutoriel issu de la combinaison du lien précédent et de documentation related to script.bin/script.fex sur le forum Olimex) :

Il faut récupérer les sunxi-tools :

git clone https://github.com/linux-sunxi/sunxi-tools

Les compiler (non, pas de ./configure) :

cd sunxi-tools
make

La compilation va échouer pour des problèmes de dépendances. Mais ce n'est pas grave : les outils dont nous avons besoin, bin2fex et fex2bin, ont été compilés avec succès.

On transforme le fichier script.bin qui se trouve sur la première partition de votre carte SD en fichier humainement compréhensible (non, on n'est pas obligé de stocker le fichier script.fex sur la carte SD, je fais ça pour m'y retrouver et pour le conserver) :

./bin2fex /path/to/SD/card/script.bin > /path/to/SD/card/script.fex

On effectue les modifications. Pour rappel, ces modifications sont (le reste de la section « [usbc0] » reste inchangée) :

[usbc0]
usb_port_type = 1
usb_detect_type = 0
usb_host_init_state = 1

On fait une copie de sauvegarde puis on crée le nouveau script.bin :

cp /path/to/SD/card/script.bin ~/script.bin.save
./fex2bin /path/to/SD/card/script.fex > /path/to/SD/card/script.bin

En bootant l'OLinuXino, on se rend compte que le load average n'est plus bloqué à 1 mais qu'il est largement inférieur. Par contre, environ 5 % du temps CPU est encore occupé par les mêmes interruptions logicielles qui se déclenchent toujours à la même fréquence ...

Je ne comprends pas ...

D'une part, en regardant le fichier arch/arm/plat-sunxi/include/plat/irqs.h de linux-sunxi, on se rend compte que eth0 utilise l'interruption numéro 87 :

#define SW_INT_IRQNO_EMAC		(55 + SW_INT_START) // SW_INT_START = 32

Cela correspond donc bien à la réalité. En suivant la même logique, l'IRQ 76 (celle qui pose problème) est attribuée à SW_INT_IRQNO_LCDCTRL0 et l'IRQ 79 est attribuée à SW_INT_IRQNO_DEFEBE0. Pour l'IRQ 79, je ne sais pas aller plus loin. Mais pour l'IRQ 76, je peux dire que je n'ai pas d'écran LCD sur mon OLinuXino et que c'est peut-être ce qui pose problème.

J'ai tenté de désactiver lcd(0|1) dans script.(fex|bin) en passant la valeur de « lcd_used » à 0, en supprimant tout sauf cette ligne (sans les mapping, la carte ne devrait pas savoir exploiter l'éventuel LCD) ainsi que de passer la valeur de « disp_init_enable » à 0, mais rien n'y fait : la charge est toujours >= 1. Par contre, les interruptions 76 et 79 ne se déclenchent plus (« 0 » dans /proc/interrupts).

D'autre part, ce n'est pas les hi (hardware interrupts) qui prennent environ 5 % du temps CPU mais les si (software interrupts). Les interruptions logicielles sont souvent traitées suite à des interruptions matérielle mais sait-on jamais ... Donc le fichier à regarder est /proc/softirqs. Mais je ne vois rien d'anormale ... Les interruptions qui se déclenchent le plus sont TIMER et SCHED ... comme sur mon RPi ou sur mes desktop. Du coup, je ne vois pas comment elles peuvent consommer environ 5 % du temps CPU alors qu'elles consomment 0 % sur mes autres systèmes.

Mes compétences s'arrêtent ici.

ÉDIT du 09/08/2014 à 19h55 : Le problème continu avec la nouvelle image Debian distribuée par Olimex depuis mars 2014, « ULTIMATE A20 Debian 4GB SD-card image release-7 with hardware accelerated video » et son noyau en version 3.4.X. La pseudo-solution exposée ici fonctionne toujours. Fin de l'édit

ÉDIT du 23/01/2016 à 18h00 : Ce problème n'apparaît plus avec le noyau packagé dans Debian (à partir de Jessie). Voir : Installer le noyau packagé par Debian sur une carte OLinuXino (et Raspberry Pi). Fin de l'édit

Reproche

Mon seul reproche à Olimex sera l'utilisation d'un format de fichier propriétaire (rar) ainsi que l'hébergement de certains éléments, comme les images de carte SD, sur Google Docs ... Sérieusement ... Comme je l'ai écrit plus haut, j'ai fait remonter ces griefs au support d'Olimex.

Auto-hébergement sur Raspberry Pi

Aujourd'hui, je vais vous faire un feedback sur comment monter son petit serveur @home avec un Raspberry Pi. Je sais que le sujet est éculé, c'est pourquoi je vais me focaliser sur les problèmes spécifiques que j'ai rencontré. Problèmes qui sont d'ailleurs plus liés à mon FAI qu'au Raspberry Pi.

Table des matières

Ça pue, c'est pas libre !

Bon, je vais affamer ce troll immédiatement.

Oui, le GPU utilise un blob propriétaire, oui, c'est mal, oui, ce genre de pratique doit cesser. Oui, Broadcom a tenté, fin 2012, de faire croire qu'ils avaient ouvert leur blob mais il n'en est rien : seul un binding maladroit en userland a été fournis à la communauté. Oui, c'est une pratique de merde.

Ceux qui, comme moi au début, pensent que c'est modérément grave pour un usage serveur qui ne fait pas usage du GPU se trompent : « L’une des tâches du bootloader est d’initialiser le matériel. Dans le cas de la Raspberry Pi, il n’y a pas de bootloader. Le SoC est la fusion d’un cœur ARM et d’un GPU (Graphics Processing Unit ou processeur graphique). Or, c’est le GPU qui cherche et charge son firmware propriétaire depuis la carde SD, initialise le système et passe le relai au processeur ARM et au noyau Linux. [...] le bootloader et toute la partie « pilotage du matériel » est l’affaire du VideoCore et non du processeur. ». Source : GNU Linux Magazine France numéro 156 pages 66 et 71.

Nuançons quand même : un desktop, un laptop ou un ordinateur de poche (mais si vous savez, un ordinateur qui fait aussi téléphone, pas intelligent du tout) est-il mieux ?

  • Sur votre desktop/laptop, vous pouvez avoir des OS libres, parfois tous vos drivers libres, toute votre installation en logiciels libres. Et votre BIOS/UEFI alors ? Pouvez-vous utiliser Coreboot sur votre machine et l'avez-vous fait ? Et quid du firmware de certains composants (lecteur/graveur CD/DVD/BD, disque dur/SSD, carte réseau, ...) ?
  • Sur votre ordinateur de poche, vous pouvez avoir des OS libres, tous vos firmwares libres dans de rares cas, toute votre installation en logiciels libres. Et la puce baseband ? Celle qui émet et reçoit sur le réseau dont personne ne connaît les spécifications ?
  • Et dans tous les cas, que ça soit desktop, laptop, ordinateur de poche ou Raspberry Pi, savez-vous à quoi servent tous les circuits, toutes les puces ? Aucune d'elle ne peut vous nuire ? Pouvez-vous le savoir ? Avez-vous les plans et les spécifications ? Non, ce n'est pas de l'Open Hardware.

Ce que j'essaye d'écrire, c'est que vous ne pouvez pas avoir beaucoup plus confiance en votre PC, en votre laptop et encore moins en votre ordinateur de proche qu'en votre Raspberry Pi. Tout est question de compromis. Certes, le RPi, c'est un blob propriétaire bien ancré dans le système. Un compromis de plus ...

Notons qu'il existe des concurrents plus libres au RPi, voir : Single-board computers - Free Software Foundation, par exemple : OLinuXino, la RaspBerry Pi version Open Source sur LinuxFr. La prochaine fois, je prendrai ça ...

C'est ni stable ni fiable

Vu le prix, oui, forcement, le RPi est limité sur la qualité de ses composants : il supporte assez mal les variations de tension, y compris sur les GPIO (contrairement à Arduino), il ne pulse pas sur les ports USB, il n'y a pas d'horloge (ça se règle avec NTP), les cartes SD ne sont pas forcement de bonne qualité, ...

Notons que l'impact de la plupart des problèmes qui seront engendrés par ces manques peut être limité par des sauvegardes régulières (et, en usage serveur, la redondance contribue à limiter les dégâts quand ça casse, j'y reviendrai) comme il se doit. À titre personnel, cela fait une quarantaine de jours que mon RPi tourne sans problèmes comme serveur. Pourtant je n'ai pas d'onduleur sur cette installation, je n'ai pas investi dans une carte SD de classe internationale hors de prix et je ne crois pas à la chance.

Usages ?

Du coup, un serveur perso à la maison pour faire quoi ?

Rien d'extraordinaire :

  • un DNSd qui fait autorité sur ma zone ;
  • tout ce qu'il faut pour faire du mail (SMTPd,IMAPd,SPF,DKIM, ...) pour une seule BAL ;
  • un serveur de messagerie instantanée (XMPP/Jabber) pour un seul utilisateur ;
  • un HTTPd pour fournir quelques pages statiques (et peut-être un aggrégateur de flux RSS, donc dynamique, à voir);
  • un screen+irssi pour IRC

J'entrevois d'autres usages persos comme un dépôt git ou du partage de fichiers (autre que scp+HTTP quoi) pour, peut-être, éventuellement, un jour.

Pour ceux qui croient encore qu'il faut une machine de guerre comme pour jouer au dernier Crysis pour se faire un petit serveur pour les usages sus-cités, bah non ... un RPi c'est déjà trop : le CPU passe son temps à ne rien faire et environ 270 Mo de RAM sont utilisés sur les 496 Mo disponibles (les 16 Mo restants vont pour le GPU, j'y reviendrai). Ça donne un ordre d'idée, non ? 🙂

Les grandes lignes pour transformer son RPi en serveur

J'utilise Raspbian et un RPi modèle B.

  • Donner un mot de passe (fort, of course) au compte root (en utilisant sudo), supprimer le compte pi, créer un compte utilisateur "normal" bien à vous.
  • Affecter le minimum de mémoire au GPU : « gpu_mem=16 » dans /boot/config.txt.
  • ÉDIT du 05/05/2014 à 23h15 : Désactiver le swap dans un fichier (cat /proc/swaps). Fin de l'édit
  • Faire les mises à jour (sauf si l'installation est fraîche, of course) :
    apt-get -y update && apt-get -y upgrade &&  apt-get -y dist-upgrade && apt-get -y autoremove && apt-get -y autoclean
  • Activer IPv6 :
    echo ipv6 >> /etc/modules
  • Changer (ou pas) d'IO scheduler pour un scheduler plus adapté aux mémoires flash :
    sed -i 's/deadline/noop/g' /boot/cmdline.txt

    L'intérêt de cette manipulation fait souvent débat de ce que j'ai vu dans les forums. Je vous conseille de tester vous même car cela dépend de la carte SD. Pour moi, le résultat est sans appel :

    Avec le scheduler deadline :

    dd if=/dev/zero of=test bs=1M count=512
    512+0 enregistrements lus
    512+0 enregistrements écrits
    536870912 octets (537 MB) copiés, 91,9373 s, 5,8 MB/s
     
    rm test
     
    timeout -s2 60 dd if=/dev/zero of=test
    631065+0 enregistrements lus
    631065+0 enregistrements écrits
    323105280 octets (323 MB) copiés, 65,3899 s, 4,9 MB/s

    Avec le scheduler NOOP :

    dd if=/dev/zero of=test bs=1M count=512
    512+0 enregistrements lus
    512+0 enregistrements écrits
    536870912 octets (537 MB) copiés, 86,9908 s, 6,2 MB/s
     
    rm test
     
    timeout -s2 60 dd if=/dev/zero of=test
    732674+0 enregistrements lus
    732674+0 enregistrements écrits
    375129088 octets (375 MB) copiés, 60,4063 s, 6,2 MB/s

    De plus, j'ai un sentiment d'une meilleure réactivité du système, en cas de fortes lectures/écritures avec le scheduler noop.

  • Désinstaller l'inutile pour un serveur (gain : 575 Mo) :
    apt-get autoremove --purge gnome-* lxde-* xserver-* desktop-* midori consolekit hicolor-icon-theme leafpad vim-* aptitude aptitude-common aspell aspell-en xarchiver wpagui tsconf scratch samba-common nfs-common ppp openbox omxplayer notification-daemon network-manager netsurf-common mupdf ncdu bluez cifs-utils dictionaries-common dillo dnsmasq-base fbset galculator gksu gpicview lightdm lightdm-gtk-greeter lxappearance lxinput lxpanel lxmenu-data lxpolkit lxrandr lxsession lxsession-edit lxshortcut lxtask lxterminal obex-data-server obexd-client gtk2-engines idle idle3 penguinspuzzle triggerhappy gcc g++ gdb gdbserver libraspberrypi0 libraspberrypi-bin libraspberrypi-dev libraspberrypi-doc isc-dhcp-client alsa-base alsa-utils wireless-tools wpasupplicant xinit strace xterm blt firmware-* lksctp-tools xkb-data kbd fontconfig-config fonts-freefont-ttf ttf-freefont ttf-dejavu-core libblas3 libatlas3-base
  • Installer votre indispensable (screen/tmux, vim/nano/emacs, bash/dash/zsh, ...).
  • Installer vos logiciels serveur et les configurer avec vos réglages habituels (exemple pour SSH : mettre en place l'auth par clé, désactiver l'auth par mot de passe, désactiver le root login, ...).
  • Redémarrer le RPi pour prendre en compte certains changements (comme le split mémoire ou l'activation d'IPv6, par exemple).

Les problèmes

Un manque de neutralité

Hé oui ... À mon grand regret, je suis chez un Fournisseur d'Accès à son Intranet au lieu d'être chez un Fournisseur d'accès à Internet. Du coup, j'ai une addresse IPv4 publique, pas d'IPv6, pas d'IP fixe, des ports bloqués en sortie (notamment le 25, néccessaire pour monter un serveur mail) et, cerise sur le gateau, les connexions entrantes (pour ceux qui parle l'iptables : état NEW) sont interdites, seules les réponses à une demande interne (RELATED,ESTABLISHED) sont autorisées ... Le top du top pour s'auto-héberger quoi. :@

Il n'y a pas 36 façons de résoudre ce problème : soutenir les FAI associatifs et prendre un VPN chez l'un d'eux (à l'heure actuelle, à ma connaissance, seul FDN et Tetaneutral.net ont un tel service, c'est aussi en projet chez ARN et Franciliens.net). Pour l'instant, mon choix s'est porté sur un VPN FDN.

Les démons UDP et l'effet VPN

Au boot, BIND et NTPd seront lancés avant que le VPN ne soit initialisé. L'interface tun sera donc montée et adressée bien après le lancement des démons. Pour une raison qui m'échappe, alors que j'ai demandé à ces deux démons d'écouter sur n'importe quelle interface, cela ne marche pas et ils n'écoutent pas sur l'interface tun quand elle devient up. Pourtant, tous les démons basés exclusivement sur TCP (nginx, sshd, postfix, dovecot, ...) fonctionnent très bien avec ce VPN.

Symptômes : NTPd ne se connecte pas aux serveurs de temps externes. BIND n'accepte aucune connexion, udp ou tcp, en v4 ... mais répond parfaitement en v6, udp comme tcp.

Oui, vous pouvez modifier l'ordre de démarrage des différents démons pour les faire passer après OpenVPN mais ça ne fonctionnera probablement pas : c'est une histoire de timing ... Si OpenVPN arrive à monter le tunnel avant que les démons soient lancés, c'est bon, sinon non.

Oui, vous pouvez demander à OpenVPN d'exécuter un script à la fin de la mise en place du tunnel pour relancer BIND et NTPd mais je trouve ça assez bof ... Pour BIND, ce n'est pas trop dérangeant (un notify sera simplement envoyé aux secondaires, rien de méchant donc) mais un restart de NTPd lui fait recommencer tout son algorithme d'obtention du temps à partir de 0, au risque de surcharger les serveurs sur lesquels vous vous synchronisez (surtout moi et mes déconnexions forcées régulières (toutes les 6H ...) ...)

Notez que l'option « persist-tun » d'OpenVPN n'est pas destinée à cet usage mais sert à ne pas détruire la tun lors d'un ping-restart.

Je résous le problème de deux manières différentes, une pour chaque démon.

BIND

BIND dispose d'une directive de configuration, « interface-interval », qui permet de rafraîchir la liste des interfaces toutes les <interface-interval> minutes. Par défaut, BIND actualise la liste des interfaces toutes les 60 minutes. Je configure cette option à 1 (dans named.conf.options, classique). Cela veut dire qu'au boot, BIND découvrira la tun au maximum 1 minute après qu'OpenVPN ait monté le tunnel.

NTPd

NTPd dispose lui aussi d'une option « -U X » qui permet de donner un intervalle, en secondes cette fois-ci, entre deux rafraichissements de la liste des interfaces. Par défaut, c'est 5 minutes. Mais ce n'est pas l'option qui convient ici et ce, pour deux raisons :

  1. D'abord car un délai insuffisant signifie qu'à chaque deconnexion, NTPd actualisera la liste des interfaces ... et recommencera donc son algorithme d'obtention du temps à 0. Un délai trop long et il mettra beaucoup de temps à configurer l'horloge au boot alors que c'est là que nous en avons le plus besoin (le RPi n'ayant pas d'horloge hardware).
  2. Ensuite car j'ai constaté que la désactivation de cette option fait que NTPd répond en v6. Avec cette option activée, il écoute bien mais ne répond pas alors qu'il n'y a pourtant aucune directive « ignore » dans son fichier de configuration. Je n'explique pas ce phénomène mais je peux le reproduire sur deux machines qui n'ont rien en commun.

Du coup, comme je ne prévois pas de redistribuer le temps à l'extérieur de mon réseau, je n'ai pas besoin d'écouter sur l'interface du VPN. Ma solution est donc de désactiver l'actualisation de la liste des interfaces et de faire en sorte que NTPd ne sorte pas par le VPN grâce à l'ajout de routes statiques plus précises.

Pour désactiver l'actualisation règulière de la liste des interfaces, il suffit d'ajouter « -U 0 » dans la variable « NTPD_OPTS » dans /etc/default/ntp.

Pour les routes, il suffit de les faire ajouter par OpenVPN, c'est le plus simple et le plus cohérent, selon moi. Cela se fait donc dans le fichier de configuration de votre VPN. Exemple :

# Pour NTPd
route 145.238.203.14 255.255.255.255 <IP_GATEWAY_DE_VOTRE_RÉSEAU>
route 192.93.2.20 255.255.255.255  <IP_GATEWAY_DE_VOTRE_RÉSEAU>

Raccourcir le chemin

Comme votre serveur est derrière un VPN, cela veut dire que, depuis votre réseau local, vos requêtes vers votre serveur sortiront par Internet jusqu'à votre fournisseur VPN puis remonterons votre VPN pour atteindre votre serveur. Même chose au retour. Ce n'est pas top ... Vu que le serveur est sur le même réseau privé (ou dans une DMZ), autant ne pas sortir de ce réseau.

On peut utiliser le fichier hosts. Exemple : 192.168.1.42 serveur.mondomaine.example

On peut ajouter une route. Exemple : ip r a <IP VPN>/32 via 192.168.1.42 dev eth0

La première méthode est plus pratique. Mais si vous avez des laptop ? Vous voudrez sans doute une configuration qui marche autant chez vous qu'à l'extérieur de votre réseau personnel. Il suffit de jouer avec iptables sur la passerelle de votre réseau. Exemple :

# Quand un PC du réseau local veut s'adresser à l'IP VPN, on le redirige vers l'ip locale et privée du RPi
iptables -t nat -A PREROUTING -i eth1 -s 192.168.1.0/24 -d <IP_VPN>/32 -j DNAT --to-destination 192.168.1.42

# Pour que la redirection précédente fonctionne, il faut aussi remplacer l'IP source par celle de la gateway
iptables -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -d 192.168.1.42/32 -j SNAT --to-source 192.168.1.254

# Optionnel : léger contrôle ...
iptables -t filter -A FORWARD -i eth1 -o eth1 -s 192.168.1.0/24 -d 192.168.1.42/32 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
iptables -t filter -A FORWARD -i eth1 -o eth1 -s 192.168.1.42/32 -d 192.168.1.0/24 -m state --state RELATED,ESTABLISHED -j ACCEPT

OpenDNSSEC/SoftHSM

Le package softhsm présent dans les dépôts segfault lors de son l'initialisation (SO PIN, USER PIN, segfault). En compilant une version plus récente, j'arrive à configurer SoftHSM et OpenDNSSEC mais ce dernier ne signe pas ma zone car il rencontre une erreur :

[adapter] error parsing RR at line 17 (Syntax error, could not parse the RR): �������������������������������������������������������������������������� [je coupe ici mais y'en a encore un bon paquet]

La ligne 17 ne contient rien de spécial si ce n'est que c'est la fin du fichier de zone ... Ce fichier de zone peut être signé par une autre installation d'OpenDNSSEC (sur une architecture amd64) donc il n'est pas en cause. Même en compilant la dernière version, avec les dernières lib, ça ne juste marche pas. Je ne sais pas comment résoudre ce problème. C'est donc une autre machine qui signe ma zone et la transfère à mon RPi pour que ce dernier la serve à tous les Internets.

Prolongements (aka ce qu'il reste à faire)

  • Mettre en place un minimum de redondance : une autre machine, quelque part, avec les mêmes services, pour combler les éventuelles pannes de la première. Je sais que les principaux services sont résistants aux pannes (queue de mails pendant quelques jours si bien configuré, TTL dans le DNS, ...) mais quid des serveurs mal-configurés (il faut s'adapter à la diversité d'Internet), des pannes longues (déménagement, panne hardware sérieuse, panne locale des réseaux (électrique, boucle locale, réseau de votre FAI, ... )) ? Les pannes longues et sérieuses, ça n'arrive pas qu'aux autres. Et puis, c'est intéressant à creuser.
  • Mettre en place un peu plus de sécurité. Le chiffrement de la carte SD me tente pas mal. 😀
  • Comme tout cela n'est pas simple à mettre en place et encore moins à maintenir dans la durée pour tout un chacun, malgré les solutions clé en main (comme Yunohost), qu'il faut bien évidemment continuer d'encourager, il convient aussi de monter des associations locales à taille humaine pour proposer de l'hébergement en communauté. Comme on fait des FAI associatifs quoi. Oui, je sais qu'il en existe déjà un certain nombre mais plus c'est mieux et surtout il faudrait peut-être proposer des VM ?

Reproche

Je n'ai qu'un reproche majeur à faire à la Raspberry Fondation (en plus du blob propriétaire et de la tentative de faire croire qu'il est passé sous licence libre, bien sûr 😛 ) : pourquoi avoir foutu des LED qui pulsent autant et pourquoi on ne peut pas les contrôler de manière logicielle comme sur un WRT54GL ?! Illuminer la moitié d'une pièce avec une carte discrète par sa taille c'est vraiment super ...

Sources

DNAME

Aujourd'hui, on va parler d'un type d'enregistrement DNS : DNAME. Je connaissais ce type d'enregistrement mais je n'avais jamais eu l'occasion de l'utiliser autrement que pour un test bidon. Comme l'occasion s'est présentée récemment, je voulais faire un petit feedback. En conséquence, je vais être assez léger. Pour creuser le sujet, il faudra aller voir sur le blog de Stéphane Bortzmeyer (j'égrène les bons liens au long de ce billet).

Qu'est ce que c'est ?

Delegation Name (DNAME) est un type d'enregistrement DNS défini dans le RFC 6672 (l'original 2672 étant obsolète) qui permet de donner un alias, un synonyme à l'intégralité d'un sous-arbre dans la hiérarchie du DNS. Avec DNAME, le nom lui-même reste inchangé et n'est pas redirigé. En comparaison, le type CNAME permet de créer un alias 1 vers 1 : un unique nom pointe sur un autre. Le sous-arbre du nom aliasé reste inchangé. En gros, mettre un DNAME sur un nom produira le même résultat que de mettre des CNAME sur chacun des sous-noms possibles.

Exemple : mycorporation.example. DNAME ultimatecorporation.example.

www.mycorporation.example. pointe sur www.ultimatecorporation.example. Si ce dernier nom existe, une requête sur www.mycorporation.example produira un résultat. NXDOMAIN dans le cas contraire.

En admettant que le nom ultimatecorporation.example. existe en type AAAA (IPv6), que donnera une demande dig AAAA mycorporation.example. ? Aucun résultat. 🙂 Le nom n'existe pas dans le type demandé. Si vous êtes tombé dans le piège, relisez bien la définition : un DNAME permet de donner un alias à un sous arbre, pas au nom lui-même. Pour résoudre ce problème :

  • n'espérez pas d'ajouter un enregistrement de type CNAME pour mycorporation.example. CNAME ne se combine avec aucun autre type (exception faite des types relatifs à DNSSEC comme RSSIG) !
  • dupliquer l'information. Dans notre cas : dupliquer le type AAAA pour les deux noms (ultimatecorporation.example. et mycorporation.example.). Ce n'est pas un alias : une éventuelle modification devra être faite pour les deux noms !
  • on pourra, peut-être, utiliser un futur nouveau type, comme BNAME ou SHADOW, tous deux proposés à l'IETF, qui permettent de combiner CNAME et DNAME : on crée un alias pour un nom et pour le sous-arbre de ce nom.

À quoi ça sert ?

Le DNAME peut-être utilisé dans les cas suivants :

  • Lorsqu'une même organisation (ou personne) enregistre son nom ou celui d'une de ses marques dans plusieurs voire tous les TLD existants. Le DNAME permet de faire pointer chaque sous-arbre vers un seul sous-arbre. Seul ce dernier devra être maintenu.
  • Lors d'une rachat ou d'une fusion d'entreprises. Pour présenter le DNAME, Stéphane Bortzmeyer utilise le renommage de Vivendi Environnement en Veolia Environnement.
  • Pour les noms de domaine en unicode (IDN). DNAME est utilisé, par exemple, dans le TLD cat.

Limites

Comme le DNAME permet uniquement de donner un alias à un sous-arbre, cela peut être gênant en fonction de l'implémentation de certains scénarios. Par exemple : sous le TLD .cat, lors de l'enregistrement d'un nom IDN, le nom ASCII est aussi réservé et un DNAME redirige le sous-arbre IDN vers le sous-arbre ASCII. Cela signifie que je ne pourrais jamais envoyer de mails à destination du domaine caballè.cat. : ce FQDN est de type DNAME donc seul le sous-arbre est aliasé ! Pas de MX, pas de SRV (XMPP par exemple), pas même de A/AAAA (si pas de MX/SRV, les serveurs de mail/jabber cherchent un A/AAAA). Le mieux serait de déléguer les deux noms (IDN/ASCII) au titulaire et libre à lui d'utiliser DNAME ou pas en complément d'une duplication des type A/AAAA/MX/SRV/SPF/ pour l'apex. C'est d'ailleurs comme cela que procède DotAsia, le registre de asia. .

Comme l'utilisation de DNAME conduit à la synthèse de CNAME, cela signifie qu'il est possible d'avoir des chaînes de CNAME qui sont, normalement, déconseillées. Exemple : si l'on a www.ultimatecorporation.example. CNAME web.ultimatecorporation.example., alors dig A www.mycorporation.example générera la réponse suivante :

mycorporation.example.                  3600	IN	DNAME	ultimatecorporation.example.
www.mycorporation.example.	        0	IN	CNAME	www.ultimatecorporation.example.
www.ultimatecorporation.example.	3600	IN	CNAME	web.ultimatecorporation.example.
web.ultimatecorporation.example.	3600	IN	A	192.0.2.1

Le DNAME est fortement méconnu car, pour les deux usages sur les trois cités plus haut, il peut être remplacé par un fichier de zone avec des noms relatifs et des liens symboliques vers ce fichier pour toutes les zones identiques. La seule limite de cette méthode est la consommation mémoire : au chargement des zones, le serveur duplique les données pour obtenir un exemplaire par zone chargée (alors que les RDATA sont identiques). Cela pose problème pour les cas d'usages où l'on a beaucoup de zones identiques comme les IDN et les variantes.

Mettre en œuvre

DNS

Rien de spécial : c'est un type d'enregistrement, rien de plus.

Si vous avez deux domaines, savoir si vous allez vous les faire déléguer et mettre un DNAME dans le fichier de zone de l'un ou si vous allez demander à l'un des domaines parent de mettre le DNAME directement dans son fichier de zone à lui est un pur choix de votre part (le premier suppose de dupliquer l'apex, le second que vous n'aurez ni mail ni XMPP ni ... sur le domaine lui-même) et en fonction de votre domaine parent (inutile de demander ça à un gTLD/ccTLD hein, je dis ça pour ceux qui obtiennent des domaines via des potes 😉 ).

Postfix

On suppose que le serveur est configuré pour traiter les mails au départ/à destination du domaine mycorporation.example. On veut aussi qu'il s'occupe du nouveau domaine équivalent ultimatecorporation.example.. Pour l'identification, j'utilise SASL.

J'utilise les directives « virtual_alias_domains » et « virtual_alias_maps » :

virtual_alias_domains = ultimatecorporation.example
virtual_alias_maps = hash:/etc/postfix/virtual_aliases

/etc/postfix/virtual_aliases contient :

@ultimatecorporation.example        @mycorporation.example

Les mails adressés à guigui@ultimatecorporation.example seront redirigés vers guigui@mycorporation.example et delivrés si cette boîte existe.

Pour pouvoir envoyer des mails avec une adresse @ultimatecorporation.example, il suffit de rajouter une entrée dans une table passée en argument de « smtpd_sender_login_maps ». Exemple ici avec ce qui deviendra une hashmap :

guigui@ultimatecorporation.example        guigui@mycorporation.example

ejabberd

Il suffit simplement d'ajouter le nouveau nom dans la directive « hosts » comme le montre l'exemple commenté dans le fichier de configuration :

{hosts, ["mycorporation.example", "ultimatecorporation.example"]}

VPN unipersonnel avec une IP failover en sortie sur un dédié OVH

L'idée du jour est d'utiliser un serveur dédié chez OVH, qui sert déjà à autre chose, pour se monter un petit VPN sans prétention. Quand je dis sans prétention c'est que je prévois ça pour un usage personnel (unipersonnel) et que je ne destine pas ce VPN à l'échange de flux hautement confidentiels (sinon ça ne finirait pas chez OVH ...). Donc si vous cherchez une config blindée haute sécurité, ce n'est pas le bon billet, désolé.

Le but de ce VPN est de me permettre d'être sur Internet quand je veux faire des tests ou autre (exemple parmi d'autres : nmap mon serveur pour vérifier qu'il n'y a rien de plus qui est ouvert sur l'extérieur que ce que je veux). Quand je dis « être sur Internet », je veux dire : être capable d'émettre et de recevoir tous les contenus et toutes les applications de mon choix sans aucune discrimination ... Ho ! La définition de la neutralité du net ! Donc éviter un filtrage de ports à la con, éviter un filtrage du type "ne peut entrer sur le réseau que ce qui fait suite à une demande de l'intérieur" (en gros : impossible d'héberger des services). C'est rageant d'être perturbé par notre FAI (Fournisseur d'Accès à son Intranet dans le cas présent) quand on veut observer quelque chose ou monter un service.

Attention toutefois : le tunnel sort chez OVH et il faut savoir qu'OVH n'a pas un impératif de neutralité. Des usages y sont clairement interdits ou soumis à autorisation préalable comme, par exemple mais pas seulement, héberger un proxy ou un nœud TOR ou utiliser des logiciels de P2P. OVH duplique aussi tous les mails sortants pour analyse temps-réel anti-spam ... Donc si vous cherchez un vrai accès à Internet, même grâce à un VPN, je vous conseille plutôt les FAI associatifs de la Fédération FDN qui offrent une telle garantie par design, sans fluctuation ni d'exceptions.

En supplément, "depuis Internet", je souhaite que mon client VPN soit vu avec une IP distincte de celle attribuée à mon dédié. Il faut donc utiliser une IP failover et faire en sorte que le trafic sorte et entre de notre dédié par cette IP.

Table des matières

Sources

Je clos le suspens de suite : ce billet est une arnaque ! On trouve les morceaux de config OpenVPN à peu près partout : OpenVPN sur le Wiki Debian.org, le man d'OpenVPN est bien fait et le petit morceau de conf pour sortir du VPN avec une IP failover est aussi documenté un peu partout : Utiliser un VPN avec une IP failover chez kdecherf (git)-[blog] %. Pour ceux qui cherchent comment monter un serveur VPN sur leur dédié OVH sans utiliser une IP failover : il suffit de faire un SNAT sur l'IP principale du serveur ou, au pire, un masquerade sur ce qui sort par eth0.

Néanmoins, parce que je vous aime bien, je vais vous donner ma config.

Trêve de blabla, on commence !

Au niveau d'OVH, c'est très simple : il suffit de commander une IP failover, de la payer et d'attendre un peu qu'elle soit active. Rien de plus. Pas besoin de définir une MAC virtuelle, rien.

Point to point et chiffrement symétrique

Dans un premier temps, on va utiliser une topologie point à point avec un chiffrement symétrique.

On installe OpenVPN sur le serveur et sur le client :

apt-get install openvpn

Pour l'instant, je ne veux pas qu'OpenVPN démarre tout seul au boot donc je lance la commande suivante sur le client et sur le serveur :

update-rc.d -f openvpn remove

On crée la config côté serveur (dans /etc/openvpn/server.conf par exemple) :

proto udp
port 1194
dev tun
 
mode p2p
 
cipher AES-256-CBC
secret /etc/openvpn/vpn-static.key
 
comp-lzo
 
verb 3
 
persist-key
persist-tun
ping 30
ping-exit 90
 
user openvpn
group openvpn
 
ifconfig 198.18.0.1 198.18.0.2
script-security 2
up /etc/openvpn/up.sh
plugin /usr/lib/openvpn/openvpn-down-root.so /etc/openvpn/down.sh

Quelques remarques :

  • Pour le choix tun/tap (route/bridge) : comme je n'ai pas besoin des fonctionnalités des tap (broadcast, donc possibilité d'utiliser NetBios/SMB, possibilité d'utiliser d'autres protocoles de couches 3, ... voir : What is the difference between bridging and routing? sur OpenVPN.net et Bridging vs. routing sur OpenVPN community), j'ai choisi le mode router/tun pour profiter de l'avantage d'avoir moins d'overhead.
  • Pour l'adressage du serveur et du client, j'ai pris le bloc 198.18.0.0/30 qui est englobé dans 198.18.0.0/15 qui est un préfixe réservé à l'IANA pour les tests et qui n'est donc pas annoncé globalement. L'idée est d'éviter une éventuelle collision. Comme ce préfixe est méconnu et que les réseaux auxquels je me connecte sont adressés soit en public soit avec les préfixes du RFC 1918, je suis sûr d'être tranquille. Notez qu'il serait peut-être plus pertinent de prendre un préfixe /30 dans 10.0.0.0/8. La probabilité de se connecter à un réseau existant utilisant ce bloc me paraît faible.
  • « plugin /usr/lib/openvpn/openvpn-down-root.so » permet de lancer le script de fin avec les droits root alors même qu'OpenVPN a, comme on le lui a demandé, perdu, dès la fin de l'initialisation, les droits root pour ceux de l'utilisateur openvpn et du groupe openvpn.

On crée la config côté client (dans /etc/openvpn/client.conf, par exemple) :

proto udp
remote <IP PRINCIPALE DU SERVEUR> 1194
dev tun
 
cipher AES-256-CBC
secret /etc/openvpn/vpn-static.key
 
comp-lzo
 
verb 3
 
persist-key
persist-tun
ping 30
ping-exit 90
explicit-exit-notify
 
user openvpn
group openvpn
 
ifconfig 198.18.0.2 198.18.0.1
route-gateway 198.18.0.1
redirect-gateway def1

Sur le serveur, on crée les deux scripts. D'abord /etc/openvpn/up.sh :

#!/bin/bash
 
ifconfig br0:1 <IP FAILOVER> netmask 255.255.255.255 broadcast <IP FAILOVER>
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s 198.18.0.0/30 ! -d 198.18.0.0/30 -j SNAT --to-source <IP FAILOVER>
iptables -t nat -A PREROUTING -d <IP FAILOVER> -j DNAT --to-destination 198.18.0.2

Puis le script /etc/openvpn/down.sh :

#!/bin/bash
 
echo 0 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -D POSTROUTING -s 198.18.0.0/30 ! -d 198.18.0.0/30 -j SNAT --to-source <IP FAILOVER>
iptables -t nat -D PREROUTING -d <IP FAILOVER> -j DNAT --to-destination 198.18.0.2
ifconfig br0:1 down

Quelques remarques :

  • J'ai configuré l'alias sur br0 car j'utilise un bridge pour attribuer des IP failover à mes conteneurs LXC (voir Utiliser LXC sur un Kimsufi). Si vous n'avez pas de VM ni de conteneurs LXC ou autre montage du même type, alors il faudra faire l'alias sur eth0.
  • Mapper 198.18.0.2 à l'IP failover suffit amplement. Néanmoins, j'ai voulu jouer la prudence au cas où le serveur émettrait avec 198.18.0.1 car je ne suis pas sur mon réseau mais sur celui d'OVH. Ce scénario ne devrait jamais se produire mais bon ... Au moins comme ça, ça sortira avec l'IP failover. Si je ne vois rien passer, OVH m'indiquera un problème avec cette IP et je saurai alors que le problème vient du VPN sans passer 5h à essayer de comprendre. Indiquer un /30 est par facilité : on pourrait utiliser les ip set pour indiquer les 2 adresses IP précises.
  • Le DNAT n'est clairement pas obligatoire. C'est pour le fun ... Si l'on veut héberger des services derrière ce VPN ...
  • Pour ceux qui cherchent comment monter un serveur VPN sur leur dédié OVH sans utiliser une IP failover, seule la première règle iptables change :
    iptables -t nat -D POSTROUTING -s 198.18.0.0/30 ! -d 198.18.0.0/30 -j SNAT --to-source <IP PRINCIPALE DU SERVEUR>

    Forcement, vous ne pouvez alors pas faire de DNAT complet mais uniquement pour certains ports que vous voulez rediriger vers votre client VPN.

  • Enfin, selon votre configuration, il faudra autoriser le transfert de paquet depuis/vers le VPN. Cela se fait dans chaîne FORWARD. 😉

On rend ces scripts exécutables :

chmod u+x /etc/openvpn/up.sh /etc/openvpn/down.sh

On crée l'utilisateur openvpn :

adduser openvpn --disabled-login --no-create-home --shell /bin/false

Sur le serveur ou sur le client, on génère la clé cryptographique :

openvpn --genkey --secret /etc/openvpn/vpn-static.key

Il faudra la transférer à l'autre partie via scp puis vérifier les droits : root:root 400.

Enfin, selon votre configuration, il faudra autoriser OpenVPN dans votre firewall, en entrée et en sortie. Aussi bien sur le client que sur le serveur.

Il est l'heure de tester (sur le client et le serveur) :

service openvpn restart

Normalement, le client doit pouvoir pinguer 198.18.0.1 et sortir sur Internet par le VPN. L'adresse IP "vue depuis Internet" doit être l'IP failover.

Pour ceux que ça intéresse, voici les configurations équivalentes mais en utilisant des tap. Pour le serveur :

proto udp
port 1194
dev tap
 
cipher AES-256-CBC
secret /etc/openvpn/vpn-static.key
 
comp-lzo
 
verb 3

persist-key
persist-tun
ping 30
ping-exit 90
 
user openvpn
group openvpn
 
ifconfig 198.18.0.1 255.255.255.252
script-security 2
up /etc/openvpn/up.sh
plugin /usr/lib/openvpn/openvpn-down-root.so "/etc/openvpn/down.sh"

Pour le client :

proto udp
remote <IP PRINCIPALE DU SERVEUR> 1194
dev tap
 
cipher AES-256-CBC
secret /etc/openvpn/vpn-static.key
 
comp-lzo
 
verb 3
 
persist-key
persist-tun
ping 30
ping-exit 90
explicit-exit-notify
 
user openvpn
group openvpn
 
ifconfig 198.18.0.2 255.255.255.252
route-gateway 198.18.0.1
redirect-gateway def1

Point to point et chiffrement asymétrique

L'inconvénient principal du chiffrement symétrique est qu'il ne permet pas le perfect forward secrecy. Bien que, comme je l'ai déjà dit, mon VPN me servira principalement à faire des tests et ne transmettra pas mes secrets les plus noirs, je me dis qu'il peut être intéressant de faire une topologie p2p avec du chiffrement asymétrique, for ze fun.

Attention à ne pas mal interpréter mes propos : le chiffrement du tunnel reste symétrique. Simplement, lors de l'initialisation, le client et le serveur échangent une clé temporaire pour réaliser le chiffrement symétrique du tunnel. C'est cet échange initial qui se fait en utilisant la cryptographie asymétrique.

Pour cette partie, on va suivre d'encore plus près le tutoriel du wiki Debian.org. Reportez-vous à la partie « TLS-enabled VPN ». La génération du matériel cryptographique est identique : seules les configurations d'OpenVPN sont différentes.

Voici la configuration du serveur :

proto udp
port 1194
dev tun
 
mode p2p
tls-server
 
ca      /etc/openvpn/easy-rsa/keys/ca.crt
cert    /etc/openvpn/easy-rsa/keys/server.crt
key     /etc/openvpn/easy-rsa/keys/server.key
dh      /etc/openvpn/easy-rsa/keys/dh1024.pem
 
comp-lzo
 
verb 3
 
persist-key
persist-tun
ping 30
ping-exit 90
 
user openvpn
group openvpn
 
ifconfig 198.18.0.1 198.18.0.2
script-security 2
up /etc/openvpn/up.sh
plugin /usr/lib/openvpn/openvpn-down-root.so /etc/openvpn/down.sh

ÉDIT du 12/01/2014 à 13h10 : Il faudra prévoir la révocation des certificats clients. C'est toujours utile en cas de perte ou de compromission, surtout si vous distribuez des accès (oui oui, le titre du billet cause d'un VPN unipersonnel mais bon) ... Fin de l'édit

La configuration du client :

proto udp
remote <IP PRINCIPALE DU SERVEUR> 1194
dev tun
 
tls-client
 
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/guigui.crt
key /etc/openvpn/easy-rsa/keys/guigui.key
 
comp-lzo
 
verb 3
 
persist-key
persist-tun
ping 30
ping-exit 90
explicit-exit-notify
 
user openvpn
group openvpn
 
ifconfig 198.18.0.2 198.18.0.1
route-gateway 198.18.0.1
redirect-gateway def1

Il est l'heure de tester (sur le client et le serveur) :

service openvpn restart

Normalement, le client doit toujours pouvoir pinguer 198.18.0.1 et sortir sur Internet par le VPN. L'adresse IP "vue depuis Internet" doit toujours être l'IP failover.

La même mais en mieux

Le résultat obtenu jusque-là est pas mal. Il manque un dernier truc : pour l'instant le script up est exécuté au démarrage d'OpenVPN, juste après la création de l'interface tun. Le down est exécuté à l'arrêt d'OpenVPN. J'aimerais que les scripts soient exécutés uniquement lorsque le client se connecte/déconnecte de mon VPN. Comme ça, le reste du temps je n'ai pas de la config qui ne sert à rien en train de tourner. Pas de forward, pas de NAT, l'IP failover ne répond pas aux requêtes, ...

Cela est possible en utilisant les directives client-connect/client-disconnect d'OpenVPN. Mais elles sont disponibles uniquement en mode serveur. Ce mode requiert l'utilisation d'un /29 au minimum donc on va avoir un peu de configuration à changer.

On s'occupe d'abord des configurations OpenVPN. Celle du serveur :

proto udp
port 1194
 
dev tun
 
mode server
max-clients 1
 
tls-server
ca      /etc/openvpn/easy-rsa/keys/ca.crt
cert    /etc/openvpn/easy-rsa/keys/server.crt
key     /etc/openvpn/easy-rsa/keys/server.key
dh      /etc/openvpn/easy-rsa/keys/dh1024.pem
 
comp-lzo
 
verb 3
 
persist-key
persist-tun
ping 30
ping-exit 90
 
user openvpn
group openvpn
 
ifconfig 198.18.0.1 198.18.0.2
ifconfig-pool 198.18.0.5 198.18.0.6
route 198.18.0.0 255.255.255.240
push "route 198.18.0.1"
 
script-security 2
client-connect "/usr/bin/sudo -u root /etc/openvpn/up.sh"
client-disconnect "/usr/bin/sudo -u root /etc/openvpn/down.sh"

La configuration du client :

proto udp
port 1194
 
dev tun
 
client
remote <IP PRINCIPALE DU SERVEUR> 1194
 
tls-client
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/guigui.crt
key /etc/openvpn/easy-rsa/keys/guigui.key
 
comp-lzo
 
verb 3
 
persist-key
persist-tun
ping 30
ping-exit 90
explicit-exit-notify
 
user openvpn
group openvpn
 
redirect-gateway def1

On remarque l'utilisation de sudo pour lancer les scripts à la connexion/déconnexion. En effet, lorsque le client se connectera ou se déconnectera, il y aura longtemps que le serveur OpenVPN aura perdu les droits root. Il faut donc rajouter une ligne au fichier /etc/sudoers :

openvpn		ALL=(root)	NOPASSWD:/etc/openvpn/up.sh,/etc/openvpn/down.sh

Les scripts d'up et de down changent aussi : on NAT le /29 et on redirige le DNAT sur la bonne IP :

#!/bin/bash
 
echo 0 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -D POSTROUTING -s 198.18.0.0/29 ! -d 198.18.0.0/29 -j SNAT --to-source <IP FAILOVER>
iptables -t nat -D PREROUTING -d <IP FAILOVER> -j DNAT --to-destination 198.18.0.6
ifconfig br0:1 down

Les mêmes modifications s'appliquent au script de déconnexion. Je vous laisse faire les changements. 🙂

Voilà, on arrive à la fin de ce que je voulais vous montrer.