1461 lines
85 KiB
HTML
1461 lines
85 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<title>Wxcafé</title>
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="author" content="wxcafé">
|
||
<link rel="icon" type="image/png" href="//wxcafe.net/theme/img/favicon.ico">
|
||
<!-- Le styles -->
|
||
<link rel="stylesheet" href="//wxcafe.net/theme/css/extra.css" type="text/css" />
|
||
<link rel="stylesheet" href="//wxcafe.net/theme/css/bootstrap.css" type="text/css" />
|
||
<link href='http://fonts.googleapis.com/css?family=Oswald&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
|
||
<script type="text/javascript">
|
||
/* <![CDATA[ */
|
||
(function() {
|
||
var s = document.createElement('script');
|
||
var t = document.getElementsByTagName('script')[0];
|
||
|
||
s.type = 'text/javascript';
|
||
s.async = true;
|
||
s.src = '//api.flattr.com/js/0.6/load.js?'+
|
||
'mode=auto&uid=wxcafe&button=compact&popout=0';
|
||
t.parentNode.insertBefore(s, t);
|
||
})();
|
||
/* ]]> */
|
||
</script> <!-- flattr button loader -->
|
||
<style type="text/css">
|
||
body {
|
||
padding-top: 60px;
|
||
padding-bottom: 40px;
|
||
}
|
||
.sidebar-nav {
|
||
padding: 9px 0;
|
||
}
|
||
.tag-1 {
|
||
font-size: 13pt;
|
||
}
|
||
.tag-2 {
|
||
font-size: 10pt;
|
||
}
|
||
.tag-2 {
|
||
font-size: 8pt;
|
||
}
|
||
.tag-4 {
|
||
font-size: 6pt;
|
||
}
|
||
</style>
|
||
<link href="//wxcafe.net/theme/css/bootstrap-responsive.css" rel="stylesheet">
|
||
<link href="//wxcafe.net/theme/css/font-awesome.css" rel="stylesheet">
|
||
<link href="//wxcafe.net/theme/css/pygments.css" rel="stylesheet">
|
||
<!-- Le fav and touch icons -->
|
||
<link rel="shortcut icon" href="//wxcafe.net/theme/images/favicon.ico">
|
||
|
||
<link href="//wxcafe.net/feeds/feed.rss.xml" type="application/atom+xml" rel="alternate" title="Wxcafé RSS Feed" />
|
||
|
||
</head>
|
||
|
||
<body>
|
||
|
||
<div class="navbar navbar-fixed-top">
|
||
<div class="navbar-inner">
|
||
<div class="container-fluid">
|
||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||
<span class="icon-bar"></span>
|
||
<span class="icon-bar"></span>
|
||
<span class="icon-bar"></span>
|
||
</a>
|
||
<a class="brand" href="//wxcafe.net/index.html">Wxcafé </a>
|
||
<div class="nav-collapse">
|
||
<ul class="nav">
|
||
<li><a href="//wxcafe.net/archives.html"><i class="icon-th-list"></i> Archives</a></li>
|
||
<li><a href="//wxcafe.net/pages/about/">A propos</a></li>
|
||
<li class="divider-vertical"></li>
|
||
<ul class="nav pull-right">
|
||
</ul>
|
||
</ul>
|
||
</div><!--/.nav-collapse -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="container-fluid">
|
||
<div class="row">
|
||
<div class="span9" id="content">
|
||
<div class="article">
|
||
<h1><a href="//wxcafe.net/posts/sed-basics/">Sed Basics</a></h1>
|
||
<div class="well small"><footer class="post-info">
|
||
<span class="label">Date</span>
|
||
<span class="published" title="2013-08-18T22:57:00+02:00">
|
||
<i class="icon-calendar"></i> Sun 18 August 2013
|
||
</span>
|
||
<br />
|
||
<span class="label">By</span>
|
||
<a href="//wxcafe.net/author/wxcafe.html"><i class="icon-user"></i>Wxcafe</a>
|
||
<br />
|
||
<span class="label">Category</span>
|
||
<a href="//wxcafe.net/category/tutoriel/"><i class="icon-folder-open"></i>Tutoriel</a>
|
||
<br />
|
||
|
||
|
||
|
||
|
||
</footer><!-- /.post-info --></div>
|
||
<div class="summary"><p><code>sed</code> est un outil Unix très largement utilisé et très pratique pour manipuler
|
||
le texte (ce qui se montre relativement indispensable dans un environnement
|
||
Unix, puisque ce système est assez porté sur le texte). Cependant, il assez peu
|
||
connu en détail, et la plupart du temps une seule fonction est utilisée : le
|
||
remplacement de texte.<br />
|
||
Or <code>sed</code> a bien plus de possibilités que ça, comme nous allons le voir.</p>
|
||
<p>Tout d’abord, rappelons les bases : <code>sed</code> est un programme Unix de base, mais
|
||
aussi un langage de manipulation de texte dérivé de <code>ed</code>, l’éditeur original.<code>ed</code> est un éditeur de ligne, conçu a l’époque ou les ordinateurs n’étaient pas
|
||
personnels et étaient utilisés avec des <a href="http://fr.wikipedia.org/wiki/telescripteur">téléscripteurs</a>, c’est a dire des
|
||
machines dépourvues d’écrans et ne permettant donc pas l’utilisation d’éditeurs
|
||
dits “visuels”, tels que vim, emacs, et globalement tous les éditeurs ayant un
|
||
curseur et affichant plusieurs lignes. <code>sed</code> est donc une évolution de <code>ed</code>, le
|
||
s signifiant stream, <code>sed</code> est un éditeur de flux, prenant donc avantage du
|
||
concept Unixien de flux de données (voir <a href="http://fr.wikipedia.org/wiki/Flux_standard">Flux standards</a>) pour éditer plus d’une ligne a la fois.
|
||
En pratique, <code>sed</code> est principalement utilisé sur des fichiers.</p>
|
||
<p><code>sed</code> a quelques options pratique, notamment <code>-s</code> qui permet d’empêcher
|
||
l’affichage systématique des lignes traitées, ou bien <code>-i</code> (pour GNU sed) qui
|
||
permet de rediriger l’output dans le fichier d’input. Cela dit, l’intérêt unique
|
||
du programme est son langage de manipulation de texte.</p>
|
||
<p><code>ed</code>, et donc <code>sed</code>, utilise un langage basé sur les séparations (en général des
|
||
/). Ainsi, la commande de base dans <code>sed</code> est </p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">/[regex]/
|
||
</pre></div>
|
||
|
||
|
||
<p>qui permet de ne sélectionner que les lignes qui matchent [regex] (et donc de
|
||
n’exécuter les commandes qui suivent que sur ces lignes.) </p>
|
||
<p><br/>
|
||
La commande <code>sed</code> la plus utilisée est bien entendu le <strong>s</strong>, qui s’utilise de
|
||
la façon suivante : </p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%"><span style="color: #f8f8f2">s</span><span style="color: #f92672">/</span><span style="color: #f8f8f2">[old</span> <span style="color: #f8f8f2">text]</span><span style="color: #f92672">/</span><span style="color: #f8f8f2">[new</span> <span style="color: #f8f8f2">text]</span><span style="color: #f92672">/</span><span style="color: #f8f8f2">[options]</span>
|
||
</pre></div>
|
||
|
||
|
||
<p>qui se propose donc de remplacer (substitute) [old text] (qui peut être une
|
||
regex) par [new text] (qui doit être un texte fixe, avec quelques
|
||
exceptions), en appliquant [options], la plus connue des options étant <code>g</code>,
|
||
qui permet d’appliquer la commande affectée a toutes les occurrences du texte
|
||
matché sur la/les lignes concernée-s.<br />
|
||
Les exceptions a la “fixité” de [new text] sont particulièrement
|
||
intéressantes. En effet, <code>sed</code> utilise un langage de regex plutôt standard,
|
||
excepté le fait qu’il permet jusqu’à 9 “holding spaces”, qui sont délimités par
|
||
\( et \), et qui sont représentées dans le texte de remplacement par \1 à
|
||
\9.</p>
|
||
<p>Par exemple, la commande </p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">sed 's/\(hello world\) world/\1/'
|
||
</pre></div>
|
||
|
||
|
||
<p>sur le texte “hello world world” renverrait comme résultat</p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">hello world
|
||
</pre></div>
|
||
|
||
|
||
<p>De la même façon, le symbole <code>&</code> dans le texte de remplacement représente le
|
||
texte original. Ainsi, la commande </p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">sed 's/hello world/& world/'
|
||
</pre></div>
|
||
|
||
|
||
<p>sur le texte “hello world” renverrait comme résultat</p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">hello world world
|
||
</pre></div>
|
||
|
||
|
||
<p><br/></p>
|
||
<p>Une autre commande utile est <strong>p</strong>, qui sert a afficher le texte présent dans
|
||
l’espace courant :</p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">/[regex]/p
|
||
</pre></div>
|
||
|
||
|
||
<p><code>sed</code> stocke en effet la ligne sur laquelle il travaille dans un espace mémoire
|
||
dédié, que j’appelle l’espace courant (pattern space en anglais). La commande<code>p</code> affiche (print) ce qui ce trouve dans cet espace. La /[regex]/ réduit
|
||
le pattern space de façon a ce qu’il ne contienne que les lignes matchant, et le <strong>p</strong> affiche donc ce dernier.</p>
|
||
<p>Un autre exemple de commande sont <strong>c</strong>, <strong>i</strong> et <strong>a</strong>, qui s’utilisent ainsi :</p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">c \
|
||
[text]
|
||
</pre></div>
|
||
|
||
|
||
<p>De la même façon, pour le i : </p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">i \
|
||
[text]
|
||
</pre></div>
|
||
|
||
|
||
<p>Et de même pour a. </p>
|
||
<p>Ces trois commandes s’utilisent de la même façon pour la bonne raison qu’elles
|
||
sont très proches. <strong>i</strong> sert a insérer du texte <em>avant</em> le pattern space. <strong>a</strong>
|
||
sert a insérer du texte <em>après</em> le pattern space, et enfin <strong>c</strong> sert a
|
||
remplacer <em>tout</em> le pattern space. Les trois utilisent [text] comme
|
||
remplacement ou insert.
|
||
Attention, les insertions se font sur la ligne précédant ou suivant le pattern
|
||
space, et non sur la ligne en question.</p>
|
||
<p>Enfin, dernière commande ne fonctionnant que ligne par ligne, <strong>d</strong> :
|
||
/[regex]/d
|
||
<strong>d</strong> (delete) supprime les contenus du pattern space.</p>
|
||
<p><code>sed</code> est un outil puissant, mais complexe. Dans un prochain article, je
|
||
parlerai des commandes multilignes et des labels.</p></div>
|
||
</div>
|
||
<hr />
|
||
<div class="article">
|
||
<h1><a href="//wxcafe.net/posts/le-chiffrement-de-partition-avec-dm-crypt-et-device-mapper/">Le chiffrement de partitions avec dm-crypt et device-mapper</a></h1>
|
||
<div class="well small"><footer class="post-info">
|
||
<span class="label">Date</span>
|
||
<span class="published" title="2013-07-10T03:18:00+02:00">
|
||
<i class="icon-calendar"></i> Wed 10 July 2013
|
||
</span>
|
||
<br />
|
||
<span class="label">By</span>
|
||
<a href="//wxcafe.net/author/wxcafe.html"><i class="icon-user"></i>Wxcafe</a>
|
||
<br />
|
||
<span class="label">Category</span>
|
||
<a href="//wxcafe.net/category/tutoriel/"><i class="icon-folder-open"></i>Tutoriel</a>
|
||
<br />
|
||
|
||
|
||
|
||
|
||
</footer><!-- /.post-info --></div>
|
||
<div class="summary"><p>Le chiffrement en tant que concept informatique est traditionnellement associé
|
||
au chiffrement de fichiers, c’est a dire au fait de passer d’un fichier <em>en
|
||
clair</em> a un fichier chiffré dit <em>cyphertext</em>. Cependant, il ne se limite pas a
|
||
ça, et peut aussi servir a garantir l’intégrité d’un système d’exploitation, ou
|
||
bien la confidentialité d’un support de stockage, par exemple. Nous allons ici
|
||
voir comment mettre en place un système de ce type sous GNU/Linux. Cet article
|
||
n’a pas pour but de vous apprendre a mettre en place un système basé sur une
|
||
procédure de boot sécurisée, mais plutôt d’expliquer les concepts qui entrent en
|
||
jeu dans l’utilisation du sous-système du noyau Linux <a href="http://en.wikipedia.org/wiki/dm-crypt"><strong>dm_crypt</strong></a> et de
|
||
présenter un rapide tutoriel concernant la création d’un support chiffré sur
|
||
lequel garder vos informations confidentielles (par exemple, votre <a href="http://wxcafe.net/posts/11/19/12/la-cryptographie-avec-pgp-et-principalement-gnupg">clé GPG</a>)</p>
|
||
<p>dm-crypt est un sous-système de device-mapper, qui est lui-même un sous-système
|
||
du noyau Linux, et s’appuie sur <a href="http://en.wikipedia.org/wiki/Linux_Unified_Key_Setup">LUKS</a>, un standard de chiffrement
|
||
de disques. Comme son nom l’indique, device-mapper est un système qui a pour but
|
||
de <strong>mapper</strong> des <strong>block devices</strong>. Pour être plus clair, le kernel considère
|
||
comme “block device” tout fichier spécial (en gros, les fichiers disques dans<code>/dev/</code>, les systèmes de fichiers type LVM, les RAID logiciels, et, dans le
|
||
cas qui nous intéresse, les systèmes de fichier chiffrés). Son mode de
|
||
fonctionnement est simple : a partir d’un “fichier de périphérique” (trad.
|
||
Wikipédia), il en “crée” un nouveau, virtuel, ayant des propriétés différentes.
|
||
Par exemple, un disque partitionné via LVM apparaîtra comme un seul disque dans
|
||
/dev, et device-mapper est requis pour pouvoir en voir les partitions (qui
|
||
apparaîtront donc dans /dev/mapper)</p>
|
||
<p>Ainsi, dans le cas qui nous intéresse ici, device-mapper prend un système de
|
||
fichier chiffré, crée un périphérique virtuel non chiffré dans /dev/mapper, et
|
||
déchiffre a la volée tous les accès disques a ce périphérique non chiffré en les
|
||
traduisant sur le système de fichier chiffré, le tout de manière tout a fait
|
||
transparente pour les applications utilisant le disque en question. Cela induit
|
||
bien entendu une baisse de performance relativement significative dans le cas
|
||
d’un chiffrement du système de fichier root, mais quasiment insignifiante dans
|
||
le cas de chiffrement de partitions de données.</p>
|
||
<p>D’ailleurs, certain-e-s se demandent peut-être comment le système peut démarrer
|
||
si le système de fichier root est chiffré. Dans ce cas précis, la procédure de
|
||
boot <strong><em>doit</em></strong> s’appuyer sur une image initrd (l’initrd est un système de
|
||
fichier minimal qui sert uniquement a initialiser le système. Les kernels de
|
||
base de la plupart des distributions GNU/Linux en utilisent un dans tous les
|
||
cas, pour des raisons de compatibilité) et sur une partition de boot qui elle
|
||
n’est pas chiffrée. Ainsi, le bootloader de niveau 2 (grub, syslinux,…) charge
|
||
en mémoire le kernel depuis la partition de boot, puis ce dernier décompresse et
|
||
charge l’initrd en RAM, celui-ci a son tour lance un script permettant de
|
||
charger les modules nécessaires a la suite du boot (que ce soit pour un boot
|
||
sans disque root local, ou bien comme ici avec un système chiffré), puis le
|
||
système de fichier “cible” est remonté sur la racine, et l’initrd est démonté
|
||
est la RAM qu’il occupait est libérée, puis la procédure de boot normale reprend
|
||
depuis le système de fichier maintenant monté sur la racine.</p>
|
||
<p>La méthode la plus évidente pour contourner le chiffrement du disque est alors
|
||
de remplacer le fichier compressé initrd dans /boot, qui n’est pas chiffrée, par
|
||
un autre modifié, copiant par exemple la phrase de passe permettant de
|
||
déchiffrer la partition cible. Plusieurs méthodes permettent de se prémunir
|
||
contre ce genre d’attaques : l’une des plus simple est de faire un checksum du
|
||
fichier initrd utilisé et reconnu comme sûr, et de vérifier lors du <em>vrai</em> boot
|
||
que l’initrd présente toujours le même checksum. Cela dit, cette méthode a
|
||
l’inconvénient d’intervenir après les faits, et de nécessiter au moins un accès
|
||
a un fichier initrd reconnu comme sûr.<br />
|
||
Une autre approche consisterait a placer le système de fichier /boot sur un
|
||
périphérique dédié, protégé en écriture de façon matérielle (par exemple, une
|
||
carte SD) ou, de façon encore plus efficace, sur un périphérique chiffré et
|
||
protégé en écriture de façon matérielle. Ainsi, il n’est pas possible pour un
|
||
attaquant de modifier ce système de fichier, et l’initrd est alors toujours de
|
||
confiance. Cependant, cela a pour conséquence de rendre la mise a jour de
|
||
l’initrd et du noyau <em>beaucoup</em> plus difficile qu’elle ne le serait sans.</p>
|
||
<p>Pour en revenir aux systèmes de fichiers chiffrés, leur gestion est faite par un
|
||
programme dédié, <code>cryptsetup</code>. Ce dernier était en charge de cryptoloop,
|
||
l’ancien sous-système de chiffrement du kernel Linux (déprécié depuis), et est
|
||
maintenant responsable de l’utilisation <em>userspace</em> de dm-crypt, qui pour sa
|
||
part est entièrement <em>kernel-space</em>. Cryptsetup permet ainsi le chiffrement, la
|
||
manipulation (montage/démontage/…) et la gestion de clé des systèmes de fichier
|
||
LUKS. Cryptsetup est cependant conçu pour être utilisé en tant que root, et les
|
||
utilisateurs qui veulent monter de systèmes de fichiers chiffrés devront ainsi
|
||
obligatoirement être capables de le faire en tant que root. </p>
|
||
<p>Voyons comment il faudrait procéder pour créer une image disque chiffrée de 1Go :<br />
|
||
Tout d’abord, il nous faut créer le fichier qui contiendra l’image. Pour cela,
|
||
dans une situation réelle ou l’on cherche a chiffrer un disque, il convient
|
||
d’utiliser /dev/urandom comme source, pour éviter la détection du système de
|
||
fichier chiffré sur le disque.
|
||
Ici, par exemple, nous allons faire : </p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">dd bs=1000 count=1000000 if=/dev/urandom of=image.img
|
||
</pre></div>
|
||
|
||
|
||
<p>Maintenant que notre image est créée, nous pouvons la chiffrer : </p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">sudo cryptsetup luksFormat image.img
|
||
</pre></div>
|
||
|
||
|
||
<p><code>cryptsetup</code> va alors nous demander si nous sommes absolument surs de vouloir
|
||
formater ce disque (nous allons donc valider en tapant YES), puis une
|
||
passphrase. Il convient ici de choisir une passphrase particulièrement sûre,
|
||
puisque toute personne ayant accès a la passphrase aura aussi accès au disque et
|
||
donc a vos secrets.<br />
|
||
Une fois cela fait, nous allons mapper cette image : </p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">sudo cryptsetup luksOpen image.img crypto
|
||
</pre></div>
|
||
|
||
|
||
<p><code>cryptsetup</code> nous redemande la passphrase, charge pendant quelques secondes,
|
||
puis nous redonne le prompt. Que s’est-il passé? En cherchant un peu, nous
|
||
voyons qu’il n’y a pas de nouveau disque dans /dev. C’est tout a fait normal. En
|
||
effet, cryptsetup (et par lui, device-mapper et dm-crypt) ne monte pas les
|
||
systèmes de fichiers chiffrés, il les mappe, et ça n’a rien a voir. On remarque
|
||
qu’est apparu dans /dev/mapper le fichier crypto. Ce fichier est le disque
|
||
virtuel qui correspond a notre image. Il se comporte comme toute partition, et
|
||
peut donc être monté, formaté, etc (il ne peut cependant pas être partitionné.
|
||
Il se comporte en effet comme une partition, et non comme un véritable disque.)
|
||
Bon, ceci fait, notre disque virtuel n’est pas formaté. Il nous reviens donc de
|
||
le faire, pour pouvoir l’utiliser. </p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">sudo mkfs.ext4 /dev/mapper/crypto
|
||
</pre></div>
|
||
|
||
|
||
<p>Maintenant que notre disque est formaté, il peut être monté : </p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">sudo mount /dev/mapper/crypto /mnt
|
||
</pre></div>
|
||
|
||
|
||
<p>Et voila, nous avons un système de fichier fonctionnel et chiffré! Si vous
|
||
voulez vérifier, un <code>mount | grep crypto</code> devrait vous donner le résultat
|
||
suivant : </p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">/dev/mapper/crypto on /mnt type ext4 (rw,relatime,data=ordered)
|
||
</pre></div>
|
||
|
||
|
||
<p>Vous pouvez maintenant commencer a stocker tous vos secrets sur ce fichier, ils
|
||
sont (en fonction de votre passphrase) en sécurité. </p>
|
||
<p>Pour résumer :</p>
|
||
<ul>
|
||
<li>
|
||
<p>Pour monter vos partitions : </p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">sudo cryptsetup luksOpen <fichier chiffré> <nom de disque virtuel>
|
||
sudo mount /dev/mapper/<nom de disque virtuel> <emplacement>
|
||
</pre></div>
|
||
|
||
|
||
</li>
|
||
<li>
|
||
<p>Pour démonter vos partitions : </p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">sudo umount <emplacement>
|
||
sudo cryptsetup luksClose <nom de disque virtuel>
|
||
</pre></div>
|
||
|
||
|
||
</li>
|
||
</ul>
|
||
<p>Pour simplifier la vie de tous, j’ai créé deux petits scripts vous permettant de
|
||
créer et de monter/démonter vos images/disques chiffré-e-s en une seule
|
||
commande. Ils se trouvent sur <a href="https://github.com/wxcafe/cryptoscripts">github</a>. </p>
|
||
<p>Par ailleurs, si vous comptez transferer votre image disque sur un véritable
|
||
disque (ou clé usb, ou autre), il est préférable de créer une partition de
|
||
taille appropriée et de faire un <code>dd if=votre_image of=/dev/votre_partition</code>
|
||
pour ce faire.</p></div>
|
||
</div>
|
||
<hr />
|
||
<div class="article">
|
||
<h1><a href="//wxcafe.net/posts/redesign-du-blog/">Redesign du blog, etc</a></h1>
|
||
<div class="well small"><footer class="post-info">
|
||
<span class="label">Date</span>
|
||
<span class="published" title="2013-06-12T19:14:00+02:00">
|
||
<i class="icon-calendar"></i> Wed 12 June 2013
|
||
</span>
|
||
<br />
|
||
<span class="label">By</span>
|
||
<a href="//wxcafe.net/author/wxcafe.html"><i class="icon-user"></i>wxcafe</a>
|
||
<br />
|
||
<span class="label">Category</span>
|
||
<a href="//wxcafe.net/category/note/"><i class="icon-folder-open"></i>Note</a>
|
||
<br />
|
||
|
||
|
||
|
||
|
||
</footer><!-- /.post-info --></div>
|
||
<div class="summary"><p>Comme vous avez pu le remarquer, ce blog a “un peu” changé récemment.</p>
|
||
<p>Du coup, expliquons. J’ai récemment monté <a href="http://serverporn.fr">serverporn</a>, et ai par la même
|
||
occasion découvert <a href="http://getpelican.com">pelican</a>. J’ai tout de suite accroché a ce générateur de
|
||
site statique en python, du fait de son efficacité, de sa facilité d’utilisation
|
||
et de sa grande customisation. En gros, pelican est un logiciel qui prend des
|
||
fichiers markdown ou reStructuredText, les passe a la moulinette d’un “thème”
|
||
constitué de templates pour les fichiers html et l’organisation du projet et
|
||
d’une partie “statique” contenant le css, et les autres fichiers nécessaires au
|
||
projet, et en fait des pages html. </p>
|
||
<p>Globalement, un thème est constitué ainsi :</p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%"><span style="color: #f8f8f2">th</span><span style="color: #960050; background-color: #1e0010">è</span><span style="color: #f8f8f2">me</span>
|
||
<span style="color: #960050; background-color: #1e0010">├──</span> <span style="color: #66d9ef">static</span>
|
||
<span style="color: #960050; background-color: #1e0010">│</span> <span style="color: #960050; background-color: #1e0010">├─</span> <span style="color: #f8f8f2">css</span>
|
||
<span style="color: #960050; background-color: #1e0010">│</span> <span style="color: #960050; background-color: #1e0010">│</span> <span style="color: #960050; background-color: #1e0010">└─</span> <span style="color: #f8f8f2">[css</span> <span style="color: #f8f8f2">files]</span>
|
||
<span style="color: #960050; background-color: #1e0010">│</span> <span style="color: #960050; background-color: #1e0010">├─</span> <span style="color: #f8f8f2">img</span>
|
||
<span style="color: #960050; background-color: #1e0010">│</span> <span style="color: #960050; background-color: #1e0010">│</span> <span style="color: #960050; background-color: #1e0010">└─</span> <span style="color: #f8f8f2">[image</span> <span style="color: #f8f8f2">files]</span>
|
||
<span style="color: #960050; background-color: #1e0010">│</span> <span style="color: #960050; background-color: #1e0010">└─</span> <span style="color: #f8f8f2">js</span>
|
||
<span style="color: #960050; background-color: #1e0010">│</span> <span style="color: #960050; background-color: #1e0010">└─</span> <span style="color: #f8f8f2">[javascript</span> <span style="color: #f8f8f2">files]</span>
|
||
<span style="color: #960050; background-color: #1e0010">└──</span> <span style="color: #f8f8f2">template</span>
|
||
<span style="color: #960050; background-color: #1e0010">├─</span> <span style="color: #f8f8f2">base.html</span>
|
||
<span style="color: #960050; background-color: #1e0010">├─</span> <span style="color: #f8f8f2">index.html</span>
|
||
<span style="color: #960050; background-color: #1e0010">├─</span> <span style="color: #f8f8f2">page.html</span>
|
||
<span style="color: #960050; background-color: #1e0010">├─</span> <span style="color: #f8f8f2">[...]</span>
|
||
<span style="color: #960050; background-color: #1e0010">└─</span> <span style="color: #f8f8f2">article.html</span>
|
||
</pre></div>
|
||
|
||
|
||
<p>Sachant que les fichiers .html sont en réalité des fichiers suivant la syntaxe
|
||
django, et utilisent des variables particulières telles <code>{{ article.content }}</code>,
|
||
par exemple. La syntaxe complète est très bien documentée dans la <a href="http://docs.getpelican.com/en/3.2/themes.html#templates-and-variables">doc</a> de
|
||
pelican.</p>
|
||
<p>L’un des grands avantages de pelican est aussi la facilité qu’il offre quand a
|
||
la mise a jour du blog.<br />
|
||
En effet, il offre un système de Makefiles permettant, grâce a de nombreuses
|
||
cibles de compilation, de régénérer le site entier, de ne générer que les
|
||
fichiers modifiés depuis la dernière génération, de générer uniquement les
|
||
fichiers n’existant pas la dernière fois, etc…
|
||
La gestion du projet en devient donc très simple, puisque après avoir écrit un
|
||
article, il suffit de faire un <code>make html</code> pour mettre a jour le blog.</p>
|
||
<p>De plus, le système de wordpress commençait a ne plus me convenir, du fait du
|
||
manque de customisation, du fait que ça soit du PHP (beurk), etc. La, avec
|
||
pelican, je contrôle bien plus ce qui est mis sur le serveur (puisque c’est moi
|
||
qui ait modifié les templates et le css), c’est lisible (puisque c’est du
|
||
python, par opposition au PHP…), et c’est plus “efficace”. Le markdown est
|
||
très pratique, je peux utiliser mon éditeur de texte de prédilection pour faire
|
||
les articles, je n’ai pas besoin d’un accès continu au net, bref, c’est plus
|
||
efficace.</p>
|
||
<p>En ce qui concerne les points négatifs : </p>
|
||
<ul>
|
||
<li>
|
||
<p>Perte des commentaires:
|
||
Je vous propose de vous référer a l’article de Gordontesos <a href="http://gordon.re/hacktivisme/la-necessite-des-commentaires.html">ici</a> quand a
|
||
mon avis sur ce sujet.</p>
|
||
</li>
|
||
<li>
|
||
<p>Perte du bouton flattr:
|
||
Il va bientôt être remis, c’est juste un manque de temps de ma part, mais vu
|
||
que toutes les pages passent par les mêmes templates, c’est assez facile a
|
||
faire.</p>
|
||
</li>
|
||
<li>
|
||
<p>Perte du spam:
|
||
Pourquoi c’est dans les points négatifs, ca?</p>
|
||
</li>
|
||
<li>
|
||
<p>Temps d’adaptation et d’appréhension du système:
|
||
Oui, pendant encore un certain temps, il y aura des glitchs plus ou moins
|
||
réguliers sur le blog, c’est parce que j’apprend a me servir de ce système
|
||
et que j’apprend du css et du html. Ca arrive, ca passera, mais dans tous
|
||
les cas ca me permet d’apprendre plein de choses, donc je mets plutôt ca
|
||
dans la catëgorie positive.</p>
|
||
</li>
|
||
</ul>
|
||
<p>Voila, c’est mon retour d’expérience sur pelican. A plus. </p></div>
|
||
</div>
|
||
<hr />
|
||
<div class="article">
|
||
<h1><a href="//wxcafe.net/posts/comment-saurik-a-roote-les-google-glass/">Comment Saurik a rooté les Google Glass</a></h1>
|
||
<div class="well small"><footer class="post-info">
|
||
<span class="label">Date</span>
|
||
<span class="published" title="2013-05-06T06:24:00+02:00">
|
||
<i class="icon-calendar"></i> Mon 06 May 2013
|
||
</span>
|
||
<br />
|
||
<span class="label">By</span>
|
||
<a href="//wxcafe.net/author/wxcafe.html"><i class="icon-user"></i>Wxcafe</a>
|
||
<br />
|
||
<span class="label">Category</span>
|
||
<a href="//wxcafe.net/category/hacking/"><i class="icon-folder-open"></i>Hacking</a>
|
||
<br />
|
||
|
||
|
||
|
||
|
||
</footer><!-- /.post-info --></div>
|
||
<div class="summary"><p>Comme vous avez pu le lire dans les médias, Saurik (Jay Freeman, connu
|
||
pour avoir développé Cydia, un “app store” alternatif pour les iTrucs),
|
||
après avoir reçu une paire de Google glass de la part de Google (de
|
||
façon assez évidente…), a trouvé intéressant d’obtenir un accès root
|
||
sur celles-ci, ce qu’il a accompli très rapidement. Des démentis de la
|
||
part de Google et de certains autres sites sont vite arrivés, disant que
|
||
les lunettes possédaient un bootloader débloqué et que de fait, le root
|
||
était facile a obtenir : il suffisait de débloquer le bootloader,
|
||
d’extraire l’OS, de le rooter hors-fonctionnement, puis de le
|
||
réinstaller, rooté, sur les lunettes.</p>
|
||
<p>Le fait est que de débloquer le bootloader laisse une trace permanente
|
||
sur les lunettes, et que Saurik n’a pas utilisé cette technique pour
|
||
rooter sa paire. Voyons comment il a fait :</p>
|
||
<p><em>Je tiens tout d’abord a préciser que toutes les informations qui vont
|
||
suivre sont extraites de <a href="http://www.saurik.com/id/16">cet article</a>, et plus précisément de la
|
||
partie “How does this exploit work”. Je tente d’apporter ma maigre
|
||
contribution a cette explication.</em></p>
|
||
<p>Donc, d’après les témoignages des quelques utilisateurs de Glass dans le
|
||
monde, il semblerait que ces dernières fonctionnent avec un système
|
||
d’exploitation Android, avec une nouvelle interface, mais avec les mêmes
|
||
outils internes: un kernel Linux, des outils userland GNU et une machine
|
||
virtuelle Java Dalvik pour les applications.</p>
|
||
<p>Saurik a donc cherché un exploit connu pour cette version d’android, et
|
||
l’a appliqué a son problème. L’exploit en question est relativement
|
||
simple. Depuis la version 4.0 d’android, le système permet la sauvegarde
|
||
des données des différentes applications, une a une, via ADB (Android
|
||
Debug Bridge, un protocole USB permettant l’accès a de nombreuses
|
||
fonctions avancées des machines fonctionnant sous android, dont, entre
|
||
autre, un shell, un accès au logs de debugging, etc… Cette
|
||
fonctionnalité est bien entendu désactivable.) Ce backup est très simple :
|
||
il crée un fichier .tgz contenant le dossier de configuration de
|
||
l’application. Lors de la restauration, le système supprime la
|
||
configuration existante, puis la remplace par celle dans l’archive gzip.</p>
|
||
<p>Le problème de sécurité vient du fait que les applications android
|
||
voient leurs données stockées dans /data/data/identifiant/, et que
|
||
/data/ a pour permissions drwxrwx–x 27 system system, ce qui
|
||
signifie que seul system et les membres du groupe system peuvent lire
|
||
dessus. Or, le fichier /data/local.prop définit de nombreux paramètres
|
||
au démarrage, et notamment un qui permet au système de déterminer s’il
|
||
fonctionne dans une VM ou sur un véritable appareil. S’il fonctionne sur
|
||
une machine virtuelle, il donne les droits root a tout utilisateur se
|
||
connectant via ADB, ce qui est ce que l’on cherche pour l’instant. Le
|
||
fait que /data/ appartienne a system veut dire que le programme de
|
||
restauration doit être setuid pour accéder aux données a l’intérieur qui
|
||
appartiennent a root (soit toutes les applications système d’android,
|
||
dont l’application paramètres, et, dans ce cas précis, l’application de
|
||
log système présente sur les google glass de test. Ainsi, nous avons un
|
||
processus tournant en tant que root, qui va écrire sur une partition qui
|
||
nous intéresse des données que nous possédons.</p>
|
||
<p>Cependant, un problème reste : le système de restauration d’Android
|
||
vérifie les données avant de restaurer, et ne restaure pas les symlinks,
|
||
ce qui nous empêche d’avoir accès directement a /data/local.prop, le
|
||
fichier qu’on cherche a modifier. Cela dit, il nous reste une
|
||
possiblité. Plaçons un dossier world-writable dans le fichier de backup,
|
||
et nous pourrons écrire dedans pendant quelques secondes, le temps que
|
||
la restauration se termine et que le système remette les permissions en
|
||
place. Ainsi, nous pouvons créer le fichier
|
||
/data/local/com.google.glass.logging/whatev/x, lien vers
|
||
/data/local.prop, et nous avons un toujours un processus tournant en
|
||
tant que root qui est en train d’écrire dans ce dossier.</p>
|
||
<p>Donc, nous allons lancer deux processus en même temps : </p>
|
||
<ul>
|
||
<li>
|
||
<p>Le premier tentera en boucle de créer le symlink. Il sera consitué de
|
||
la commande suivante, depuis un shell sur les lunettes :</p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">while ! ln -s /data/local.prop /data/data/com.google.glass.logging/whatev/x 2>/dev/null
|
||
do :
|
||
done
|
||
</pre></div>
|
||
|
||
|
||
</li>
|
||
<li>
|
||
<p>Le deuxième sera le processus de restauration de notre exploit. Celui
|
||
ci, pour une plus grande chance de réussite, devra être suffisamment
|
||
lourd : au moins \~50Mo. Il devra contenir whatev/bigfile et whatev/x,
|
||
pour qu’il crée whatev, prenne du temps a copier bigfile, puis écrive
|
||
dans x après que le symlink soit effectif. La commande sera, depuis
|
||
l’ordinateur host :</p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">adb restore exploit.ab
|
||
</pre></div>
|
||
|
||
|
||
<p>Ces commandes vont fonctionner de concert pour nous donner un accès root :<br />
|
||
- Le processus de restauration va créer le dossier whatev, qui sera
|
||
world-readable. Il va commencer a copier le fichier bigfile.<br />
|
||
- Le processus de symlink va créer le lien
|
||
/data/data/com.google.glass.logging/whatev/x, pointant vers
|
||
/data/local.prop, puis rendre l’âme proprement.<br />
|
||
- Le processus de restauration, ayant enfin fini de copier
|
||
whatev/bigfile, copiera les contenus que nous voulons dans whatev/x, qui
|
||
est lié a /data/local.prop. Comme le processus est setuid root, il ne se
|
||
rendra compte de rien, et écrira tout dans /data/local.prop.</p>
|
||
</li>
|
||
</ul>
|
||
<p>And voilà! On a écrit ce que l’on veut dans /data/local.prop, ce qui
|
||
nous permet de faire croire a android qu’il tourne dans une machine
|
||
virtuelle (ce que l’on veut, c’est en fait “ro.kernel.qemu=1”, qui
|
||
indique au noyau qu’il tourne dans qemu, un système de VM).</p>
|
||
<p>Il nous reste a rebooter, depuis l’ordinateur host :</p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">adb reboot
|
||
</pre></div>
|
||
|
||
|
||
<p>Puis nous remontons la partitions système en lecture/écriture (r/w),
|
||
depuis le host :</p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">adb shell "mount -o remount,rw /system"
|
||
</pre></div>
|
||
|
||
|
||
<p>Nous copions le binaire <a href="https://data.wxcafe.net/uploads/android/glass/su">su</a> vers l’appareil :</p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">adb push su /system/xbin
|
||
</pre></div>
|
||
|
||
|
||
<p>Nous donnons les bonnes permissions a ce binaire, afin de pouvoir
|
||
l’exécuter plus tard :</p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">adb shell "chmod 6755 /system/xbin/su"
|
||
</pre></div>
|
||
|
||
|
||
<p>Ensuite, nous supprimons le fichier /data/local.prop, pour pouvoir
|
||
redémarrer normalement :</p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">adb shell "rm /data/local.prop"
|
||
</pre></div>
|
||
|
||
|
||
<p>Enfin, nous redemarrons a nouveau :</p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">adb reboot
|
||
</pre></div>
|
||
|
||
|
||
<p>Et voila, une paire de google glass rootée!</p>
|
||
<p>Il est bon de préciser que cette manipulation n’est possible que parce
|
||
que les lunettes tournent sous une ancienne version d’android, et que ce
|
||
bug a été fixé depuis.</p>
|
||
<p>Il serait aussi interessant de couvrir les problèmes de vie privée
|
||
qu’engendrent les Google Glass, et ce sera fait dans un autre billet.</p>
|
||
<p>A bientôt!</p></div>
|
||
</div>
|
||
<hr />
|
||
<div class="article">
|
||
<h1><a href="//wxcafe.net/posts/monter-son-propre-serveur-partie-1/">Monter son propre serveur, partie 1: le serveur et l'apache.</a></h1>
|
||
<div class="well small"><footer class="post-info">
|
||
<span class="label">Date</span>
|
||
<span class="published" title="2013-03-18T09:51:00+01:00">
|
||
<i class="icon-calendar"></i> Mon 18 March 2013
|
||
</span>
|
||
<br />
|
||
<span class="label">By</span>
|
||
<a href="//wxcafe.net/author/wxcafe.html"><i class="icon-user"></i>Wxcafe</a>
|
||
<br />
|
||
<span class="label">Category</span>
|
||
<a href="//wxcafe.net/category/tutoriel/"><i class="icon-folder-open"></i>Tutoriel</a>
|
||
<br />
|
||
|
||
|
||
|
||
|
||
</footer><!-- /.post-info --></div>
|
||
<div class="summary"><p>Il y a un certain temps, j’avais parlé du concept du self-hosting. Il
|
||
s’agit de posséder son propre serveur, et donc, par extension, ses
|
||
données. </p>
|
||
<p>Bien entendu, il n’est pas nécessaire pour cela de posséder
|
||
physiquement son propre serveur (encore que ce soit possible, mais ce
|
||
n’est pas le sujet abordé ici.)<br />
|
||
Nous expliquerons ici les étapes nécessaires pour arriver a avoir un
|
||
serveur utilisable, du moment ou vous arrivez sur le système fraichement
|
||
installé, au moment ou vous possédez un serveur avec tous les paquets
|
||
nécessaires a l’utilisation que l’on veut en faire ici d’installés.
|
||
Cette partie va consister a paramétrer le système (ici un debian
|
||
squeeze. Il est bien sur possible de faire la même chose avec a peu près
|
||
toutes les distributions Linux disponibles, tout comme avec les BSD et
|
||
tous les autres systèmes UNIX, mais je vais ici me limiter a debian 6.0.x
|
||
squeeze, parce que c’est une distribution simple a utiliser comme
|
||
serveur, stable, et facile a configurer (puisqu’une bonne partie de la
|
||
configuration est déjà faite et incluse dans le paquet), donc adaptée au
|
||
but de cet article, a savoir rendre l’installation simple et
|
||
compréhensible).</p>
|
||
<p>La première chose a faire est bien entendu d’obtenir le serveur en lui
|
||
même. Cette partie de la chose ne sera pas traitée dans cet article. Il
|
||
existe en effet un nombre infini d’obtenir un serveur, que ce soit en le
|
||
louant chez OVH/1&1/n’importe quel autre hébergeur commercial, en
|
||
participant a un système d’hébergement collaboratif (je vous laisse
|
||
chercher), en achetant un serveur et en le faisant fonctionner de chez
|
||
vous, en utilisant un vieux PC… Bref, les possibilités sont multiples.
|
||
Dès lors que vous avez accès a un système debian serveur, peu importe sur
|
||
quel matériel il fonctionne, et a priori peu importe aussi la manière
|
||
dont vous y accédez, le résultat est le même (et la procédure aussi…).
|
||
Dans cet article, nous parlerons de la configuration de base, du moment
|
||
ou vous avez le serveur vierge dans les mains au moment ou vous
|
||
installez le serveur http.</p>
|
||
<p>Dans cet article, lorsque est précisée le type d’IP a utiliser, il
|
||
convient de mettre ce type précisément. Quand le type n’est pas
|
||
précisée, libre a vous de choisir ipv4 ou ipv6.</p>
|
||
<p>Bref. Commençons au point ou vous avez un accès root a votre serveur,
|
||
n’ayant soit aucun mot de passe, soit un choisi par l’hébergeur, et ou
|
||
rien n’est configuré. Connectez vous a celui-ci (ssh root@). Commencez
|
||
donc par faire un <code>passwd</code>, pour mettre au plus vite un mot de passe
|
||
solide sur le compte root. Continuons en allant vite mettre en place le
|
||
nom de domaine. Pour cela, votre registrar doit vous fournir une
|
||
interface vous permettant d’éditer l’entrée DNS pour votre nom de
|
||
domaine. </p>
|
||
<p>Cette entrée doit donc pour l’instant ressembler a ca :</p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%"> <votre nom de domaine> NS 1
|
||
IN MX 1
|
||
IN A <IPv4 de votre serveur>
|
||
IN AAAA <IPv6 de votre serveur>
|
||
</pre></div>
|
||
|
||
|
||
<p>Cela vous permet de rediriger tout le trafic se référant a votre nom de
|
||
domaine vers votre ip (le fonctionnement exact du DNS est assez
|
||
compliqué a expliquer, donc on va dire que c’est de la magie pour
|
||
l’instant, ca sera peut être le sujet d’un autre article), et d’indiquer
|
||
que les mails @votre-nom-de-domai.ne doivent aussi être redirigés vers
|
||
votre serveur, ce qui est un bon début. Faisons un petit point sécurité
|
||
ici : pour accéder a votre serveur, il vous suffit actuellement de taper
|
||
le mot de passe root.</p>
|
||
<p>root est un utilisateur <strong>assez</strong> répandu, et il est assez simple de
|
||
bruteforcer le mot de passe. (<em>Relativement</em> assez simple, en fonction
|
||
du nombre de caractères, ça prend plus ou moins de temps, et si vous
|
||
avez suffisamment de caractères, ça peut prendre un temps assez
|
||
conséquent. Cela dit, il vaut mieux être prudent…) Ainsi, nous allons
|
||
arrêter d’utiliser root et nous allons commencer a utiliser des couples
|
||
clés publiques/privées pour nous connecter au serveur.<br />
|
||
Cela se fait en deux temps : tout d’abord, créer un nouvel utilisateur,
|
||
grâce auquel nous administrerons le serveur a l’avenir; puis configurer
|
||
OpenSSH pour que celui ci n’accepte que les connections par clés et plus
|
||
celles sur root.</p>
|
||
<p>Commençons par ajouter un utilisateur. Si vous êtes sous debian, cela se
|
||
fait avec adduser, qui est interactif (vous ne devriez pas avoir de
|
||
problème avec, puisqu’il crée tout les dossiers et fichiers nécessaires,
|
||
et vous pose toutes les questions utiles pour vous aider.) sinon, vous
|
||
devrez utiliser useradd, qui est (en plus d’être très chiant a
|
||
distinguer de l’autre, bien plus chiant a utiliser. (adduser est en fait
|
||
un simple script permettant l’utilisation d’useradd plus facilement.)</p>
|
||
<p>Avec adduser, vous pouvez soit utiliser le mode interactif en tapant
|
||
juste <code>adduser <username></code>, soit utiliser le mode non-interactif
|
||
en faisant un <code>adduser --group <username></code></p>
|
||
<p>Avec useradd, vous devrez utiliser la commande suivante : <code>useradd -m
|
||
-N -g <username></code>. Cette commande ajoutera un utilisateur, créera
|
||
son dossier principal dans /home/, et l’ajoutera au groupe du même nom
|
||
que lui (ce qui est en général nécessaire pour des questions de vie
|
||
privée).</p>
|
||
<p>Il convient maintenant d’ajouter cet utilisateur aux groupes qu’il sera
|
||
amené a administrer: <code>usermod <username> -a -G www-data postfix
|
||
users staff sudo wheel</code>, puis de changer son mot de passe
|
||
<code>passwd</code>. Enfin, ajoutons le aux utilisateurs autorisés a utiliser
|
||
sudo: <code>echo "%sudo ALL=(ALL) ALL" >> /etc/sudoers</code><br />
|
||
Enfin, changeons d’utilisateur : <code>su</code>. A ce point, vous avec un
|
||
utilisateur complètement fonctionnel et utilisable pour toutes les
|
||
taches d’administration. Si vous devez encore utiliser root, c’est que
|
||
quelque chose ne va pas.</p>
|
||
<p>Vous êtes donc loggés sur le système en tant qu’utilisateur normal. Nous
|
||
allons maintenant passer a la phase 2 du plan : désactiver le login ssh
|
||
root et le login ssh par mot de passe.<br />
|
||
Tout d’abord, qu’est-ce qu’un login par clé ssh? Il s’agit en fait d’un
|
||
système assez semblable a celui vous permettant de chiffrer vos mail :
|
||
vous avec une clé publique et une clé privée sur le client, et la clé
|
||
publique est aussi sur le serveur. Lorsque vous vous connectez, openssh
|
||
vérifie que vous possédez la clé privée qui correspond a la clé publique
|
||
stockée sur le serveur (pour votre utilisateur, bien entendu). Il est
|
||
également possible d’utiliser plusieurs clés publique pour chaque<br />
|
||
utilisateur.</p>
|
||
<p>Bref, maintenant que nous avons la théorie, passons a la pratique : tout
|
||
d’abord, il nous faut générer un couple de clés publique/privée sur le
|
||
client. Openssh fait ça via la commande <code>ssh-keygen -t rsa</code> (le -t
|
||
rsa précise a ssh que nous voulons un chiffrement rsa, qui est
|
||
suffisamment solide pour cette utilisation.) Entrez les informations que
|
||
ssh-keygen vous demande. Trois fichiers devraient maintenant se trouver
|
||
dans votre dossier .ssh/ : id_rsa, id_rsa.pub, et known_hosts.<br />
|
||
known_hosts liste les serveurs auxquels vous vous êtes connectés déjà
|
||
une fois (pour éviter les attaques MITM, mais bref). Non, ce qui nous
|
||
intéresse ici c’est id_rsa et id_rsa.pub . id_rsa contient votre clé
|
||
privée, sauvegardez la sur une clé USB ou notez la sur un bout de
|
||
papier, si vous la perdez, vous ne pourrez plus vous connecter au
|
||
serveur. (planquez la clé usb/le bout de papier…) id_rsa.pub, quand a
|
||
lui, contient votre clé publique. Copiez la sur le serveur, avec un<code>scp ~/.ssh/id_rsa.pub <username>@<votre nom de domaine>:~/</code> , ou
|
||
en la copiant a la main, si ça vous amuse. </p>
|
||
<p>Vous avez maintenant un fichier id_rsa.pub dans votre dossier personnel
|
||
sur le serveur, il faut le mettre a un endroit ou openssh le reconnaitra.
|
||
Il est donc nécessaire de créer le dossier .ssh (<code>mkdir .ssh</code>), puis
|
||
de déplacer ce fichier a la bonne place (<code>mv ~/id_rsa.pub ~/.ssh/authorized_keys</code>).
|
||
Testez si ça fonctionne : ouvez un autre terminal, et<br />
|
||
connectez vous a votre serveur (<code>ssh <username>@<votre nom de
|
||
domaine></code>), et il ne devrait pas vous demander de mot de passe.<strong>Si
|
||
il vous en demande un, NE PASSEZ PAS A LA SUITE. Quelque chose a foiré,
|
||
donc vérifiez que vous avez suivi correctement les instruction
|
||
ci-dessus.</strong></p>
|
||
<p>Continuons. Il ne nous reste plus qu’a installer le serveur web, et a le
|
||
configurer: </p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%">sudo apt-get install \
|
||
apache2 apache2.2-common apache2-doc apache2-mpm-prefork \
|
||
apache2-utils libexpat1 ssl-cert libapache2-mod-php5 \
|
||
php5 php5-common php5-gd php5-cgi libapache2-mod-fcgid \
|
||
apache2-suexec php-pear php-auth php5-mcrypt mcrypt \
|
||
php5-imagick imagemagick libapache2-mod-suphp libruby \
|
||
libapache2-mod-ruby
|
||
</pre></div>
|
||
|
||
|
||
<p>(faisons large, on aura besoin de l’excédent plus tard…), puis activons les<br />
|
||
mods apache en faisant <code>a2enmod suexec rewrite ssl actions include
|
||
dav_fs dav auth_digest</code>, et faisons en sorte que ces activations
|
||
soient prises en compte par apache via un <code>sudo service apache2
|
||
restart</code> </p>
|
||
<p>Le serveur fonctionne, maintenant, il est necessaire de lui expliquer
|
||
comment fonctionner sur notre nom de domaine et ou trouver les fichiers
|
||
a envoyer. </p>
|
||
<p>Pour cela, nous allons faire un simple <code>ln -s /etc/apache2/sites-{available,enabled}/default</code>, car apache est assez
|
||
sympa pour nous filer un fichier de configuration par défaut. Il nous
|
||
faut encore l’éditer, en changeant l’adresse mail au début du document
|
||
par la votre, et en changeant <code>AllowOverride none</code> en <code>AllowOverride All</code>,
|
||
et enfin redémarrer apache pour qu’il prenne en compte les
|
||
modifications, par un <code>sudo service apache2 restart</code> </p>
|
||
<p>Et maintenant, il vous reste a apprendre le html, parce que ca y est,
|
||
votre serveur est fonctionnel! Voila voila. Dans la prochaine partie, on
|
||
verra l’installation du serveur mail (c’est suffisamment complexe pour
|
||
prendre un article seul…)</p></div>
|
||
</div>
|
||
<hr />
|
||
<div class="article">
|
||
<h1><a href="//wxcafe.net/posts/pourquoi-je-vais-quitter-linux-pour-passer-a-freebsd/">Pourquoi je vais quitter linux pour passer a FreeBSD.</a></h1>
|
||
<div class="well small"><footer class="post-info">
|
||
<span class="label">Date</span>
|
||
<span class="published" title="2013-02-04T17:41:00+01:00">
|
||
<i class="icon-calendar"></i> Mon 04 February 2013
|
||
</span>
|
||
<br />
|
||
<span class="label">By</span>
|
||
<a href="//wxcafe.net/author/wxcafe.html"><i class="icon-user"></i>Wxcafe</a>
|
||
<br />
|
||
<span class="label">Category</span>
|
||
<a href="//wxcafe.net/category/ranting/"><i class="icon-folder-open"></i>Ranting</a>
|
||
<br />
|
||
|
||
|
||
|
||
|
||
</footer><!-- /.post-info --></div>
|
||
<div class="summary"><p><em>This is subject to debate, and as most of the actors in this field are
|
||
not French-speaker, there is an English version of this text <a href="http://data.wxcafe.net/archives/126">here</a></em></p>
|
||
<p>Bon, voila. J’ai passé le cap. Je suis sous GNU/Linux depuis un certain
|
||
temps, maintenant, et depuis un certain temps je remarque des
|
||
changements malvenus. Bien entendu, au début, je n’avais pas les
|
||
connaissances nécessaires pour comprendre ne serait-ce que ces
|
||
modifications existaient. Et puis certaines sont arrivées avant que je
|
||
n’ai même idée que quelque chose dans mon système d’exploitation avait
|
||
cette fonction la. Par exemple, udev, ou policykit/consolekit/. A
|
||
l’époque, je n’avais aucune idée de la façon dont les disques étaient
|
||
montés sur mon système. Le premier système non-Windows que j’ai utilisé
|
||
fut Ubuntu 9.10 Karmic Koala, et il était encore trop tôt pour que je
|
||
cherche a démonter le système pour comprendre comment il fonctionnait en
|
||
profondeur. Cependant, avec le temps, les connaissances s’accumulant et
|
||
mon niveau de compréhension du système s’améliorant, j’ai commencé a
|
||
remarquer que certain bouts de l’OS ne collaient pas exactement avec les
|
||
autres. Bien sur, je ne saurais dire si cette réalisation s’est faite a
|
||
cause de la recrudescence de ces bouts d’OS, ou bien juste a cause de ma
|
||
compréhension plus poussée. Toujours est-il que ces petits bouts d’OS ne
|
||
s’adaptant pas au reste du système se faisaient de plus en plus visible.
|
||
Et puis, un jour, j’en ai eu marre de voir unity sur ma machine, et j’ai
|
||
choisi de passer a Archlinux. C’était avant le passage a systemd. Ce
|
||
système me convenait bien. Si je n’installais pas Gnome, ce que je ne
|
||
comptais pas faire, il ne me forçait pas a installer un *kit
|
||
quelconque, ni dbus. Oui, udev était toujours la, mais c’était le moins
|
||
envahissant de ceux la.</p>
|
||
<p>Mais Archlinux est passé a systemd. Attention hein, je ne critique ici
|
||
ni systemd, ni udev, ni même les <em>kit, et surtout pas Archlinux. Les
|
||
premiers sont probablement très efficaces dans leur domaine, et le
|
||
second n’a pas <strong>vraiment</strong> eu le choix, rapport a la philosophie de la
|
||
distribution d’avoir au plus vite les dernières versions de tout.
|
||
Cependant, systemd, tout comme udev et les </em>kits (bien que ce ne soient
|
||
pas les seuls a faire ça…) ont un problème très précis, qui n’importe
|
||
pas a tout le monde, mais qui est très gênant pour ceux a qui il
|
||
importe, et ce problème est que ces systèmes ne respectent absolument
|
||
pas la philosophie UNIX. La philosophie UNIX, pour rappel, se résume en
|
||
ces 9 principes :</p>
|
||
<ol>
|
||
<li>Ce qui est petit est beau</li>
|
||
<li>Faites en sorte que chaque programme fasse une chose, bien.</li>
|
||
<li>Faites un prototype aussi vite que possible</li>
|
||
<li>Choisissez la portabilité plutôt que l’efficacité</li>
|
||
<li>Stockez les données dans des fichiers textes.</li>
|
||
<li>Utilisez ce qui existe déjà a votre avantage. [<strong>1</strong>]</li>
|
||
<li>Utilisez des scripts shells pour faciliter la portabilité et la
|
||
réutilisation.</li>
|
||
<li>Évitez les UI qui “capturent” l’utilisateur.</li>
|
||
<li>Faites de chaque programme un filtre.</li>
|
||
</ol>
|
||
<p>Alors bien entendu, un système d’exploitation est fait pour évoluer, et
|
||
on pourrait penser qu’UNIX a fait son temps. Cependant, ce n’est pas
|
||
exactement la façon dont l’informatique fonctionne. Effectivement, les
|
||
standards, les systèmes d’exploitation, les logiciels, tout doit évoluer
|
||
- ou mourir - et UNIX ne fait pas exception a la règle. Mais ce n’est
|
||
pas d’UNIX que nous parlons ici. C’est de la <em>philosophie</em> UNIX. Et
|
||
celle-ci n’a pas fait son temps, <strong>elle a fait ses preuves.</strong> La
|
||
philosophie UNIX, en plus d’être efficace sur le papier, a aussi 44 ans
|
||
de tests derrière elle, et fonctionne aussi bien qu’au premier jour.<br />
|
||
La philosophie UNIX est aussi et surtout une garantie d’utilisabilité
|
||
et de simplicité pour les administrateurs systèmes, pour les
|
||
développeurs, bref pour tous ceux qui font de l’informatique<em>sérieusement</em> (je ne dis pas que les autres métiers de l’informatique
|
||
ne sont pas sérieux, je prend juste ceux-ci comme exemples parce que ce
|
||
sont ceux qui sont les plus proches du système).</p>
|
||
<p>Tous OS se doit d’avoir un système standardisé pour faire communiquer
|
||
les programmes entre eux. UNIX a un système de pipes, des sortes de
|
||
fichiers spéciaux permettant d’échanger des informations. C’est
|
||
efficace, ça respecte le “tout est fichier”, c’est standard, c’est
|
||
simple a comprendre, bref, ça fonctionne parfaitement. Dbus vient
|
||
remplacer ça, avec une interface qui n’est explicitement pas faite pour
|
||
être utilisée a la ligne de commande mais a l’aide d’APIs, et un
|
||
programme monolithique qui effectue sa tache d’une façon complètement
|
||
obscure pour l’utilisateur. Alors bien sur, il l’effectue d’une façon
|
||
efficace, cette tache. Oui, ça va plus vite qu’avant. Oui, c’est plus
|
||
“rangé”, ça fait moins “fouillis”. Mais c’est moins efficace. C’est<em>beaucoup</em> moins utilisable pour l’utilisateur final. C’est
|
||
horriblement chiant pour les sysadmins, parce qu’ils ne peuvent plus
|
||
lire facilement les échanges entre programmes. C’est peu pratique, en
|
||
fin de compte. Et ça ne respecte pas du tout la philosophie UNIX.<br />
|
||
Systemd prend le même parti de créer une interface unifiée, accessible
|
||
via des appels a des APIs uniquement, complètement obscure, extrêmement
|
||
abstraite, bien entendu monolithique, et très peu ouverte a la
|
||
modification par l’utilisateur final. Alors oui, il parait que ça
|
||
augmente la vitesse de boot. Eh bien, au risque d’en choquer quelques
|
||
uns, je préfère avoir un système qui boote <em>légèrement</em> plus lentement
|
||
et que je puisse modifier facilement, et qui soit ouvert, compréhensible
|
||
et distribué. C’est presque comme si les projets freedesktop.org avaient
|
||
pour but de remplacer la base UNIX de linux en créant un système
|
||
concurrent, bâtard, bâti sur le kernel Linux mais n’employant plus les
|
||
systèmes basiques d’UNIX.</p>
|
||
<p>Le problème est qu’il est facilement visible que la direction prise par
|
||
la communauté Linux n’est pas celle du retour sur les systèmes UNIX ni
|
||
celle du développement de solutions respectant la philosophie UNIX, mais
|
||
remises au gout du jour (?), mais est bien d’accepter et de pousser les
|
||
changements apportés par les projets freedesktop.org directement dans le
|
||
cœur du système lui même. Ainsi, Fedora (très près de Red Hat, dont font
|
||
partie de nombreux développeurs de ces projets), a déjà adopté tous ces
|
||
changements (archlinux aussi, mais pour d’autres raisons…), et on peut
|
||
compter sur le fait que les autres distributions l’adopteront un jour ou
|
||
l’autre.</p>
|
||
<p>Bon, maintenant que nous avons, si ce n’est démontré la nocivité de ces
|
||
systèmes, tout du moins exprimé les raisons qui font qu’ils me
|
||
déplaisent, on pourrait penser qu’il suffit de passer a une distribution
|
||
n’incluant pas systemd, voire a une distribution n’incluant pas du tout
|
||
de contenus freedesktop.org, et de vivre avec le fait de ne pas être sur
|
||
archlinux. Cependant, avec un peu de réflexion, on voit que si des
|
||
distributions comme archlinux et Fedora ont adopté systemd (et
|
||
qu’OpenSUSE est en train de l’intégrer), il est probable que cela
|
||
devienne un standard au fil des années, et que seuls survivent systemd
|
||
et upstart, le gestionnaire de démarrage d’ubuntu, qui ne changera
|
||
probablement pas (je les vois mal revenir en arrière sur ce point.)
|
||
Toujours est-il que l’init héritée du System V semble condamnée a mourir
|
||
sous Linux. Il pourrait être judicieux de passer sous debian squeeze,
|
||
qui ne recevra probablement jamais la mise a jour, ou a wheezy, qui ne
|
||
la recevra probablement que dans 2/3 ans. Cependant, cette période est
|
||
toujours trop courte, et met sur mon système d’exploitation une date
|
||
d’expiration, chose qui ne me plait que moyennement. Non, la solution
|
||
est de passer sous un système autre, qui ait son propre système d’init
|
||
(ou qui ne risque pas de passer sous systemd). Dans ce cas, deux options
|
||
principales s’ouvrent a moi: OpenSolaris et *BSD. Minix n’est pas
|
||
vraiment un choix, vu le peu de programmes qu’il permet de faire
|
||
fonctionner et le fait qu’il ne soit disponible que sur i386, ce qui
|
||
n’est pas vraiment avantageux au vu de mon système en x86_64. Haiku
|
||
n’est pas un choix non plus, puisque le but est de rester dans une
|
||
optique UNIX.</p>
|
||
<p>OpenSolaris est un système d’exploitation tout a fait valable. Je n’ai
|
||
en théorie aucun problème sur cet OS, sauf que certains choix de design
|
||
ne correspondent pas du tout a l’idée que j’ai d’un OS. En effet,
|
||
OpenSolaris ressemble assez a Debian dans sa vision du fonctionnement de
|
||
ses outils, avec des paquets modifiés pour les rendre plus simples a
|
||
utiliser (fichiers de configuration fournis par défaut, par exemple, et
|
||
autres patchs “release-only”), et une tendance a faire des scripts et
|
||
des outils installés par défaut pour tout et n’importe quoi. Bref, cela
|
||
n’est pas le sujet. Il convient aussi de voir qu’avec la récente
|
||
acquisition de Sun par Oracle, il est possible que le projet OpenSolaris
|
||
n’ait pas de très beaux jours devant lui (la <a href="http://hub.opensolaris.org/bin/view/Main/">page d’accueil</a> du
|
||
projet affiche d’ailleurs un ÉNORME logo Oracle, du meilleur gout.)</p>
|
||
<p>Il reste donc *BSD. Pourquoi choisir FreeBSD plutôt qu’OpenBSD, NetBSD
|
||
ou DragonFlyBSD (pour ne citer que les plus connus) ? Et bien c’est
|
||
simple : pour aucune raison particulière. OpenBSD et NetBSD ont pour
|
||
réputation d’être orientées sécurité, et d’après ce que j’ai pu en voir
|
||
DFBSD ressemble aussi au système de l’assistance a l’user a outrance
|
||
décris plus haut. Mais la vérité est que je n’ai pas fait suffisamment
|
||
de recherches et que FreeBSD ne va me voir arriver que par hasard, parce
|
||
qu’entre toutes les BSD ca me semble la plus sympa et la plus agréable a
|
||
utiliser, plus le fait que le système de ports me convient bien (j’aime
|
||
pouvoir configurer mes logiciels de façon assez profonde.)</p>
|
||
<p>Voila, c’est mon avis sur ce “problème” actuel du monde de Linux. Bien
|
||
entendu, je continuerai a utiliser Linux, et je ne peux qu’espérer que
|
||
les systèmes tels que systemd ou dbus ne disparaissent, ou tout du moins
|
||
n’apparaissent jamais chez certaines distributions, créant de ce fait un
|
||
choix pour les utilisateurs.<br />
|
||
[1]: Je n’ai pas trouvé de traduction satisfaisante a “software leveraging”, mais l’idée est la…*</p></div>
|
||
</div>
|
||
<hr />
|
||
<div class="article">
|
||
<h1><a href="//wxcafe.net/posts/update-et-pensees-a-propos-du-raspberry-pi/">Update et pensées a propos du Raspberry Pi</a></h1>
|
||
<div class="well small"><footer class="post-info">
|
||
<span class="label">Date</span>
|
||
<span class="published" title="2013-01-27T01:55:00+01:00">
|
||
<i class="icon-calendar"></i> Sun 27 January 2013
|
||
</span>
|
||
<br />
|
||
<span class="label">By</span>
|
||
<a href="//wxcafe.net/author/wxcafe.html"><i class="icon-user"></i>Wxcafe</a>
|
||
<br />
|
||
<span class="label">Category</span>
|
||
<a href="//wxcafe.net/category/ranting/"><i class="icon-folder-open"></i>Ranting</a>
|
||
<br />
|
||
|
||
|
||
|
||
|
||
</footer><!-- /.post-info --></div>
|
||
<div class="summary"><p>Bon.<br />
|
||
J’ai annoncé il y a environ 20 jours que j’avais pour projet de faire
|
||
une Piratebox basée sur un Raspberry Pi, <del>astucieusement</del> nommée
|
||
PiRatBox. Il se trouve qu’après de nombreux essais, un problème
|
||
récurrent apparait: le Raspberry Pi n’est pas capable de fournir assez
|
||
de courant par défaut pour faire fonctionner a la fois un disque dur et
|
||
une antenne WiFi.<br />
|
||
Alors, autant il me semble évident qu’avec une
|
||
alimentation provenant d’un port USB a 2A (max), je n’avais pas
|
||
énormément de chances d’avoir 2A sur chacun des ports host du Raspi,
|
||
autant avoir moins de 250 mA sur chacun de ces ports me semble un tout
|
||
petit peu exagéré en terme de rentabilité. </p>
|
||
<p>De même, le fait de ne pas pouvoir désactiver le port Ethernet (ne me
|
||
servant a rien) (vous savez, celui qui est monté en USB…), qui
|
||
consomme énormément, est assez louche. Il devrait toujours être possible
|
||
de désactiver une device USB, me semble-t-il, au niveau logiciel. La,
|
||
bien qu’il soit surement possible de la désactiver au niveau du kernel,
|
||
il n’est pas <strong>simplement</strong> possible de la “débrancher”. Ce qui est bien
|
||
chiant, étant donné le besoin évident de puissance électrique dans
|
||
lequel on se retrouve. </p>
|
||
<p>Bon, je dois avouer n’avoir pas testé de lancer les différents services
|
||
composant le système des piratebox sous arch, pour la simple <del>et
|
||
bonne</del> raison qu’arch utilise systemd et qu’il n’existe pas de wrapper
|
||
systemd pour les daemons piratebox, et que j’ai la flemme d’en faire,
|
||
parce que systemd est une horreur a utiliser avec les scripts init. Donc
|
||
non, j’utiliserai debian. Le problème d’utiliser debian dans ce cas
|
||
précis est que apt/dpkg a une gestion des dépendances dans un sens mais
|
||
pas dans l’autre, en ce sens que si on installe un package “haut”, c’est
|
||
a dire dépendant de plusieurs autres packages, apt/dpkg se charge
|
||
efficacement d’installer toutes les dépendances nécessaires, tandis que
|
||
si on désinstalle un package “bas”, c’est a dire sur lequel de nombreux
|
||
autres packages dépendent, apt/dpkg ne désinstalle pas ces packages
|
||
“hauts”, ce qui pose un vrai problème quand on se retrouve sur un
|
||
Raspberry Pi, puisqu’il n’y a pas de moyen “facile” de choisir ce qui
|
||
sera installé sur le système avant l’installation proprement dite
|
||
(puisque le moyen “universel” d’installation sur Raspberry Pi est le dd
|
||
vers la SD qui sert de disque système.)</p>
|
||
<p>Il y a <strong>énormément</strong> d’autres critiques que l’ont pourrait faire
|
||
concernant le Raspberry Pi. Son système de démarrage a s’arracher les
|
||
cheveux, par exemple. En effet, plutôt que de faire comme tout pc
|
||
normalement constitué ou la partie calcul démarre, lance le bootloader,
|
||
cherche le kernel de l’OS qui lui même se lance, initialise le hardware,
|
||
etc…, a un système bâtard du au fait que la puce au centre de la carte
|
||
est a la base une puce graphique a laquelle on a greffé un cœur de
|
||
calcul (probablement au fond d’une cour d’immeuble, dans les quartiers
|
||
pauvres de Bratislava, vu la propreté de la greffe…), et le moyen le
|
||
plus efficace qu’aient trouvé les personnes ayant implémenté cette
|
||
atrocité de gérer le boot est donc de faire démarrer le cœur graphique
|
||
en premier, ce dernier exécute un code propriétaire pour démarrer le
|
||
cœur de calcul, qui a son tour lance le bootloader qui cherche le kernel
|
||
etc… </p>
|
||
<p>Ce qui non seulement complique énormément le boot, non seulement ajoute
|
||
du code propriétaire a un projet se disant libre, mais en plus n’est<strong>visiblement</strong> pas fait pour être utilisé de cette manière. Le hack,
|
||
oui, mais uniquement quand c’est bien réalisé, sinon je dis non. </p>
|
||
<p>Enfin, le projet que j’avais est toujours en cours de réalisation. Je
|
||
le terminerai dès que j’aurai récupéré les outils nécessaires pour
|
||
monter mon alimentation personnalisée pour le Raspberry Pi. Et une fois
|
||
que cela sera fait, ce Raspi restera une Piratebox pour le reste de sa
|
||
vie. Les problèmes qu’il m’a posé, qu’il n’aurait pas du me poser, m’ont
|
||
trop agacé pour que j’aie envie de le sortir et de jouer avec une fois
|
||
sa mission remplie. </p>
|
||
<p>Dommage.</p></div>
|
||
</div>
|
||
<hr />
|
||
<div class="article">
|
||
<h1><a href="//wxcafe.net/posts/update/">Update</a></h1>
|
||
<div class="well small"><footer class="post-info">
|
||
<span class="label">Date</span>
|
||
<span class="published" title="2013-01-05T18:32:00+01:00">
|
||
<i class="icon-calendar"></i> Sat 05 January 2013
|
||
</span>
|
||
<br />
|
||
<span class="label">By</span>
|
||
<a href="//wxcafe.net/author/wxcafe.html"><i class="icon-user"></i>Wxcafe</a>
|
||
<br />
|
||
<span class="label">Category</span>
|
||
<a href="//wxcafe.net/category/note/"><i class="icon-folder-open"></i>Note</a>
|
||
<br />
|
||
|
||
|
||
|
||
|
||
</footer><!-- /.post-info --></div>
|
||
<div class="summary"><p>Juste une petite note pour annoncer le prochain article, consacré a la
|
||
fabrication d’une PirateBox basée sur un Raspberry Pi. Voila, a bientôt
|
||
sur le blog!</p></div>
|
||
</div>
|
||
<hr />
|
||
<div class="article">
|
||
<h1><a href="//wxcafe.net/posts/mutt-ou-le-client-email-le-meilleur-moins-mauvais/">Mutt ou le client email le <del>meilleur</del> moins mauvais</a></h1>
|
||
<div class="well small"><footer class="post-info">
|
||
<span class="label">Date</span>
|
||
<span class="published" title="2013-01-02T02:12:00+01:00">
|
||
<i class="icon-calendar"></i> Wed 02 January 2013
|
||
</span>
|
||
<br />
|
||
<span class="label">By</span>
|
||
<a href="//wxcafe.net/author/wxcafe.html"><i class="icon-user"></i>Wxcafe</a>
|
||
<br />
|
||
<span class="label">Category</span>
|
||
<a href="//wxcafe.net/category/tutoriel/"><i class="icon-folder-open"></i>Tutoriel</a>
|
||
<br />
|
||
|
||
|
||
|
||
|
||
</footer><!-- /.post-info --></div>
|
||
<div class="summary"><p>Les clients mails ont une particularité en commun : ils sont tous
|
||
<del>très</del> mauvais. Cela pour nombre de raisons, mais la principale reste
|
||
que leurs interfaces/raccourcis claviers ne sont pas efficaces pour une
|
||
utilisation <strong>a la</strong> UNIX<br />
|
||
Cependant, un d’entre eux se démarque par sa moins-mauvais-itude, c’est
|
||
le relativement bien connu <del>Outlook Express 2003</del> Mutt!<br />
|
||
Mutt est un client mail en ligne de commande, qui, comme le dit sa page
|
||
d’accueil, <a href="http://www.mutt.org">“just sucks less”</a>. Dans les faits, mutt est assez
|
||
chiant a configurer mais particulièrement pratique a utiliser après.</p>
|
||
<p>La configuration de mutt se fait dans le fichier <code>.muttrc</code> ou dans
|
||
<code>/etc/Muttrc</code>, et il est courant d’utiliser offlineimap en
|
||
conjonction avec celui ci, de façon a accéder aux mails même sans accès
|
||
internet (mutt dispose d’un système d’accès IMAP/POP et SMTP, mais ne
|
||
crée pas de cache, ce qui empêche la consultation des emails sans
|
||
connexion internet.) La configuration d’offlineimap se fait dans<code>~/.offlineimaprc</code> ou dans rien d’autre en fait, c’est une config
|
||
par user. Offlineimap est un petit logiciel en python qui synchronise un
|
||
dossier en Maildir avec un serveur IMAP, ce qui tombe bien puisque
|
||
justement mutt accepte les dossiers au format Maildir. (De plus, cela va
|
||
tout a fait dans le sens de la libération des données en cela que vous
|
||
possédez vos mails en local.)<br />
|
||
Bref, passons aux choses serieuses : le code. Déjà, installez
|
||
offlineimap et <a href="http://data.wxcafe.net/scripts/mutt-sidebar.sh">ce script</a> fait par moi, qui vous permet d’installer
|
||
mutt avec le patch sidebar, qui crée un listing des dossiers sur la
|
||
partie gauche.<br />
|
||
Ensuite, voyons pour la partie configuration :<br />
|
||
Ma configuration d’offlineimap :</p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%"><span style="color: #75715e">## Config file for offlineimap</span>
|
||
<span style="color: #75715e">## Originally located in ~/.offlineimaprc</span>
|
||
<span style="color: #75715e">## This should not be edited without creating a copy before</span>
|
||
<span style="color: #75715e">## Created by Wxcafe (Clément Hertling)</span>
|
||
<span style="color: #75715e">## Published under CC-BY-SA</span>
|
||
|
||
<span style="color: #f8f8f2">[general]</span>
|
||
<span style="color: #75715e"># List of accounts to be synced, separated by a comma.</span>
|
||
<span style="color: #f8f8f2">accounts</span> <span style="color: #f92672">=</span> <span style="color: #f8f8f2">main</span>
|
||
|
||
<span style="color: #f8f8f2">[Account</span> <span style="color: #f8f8f2">main]</span>
|
||
<span style="color: #75715e"># Identifier for the local repository; e.g. the maildir to be synced via IMAP.</span>
|
||
<span style="color: #f8f8f2">localrepository</span> <span style="color: #f92672">=</span> <span style="color: #f8f8f2">main</span><span style="color: #f92672">-</span><span style="color: #f8f8f2">local</span>
|
||
<span style="color: #75715e"># Identifier for the remote repository; i.e. the actual IMAP, usually non-local.</span>
|
||
<span style="color: #f8f8f2">remoterepository</span> <span style="color: #f92672">=</span> <span style="color: #f8f8f2">main</span><span style="color: #f92672">-</span><span style="color: #f8f8f2">remote</span>
|
||
<span style="color: #75715e"># Status cache. Default is plain, which eventually becomes huge and slow.</span>
|
||
<span style="color: #f8f8f2">status_backend</span> <span style="color: #f92672">=</span> <span style="color: #f8f8f2">sqlite</span> <span style="color: #960050; background-color: #1e0010">#</span> <span style="color: #f8f8f2">le</span> <span style="color: #f8f8f2">type</span> <span style="color: #f8f8f2">de</span> <span style="color: #f8f8f2">cache.</span> <span style="color: #f8f8f2">(plain</span> <span style="color: #f8f8f2">ou</span> <span style="color: #f8f8f2">sqlite)</span>
|
||
|
||
<span style="color: #f8f8f2">[Repository</span> <span style="color: #f8f8f2">main</span><span style="color: #f92672">-</span><span style="color: #f8f8f2">local]</span>
|
||
<span style="color: #75715e"># Currently, offlineimap only supports maildir and IMAP for local repositories.</span>
|
||
<span style="color: #f8f8f2">type</span> <span style="color: #f92672">=</span> <span style="color: #f8f8f2">Maildir</span> <span style="color: #960050; background-color: #1e0010">#</span> <span style="color: #f8f8f2">le</span> <span style="color: #f8f8f2">type</span> <span style="color: #f8f8f2">de</span> <span style="color: #f8f8f2">stockage</span> <span style="color: #f8f8f2">(Maildir</span> <span style="color: #f8f8f2">ou</span> <span style="color: #f8f8f2">IMAP)</span>
|
||
<span style="color: #75715e"># Where should the mail be placed?</span>
|
||
<span style="color: #f8f8f2">localfolders</span> <span style="color: #f92672">=</span> <span style="color: #f92672">~/</span><span style="color: #f8f8f2">Emails</span><span style="color: #f92672">/</span> <span style="color: #960050; background-color: #1e0010">#</span> <span style="color: #f8f8f2">le</span> <span style="color: #f8f8f2">dossier</span> <span style="color: #f8f8f2">dans</span> <span style="color: #f8f8f2">lequel</span> <span style="color: #f8f8f2">vous</span>
|
||
<span style="color: #75715e"># voulez que vos emails apparaissent</span>
|
||
|
||
<span style="color: #f8f8f2">[Repository</span> <span style="color: #f8f8f2">main</span><span style="color: #f92672">-</span><span style="color: #f8f8f2">remote]</span>
|
||
<span style="color: #75715e"># Remote repos can be IMAP or Gmail, the latter being a preconfigured IMAP.</span>
|
||
<span style="color: #f8f8f2">type</span> <span style="color: #f92672">=</span> <span style="color: #f8f8f2">IMAP</span>
|
||
<span style="color: #f8f8f2">remotehost</span> <span style="color: #f92672">=</span> <span style="color: #75715e">//placeholderhost// # le serveur de votre messagerie</span>
|
||
<span style="color: #f8f8f2">remoteuser</span> <span style="color: #f92672">=</span> <span style="color: #75715e">//placeholderusername// # votre nom d'utilisateur</span>
|
||
<span style="color: #f8f8f2">remotepass</span> <span style="color: #f92672">=</span> <span style="color: #75715e">//placeholderpassword// # votre mot de passe</span>
|
||
<span style="color: #f8f8f2">cert_fingerprint</span> <span style="color: #f92672">=</span> <span style="color: #75715e">//placeholdercert// # le certificat du serveur (IMAPS only)</span>
|
||
</pre></div>
|
||
|
||
|
||
<p>Ça devrait être assez simple a lire, j’ai tout bien commenté :3<br />
|
||
Puis ma config mutt :</p>
|
||
<div class="codehilite" style="background: #272822"><pre style="line-height: 125%"><span style="color: #75715e">## Mutt MUA configuration file</span>
|
||
<span style="color: #75715e">## This file should not be edited without creating a copy</span>
|
||
<span style="color: #75715e">## File Created and edited by Wxcafe (Clément Hertling)</span>
|
||
<span style="color: #75715e">## Published under CC-BY-SA</span>
|
||
|
||
<span style="color: #960050; background-color: #1e0010">#</span> General config for reading (fetched via offlineimap)
|
||
|
||
set mbox_type = Maildir
|
||
<span style="color: #960050; background-color: #1e0010">#</span> type de boite mail (voir dans offlineimap, mailbox par defaut)
|
||
|
||
set folder = ~/Email/
|
||
<span style="color: #960050; background-color: #1e0010">#</span> dossier root mailbox/imap
|
||
|
||
set spoolfile = +INBOX
|
||
<span style="color: #960050; background-color: #1e0010">#</span> dossier d'inbox
|
||
|
||
set mbox = +'All Mail'
|
||
<span style="color: #960050; background-color: #1e0010">#</span> dossier ou archiver les emails
|
||
|
||
set copy = yes
|
||
<span style="color: #960050; background-color: #1e0010">#</span> yes pour copier les messages dans les differents dossier, no pour...
|
||
<span style="color: #960050; background-color: #1e0010">#</span> enfin voila quoi.
|
||
|
||
set header_cache = /.hcache/
|
||
<span style="color: #960050; background-color: #1e0010">#</span> dossier ou sont stockés les headers (pour le cache)
|
||
|
||
set record = +Sent
|
||
<span style="color: #960050; background-color: #1e0010">#</span> dossier dans lequel sont stockés les messages envoyés
|
||
|
||
set postponed = +Drafts
|
||
<span style="color: #960050; background-color: #1e0010">#</span> dossier dans lequel sont stockés les brouillons
|
||
|
||
mailboxes = +INBOX +Drafts +Sent +Trash +All\ Mail
|
||
<span style="color: #960050; background-color: #1e0010">#</span> liste des dossiers qui vont apparaitre dans la colonne de gauche
|
||
|
||
<span style="color: #960050; background-color: #1e0010">#</span> General config for sending (using Mutt's native support)
|
||
|
||
set smtp_pass = 'password_placeholder'
|
||
<span style="color: #960050; background-color: #1e0010">#</span> votre mot de passe
|
||
|
||
set smtp_url = "smtp://username@whatev.org:465/"
|
||
<span style="color: #960050; background-color: #1e0010">#</span> l'url ou envoyer les emails
|
||
|
||
set send_charset = "utf-8"
|
||
<span style="color: #960050; background-color: #1e0010">#</span> UTF8, NE PAS CHANGER
|
||
|
||
set signature = ".sign"
|
||
<span style="color: #960050; background-color: #1e0010">#</span> vous pouvez mettre votre signature dans .sign
|
||
|
||
set sig_on_top = yes
|
||
<span style="color: #960050; background-color: #1e0010">#</span> il est d'usge de mettre no ici. Cependant, je trouve ca plus lisible
|
||
<span style="color: #960050; background-color: #1e0010">#</span> comme ca.
|
||
|
||
set ssl_verify_host = no
|
||
<span style="color: #960050; background-color: #1e0010">#</span> mettez yes ici si votre serveur a un certificat configuré correctement
|
||
|
||
set hostname = "wxcafe.net"
|
||
<span style="color: #960050; background-color: #1e0010">#</span> mettez l'adresse de votre serveur ici
|
||
|
||
<span style="color: #960050; background-color: #1e0010">#</span> Misc settings
|
||
|
||
auto_view text/html
|
||
<span style="color: #960050; background-color: #1e0010">#</span> la façon de voir les emails par défaut.
|
||
|
||
set date_format = "%y-%m-%d %T"
|
||
<span style="color: #960050; background-color: #1e0010">#</span> format de date d'envoi/de reception.
|
||
|
||
set index_format = "%2C | %Z [%D] %-30.30F (%-4.4c) %s"
|
||
<span style="color: #960050; background-color: #1e0010">#</span> format de l'index (la présentation de l'interface)
|
||
<span style="color: #960050; background-color: #1e0010">#</span> voir http://www.mutt.org/doc/manual/manual-6.html<span style="color: #75715e">#</span><span style="color: #a6e22e">index_format</span>
|
||
|
||
set sort_alias = alias
|
||
set reverse_alias = yes
|
||
set alias_file = "<span style="color: #f8f8f2">$HOME</span>/.mutt/aliases"
|
||
<span style="color: #960050; background-color: #1e0010">#</span> liste des alias noms/email. a créer et remplir vous même.
|
||
<span style="color: #960050; background-color: #1e0010">#</span> format : "alias short_name long_email_adress"
|
||
source <span style="color: #f8f8f2">$alias_file</span>
|
||
|
||
set beep = no
|
||
<span style="color: #960050; background-color: #1e0010">#</span> ne pas biper. CE SON ME TUE T.T
|
||
|
||
set tilde = yes
|
||
set sleep_time = 0
|
||
<span style="color: #960050; background-color: #1e0010">#</span> ?
|
||
|
||
set sidebar_visible = yes
|
||
set sidebar_width = 15
|
||
<span style="color: #960050; background-color: #1e0010">#</span> parametres de la barre coté gauche
|
||
|
||
set realname = "Clément Hertling (Wxcafé)"
|
||
set from = "wxcafe@wxcafe.net"
|
||
set use_from = yes
|
||
set certificate_file = "<span style="color: #f8f8f2">$HOME</span>/.mutt/cacert"
|
||
<span style="color: #960050; background-color: #1e0010">#</span> parametres d'envoi. mettez vos propres infos a la place des miennes...
|
||
|
||
set edit_headers = yes
|
||
<span style="color: #960050; background-color: #1e0010">#</span> vous permet de vois les headers des mails. j'aime, donc je laisse.
|
||
|
||
<span style="color: #960050; background-color: #1e0010">#</span> Macros
|
||
|
||
<span style="color: #960050; background-color: #1e0010">#</span> le titre dit tout. index veut dire que la macro est active dans les menus,
|
||
<span style="color: #960050; background-color: #1e0010">#</span> pager qu'elle l'est dans la visionneuse, les deux qu'elle l'est dans les
|
||
<span style="color: #960050; background-color: #1e0010">#</span> deux
|
||
<span style="color: #960050; background-color: #1e0010">#</span> \C represente la touche Control
|
||
|
||
bind index,pager \Cp sidebar-prev
|
||
<span style="color: #960050; background-color: #1e0010">#</span> Control+p -> remonter d'un dossier dans la sidebar
|
||
|
||
bind index,pager \Cn sidebar-next
|
||
<span style="color: #960050; background-color: #1e0010">#</span> Control+n -> descendre d'un dossier dans la sidebar
|
||
|
||
bind index,pager \Co sidebar-open
|
||
<span style="color: #960050; background-color: #1e0010">#</span> Control+o -> ouvrir le dossier selectionné dans la sidebar
|
||
|
||
macro index,pager d "=Trash" "Trash"
|
||
<span style="color: #960050; background-color: #1e0010">#</span> d supprime le message en cours
|
||
|
||
bind pager previous-line
|
||
<span style="color: #960050; background-color: #1e0010">#</span> permet de monter d'une ligne avec la touche up, au lieu de changer de message.
|
||
|
||
bind pager next-line
|
||
<span style="color: #960050; background-color: #1e0010">#</span> permet de descendre d'une ligne avec la touche down, au lieu de changer de
|
||
<span style="color: #960050; background-color: #1e0010">#</span> message
|
||
|
||
bind pager j next-line
|
||
bind pager k previous-line
|
||
<span style="color: #960050; background-color: #1e0010">#</span> raccourcis vim
|
||
|
||
<span style="color: #960050; background-color: #1e0010">#</span> PGP signing commands
|
||
|
||
set pgp_decode_command="gpg %?p?--passphrase-fd 0? --no-verbose --batch --output - %f"
|
||
set pgp_verify_command="gpg --no-verbose --batch --output - --verify %s %f"
|
||
set pgp_decrypt_command="gpg --passphrase-fd 0 --no-verbose --batch --output - %f"
|
||
set pgp_sign_command="gpg --no-verbose --batch --output - --passphrase-fd 0 --armor --detach-sign --textmode %?a?-u %a? %f"
|
||
set pgp_clearsign_command="gpg --no-verbose --batch --output - --passphrase-fd 0 --armor --textmode --clearsign %?a?-u %a? %f"
|
||
set pgp_encrypt_only_command="pgpewrap gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --always-trust --encrypt-to 0x******** -- -r %r -- %f"
|
||
set pgp_encrypt_sign_command="pgpewrap gpg --passphrase-fd 0 --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --always-trust --encrypt-to 0x******** -- -r %r -- %f"
|
||
set pgp_import_command="gpg --no-verbose --import -v %f"
|
||
set pgp_export_command="gpg --no-verbose --export --armor %r"
|
||
set pgp_verify_key_command="gpg --no-verbose --batch --fingerprint --check-sigs %r"
|
||
set pgp_list_pubring_command="gpg --no-verbose --batch --with-colons --list-keys %r"
|
||
set pgp_list_secring_command="gpg --no-verbose --batch --with-colons --list-secret-keys %r"
|
||
set pgp_autosign=yes
|
||
set pgp_sign_as=0x********
|
||
<span style="color: #960050; background-color: #1e0010">#</span> remplacez 0x******** par votre identifiant PGP!!!!!
|
||
|
||
set pgp_replyencrypt=no
|
||
set pgp_timeout=7200
|
||
set pgp_good_sign="^gpg: Good signature from"
|
||
|
||
<span style="color: #960050; background-color: #1e0010">#</span> si vous ne comptez pas utiliser PGP, commentez toute cette section, depuis
|
||
<span style="color: #960050; background-color: #1e0010">#</span> PGP signing options
|
||
|
||
<span style="color: #960050; background-color: #1e0010">#</span> Palette for use with the Linux console. Black background.
|
||
|
||
<span style="color: #960050; background-color: #1e0010">#</span> Schéma de couleur Rouge et Noir. Commentez si vous voulez le
|
||
<span style="color: #960050; background-color: #1e0010">#</span> défaut noir et blanc.
|
||
<span style="color: #960050; background-color: #1e0010">#</span> d'autres schémas sont trouvables sur google et autre.
|
||
|
||
color hdrdefault red black
|
||
color quoted brightblack black
|
||
color signature brightblack black
|
||
color attachment red black
|
||
color message brightwhite black
|
||
color error brightred black
|
||
color indicator black red
|
||
color status white black
|
||
color tree white black
|
||
color normal white black
|
||
color markers red black
|
||
color search white black
|
||
color tilde brightmagenta black
|
||
color index red black ~F
|
||
color index red black "~N|~O"
|
||
</pre></div>
|
||
|
||
|
||
<p>Voila, pour plus d’informations vous pouvez aller voir le manuel de mutt
|
||
@ <a href="http://www.mutt.org/doc/manual/">http://www.mutt.org/doc/manual/</a><br />
|
||
J’espère que cette configuration “toute faite” vous aidera a commencer
|
||
a utiliser mutt. Il est tout de fois important de se souvenir
|
||
qu’utiliser une configuration toute faire n’aide pas a comprendre un
|
||
programme ou un système, et que cette façon de faire devrait être
|
||
réservée a l’introduction ou a des situations ou il est absolument
|
||
nécessaire d’avoir rapidement une configuration fonctionnelle (c’est a
|
||
dire, dans le cas d’un client email, euh… jamais?). Je vous invite
|
||
donc a relire les annotations dont sont parsemés les fichiers de
|
||
configuration en question, et surtout a lire le manuel, a chercher sur
|
||
<del>Bing</del> <del>Google</del> <del>Yahoo</del> Seeks, et globalement
|
||
a tenter de comprendre les configurations en question et a les améliorer!</p></div>
|
||
</div>
|
||
<hr />
|
||
<div class="pagination">
|
||
<ul>
|
||
<li class="prev"><a href="//wxcafe.net/index.html">← Previous</a></li>
|
||
<li class="">
|
||
<a href="//wxcafe.net/index.html">1</a>
|
||
</li>
|
||
<li class="active">
|
||
<a href="//wxcafe.net/index2.html">2</a>
|
||
</li>
|
||
<li class="next disabled"><a href="#">→ Next</a></li>
|
||
</ul>
|
||
</div>
|
||
</div><!--/span-->
|
||
<div class="span3 well sidebar-nav" id="sidebar">
|
||
<ul class="nav nav-list">
|
||
|
||
|
||
<!-- Categories links -->
|
||
<li class="nav-header"><h4><i class="icon-folder-close icon-large"></i> Categories</h4></li>
|
||
<li>
|
||
<a href="//wxcafe.net/category/hacking/">
|
||
<i class="icon-folder-open icon-large"></i>Hacking
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a href="//wxcafe.net/category/note/">
|
||
<i class="icon-folder-open icon-large"></i>Note
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a href="//wxcafe.net/category/oses/">
|
||
<i class="icon-folder-open icon-large"></i>OSes
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a href="//wxcafe.net/category/ranting/">
|
||
<i class="icon-folder-open icon-large"></i>Ranting
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a href="//wxcafe.net/category/tutoriel/">
|
||
<i class="icon-folder-open icon-large"></i>Tutoriel
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a href="//wxcafe.net/category/vidya-games/">
|
||
<i class="icon-folder-open icon-large"></i>Vidya Games
|
||
</a>
|
||
</li>
|
||
<hr>
|
||
|
||
<!-- Social links -->
|
||
<li class="nav-header"><h4><i class="icon-exchange"></i> social</h4></li>
|
||
<a class="FlattrButton" style="display:none;"
|
||
title="//wxcafe.net"
|
||
style="padding-top: 10px;"
|
||
rel="flattr;
|
||
url://wxcafe.net;
|
||
title://wxcafe.net;
|
||
button:compact;
|
||
popout:0;
|
||
uid:wxcafe;
|
||
category:blog;"
|
||
href="//wxcafe.net">flattr</a>
|
||
<li><a href="https://twitter.com/wxcafe"><i class="icon-twitter icon-large"></i> Twitter</a></li>
|
||
<li><a href="https://github.com/wxcafe"><i class="icon-github icon-large"></i> Github</a></li>
|
||
<li><a href="mailto://wxcafe@wxcafe.net"><i class="icon-envelope icon-large"></i> Email</a></li>
|
||
<li><a href="https://pub.wxcafe.net/wxcafe.asc"><i class="icon-key icon-large"></i> Gpg</a></li>
|
||
<li><a href="https://www.openstreetmap.org/relation/105146"><i class="icon-map-marker icon-large"></i> IRL</a></li>
|
||
|
||
<hr>
|
||
|
||
<!-- Links -->
|
||
<li class="nav-header"><h4><i class="icon-external-link"></i> Links</h4></li>
|
||
<li><a href="https://github.com/wxcafe/blog-source"><i class="icon-code icon-large "></i> Source!</a></li>
|
||
<li><a href="http://git.wxcafe.net"><i class="icon-github-sign icon-large "></i> Public Git</a></li>
|
||
<hr>
|
||
|
||
<!--- RSS feed -->
|
||
<li class="nav-header"><h4><i class="icon-rss"></i> feeds</h4></li>
|
||
<li><a href="//wxcafe.net/feeds/feed.rss.xml" rel="alternate"><i class="icon-bookmark-empty icon-large"></i> RSS</a></li>
|
||
<li><a href="//wxcafe.net/feeds/feed.atom.xml" rel="alternate"><i class="icon-bookmark-empty icon-large"></i> Atom</a></li>
|
||
|
||
|
||
</ul> </div><!--/.well -->
|
||
</div><!--/row-->
|
||
<hr>
|
||
<footer>
|
||
<address id="about">
|
||
Proudly powered by <a href="http://pelican.notmyidea.org/">Pelican</a>,
|
||
which takes great advantage of <a href="http://python.org">Python</a>.<br />
|
||
Powered by <a href="https://github.com/getpelican/pelican-themes/tree/master/bootstrap2">bootstrap2</a> theme, thanks!
|
||
</address>
|
||
</footer>
|
||
</div><!--/.fluid-container-->
|
||
</body>
|
||
</html> |