Blog de Victor Héryhttps://blog.victor-hery.com/2024-02-26T10:22:00+01:00SSH over Openssl over Haproxy2024-02-26T10:22:00+01:002024-02-26T10:22:00+01:00Victortag:blog.victor-hery.com,2024-02-26:/2024/02/ssh-openssl-haproxy.html<p class="first last">contourner les blocages</p>
<div class="section" id="contexte">
<h2><a class="toc-backref" href="#id2">Contexte</a></h2>
<p>Parfois, en entreprise ou dans les hôtels, des règles de sécurité sont mises en place pour empêcher les employés de sortir sur d'autres ports que l'http⋅s (ports 80 et 443)</p>
<p>Selon l'intelligence du matériel utilisé, il sera capable de détecter si le flux est de l'http, du ssh, ou un autre protocole interdit et en conséquence, contourner ce genre de protection peut s'avérer complexe.</p>
<p>Bien entendu, jamais je ne conseillerai de contourner les protections mises en place par votre entreprise 😇
Par contre, rien n'empêche de donner un coup de main à votre SI en pointant les failles du système qu'une personne mal intentionnée pourrait utiliser.</p>
<p>Je vous invite à consulter votre charte informatique quand aux éventuelles conséquences, mais sachez que <strong>si protection il y a, vous devez légalement en être informé par écrit</strong>.</p>
<p>Cela étant posé, je vais ici vous proposer d'utiliser Haproxy pour passer outre 2 types de protections :</p>
<ol class="arabic simple">
<li>Un blocage des ports autres que 80/443 sans vérification du type de protocole</li>
<li>Un blocage des ports autres que 80/443, avec vérification du type de protocole</li>
</ol>
<p>L'objectif sera de faire passer <strong>un flux ssh</strong> sur le port 443 (étape 1), puis de <strong>l'encapsuler dans du SSL</strong> (étape 2).</p>
<p>Je partirai du principe que vous avez un serveur avec Haproxy installé et fonctionnel, par exemple pour servir vos sites habituels.</p>
<p><strong>Disclaimer 1 :</strong> Cette technique vous permettra d'utiliser toutes les fonctionnalités de SSH. J'écris cet article depuis le boulot en committant via un tunnel SSH sur openssl vers mon repo git. Avec l'accord de l'équipe sécurité et pour entretenir sa forme bien sûr. 😁</p>
<p><strong>Disclaimer 2 :</strong> Retrouvez à la fin de l'article les configurations complètes si vous êtes pressés ^^</p>
<p>PS: Dans le cas où le filtrage se ferait avec un système de <a class="reference external" href="https://fr.wikipedia.org/wiki/Deep_packet_inspection">Deep Packet Inspection</a> qui désencapsule les flux SSL pour les analyser, cela ne fonctionnera pas. Mais si vous avez une protection de ce genre, ça sous-entends que l'entreprise peut (et le fait) voir absolument tout ce que vous faites en https, que ça soit les mots de passe de votre banque ou les messages privés envoyés sur votre discord. Je vous invite à insulter votre DSI (Avec virulence) puis à changer de boite 😄</p>
</div>
<div class="section" id="etape-1-ssh-sur-443">
<h2><a class="toc-backref" href="#id3">Étape 1 : SSH sur 443</a></h2>
<p>La première étape va consister à assez simplement faire passer votre flux SSH sur le port 443. Si vous rencontrez un simple pare-feu qui bloque tous les ports sauf le 443, cela permettra de contourner le blocage sans problème.</p>
<p>Côté serveur on pourrait simplement faire écouter sshd sur ce port, ou utiliser iptables pour NATer le port 443 vers le port 22 de votre serveur <strong>mais</strong> c'est moins fun, et puis si vous avez des sites web votre port 443 est déjà utilisé.</p>
<p>C'est là qu'Haproxy va intervenir car il est capable de détecter si le flux entrant est du SSH ou de l'http !
Cette étape est assez simple, on va demander à Haproxy de rediriger le flux http (plus précisément, ssl) vers votre frontend habituel, et le flux ssh <strong>vers un serveur particulier</strong>. On verra ensuite une technique pour dire à Haproxy quel serveur ssh on souhaite joindre 😄</p>
<div class="figure">
<img alt="Description de l'objectif à atteindre : Un frontend Public 443 redistribue les flux vers un backend SSH et un backend SSL, ce dernier renvoyant ensuite vers le fronted HTTP SSL habituel" src="https://blog.victor-hery.com/images/ssh-openssl-haproxy/ssh_simple.png" style="width: 500px;"/>
<p class="caption">Première étape : séparer SSH et SSL</p>
</div>
<div class="section" id="id1">
<span id="frontend-tcp-ssl-ssh"></span><h3><a class="toc-backref" href="#id4">Frontend TCP SSL/SSH</a></h3>
<p>Tout d'abord on va modifier votre frontend qui écoute sur le port 443. En toute logique, il devrait écouter sur l'adresse IP exposée vers l'extérieur, mais on va lui dire d'écouter plutôt sur l'adresse localhost, afin de créer ensuite un nouveau frontend qui s'occupera des accès entrants.</p>
<p>Modifiez donc votre frontend existant :</p>
<div class="highlight"><pre><span></span>frontend ft_tcpssl
<span class="c1"># Local frontend</span>
<span class="nb">bind</span> <span class="m">127</span>.0.0.1:1443 ssl crt /etc/your/certs accept-proxy
mode http
<span class="o">[</span>...<span class="o">]</span> <span class="c1"># Vos acl et traitement http classiques</span>
</pre></div>
<p>Modifiez bien sûr le chemin <tt class="docutils literal">/etc/your/certs</tt> par votre répertoire habituel pour stocker vos certificats.</p>
<p>L'option <a class="reference external" href="http://docs.haproxy.org/2.4/configuration.html#5.1-accept-proxy">accept-proxy</a> indique de n'accepter que les connexions de type PROXY, ce qui sera le cas via notre chaine de frontend/backend Haproxy et assure de garder un maximum d'information sur la connexion d'origine.</p>
<p>Ensuite, on va configurer un nouveau frontend qui se chargera de recevoir le flux sur 443 et de filtrer le flux chiffré en SSL (typiquement de l'https) de celui chiffré via SSH</p>
<p>Pour cela :</p>
<div class="highlight"><pre><span></span>frontend <span class="m">443</span>-in
<span class="nb">bind</span> YOUR_IP:443
mode tcp <span class="c1"># On est en TCP ici et pas encore en http</span>
<span class="c1"># On verifie les types de trafics parmi tcp over ssl, http et SSH</span>
tcp-request inspect-delay 5s <span class="c1"># Une connexion ssh peut être longuette à s'établir, on prends le temps d'inspecter le flux</span>
acl trafic_ssl req.ssl_ver gt <span class="m">0</span>
acl trafic_ssh_raw req.payload<span class="o">(</span><span class="m">0</span>,7<span class="o">)</span> -m str SSH-2.0
</pre></div>
<p>Ici on définit <strong>deux ACLs</strong> :</p>
<ul class="simple">
<li>L'acl <tt class="docutils literal">trafic_ssl</tt> se base simplement sur le fait que le flux est chiffré avec ssl</li>
<li>l'acl <tt class="docutils literal">trafic_ssh_raw</tt> quand à elle, vérifie les 7 premiers bits de payload de la connexion TCP, qui contiennent <tt class="docutils literal"><span class="pre">SSH-2.0</span></tt> dans le cas d'une transaction SSH !</li>
</ul>
<p>Sur la base de ces ACL, on peut facilement rediriger vers les backends qui vont bien</p>
<div class="highlight"><pre><span></span><span class="c1"># Si SSL on envoie au backend TCP pour dechiffrement</span>
use_backend bk_tcpssl <span class="k">if</span> trafic_ssl
<span class="c1"># Si ssh direct on envoie au backend ssh</span>
use_backend bk_ssh <span class="k">if</span> trafic_ssh_raw
</pre></div>
</div>
<div class="section" id="backends-ssl-et-ssh">
<h3><a class="toc-backref" href="#id5">Backends SSL et SSH</a></h3>
<p>On va pouvoir établir les backends :</p>
<div class="highlight"><pre><span></span>backend bk_tcpssl
mode tcp
timeout server 2h
server ft_tcpssl <span class="m">127</span>.0.0.1:1443 send-proxy
backend bk_ssh
mode tcp
timeout server 2h
server ssh SSH_IP_SERVER:22
</pre></div>
<p>On retrouve ici le frontend <tt class="docutils literal">ft_tcpssl</tt>, votre frontend habituel qui gère l'https, avec le mot clef <tt class="docutils literal"><span class="pre">send-proxy</span></tt> pour transmettre le flux sur localhost en mode PROXY.</p>
<p>Le bk_ssh quand à lui reste très simple, vous indiquez l'adresse IP du serveur sur lequel vous souhaitez vous connecter en ssh comme cible du backend.
(Rappel, on verra ensuite comment se connecter à plusieurs serveurs ssh sans devoir en indiquer un en dur 😜 )</p>
<p>Cette première configuration est assez simple, et vous permettra simplement en lançant une connexion SSH sur le port 443 de vous retrouver sur votre serveur habituel.</p>
<p>Les connexions pourront se faire par clef ou par mot de passe, de la manière dont vous fonctionnez en général !</p>
<div class="highlight"><pre><span></span>ssh -p <span class="m">443</span> YOUR_IP
</pre></div>
</div>
</div>
<div class="section" id="etape-2-ssh-sur-ssl">
<h2><a class="toc-backref" href="#id6">Étape 2 : SSH sur SSL</a></h2>
<p>Dans cette 2eme étape, on va ajouter une brique qui permettra d'injecter un flux SSH dans une connexion chiffrée avec SSL.</p>
<p>Bien que techniquement plus complexe à utiliser et à configurer, on ajoute ici 2 gros avantages.</p>
<ol class="arabic simple">
<li>Un pare-feu intelligent capable de faire la différence entre https et ssh sera incapable de bloquer ce nouveau flux, qu'il ne pourra que considérer comme de l'https</li>
<li>La possibilité d'utiliser l'en-tête SNI des connexions SSL pour choisir dynamiquement la cible de notre connexion SSH</li>
</ol>
<p>On garde la configuration précédente, mais on va ajouter une nouvelle vérification de flux <strong>une fois le SSL déchiffré</strong>, pour voir si on à affaire à de l'http ou du SSH !</p>
<div class="figure">
<img alt="Description de l'objectif à atteindre : Un frontend Public 443 redistribue les flux vers un backend SSH et un backend SSL, ce dernier renvoyant ensuite vers un nouveau frontend SSL. Ce nouveau frontend va se charger de déchiffrer le flux SSL, puis de rediriger le flux final vers le frontend HTTP habituel ou vers le serveur SSH demandé." src="https://blog.victor-hery.com/images/ssh-openssl-haproxy/ssh_over_ssl.png" style="width: 700px;"/>
<p class="caption">Deuxième étape : Séparer SSH et HTTP depuis le flux SSL</p>
</div>
<div class="section" id="modifications-du-frontend-ssl">
<h3><a class="toc-backref" href="#id7">Modifications du frontend SSL</a></h3>
<p>La première modification va se faire sur le <strong>frontend SSL</strong>, qui va porter en plus du déchiffrement classique du flux, de nouveaux tests pour détecter une connexion SSH.</p>
<p>On va en gros faire le même traitement sur les en-têtes des paquets que dans notre première étape de <a class="reference internal" href="#frontend-tcp-ssl-ssh">frontend-tcp-ssl-ssh</a>, mais cette fois sur le flux SSL déchiffré.</p>
<p>Comme ce ne sera plus votre frontend http standard qui déchiffrera le flux, on va le modifier de nouveau pour écouter sur le port 80 sans chiffrement (rien ne sort, tout reste en interne)</p>
<div class="highlight"><pre><span></span>frontend http_in
<span class="c1"># Local frontend</span>
<span class="nb">bind</span> <span class="m">127</span>.0.0.1:80 accept-proxy
mode http
<span class="o">[</span>...<span class="o">]</span> <span class="c1"># Vos acl et traitement http classiques</span>
</pre></div>
<p>Et <strong>on récupère le port 1443 du localhost</strong> vers lequel notre backend TCP déjà existant renvoie le flux pour traiter notre flux SSL :</p>
<div class="highlight"><pre><span></span>frontend ft_tcpssl
<span class="nb">bind</span> <span class="m">127</span>.0.0.1:1443 ssl crt /etc/haproxy/cert/ accept-proxy
mode tcp <span class="c1"># On reste en TCP pour le moment</span>
<span class="c1"># On enrichit les logs avec les infos venant du TCP</span>
log-format <span class="s2">"%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq dst:%[var(sess.dst)] http:%[var(sess.ishttp)] ssh:%[var(sess.isssh)] "</span>
tcp-request content set-var<span class="o">(</span>sess.dst<span class="o">)</span> ssl_fc_sni
tcp-request content set-var<span class="o">(</span>sess.ishttp<span class="o">)</span> req.proto_http
tcp-request content set-var<span class="o">(</span>sess.isssh<span class="o">)</span> req.payload<span class="o">(</span><span class="m">0</span>,7<span class="o">)</span>
<span class="c1"># Une fois le flux ssl déchiffré on peut verifier la payload pour du SSH</span>
tcp-request inspect-delay 5s
acl trafic_ssh req.payload<span class="o">(</span><span class="m">0</span>,7<span class="o">)</span> -m beg <span class="s2">"SSH-2.0"</span>
tcp-request content accept <span class="k">if</span> trafic_ssh <span class="c1"># accept SSH</span>
<span class="c1"># Et enfin, on transmet vers les backends</span>
use_backend bk_local_https <span class="k">if</span> HTTP
use_backend bk_sshssl <span class="k">if</span> trafic_ssh
</pre></div>
<p>On a déjà vu la plupart de ces options dans la première partie, mis à part le fait qu'on déchiffre le flux, rien de nouveau ici 😄</p>
<p>L'intelligence va se faire dans les backends ! Notamment celui du SSH</p>
</div>
<div class="section" id="backend-ssh-enrichit-au-ssl">
<h3><a class="toc-backref" href="#id8">Backend SSH enrichit au SSL</a></h3>
<p>Le premier backend est très simpliste, il va renvoyer vers votre frontend http classique, pour un traitement du flux HTTP sans plus de fioriture :</p>
<div class="highlight"><pre><span></span>backend bk_local_https
mode http
http-request add-header X-Forwarded-Proto https
server httplocal <span class="m">127</span>.0.0.1:80 send-proxy
</pre></div>
<p>Là où on va prendre un peu plus de temps, c'est sur le backend SSH :</p>
<div class="highlight"><pre><span></span>backend bk_sshssl
mode tcp
timeout server 2h
<span class="c1"># Avec le SSL et ses headers SNI on peut choisir le serveur cible</span>
<span class="c1">## NEED haproxy > 2.0</span>
tcp-request content set-dst var<span class="o">(</span>sess.dst<span class="o">)</span>
server ssh <span class="m">0</span>.0.0.0:22
</pre></div>
<p>Ici, on reste en TCP, mais la magie se passe avec la ligne <tt class="docutils literal"><span class="pre">set-dst</span></tt>. Grâce à ça, en utilisant la variable <tt class="docutils literal">sess.dst</tt> définie plus haut dans le frontend, on est capable de modifier à la volée la destination de notre flux SSH.</p>
<p>Cela va nous permettre de taper sur <strong>n'importe quel serveur SSH</strong>, rien qu'en modifiant le champs SNI de notre commande <tt class="docutils literal">ssh</tt> ! C'est donc beaucoup plus souple que la redirection en dure vers un mono-serveur comme dans notre première partie.</p>
<p>C'est également <strong>plus risqué</strong>, puisque techniquement n'importe qui sachant que vous avez implémenté ça pourrait s'en servir pour rebondir vers n'importe quel serveur en SSH, comme si la connexion venait de votre propre connexion.
Notamment, on pourrait initier des attaques (DDOS, bruteforce, crawl, ...) en traversant haproxy et en se planquant derrière votre IP.</p>
<p>On va donc voir comment limiter ces exploits !</p>
</div>
<div class="section" id="securiser-l-acces-ssh">
<h3><a class="toc-backref" href="#id9">Sécuriser l'accès SSH</a></h3>
<p>J'ai mis en place plusieurs garde-fou :</p>
<ul class="simple">
<li>Frapper avant d'entrer : pour tromper les bots, on va faire en sorte qu'il faille initier 3 connexions à la suite avant de réellement se connecter</li>
<li>Pas plus de 50 connexions simultanées autorisée</li>
<li>Connexion uniquement à une liste de serveurs autorisés</li>
</ul>
<p>On va devoir créer une sticky table dédiée à travers un backend dummy, car de base il n'existe qu'une seule <tt class="docutils literal"><span class="pre">stick-table</span></tt> par proxy (<a class="reference external" href="http://docs.haproxy.org/2.8/configuration.html#stick-table">http://docs.haproxy.org/2.8/configuration.html#stick-table</a>)</p>
<p>On va également enrichir notre backend <tt class="docutils literal">bk_sshssl</tt>
<strong>Note</strong> : À l'exception de l'acl utilisant le SNI, ces sécurités peuvent être ajoutée au backend ssh <tt class="docutils literal">bk_ssh</tt> tout simple vu plus haut !</p>
<div class="highlight"><pre><span></span><span class="c1"># Pour avoir plusieurs sticky-table, on utilise un dummy backend</span>
backend dummy_st_sshssl_src
stick-table <span class="nb">type</span> ip size 1m expire 12h store conn_rate<span class="o">(</span>30m<span class="o">)</span>
backend bk_sshssl
mode tcp
timeout server 2h
<span class="c1"># Serveurs autorisés</span>
acl allowed_destination var<span class="o">(</span>sess.dst<span class="o">)</span> -m ip RESEAU/24 IP/32
tcp-request content reject <span class="k">if</span> ! allowed_destination
<span class="c1"># On frappe avant d'entrer !</span>
tcp-request content track-sc0 src table dummy_st_sshssl_src
tcp-request content reject <span class="k">if</span> <span class="o">{</span> sc0_conn_rate<span class="o">(</span>dummy_st_sshssl_src<span class="o">)</span> le <span class="m">3</span> <span class="o">}</span>
<span class="c1"># Pas plus de 50 requêtes simultanees</span>
tcp-request content reject <span class="k">if</span> <span class="o">{</span> sc0_conn_rate<span class="o">(</span>dummy_st_sshssl_src<span class="o">)</span> gt <span class="m">50</span> <span class="o">}</span>
<span class="c1"># Avec le SSL et ses headers SNI on peut choisir le serveur cible</span>
<span class="c1">## NEED haproxy > 2.0</span>
tcp-request content set-dst var<span class="o">(</span>sess.dst<span class="o">)</span>
server ssh <span class="m">0</span>.0.0.0:22
</pre></div>
<p>Modifiez comme bon vous semble <tt class="docutils literal">RESEAU/24</tt> ou <tt class="docutils literal">IP/32</tt> pour indiquer les réseaux ou serveurs autorisés à être joint par ces connexion SSH. Il vous suffit de les séparer par des espaces.</p>
</div>
<div class="section" id="et-comment-qu-on-s-y-connecte">
<h3><a class="toc-backref" href="#id10">Et comment qu'on s'y connecte ?</a></h3>
<p>Pour vous y connecter, il faudra indiquer à SSH d'encapsuler son flux dans du SSL :</p>
<div class="highlight"><pre><span></span>ssh -o <span class="nv">ProxyCommand</span><span class="o">=</span><span class="s2">"openssl s_client -quiet -connect IP_HAPROXY:443 -servername IP_A_SSH"</span> -l USER dummy.name
</pre></div>
<p>Avec :</p>
<ul class="simple">
<li><tt class="docutils literal">IP_HAPROXY</tt>: Le hostname ou l'adresse IP de votre proxy</li>
<li><tt class="docutils literal">IP_A_SSH</tt>: L'adresse IP que vous souhaitez réellement atteindre en ssh</li>
<li><tt class="docutils literal"><span class="pre">-l</span> USER</tt> : L'utilisateur ssh à utiliser</li>
<li><tt class="docutils literal">dummy.name</tt>: Contrairement à une connexion ssh classique, ce nom ne sera jamais ni résolu ni utilisé pour joindre le serveur ssh. <strong>Néanmoins</strong> c'est sous ce nom que l'empreinte SSH du serveur sera enregistrée dans votre fichier known_hosts, donc je vous conseille de le changer pour un nom pertinent en rapport avec <tt class="docutils literal">IP_A_SSH</tt></li>
</ul>
<p>Au passage <strong>petit conseil d'expérience</strong>, par défaut haproxy traite les flux dans un contexte "question/réponse", puisqu'après tout http fonctionne rarement en flux continu, contrairement à SSH.
Du coup, ça génère des déconnexions de vos sessions SSH si elle ne font rien pendant quelques minutes/secondes, ce qui est un peu chiant.</p>
<p>Je vous invite à ajouter <strong>côté client ssh</strong> une configuration keepalive pour que votre client se charge d'envoyer des ping dans le tunnel et ainsi maintenair la connexion :</p>
<div class="highlight"><pre><span></span>$ cat ~/.ssh/config
Host *
ServerAliveInterval <span class="m">10</span>
</pre></div>
<p>Ici on envoie un ping au serveur toutes les 10 secondes, à ajuster selon votre configuration de timeout haproxy.</p>
</div>
</div>
<div class="section" id="au-final">
<h2><a class="toc-backref" href="#id11">Au final</a></h2>
<p>Et voila, votre proxy SSH over SSL est prêt à affronter le monde et ses pare-feux !</p>
<div class="highlight"><pre><span></span><span class="c1">##############</span>
<span class="c1">### TCP IN ###</span>
<span class="c1">##############</span>
frontend <span class="m">443</span>-in
<span class="nb">bind</span> YOUR_IP:443
mode tcp <span class="c1"># On est en TCP ici et pas encore en http</span>
<span class="c1"># On verifie les types de trafics parmi tcp over ssl, http et SSH</span>
tcp-request inspect-delay 5s <span class="c1"># Une connexion ssh peut être longuette à s'établir, on prends le temps d'inspecter le flux</span>
acl trafic_ssl req.ssl_ver gt <span class="m">0</span>
acl trafic_ssh_raw req.payload<span class="o">(</span><span class="m">0</span>,7<span class="o">)</span> -m str SSH-2.0
<span class="c1"># Si SSL on envoie au backend TCP pour dechiffrement</span>
use_backend bk_tcpssl <span class="k">if</span> trafic_ssl
<span class="c1"># Si ssh direct on envoie au backend ssh</span>
use_backend bk_ssh <span class="k">if</span> trafic_ssh_raw
<span class="c1"># Pour avoir plusieurs sticky-table, on utilise un dummy backend</span>
backend dummy_st_sshssl_src
stick-table <span class="nb">type</span> ip size 1m expire 12h store conn_rate<span class="o">(</span>30m<span class="o">)</span>
backend bk_tcpssl
mode tcp
timeout server 2h
server ft_tcpssl <span class="m">127</span>.0.0.1:1443 send-proxy
backend bk_ssh
mode tcp
timeout server 2h
<span class="c1"># On frappe avant d'entrer !</span>
tcp-request content track-sc0 src table dummy_st_ssh_src
tcp-request content reject <span class="k">if</span> <span class="o">{</span> sc0_conn_rate<span class="o">(</span>dummy_st_ssh_src<span class="o">)</span> le <span class="m">3</span> <span class="o">}</span>
<span class="c1"># Pas plus de 50 requêtes simultanees</span>
tcp-request content reject <span class="k">if</span> <span class="o">{</span> sc0_conn_rate<span class="o">(</span>dummy_st_ssh_src<span class="o">)</span> gt <span class="m">50</span> <span class="o">}</span>
server ssh SSH_IP_SERVER:22
<span class="c1">####################</span>
<span class="c1">### TCP OVER SSL ###</span>
<span class="c1">####################</span>
frontend ft_tcpssl
<span class="nb">bind</span> <span class="m">127</span>.0.0.1:1443 ssl crt /etc/haproxy/cert/ accept-proxy
mode tcp <span class="c1"># On reste en TCP pour le moment</span>
<span class="c1"># On enrichit les logs avec les infos venant du TCP</span>
log-format <span class="s2">"%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq dst:%[var(sess.dst)] http:%[var(sess.ishttp)] ssh:%[var(sess.isssh)] "</span>
tcp-request content set-var<span class="o">(</span>sess.dst<span class="o">)</span> ssl_fc_sni
tcp-request content set-var<span class="o">(</span>sess.ishttp<span class="o">)</span> req.proto_http
tcp-request content set-var<span class="o">(</span>sess.isssh<span class="o">)</span> req.payload<span class="o">(</span><span class="m">0</span>,7<span class="o">)</span>
<span class="c1"># Une fois le flux ssl déchiffré on peut verifier la payload pour du SSH</span>
tcp-request inspect-delay 5s
acl trafic_ssh req.payload<span class="o">(</span><span class="m">0</span>,7<span class="o">)</span> -m beg <span class="s2">"SSH-2.0"</span>
tcp-request content accept <span class="k">if</span> trafic_ssh <span class="c1"># accept SSH</span>
<span class="c1"># Et enfin, on transmet vers les backends</span>
use_backend bk_local_https <span class="k">if</span> HTTP
use_backend bk_sshssl <span class="k">if</span> trafic_ssh
backend bk_local_https
mode http
http-request add-header X-Forwarded-Proto https
server httplocal <span class="m">127</span>.0.0.1:80 send-proxy
backend bk_sshssl
mode tcp
timeout server 2h
<span class="c1"># Serveurs autorisés</span>
acl allowed_destination var<span class="o">(</span>sess.dst<span class="o">)</span> -m ip RESEAU/24 IP/32
tcp-request content reject <span class="k">if</span> ! allowed_destination
<span class="c1"># On frappe avant d'entrer !</span>
tcp-request content track-sc0 src table dummy_st_sshssl_src
tcp-request content reject <span class="k">if</span> <span class="o">{</span> sc0_conn_rate<span class="o">(</span>dummy_st_sshssl_src<span class="o">)</span> le <span class="m">3</span> <span class="o">}</span>
<span class="c1"># Pas plus de 50 requêtes simultanees</span>
tcp-request content reject <span class="k">if</span> <span class="o">{</span> sc0_conn_rate<span class="o">(</span>dummy_st_sshssl_src<span class="o">)</span> gt <span class="m">50</span> <span class="o">}</span>
<span class="c1"># Avec le SSL et ses headers SNI on peut choisir le serveur cible</span>
<span class="c1">## NEED haproxy > 2.0</span>
tcp-request content set-dst var<span class="o">(</span>sess.dst<span class="o">)</span>
server ssh <span class="m">0</span>.0.0.0:22
<span class="c1">####################</span>
<span class="c1">### HTTP & HTTPS ###</span>
<span class="c1">####################</span>
frontend http_in
<span class="c1"># Local frontend</span>
<span class="nb">bind</span> <span class="m">127</span>.0.0.1:80 accept-proxy
mode http
<span class="o">[</span>...<span class="o">]</span> <span class="c1"># Vos acl et traitement http classiques</span>
</pre></div>
</div>
Rudder et Git2019-12-08T20:19:00+01:002019-12-08T20:19:00+01:00Victortag:blog.victor-hery.com,2019-12-08:/2019/12/rudder-et-git.html
<h1 id="git">Git ?</h1>
<p>Dernièrement, on est tombé sur un truc par hasard en bossant avec Rudder.</p>
<p>Tout le système de directives est en fait stocké et versionné grâce à <a href="https://fr.wikipedia.org/wiki/Git">git</a>, c'est ce qui permet de gérer les retours en arrière et également de spécifier des messages dans l'interface pour expliquer les changements …</p>
<h1 id="git">Git ?</h1>
<p>Dernièrement, on est tombé sur un truc par hasard en bossant avec Rudder.</p>
<p>Tout le système de directives est en fait stocké et versionné grâce à <a href="https://fr.wikipedia.org/wiki/Git">git</a>, c'est ce qui permet de gérer les retours en arrière et également de spécifier des messages dans l'interface pour expliquer les changements.</p>
<p>Il en dérive du coup des possibilités assez intéressantes, comme le fait de pouvoir stocker ces infos sur un git distant, utiliser un serveur de test pour vérifier les techniques, fonctionner avec des Merge Requests, etc.</p>
<p>Je vais ici proposer une configuration basique, mais il est possible ensuite d'utiliser toute la puissance de git avec rudder ^^</p>
<h1 id="configuration">Configuration</h1>
<p>Il vous faut bien sûr un serveur rudder fonctionnel, ainsi qu'un repository git dans lequel vous stockerez vos directives.</p>
<p>Étant donné tout ce qui est stockés dans les directives (mots de passe, utilisateurs, clefs ssh, ...), je vous conseille de garder ce repository privé :-)</p>
<p>Rendez vous sur votre serveur rudder, et connectez vous avec votre utilisateur rudder (en général, root)</p>
<div class="highlight"><pre><span></span><code>$ <span class="nb">cd</span> /var/rudder/configuration-repository
</code></pre></div>
<p>Vous allez avoir besoin d'une clef ssh pour vous connecter automatiquement</p>
<div class="highlight"><pre><span></span><code>$ ssh-keygen -t rsa -b <span class="m">4096</span> -C <span class="s2">"votre.rudder.tld"</span>
<span class="c1">### N'indiquez pas de mot de passe pour permettre la connexion automatique ###</span>
$ cat ~/.ssh/id_rsa.pub
</code></pre></div>
<p>Créez un utilisateur sur votre repo git et configurez-le avec la clef ssh récupérée plus haut pour que votre utilisateur puisse se connecter.</p>
<p>Vous pouvez vérifier la connexion via :</p>
<div class="highlight"><pre><span></span><code>$ ssh -T gituser@votre.git.tld
</code></pre></div>
<p>On va ensuite ajouter le nouveau repo git et l'initialiser :</p>
<div class="highlight"><pre><span></span><code>$ <span class="nb">cd</span> /var/rudder/configuration-repository
$ git remote add origin https://url_de_votre_repo_git
$ git status
$ git push --set-upstream origin master
</code></pre></div>
<p>Enfin, pour automatiser le push lors que vous modifiez des choses dans l'interface web de rudder, on va créer un hook git :</p>
<div class="highlight"><pre><span></span><code>$ <span class="nb">cd</span> /var/rudder/configuration-repository
$ cat <span class="s"><<EOF > .git/hooks/post-commit</span>
<span class="s">#!/bin/bash</span>
<span class="s">git push origin master</span>
<span class="s">EOF</span>
$ chmod +x .git/hooks/post-commit
</code></pre></div>
<p>Le hook est simple et va juste envoyer un <code>git push</code> vers votre repo distant dès qu'un commit est effectué via l'interface web, ce qui permettra de garder le repo à jour.</p>
<h1 id="aller-plus-loin">Aller plus loin</h1>
<p>Avec ce système, vous pouvez envisager d'industrialiser l'utilisation de rudder !</p>
<p>En plus des possibilités de sauvegardes/restauration très faciles des directives en cas de boulettes, et de suivi précis de ce qui est fait et par qui, quelques autres effets kiss cool sont possibles.</p>
<p>En effet, l'un des "inconvénient" de rudder est qu'il permet trèèès facilement de tout casser sur vos serveurs en déployant une directive foireuse.
Maintenant, il devient très simple de créer un serveur rudder de test, utilisant par exemple des machines virtuelles, et publiant les modifications sur une branche de développement.</p>
<p>Et une fois les directives testées, une merge request, une vérification des collègues, un petit merge dans la branche master, et hop ! On envoie en production les nouvelles directives ! 😘</p>
<p>En gros, intégrer rudder à un système de déploiement continu et de tests est largement facilité :-)</p>
<p>N'hésitez pas à proposer vos utilisations et astuces utilisant rudder et git dans les commentaires !</p>Suivre vos serveurs avec rudder2019-07-28T18:32:00+02:002019-07-28T18:32:00+02:00Victortag:blog.victor-hery.com,2019-07-28:/2019/07/rudder-outil-conformite.html<p class="first last">conformité et maîtrise opérationnelle</p>
<div class="section" id="la-conformite-kesako">
<h2><a class="toc-backref" href="#id1">La conformité, késako ?</a></h2>
<p>Ce que l'on appelle la conformité dans le monde merveilleux des sysadmins, c'est ce qui va vous permettre de maintenir et de faire fonctionner vos serveurs sur le long terme.</p>
<p>Parmis les étapes les plus connues de la vie d'un serveur, il y a son installation, sa configuration puis son utilisation (serveur web, applicatif, ...).</p>
<p><strong>La conformité va intervenir juste après l'installation du serveur.</strong> Ce n'est pas du déploiement, ni de la supervision, c'est ce qui va vous permettre de vous assurer que votre serveur ne dérive pas, que sa configuration reste correcte et qu'il continue de ressembler à ce qu'il doit être.</p>
<p><strong>Note :</strong> Dans le monde merveilleux des DevOps, vous entendrez aussi parler de Maintenance en Conditions Opérationnelles (MCO).</p>
<p>Différents outils existent qui font plus ou moins ce travail, comme puppet dont les agents permettent de faire des modifications dans la vie du serveur, ou Ansible dont on peut rejouer les playbooks pour recaler un serveur qui aurait divergé.</p>
<p>Cela étant, peu d'outils sont spécifiquement dédiés à ce besoin, et c'est le cas de <a class="reference external" href="https://www.rudder.io">rudder</a>.</p>
<div class="figure">
<img alt="Quelques informations d'inventaire" src="https://blog.victor-hery.com/images/rudder-outil-conformite/node_breakdown.png" style="width: 700px;"/>
<p class="caption">De jolis camemberts d'inventaires</p>
</div>
<p>L'idée est simple : vous définissez des règles que vos serveurs doivent suivre, et rudder s'assure qu'ils s'y conforment, détecte les changements et les corrige le cas échéant.</p>
<p>Si vous avez besoin que votre <strong>motd contienne des infos légales</strong> et de vous assurez qu'elles sont toujours présentes. Si vous voulez être sûr que <strong>la connexion SSH root est désactivée et le reste</strong>. Si vous voulez pouvoir <strong>déployer des clefs SSH autorisées</strong> à se connecter au serveur et surveiller que personne n'en ajoute de nouvelles dans votre dos. Ou encore <strong>pouvoir massivement ajouter et supprimer des utilisateurs systèmes</strong> quand quelqu'un quitte ou rejoint la boite.</p>
<p>Alors vous avez besoin de conformité, et rudder est fait pour vous !</p>
<p>Ce schéma définit bien où se situe rudder dans les différentes étapes d'exploitation :</p>
<div class="figure">
<img alt="rudder en exploitation" src="https://blog.victor-hery.com/images/rudder-outil-conformite/schema-rudder-build-run.png" style="width: 700px;"/>
<p class="caption">Rudder, outil géré par le Run</p>
</div>
<p>En espérant que le concept de conformité vous soit déjà un peu plus familier, passons à la suite !</p>
</div>
<div class="section" id="installons-rudder">
<h2><a class="toc-backref" href="#id2">Installons Rudder</a></h2>
<p>Rudder consiste en deux composants principaux. Le serveur, et les agents.</p>
<div class="section" id="serveur-rudder">
<h3><a class="toc-backref" href="#id3">Serveur Rudder</a></h3>
<p>Le server va compiler un nombre d'informations assez importantes, et notamment les différentes règles et techniques pour définir les ordres à envoyer aux agents.</p>
<p>Mieux vaut donc prévoir un serveur relativement costaud. 4Go de RAM me parait un minimum si vous compter gérer plus d'une 20aine de serveur.</p>
<p>En outre rudder conseille de séparer vos partitions, notamment /var où il écrira par défaut, car il peut générer beaucoup de données.</p>
<p>Lançons donc notre petite installation, pour du debian :</p>
<div class="highlight"><pre><span></span>wget --quiet -O- <span class="s2">"https://repository.rudder.io/apt/rudder_apt_key.pub"</span> <span class="p">|</span> sudo apt-key add -
<span class="nb">echo</span> <span class="s2">"deb http://repository.rudder.io/apt/5.0/ </span><span class="k">$(</span>lsb_release -cs<span class="k">)</span><span class="s2"> main"</span> > /etc/apt/sources.list.d/rudder.list
apt-get update
apt-get install rudder-server-root
</pre></div>
<p>Une fois l'installation terminée, rudder met à disposition un script pour permettre de configurer le serveur en répondant à quelques questions :</p>
<div class="highlight"><pre><span></span>/opt/rudder/bin/rudder-init
</pre></div>
<p>Notamment, pensez à configurer les réseaux qui seront <strong>autorisés à se connecter</strong> au serveur, surtout si vous compter l'utiliser sur des réseaux qui ne sont pas privés.</p>
<p>Finalement, le script vous fourni une URL où vous connecter à l'interface. Pour la première connexion, les identifiants sont tout simplement <cite>admin / admin</cite></p>
<p>Inutile de dire que je vous recommande de les changer 😋</p>
<p>Votre serveur est prêt, vous pouvez commencer à vous balader !</p>
</div>
<div class="section" id="agents-rudder">
<h3><a class="toc-backref" href="#id4">Agents Rudder</a></h3>
<p>Sans agent, le serveur ne vous sert pas à grand chose. Les agents sont les machines que vous souhaitez surveiller et qui viendront rendre des comptes au serveur.</p>
<p>Rudder fournit une <a class="reference external" href="https://docs.rudder.io/reference/5.0/installation/operating_systems.html#_for_rudder_nodes">liste de compatibilité</a>. plutôt importante. L'inscription au support payant permet de supporter des OS plus anciens ou exotiques, à vous de voir selon vos besoins.</p>
<p>Normalement de base votre serveur rudder devrait également être considéré comme un agent, après tout lui aussi doit être conforme.</p>
<p>Mais pour l'exemple, on va en installer un 2eme.</p>
<p>Sur une machine différente du serveur rudder :</p>
<div class="highlight"><pre><span></span>wget --quiet -O- <span class="s2">"https://repository.rudder.io/apt/rudder_apt_key.pub"</span> <span class="p">|</span> sudo apt-key add -
<span class="nb">echo</span> <span class="s2">"deb http://repository.rudder.io/apt/5.0/ </span><span class="k">$(</span>lsb_release -cs<span class="k">)</span><span class="s2"> main"</span> > /etc/apt/sources.list.d/rudder.list
apt-get update
apt-get install rudder-agent
</pre></div>
<p>Une fois l'agent installé, il ne démarre pas directement.</p>
<p>Il va falloir lui spécifier où est son serveur via le fichier <cite>/var/rudder/cfengine-community/policy_server.dat</cite>. Indiquez tout simplement l'IP ou le hostname du serveur rudder.</p>
<p>Une fois cela fait vous pouvez le démarrer :</p>
<div class="highlight"><pre><span></span>rudder agent start
</pre></div>
<p><strong>Note :</strong> cette commande est un wrapper pour les différents systèmes de gestion de services (initd, sysvinit, systemd, ...).
De plus pour éviter à un attaquant une désactivation trop facile, rudder installe diverses crons pour vérifier que l'agent tourne et le relancer si besoin.
Une fois lancé, il devient donc assez difficile de se débarrasser de l'agent sauf à le supprimer complètement 😉</p>
</div>
</div>
<div class="section" id="les-regles">
<h2><a class="toc-backref" href="#id5">Les règles</a></h2>
<p>Dans rudder, les <strong>règles</strong> sont l'état que vous souhaitez appliquer sur vos serveurs. Elles sont composées de <strong>techniques</strong> que vous pouvez combiner de différentes manières.</p>
<p>Il y en a une infinité selon vos besoins et votre imagination, mais la première chose à appréhender est que vous pouvez décider de les <strong>rendre obligatoires, ou simplement surveiller</strong>.</p>
<div class="section" id="audit-et-enforce">
<h3><a class="toc-backref" href="#id6">Audit et Enforce</a></h3>
<p>Ces 2 possibilités se présentent sous les mots clés Audit et Enforce.</p>
<p>En mode <strong>Audit</strong>, une règle se contentera de comparer ses ordres avec l'état réel du système, et de remonter les différences.
Cela vous permet notamment de <strong>surveiller</strong> l'état d'un serveur, voir s'il change de configuration, tester vos techniques, etc.</p>
<p>En mode <strong>Enforce</strong> par contre, on est beaucoup plus rentre-dedans. Dans ce mode, si un système diverge des techniques qui doivent s'appliquer, alors rudder remontera toujours l'information, mais surtout il prendra la décision de <strong>corriger</strong> le problème.</p>
<p>Cela peut se traduire par des suppressions d'utilisateurs nouvellement créés, la modification des clefs SSH déployés, la reinitialisation de telle ou telle configuration sur le serveur, tout dépend de vos règles.</p>
<p>A l'installation, rudder déploie des règles en Enforce qui vont lui permettre de <strong>gérer les agents</strong> (vérifier la configuration de l'agent, le mettre à jour, s'asurer qu'il est lancé, ...).</p>
<p>Ces règles sont utiles notamment pour rendre plus difficile à un attaquant la désactivation de rudder.</p>
<div class="figure">
<img alt="Les règles de configuration de l'agent rudder" src="https://blog.victor-hery.com/images/rudder-outil-conformite/rudder_agent_basic.png" style="width: 500px;"/>
<p class="caption">Les règles de configuration de l'agent rudder</p>
</div>
<p>Par la suite vous allez pouvoir ajouter vos propres règles, et pouvoir choisir si vous souhaitez qu'elles fassent des actions (Enforce) ou se contentent de surveiller les problèmes (Audit).</p>
</div>
<div class="section" id="les-techniques">
<h3><a class="toc-backref" href="#id7">Les Techniques</a></h3>
<p>Les techniques sont la brique élémentaire qui va vous permettre de construire vos règles à appliquer. Rudder en contient un certain nombre de base, mais il existe également un éditeur qui vous permet de créer les vôtres de manière plutôt simple.</p>
<p>Voici quelques exemples de techniques existantes qui vous permettent de jouer un peu :</p>
<div class="figure">
<img alt="Une technique pour forcer un texte dans votre motd" src="https://blog.victor-hery.com/images/rudder-outil-conformite/technique_motd.png" style="width: 80%;"/>
<p class="caption">Une technique qui vous permet de forcer un texte dans votre motd</p>
</div>
<div class="figure">
<img alt="Une technique pour vous assurer qu'une clef ssh est présente" src="https://blog.victor-hery.com/images/rudder-outil-conformite/technique_ssh.png" style="width: 80%;"/>
<p class="caption">Une technique qui vous permet de vous assurer que votre clef ssh est présente pour la connexion</p>
</div>
<div class="figure">
<img alt="Une technique pour vérifier qu'un utilisateur est bien créé" src="https://blog.victor-hery.com/images/rudder-outil-conformite/technique_user.png" style="width: 80%;"/>
<p class="caption">Une technique qui vous permet de créer un utilisateur et de vous assurer qu'il reste présent</p>
</div>
<p>Ce sont là <strong>quelques exemples</strong>, mais là où cela devient vraiment puissant, c'est que ces techniques peuvent tout à fait se combiner.</p>
<p>Par exemple, rien ne vous empêche de vous assurer qu'un utilisateur "sauvegarde" existe sur vos serveur, et qu'il autorise la connexion avec la clef ssh spécifique de votre outil de backup.</p>
<p>Ou bien que l'utilisateur "sauvegarde" n'est présent que sur vos hyperviseurs, pour permettre de sauvegarder vos machines virtuelles.</p>
<p>Ou encore que le stagiaire dispose d'un compte sur les serveurs de développement, mais <strong>jamais sur les serveurs de production</strong>.</p>
<p>Tout en étant assuré que le motd contient bien les infos légales prévenant que la connexion n'est pas autorisée, et que personne n'a été le supprimer pour être blindé en cas d'audit.</p>
<p>Vous pouvez aussi déployer sur <strong>l'intégralité de vos 3000 serveurs</strong> la clef SSH de la nouvelle recrue, pourquoi pas avec des droits restreints, en moins de 5 minutes 😉</p>
</div>
</div>
<div class="section" id="enregistrer-un-serveur">
<h2><a class="toc-backref" href="#id8">Enregistrer un serveur</a></h2>
<p>Pour éviter de vous retrouver à déployer vos règles n'importe où, rudder demande à ce que les nouveaux serveurs soient <strong>enregistrés</strong> avant de pouvoir être utilisés.</p>
<p>Il est possible de gérer cet enregistrement plus ou moins automatiquement, mais par défaut c'est manuel.</p>
<p>Cela signifie que dès qu'un serveur a son agent qui démarre, il va apparaître dans l'interface de rudder, et vous pourrez définir si oui ou non il est légitime, l'assigner à des groupes, lui indiquer des règles, etc.</p>
<p>Vous pouvez également définir des <strong>templates</strong> qui permettront de déployer directement des règles sur certains types de serveurs. Par exemple, s'il s'agit d'un hyperviseur ou d'une VM, s'il est formaté d'une certaine manière, s'il dispose d'un OS particulier, si un serveur web est installé, ...</p>
<p>Rien ne vous empêche donc de déployer votre serveur avec votre outil de déploiement préféré (ansible, salt, etc), lui installer sa suite logicielle nécessaire, puis laisser ensuite rudder ajouter les utilisateurs, configurer les sauvegardes, préparer tout le bousin légal, remonter un inventaire complet de l'intégralité du système.</p>
<p>Et en bonus, rudder vous assure que tout reste en l'état pendant la durée de vie du serveur et vous sors de jolis diagrammes en camembert pour vous montrer des aperçus de ce qui se passe 😄</p>
<p>Si vous souhaitez enregistrer en masse des serveurs existants, par exemple parce que vous déployez rudder sur votre infra existante, je vous conseille tout de même de configurer vos règles en <strong>Audit</strong> pour être sur de ne rien casser et vous permettre de faire un point sur l'état de l'infrastructure.</p>
</div>
<div class="section" id="conclusion">
<h2><a class="toc-backref" href="#id9">Conclusion</a></h2>
<p>J'ai présenté dans cet article les concepts de base de la compliance et de comment utiliser rudder pour permettre de répondre à cette problématique.</p>
<p>C'est un outil vraiment très pratique et qui laisse une grande part à l'imagination pour gérer votre infrastructure avec la souplesse de ses techniques, je l'utilise personnellement depuis presque 4 ans au quotidien et j'en suis vraiment très content.</p>
<p>Avoir un pool de serveurs à gérer n'a jamais été aussi agréable !</p>
<p>Si cet article vous a plu, ou si vous souhaitez que j'aborde plus en détails certains points de rudder, n'hésitez pas à laisser un commentaire !</p>
</div>
Python et virtualenv avec pyenv2019-04-23T06:43:00+02:002019-04-23T06:43:00+02:00Victortag:blog.victor-hery.com,2019-04-23:/2019/04/python-et-pyenv.html
<h1 id="une-petite-introduction">Une petite introduction</h1>
<p><a href="https://github.com/pyenv/pyenv/">pyenv</a> est un logiciel de gestion de <strong>version python</strong>. Ça parait simple ! Mais pourquoi me direz vous ? </p>
<p>Tout ceux qui ont déjà développés avec python savent que c'est assez vite le bordel entre python 2 et python 3. La version 3 amène énormément de changement, et en …</p>
<h1 id="une-petite-introduction">Une petite introduction</h1>
<p><a href="https://github.com/pyenv/pyenv/">pyenv</a> est un logiciel de gestion de <strong>version python</strong>. Ça parait simple ! Mais pourquoi me direz vous ? </p>
<p>Tout ceux qui ont déjà développés avec python savent que c'est assez vite le bordel entre python 2 et python 3. La version 3 amène énormément de changement, et en conséquence cela fait des années qu'elle n'est pas massivement adoptée...<br/>
De nombreux logiciels ne sont encore compatibles qu'avec python 2.7, et impliquent un travail de développement assez conséquent pour être compatible avec python 3, sans parler d'être compatible avec les 2 versions simultanément.</p>
<p>Il est donc devenu quasiment standard de posséder sur un système <strong>2 versions de python</strong>, la dernière 2.7 et la dernière 3.5, dans l'optique de gérer les différents logiciels selon leurs besoins.</p>
<p>En outre python possède un concept relativement unique et très intéressant : le virtualenv, dont vous pourrez trouver une excellente intro ici : <a href="https://noskillbrain.fr/2017/12/26/virtualenv-wrappervirtualenv/">virtualenv - Inversion n°42 du génome</a>.<br/>
Ce système permet d'utiliser un environnement python dédié à un logiciel, avec ses propres librairies, afin de répondre parfaitement aux prérequis d'un logiciel, même s'il utilise des versions de librairies non inclues dans votre système. </p>
<p>Tout ceci, bien que très intéressant (de mon point de vue 😂) est quand même globalement <strong>un beau merdier</strong>, faut dire ce qui est.<br/>
Et en plus python a officiellement annoncé que la version 2.7 ne serait plus <a href="https://pythonclock.org/">supportée à échéance 2020</a>.</p>
<p>C'est ici qu'intervient <strong>pyenv</strong>, en tant que gestionnaire de version python et en bonus de virtualenv !</p>
<h1 id="passons-a-linstallation">Passons à l'installation</h1>
<h2 id="prerequis">Prérequis</h2>
<p>Les prérequis sont listés sur le <a href="https://github.com/pyenv/pyenv/wiki#suggested-build-environment">wiki de pyenv</a> et disponibles pour différents OS.</p>
<p>Pour les plus classiques, sous Debian : </p>
<div class="highlight"><pre><span></span><code>sudo apt-get update<span class="p">;</span> sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
</code></pre></div>
<p>ou Fedora :</p>
<div class="highlight"><pre><span></span><code><span class="err">sudo dnf install -y make gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel</span>
</code></pre></div>
<p>Notez que ces prérequis ne concernent pas l'installation de pyenv lui-même, mais ce qui est nécessaire pour l'utiliser, et notamment compiler les versions python :-)</p>
<h2 id="installons-pyenv">Installons pyenv</h2>
<p>L'installation reste somme toute classique. Vous pouvez passer directement par le <a href="https://github.com/pyenv/pyenv/#installation">dépôt git</a>, ou par brew si vous utilisez Mac OSX.</p>
<p>Cela dit, je vous conseille d'utiliser le petit <strong><a href="https://github.com/pyenv/pyenv-installer">wrapper</a></strong> réalisé par le développeur pour gérer l'installation de pyenv. En effet il présente l'avantage outre le fait d'installer pyenv, d'activer quelques <strong>modules</strong> bien pratiques, notamment celui permettant de jouer avec les virtualenv !</p>
<div class="highlight"><pre><span></span><code>$ curl https://pyenv.run <span class="p">|</span> bash
</code></pre></div>
<p>Vous me direz que c'est très mal d'exécuter des scripts bash depuis le net de cette façon ! Je vous dirais que oui en effet, mais j'ai ici pris la peine de le lire, et il se contente de faire <strong>quelques git clone</strong>, rien de répréhensible.</p>
<p>Je vous invite à ne pas me faire confiance et à aller regarder par vous même 😘</p>
<p>Une fois le script exécuté et comme il vous invite à le faire, ajoutez dans votre fichier <code>~/.bashrc</code> les lignes suivantes si elles ne sont pas déjà présentes : </p>
<div class="highlight"><pre><span></span><code><span class="nb">export</span> <span class="nv">PATH</span><span class="o">=</span><span class="s2">"~/.pyenv/bin:</span><span class="nv">$PATH</span><span class="s2">"</span>
<span class="nb">eval</span> <span class="s2">"</span><span class="k">$(</span>pyenv init -<span class="k">)</span><span class="s2">"</span>
<span class="nb">eval</span> <span class="s2">"</span><span class="k">$(</span>pyenv virtualenv-init -<span class="k">)</span><span class="s2">"</span>
</code></pre></div>
<p>Ces lignes, exécutées à chaque ouverture d'un shell bash, vont permettre à pyenv d'insérer dans votre PATH les chemins vers toutes ses différentes versions installées.<br/>
Vous y gagnez en plus <strong>une auto-completion</strong> bien pratique.</p>
<h1 id="quoiquon-en-fait">Quoiqu'on en fait ?</h1>
<p>Bien, pyenv est installé, et maintenant ? Maintenant, jouons mes amis, jouons !</p>
<h2 id="versions-python">Versions python</h2>
<p>De base avec pyenv, vous verrez uniquement la version python de base livrée avec votre système :</p>
<div class="highlight"><pre><span></span><code>$ pyenv versions
* system <span class="o">(</span><span class="nb">set</span> by /home/victor/.pyenv/version<span class="o">)</span>
</code></pre></div>
<p>Cependant, vous pouvez en installer de nouvelles très facilement. Je vous conseille à minima d'activer les versions <code>2.7.15</code> et <code>3.7.2</code>, dernières versions en date lors de <strong>l'écriture</strong> de cet article.<br/>
Bien entendu, n'hésitez pas à adapter avec vos besoins et/ou les dernières versions lors de votre <strong>lecture</strong> de cet article 😋 </p>
<div class="highlight"><pre><span></span><code>pyenv install <span class="m">2</span>.7.15
pyenv install <span class="m">3</span>.7.2
</code></pre></div>
<p><strong>Attention</strong>, pyenv ne gère que les versions qu'il connait ! Elles peuvent différer des dernières versions sorties par les développeurs de python tant que pyenv n'aura pas été mis à jour (à la manière d'un <code>apt-get update</code>).<br/>
Il peut aussi s'écouler un peu de temps entre la sortie d'un patch des développeurs de python et son intégration dans pyenv.</p>
<p>Vous pouvez lister les versions connues avec : </p>
<div class="highlight"><pre><span></span><code>pyenv install --list
</code></pre></div>
<p>Et vous pouvez mettre à jour pyenv avec :</p>
<div class="highlight"><pre><span></span><code>pyenv update
</code></pre></div>
<p>Une fois vos versions préférées de python installées, vous pouvez vérifier que tout est ok :</p>
<div class="highlight"><pre><span></span><code>$ pyenv versions
* system <span class="o">(</span><span class="nb">set</span> by /home/victor/.pyenv/version<span class="o">)</span>
<span class="m">2</span>.7.15
<span class="m">3</span>.7.2
</code></pre></div>
<p>Le petit <strong>asterisk</strong> indique la version actuellement configurée par défaut.</p>
<h2 id="virtualenvs">Virtualenv(s)</h2>
<p>Avec au moins une version python d'installée, on va pouvoir commencer à jouer un peu avec les <strong>virtualenv</strong> !<br/>
Pour rappel, un virtualenv permet de mettre en place un environnement python isolé, où vous pourrez installer les librairies spécifiques dont vous avez besoin pour un logiciel particulier.</p>
<p>Mettons que comme dans l'article de <a href="https://noskillbrain.fr/2017/12/26/virtualenv-wrappervirtualenv/">noskillbrain</a> vous souhaitez utiliser plusieurs versions d'Ansible.<br/>
On peut tout simplement créer <strong>2 virtualenv</strong>, un pour <code>ansible 2.6</code> et un pour <code>ansible 2.7</code>, en utilisant python <code>3.7.2</code> :</p>
<div class="highlight"><pre><span></span><code>pyenv virtualenv <span class="m">3</span>.7.2 ansible-26
pyenv virtualenv <span class="m">3</span>.7.2 ansible-27
</code></pre></div>
<p>J'ai ici créé 2 virtualenvs, mais ils sont pour l'instant vides :</p>
<div class="highlight"><pre><span></span><code>$ pyenv virtualenvs
<span class="m">3</span>.7.2/envs/ansible-26 <span class="o">(</span>created from /home/victor/.pyenv/versions/3.7.2<span class="o">)</span>
<span class="m">3</span>.7.2/envs/ansible-27 <span class="o">(</span>created from /home/victor/.pyenv/versions/3.7.2<span class="o">)</span>
ansible-26 <span class="o">(</span>created from /home/victor/.pyenv/versions/3.7.2<span class="o">)</span>
ansible-27 <span class="o">(</span>created from /home/victor/.pyenv/versions/3.7.2<span class="o">)</span>
</code></pre></div>
<p>Et comme pyenv a le bon goût d'auto-compléter ses commandes, quelques tabulations vous permette d'activer rapidement un env :</p>
<div class="highlight"><pre><span></span><code><span class="o">[</span>victor:~<span class="o">]</span> $ pyenv activate ansible-26
<span class="o">[</span>victor:~<span class="o">]</span> <span class="o">[</span>ansible-26<span class="o">]</span> $
</code></pre></div>
<p>Une fois dans votre env, vous pouvez tranquillement installer votre version d'ansible en utilisant pip :</p>
<div class="highlight"><pre><span></span><code>$ pip install <span class="nv">ansible</span><span class="o">==</span><span class="m">2</span>.6
</code></pre></div>
<p>Vous pouvez également directement changer de virtualenv :</p>
<div class="highlight"><pre><span></span><code>pyenv activate ansible-27
</code></pre></div>
<p>Ou encore sortir du virtualenv </p>
<div class="highlight"><pre><span></span><code><span class="o">[</span>victor:~<span class="o">]</span> <span class="o">[</span>ansible-26<span class="o">]</span> $ pyenv deactivate
<span class="o">[</span>victor:~<span class="o">]</span> $
</code></pre></div>
<h1 id="conclusion">Conclusion</h1>
<p>Comme vous le voyez, gérer un virtualenv avec pyenv est vraiment très simple (sans parler de gérer des versions python 😄).</p>
<p>Vous pouvez maintenant gérer vos virtualenv facilement, sans devoir ajouter des alias dans votre bashrc pour chacun d'entre eux ou vous souvenir des chemin à activer 😉.</p>
<p>pyenv a d'autres mécanismes sympathiques, comme la possibilité d'activer automatiquement des versions par répertoire, exécuter des logiciels avec une version spécifique, etc.<br/>
Je n'en parlerai pas dans cette introduction, mais n'hésitez pas à parcourir le <a href="https://github.com/pyenv/pyenv">github</a> du développeur et son wiki associé, plein de bonnes idées.</p>Installer un serveur SFTP avec ProFTPd2019-03-26T06:48:00+01:002019-03-26T06:48:00+01:00Victortag:blog.victor-hery.com,2019-03-26:/2019/03/installer-sftp-proftpd.html
<h1 id="pourquoi-sftp">Pourquoi sftp ?</h1>
<p>Le protocole <a href="https://fr.wikipedia.org/wiki/File_Transfer_Protocol">FTP</a> est très utilisé dans le monde de l'hébergement
web (mais pas que) pour transférer des fichiers grâce à sa robustesse et sa simplicité.</p>
<p>Cependant, il n'est pas sécurisé par défaut, et tous les transferts se font donc en clair, ce qui à mon sens est …</p>
<h1 id="pourquoi-sftp">Pourquoi sftp ?</h1>
<p>Le protocole <a href="https://fr.wikipedia.org/wiki/File_Transfer_Protocol">FTP</a> est très utilisé dans le monde de l'hébergement
web (mais pas que) pour transférer des fichiers grâce à sa robustesse et sa simplicité.</p>
<p>Cependant, il n'est pas sécurisé par défaut, et tous les transferts se font donc en clair, ce qui à mon sens est l'un de ses plus gros défaut.<br/>
Comme pour pas mal d'autre protocoles, il existe FTPs qui rajoute une couche SSL par dessus FTP, mais de la même manière que les autres protocoles,
elle reste relativement complexe à configurer, nécessite un certificat SSL à renouveler, etc.</p>
<p>C'est pourquoi nous allons parler ici de <a href="https://fr.wikipedia.org/wiki/SSH_File_Transfer_Protocol">sftp</a> qui se sert de la couche SSH déjà présente sur
la plupart des serveurs Linux pour sécuriser FTP.</p>
<p>Plusieurs avantages à la fois par rapport à FTPs et par rapport à scp (qui est le système de transfert intégré à ssh)</p>
<ul>
<li>On utilise des clefs ssh pour le chiffrement, pas de renouvellement, pas de signature par un tiers</li>
<li>On peut utiliser toutes les commandes de manipulations de fichier de FTP, plus avancées que scp</li>
<li>La configuration d'un chroot est ultra simple car elle peut s'appuyer sur les mécanismes intégrés de FTP</li>
<li>On peut utiliser une clef SSH pour l'authentification</li>
<li>On élimine le problème de connexion passif/actif de FTP</li>
<li>La plupart des logiciels FTP du marché supportent également sftp</li>
</ul>
<p>Dans cet article qui se veut un pense-bête, j'utiliserai (proftpd)[http://proftpd.org/] pour implémenter sftp car la configuration est plutôt intuitive et simple, facile à automatiser.</p>
<h1 id="installation-de-proftpd">Installation de proftpd</h1>
<h2 id="installation">Installation</h2>
<p><strong>Note</strong> Ce tutoriel se base sur Debian car je n'ai pas de centos sous la main. Néanmoins, mis à part le gestionnaire de paquet et peut être l'emplacement des fichiers de conf, la configuration est similaire. </p>
<p>Proftpd étant supporté par la plupart des distributions connues, l'installation se fait via le gestionnaire de paquets :</p>
<div class="highlight"><pre><span></span><code>sudo apt-get install proftpd
</code></pre></div>
<p>Une fois installé, éditez le fichier <code>/etc/proftpd/proftpd.conf</code> et modifiez le <code>ServerName</code>. Cela représentera le nom du serveur présenté lors de la connexion.</p>
<div class="highlight"><pre><span></span><code>ServerName <span class="s2">"ftp.monserveur.tld"</span>
</code></pre></div>
<h2 id="chroot">chroot</h2>
<p>L'un des mécanismes les plus plaisant de proftpd est sa capacité à permettre de manière très simple l'utilisation d'un <a href="https://fr.wikipedia.org/wiki/Chroot">chroot</a>.</p>
<p>Concrètement, l'utilisateur sera "bloqué" dans son répertoire parent sans aucun moyen d'en sortir, et notamment sans moyen d'aller se balader sur le reste du système.<br/>
Il ne pourra voir que le répertoire à l'intérieur duquel vous l'avez restreint, et ses sous répertoires.</p>
<p>Pour cela, éditez le fichier <code>/etc/proftpd/proftpd.conf</code>. Trouvez la directive <code>DefaultRoot</code>, qui est par défaut commentée (par un <code>#</code>).</p>
<p>Décommentez la directive :</p>
<div class="highlight"><pre><span></span><code>DefaultRoot ~
</code></pre></div>
<p>Et c'est tout !</p>
<p>Bien entendu n'oubliez pas de redémarrer proftpd après cette modification.</p>
<div class="highlight"><pre><span></span><code>systemctl restart proftpd.service
</code></pre></div>
<h1 id="activation-de-sftp">Activation de sftp</h1>
<p>Une fois ces préambules terminés, on va attaquer sftp lui-même.</p>
<p>Pour cela on va utiliser une technique très similaire aux "virtual hosts" d'un serveur web.</p>
<p>Créez le fichier <code>etc/proftpd/conf.d/sftp.conf</code> et éditez le. On va le remplir avec un hôte virtuel proftpd :</p>
<div class="highlight"><pre><span></span><code><IfModule mod_sftp.c>
SFTPEngine on
Port <span class="m">2222</span>
SFTPLog /var/log/proftpd/sftp.log
<span class="c1"># On utilise les même clefs ssh que celles du serveur openssh</span>
SFTPHostKey /etc/ssh/ssh_host_rsa_key
SFTPHostKey /etc/ssh/ssh_host_dsa_key
SFTPAuthMethods publickey password
SFTPAuthorizedUserKeys file:/etc/proftpd/authorized_keys/%u
RequireValidShell off
AuthOrder mod_auth_file.c
<span class="c1"># Enable compression</span>
SFTPCompression delayed
</IfModule>
</code></pre></div>
<h2 id="signification-de-la-configuration">Signification de la configuration</h2>
<p>La configuration que l'on indique pour sftp se construit de la manière suivante :</p>
<ul>
<li><code>IfModule</code> n'active ce bloc que si proftpd contient le module sftp (ce qui est le cas dans les paquets en général)</li>
<li><code>SFTPEngine on</code> va activer sftp</li>
<li><code>Port</code> vous permet de spécifier le port d'écoute. Choisissez un port différent du FTP standard (port 21)</li>
<li><code>SFTPLog</code> vous permet de spécifier un fichier de log spécial pour les connexions sftp</li>
<li><code>SFTPHostKey</code> va définir quelles clefs SSH utiliser pour chiffrer la connexion</li>
<li><code>SFTPAuthMethods</code> permet de spécifier quelles méthodes sont authorisées pour la connexion à sftp<ul>
<li><code>publickey</code> va vous permettre d'utiliser un fichier de clef ssh publiques</li>
<li><code>password</code> va vous permettre d'utiliser le système utilisateur/mot de passe classique de votre serveur ftp</li>
</ul>
</li>
<li><code>SFTPAuthorizedUserKeys</code> est le fichier qui contient les clefs publiques pour autoriser la connexion</li>
<li><code>RequireValidShell</code> va désactiver le fait que vos utilisateurs doivent disposer d'un shell valide (utile pour les utilisateurs virtuels)</li>
<li><code>AuthOrder</code> définit quel type d'authentification utiliser en priorité. Ici un fichier pour nos utilisateurs virtuels</li>
<li><code>SFTPCompression</code> définit de quelle manière compresser le flux pendant la connexion. <code>delayed</code> signifie que sftp n'activera la compression que si l'authentification est réussie</li>
</ul>
<h1 id="utilisateurs-virtuels">Utilisateurs virtuels</h1>
<p>Un autre des mécanismes sympas de proftpd, c'est sa capacité à gérer les utilisateurs virtuels.</p>
<p>Avec la conf ci-dessus, vous pouvez vous connecter avec des utilisateurs systèmes, des utilisateurs qui existent sur votre serveur.</p>
<p>Outre le fait que c'est gênant niveau sécurité (il ont un UID/GID existant, ils peuvent tenter d'accéder à un shell, ...), c'est peu pratique si vous avez beaucoup d'utilisateurs.<br/>
Pour compenser ce défaut, on va utiliser des utilisateurs virtuels, c'est à dire qu'ils n'existent que du point de vue de proftpd.</p>
<p>Ici j'utiliserai une configuration assez simple avec des utilisateurs dans des fichiers, mais sachez qu'il est possible de brancher proftpd à une base de données pour récupérer les utilisateurs.</p>
<h2 id="de-la-consideration-sur-les-uid">De la considération sur les uid</h2>
<p>Pour des utilisateurs virtuels, rien n'oblige à utiliser un <code>uid</code> correspondant à un véritable utilisateur du système, puisqu'il n'existe que dans proftpd.</p>
<p>Néanmoins, il est <strong>important</strong> de prendre en compte que cet utilisateur va créer des fichiers sur le système, qu'ils auront l'uid de l'utilisateur, et qu'il va donc y avoir intéraction entre un espace virtuel et le système tout ce qu'il y a de plus physique.</p>
<p>Quelques considérations sont donc à garder en tête</p>
<ul>
<li>N'utilisez pas l'uid <code>0</code> qui correspond à root</li>
<li>Utilisez un uid au dessus de 1000, ceux en dessous étant réservés aux services du système</li>
<li>Si vous devez intéragir avec un service (serveur web par exemple), vous pouvez utiliser son uid pour que l'utilisateur ait le droit de toucher aux fichiers.</li>
<li><strong>N'utilisez pas l'uid <code>0</code> qui correspond à root !</strong></li>
<li>Évitez d'utiliser un uid correspondant à un utilisateur existant pour éviter les fuites</li>
<li>N'oubliez pas que le répertoire de l'utilisateur virtuel devra coller à l'uid virtuel ou il ne pourra rien écrire</li>
<li>N'utilisez-pas-l'uid <code>0</code> qui-correspond-à-root. Merci. 😘</li>
<li>Il en va de même pour le GID (groupe id) que pour l'uid</li>
</ul>
<h2 id="activer-les-utilisateurs-virtuels-sur-proftpd">Activer les utilisateurs virtuels sur proftpd</h2>
<p>Pour permettre d'utiliser des fichiers contenant nos utilisateurs virtuels, on va créer le fichier <code>/etc/proftpd/conf.d/auth.conf</code>.</p>
<p>À l'intérieur indiquez :</p>
<div class="highlight"><pre><span></span><code>AuthGroupFile /etc/proftpd/ftp.group
AuthUserFile /etc/proftpd/ftp.passwd
</code></pre></div>
<p>Ensuite vous pouvez créer vos utilisateurs avec la commande suivante :</p>
<div class="highlight"><pre><span></span><code>ftpasswd --passwd --file<span class="o">=</span>/etc/proftpd/ftp.passwd --uid<span class="o">=</span>UID --home<span class="o">=</span>/path/to/home --shell<span class="o">=</span>/bin/false --sha256 --name<span class="o">=</span>USERNAME
</code></pre></div>
<p>Un prompt vous demandera de taper le mot de passe de votre utilisateur.</p>
<ul>
<li><code>--passwd</code> indique que l'on créé un utilisateur à stocker dans un fichier AuthPasswd</li>
<li><code>--file</code> spécifie le fichier où stocker l'utilisateur</li>
<li><code>--uid</code> l'uid de votre utilisateur, selon votre choix précédent</li>
<li><code>--home</code> le répertoire où votre utilisateur sera restreint</li>
<li><code>--shell</code> par sécurité, on va désactiver le shell pour l'utilisateur</li>
<li><code>--sha256</code> le mot de passe doit être chiffré en sha256</li>
<li><code>--name</code> est bien sûr le nom de votre utilisateur</li>
</ul>
<p><strong>Note :</strong> ici on créé un groupe par défaut qui a le même gid que l'uid utilisateur.<br/>
Pour affiner les droits, on peut ensuite créer un groupe spécifique :</p>
<div class="highlight"><pre><span></span><code>ftpasswd --group --file<span class="o">=</span>/etc/proftpd/ftp.group --gid<span class="o">=</span>GID --member<span class="o">=</span>USERNAME1 --member<span class="o">=</span>USERNAME2 --name<span class="o">=</span>GROUPE1
</code></pre></div>
<ul>
<li><code>--group</code> indique que l'on va créer un groupe à stocker dans un fichier AuthGroup</li>
<li><code>--file</code> est le fichier où stocker ce groupe</li>
<li><code>--gid</code> le groupe id à utiliser pour votre groupe</li>
<li><code>--member</code> la liste des utilisateurs à inclure dans le groupe. Plusieurs occurences permettent d'ajouter plusieurs utilisateurs</li>
<li><code>--name</code> le nom de votre groupe</li>
</ul>
<p>Après ça, vous pouvez utiliser votre serveur ftp pour vous connecter en sftp de manière sécurisé !</p>Ceph - utiliser le reste d'un disque partitionné2019-02-26T06:53:00+01:002019-02-26T06:53:00+01:00Victortag:blog.victor-hery.com,2019-02-26:/2019/02/ceph-utiliser-disque-restant.html
<h1 id="introduction-et-disclaimer">Introduction et disclaimer</h1>
<p>Parfois sur un serveur, on se retrouve avec un disque de grande capacité qui ne vous sert à rien, parce que par exemple vous avez juste besoin de quelques centaines de Go pour installer un système.</p>
<p>Si vous utilisez en outre un système de stockage distribué (ici …</p>
<h1 id="introduction-et-disclaimer">Introduction et disclaimer</h1>
<p>Parfois sur un serveur, on se retrouve avec un disque de grande capacité qui ne vous sert à rien, parce que par exemple vous avez juste besoin de quelques centaines de Go pour installer un système.</p>
<p>Si vous utilisez en outre un système de stockage distribué (ici <a href="https://ceph.com">ceph</a>), cela rend cette perte encore plus dommage, puisque la tentation est grande d'utiliser le reste du disque pour l'intégrer au cluster.</p>
<p>Avec ceph, c'est possible !<br/>
En effet comme il se sert de partitions toute simple et non d'un disque entier, il est possible de le nourrir avec ce qu'il reste d'espace sur votre disque.</p>
<p>Il y a bien sûr des contraintes que l'on va détailler dans les disclaimers suivants.</p>
<h2 id="disclaimer-1">Disclaimer 1</h2>
<p>Mieux vaut que la taille restante de votre disque soit proche de celle des autres disques du cluster.</p>
<p><strong>Ajouter 100Go de disque à un cluster utilisant des disques de 3To n'a au mieux aucun intérêt et au pire peut être risqué !</strong></p>
<h2 id="disclaimer-2">Disclaimer 2</h2>
<p><strong>GROS DISCLAIMER</strong></p>
<p>Utiliser le disque où il y a votre système installé va partager les IO du disque entre ceph et l'OS ! </p>
<p>Ceph peut être un très gros consommateur de lecture/écriture, il est donc <strong>important</strong> de ne faire ça que si votre système a besoin de peu d'io.</p>
<ul>
<li>Ne le faites pas si vous utilisez un disque lent (5400trs/min ? c'est mort. 7200 trs/min ? Ça peut passer si votre OS n'écrit rien)</li>
<li>Ne le faites pas si votre OS utilise de nombreux IO (service de BDD installé dessus, nombreux logs, ...)</li>
<li>Surveillez vos IO et la charge dans le temps après la configuration</li>
<li>Ne le faites pas si vous ne savez pas ce que vous faites :kissing:hearth:</li>
</ul>
<h1 id="manipulations">Manipulations</h1>
<p>L'idée est simple. On va formater le disque à la main et s'en servir pour l'intégrer dans ceph.</p>
<p>Comme toute idée simple, le potentiel de ratage est important, je vais donc volontairement détailler les choses auxquelles faire attention.</p>
<p>Ouais je sais je suis un peu chiant, que voulez vous, c'est l'apprentissage de la vie en production qui parle :-D</p>
<h2 id="hypotheses">Hypothèses</h2>
<p><strong>À lire</strong></p>
<p>Je pars ici du principe que les binaires ceph sont déjà installés sur votre système (si par exemple vous utilisez un autre disque du serveur pour ceph)<br/>
Si ce n'est pas le cas, commencez par attaquer la <a href="http://docs.ceph.com/docs/master/install/">documentation</a> :-)</p>
<p>Je vais également prendre un <strong>exemple</strong> de partitionnement existant pour la numérotation des partitions.<br/>
<strong>Adaptez</strong> cet exemple avec votre situation pour éviter d'écraser des partitions existantes !</p>
<h2 id="notre-exemple">Notre exemple</h2>
<p>Dans cet exemple on va se baser sur un disque de 3To qui possède déjà 4 partitions :</p>
<div class="highlight"><pre><span></span><code><span class="c1"># fdisk -l /dev/sda</span>
Disk /dev/sda: <span class="m">2</span>.7 TiB, <span class="m">3000592982016</span> bytes, <span class="m">5860533168</span> sectors
Device Start End Sectors Size Type
/dev/sda1 <span class="m">4096</span> <span class="m">67112959</span> <span class="m">67108864</span> 32G Linux swap
/dev/sda2 <span class="m">67112960</span> <span class="m">68161535</span> <span class="m">1048576</span> 512M Linux filesystem
/dev/sda3 <span class="m">68161536</span> <span class="m">277876735</span> <span class="m">209715200</span> 100G Linux filesystem
/dev/sda4 <span class="m">2048</span> <span class="m">4095</span> <span class="m">2048</span> 1M BIOS boot
</code></pre></div>
<p>Comme vous le voyez on utilise déjà environ 132Go, on va donc s'occuper de récupérer les 2,8To restant.</p>
<p><strong>Là encore, pensez à adapter les numéros de partitions dans la suite !</strong></p>
<p>On va également utiliser <strong>sgdisk</strong> car c'est l'outil de configuration qu'utilise ceph lui-même quand il doit préparer un disque complet, et il fait le taf exactement comme les binaires ceph s'attendent à le voir fait.</p>
<h2 id="partitionnement">Partitionnement</h2>
<p>Ceph a besoin d'une partition de type <code>Ceph OSD</code> d'une centaine de Mo pour ses méta données, qui <strong>doit</strong> porter le nom <code>ceph data</code>.<br/>
On va donc lui créer une 5eme partition nommée <code>ceph data</code> de type <code>4fbd7e29-9d25-41b8-afd0-062c0ceff05d</code>. (cf <a href="https://en.wikipedia.org/wiki/GUID_Partition_Table">wikipedia</a>)</p>
<p><strong>Ici modifiez les <code>5:</code> pour coller avec votre propre numéro de partition.</strong> Il y a quatre <code>5:</code> à changer.</p>
<div class="highlight"><pre><span></span><code>sgdisk --new<span class="o">=</span><span class="m">5</span>:0:+100M --change-name<span class="o">=</span><span class="s2">"5:ceph data"</span> --partition-guid<span class="o">=</span><span class="m">5</span>:<span class="k">$(</span>uuidgen -r<span class="k">)</span> --typecode<span class="o">=</span><span class="m">5</span>:4fbd7e29-9d25-41b8-afd0-062c0ceff05d -- /dev/sda
partprobe <span class="c1"># partprobe nous permet ici de relire à chaud les partitions d'un disque en cours d'utilisation.</span>
</code></pre></div>
<p>On va ensuite créer une 6ème partition utilisant tout le reste du disque.<br/>
Celle-ci doit s'appeler <code>ceph block</code> et être de type <code>CAFECAFE-9B03-4F30-B4C6-B4B80CEFF106</code> (oui oui cafe cafe, là encore confer <a href="https://en.wikipedia.org/wiki/GUID_Partition_Table">wikipedia</a>)</p>
<p><strong>Là encore</strong> modifiez les numéros <code>6:</code> pour coller à votre partition. Il y a trois <code>6:</code> à changer cette fois.</p>
<div class="highlight"><pre><span></span><code>sgdisk --largest-new<span class="o">=</span><span class="m">6</span> --change-name<span class="o">=</span><span class="s2">"6:ceph block"</span> --typecode<span class="o">=</span><span class="m">6</span>:CAFECAFE-9B03-4F30-B4C6-B4B80CEFF106 -- /dev/sda
partprobe
</code></pre></div>
<h2 id="activation">Activation</h2>
<p>Une fois le partitionnement terminé, il ne nous reste plus qu'à dire à ceph d'utiliser le disque :</p>
<p><strong>Comme toujours</strong>, modifiez vos partitions pour coller à votre cas ! Ici <code>sda5</code> représente la partition ceph-osd, <code>sda6</code> le reste du disque.</p>
<div class="highlight"><pre><span></span><code>ceph-disk prepare --bluestore /dev/sda5 /dev/sda5 /dev/sda6
ceph-disk activate /dev/sda5
</code></pre></div>
<p>Et voila, une fois le <code>ceph-disk activate</code> terminé, votre nouvel osd est prêt et intégré au cluster ceph !</p>
<p>Enjoy :-)</p>Kubernetes et ceph sont dans un bateau2019-01-15T10:33:00+01:002019-01-15T10:33:00+01:00Victortag:blog.victor-hery.com,2019-01-15:/2019/01/peertube-k8s-ceph.html
<h1 id="de-quoi-va-t-on-parler-aujourdhui">De quoi va-t-on parler aujourd'hui</h1>
<h2 id="mise-en-contexte">Mise en contexte</h2>
<p>Car oui, il faut du contexte !</p>
<p>Je gère depuis maintenant un an <strong><a href="https://videos.pair2jeux.tube">une instance</a> utilisant <a href="https://joinpeertube.org/en/">Peertube</a></strong> pour héberger des vidéos dédiées au monde vidéoludique francophone.</p>
<p>A l'origine mis en place pour aider au projet et tester la version beta sur un petit …</p>
<h1 id="de-quoi-va-t-on-parler-aujourdhui">De quoi va-t-on parler aujourd'hui</h1>
<h2 id="mise-en-contexte">Mise en contexte</h2>
<p>Car oui, il faut du contexte !</p>
<p>Je gère depuis maintenant un an <strong><a href="https://videos.pair2jeux.tube">une instance</a> utilisant <a href="https://joinpeertube.org/en/">Peertube</a></strong> pour héberger des vidéos dédiées au monde vidéoludique francophone.</p>
<p>A l'origine mis en place pour aider au projet et tester la version beta sur un petit serveur seul dans son coin, les limites se sont assez vite faite sentir quand les gens intéressés par le projet ont commencés à devenir plus nombreux (et c'est cool !)
Le <strong>stockage</strong> notamment est une grosse problématique pour <strong>les vidéos</strong>, et c'est ce point qui a vite présenté un goulot d'étranglement.
Pour proposer un service de qualité, je voulais utiliser un <strong>stockage réparti</strong> ou à minima sécurisé, car les sauvegardes d'une telle quantité de données ne sont pas sans poser également quelques problèmes. Techniquement, il me fallait donc du <strong>RAID en mono-serveur</strong>, ou un <strong>stockage de type distribué</strong> (ceph, glusterfs, moosefs, ...)</p>
<p>Malheureusement en cherchant de meilleurs solution de stockage, il est assez vite apparu que les solutions de type Amazon S3 étaient les plus répandues, extensibles, garanties, etc.. Et surtout, totalement peu sûre et chez des GAFAM, chose que je voulais <strong>éviter absolument</strong> pour un projet dont l'optique est de proposer une alternative à Youtube !</p>
<p>De même, les <strong>stockages distribués</strong> plus standards que l'on peut trouver chez Scaleway, OVH ou Hetzner <strong>coutent une fortune</strong> dès que l'on veut de la <strong>quantité</strong> (au dessus de 500Go, préparez l'héritage pour le payer).</p>
<p>Associé au fait que j'aime bien faire moi-même les choses, j'ai donc décidé de <strong>partir sur une infrastructure maison</strong>, en place maintenant depuis 6 mois, et c'est celle-ci que je vais maintenant vous proposer :-)</p>
<h2 id="mise-en-technique">Mise en technique</h2>
<p>Mes <strong>besoins techniques</strong> étaient donc les suivants :</p>
<ul>
<li><a href="https://kubernetes.io/">Kubernetes</a> pour sa capacité à héberger en cluster des images dockers (et donc les différents outils nécessaire à Peertube)</li>
<li><a href="https://ceph.com/">Ceph</a> pour le stockage, bien connu, plutôt robuste avec de très bonnes performances et supporté par Kubernetes</li>
<li>Un réseau dédié au stockage et au trafic interne de Kubernetes, donc un réseau privé (dans l'idéal chiffré) avec un bon débit</li>
<li>Des serveurs (3 pour commencer) pour faire tourner tout ça, disposant d'un SSD pour le système et d'un disque dur que l'on dédiera au stockage Ceph</li>
<li>Des serveurs disposant au minimum de 16Go de RAM et d'un CPU i7 pour faire tourner Peertube tout en tenant la charge supplémentaire de Kubernetes et Ceph</li>
</ul>
<p>Ceux qui sont un peu familier avec les offres de serveur privés existantes savent que pour les serveurs notamment, c'est une configuration très difficile à trouver.
Pour des questions de commodité les hébergeurs proposent en effet des serveurs proposant soit peu de disque en SSD, soit de gros volumes de stockage en HDD, mais pas de mix des deux.</p>
<p>C'est pourquoi je vous propose ici un <strong>compromis</strong>, avec des <strong>hypothèses simplificatrices</strong> qui présentent des risques mais que j'ai décidé d'accepter, on en parlera à la fin.</p>
<ul>
<li>3 serveurs chez <a href="https://www.hetzner.com/sb?country=fr">Hetzner</a> (qui propose des serveurs peu cher avec un trafic mensuel très correct)</li>
<li>2 disques HDD de 3To par serveur, core i7, 16Go de RAM</li>
<li>Un réseau VPN privé monté entre les serveurs pour gérer le trafic Kubernetes et Ceph</li>
<li>Un des disques sera entièrement dédié à Ceph. L'autre permettra sur une partition de 100Go d'installer le système, le reste devant à terme être intégré à ceph</li>
</ul>
<p>Nous voila donc avec la base, <strong>le matériel pour lancer notre infrastructure</strong>. Y'a plus qu'à !</p>
<h1 id="installation-des-serveurs">Installation des serveurs</h1>
<p>L'idée de l'installation va être de garder un <strong>maximum de place</strong> pour le cluster ceph. Les serveurs doivent être <strong>jetables</strong> et <strong>remplaçables</strong> facilement, on a donc pas besoin de RAID ou de sécuriser particulièrement le système.</p>
<p>Pour cela on va se baser sur une partition de <strong>100Go</strong> pour le système sur le premier disque dur, le deuxième est laissé entièrement vierge.
Normalement votre hébergeur doit vous laisser la main sur ce formatage pour des serveurs physiques, chez Hetzner ça passe par un <a href="https://wiki.hetzner.de/index.php/Installimage/en">fichier texte</a> à remplir en mode rescue.
Debian 9 est une bonne base pour notre infrastructure. J'aurai bien voulu en profiter pour le chiffrer, mais on sort du cadre de cet article et de ma motivation ici :-D</p>
<h2 id="openvpn">Openvpn</h2>
<p>A moins que vous ayez le budget en conséquence pour vous payer un réseau privé sécurisé entre vos serveurs, on va ici se baser sur Openvpn pour monter un réseau chiffré qui servira à la fois pour ceph et pour kubernetes.</p>
<p>L'idée étant de ne pas avoir de point faible dans l'infrastructure, on va contourner la faiblesse client/serveur d'Openvpn en utilisant une technique de <strong>Ring</strong> :
Chaque <strong>client</strong> VPN est également <strong>serveur</strong> VPN, et peut donc se connecter aux autre ou recevoir leurs connexions. De cette manière on passe d'une topologie en étoile à une topologie en cercle, plus robuste !</p>
<p><img alt="Ring VPN" src="/images/peertube-k8s-ceph/ringvpn.png"/></p>
<p>On va commencer par configurer un serveur VPN en étoile classique et ses clients, de la même manière que dans mon article sur <a href="https://blog.victor-hery.com/2017/12/serveur-openvpn-sous-debian-9-et-systemd.html">installer openvpn sur debian 9</a>.</p>
<p>Une fois le serveur VPN fonctionnel et vos 2 clients connectés dessus (les 2 autres serveurs physiques), on va le transformer en structure en cercle.</p>
<p>Pour cela c'est très simple, il suffit de copier le fichier de configuration du serveur <strong>et ses clefs</strong> sur les différents serveurs physiques, exactement comme pour le premier serveur VPN.
Une fois ces serveur démarrés, vous disposez de 3 serveurs VPN identiques.</p>
<p><strong>Attention</strong>, vous aurez remarqué que le serveur VPN original n'a pas de client, c'est normal car il ne se connectera à personne pour éviter les boucles réseaux. Notez le sens des flèches sur le schéma ci-dessus.</p>
<p>Mais vos clients ne se connectent toujours qu'au premier serveur, et c'est ici qu'arrive la subtilité du cercle.
On va modifier les fichiers de configuration <strong>clients</strong> pour leur dire qu'il y a plusieurs serveurs disponibles :</p>
<div class="highlight"><pre><span></span><code><span class="err">remote XXX.XXX.XXX.XXX 1994</span>
<span class="err">remote YYY.YYY.YYY.YYY 1994</span>
<span class="err">keepalive 30 120</span>
</code></pre></div>
<p>Ici on dit à notre client VPN d'essayer de se connecter à XXX en premier. S'il n'est pas disponible, il va essayer de se connecter à YYY.
Au cas où un serveur est indisponible, <code>keepalive</code> signifie qu'il va essayer toutes les 30 secondes ses différents <code>remote</code>, avec un timeout de 120 secondes.</p>
<p>Ainsi en cas de panne d'un serveur, au bout de 120 secondes max les clients essaieront de se connecter au serveur suivant et reconstruiront le réseau.</p>
<p>Il s'agit ici d'un compromis, car en cas de panne du serveur principal, votre cluster sera dans le noir pendant plusieurs minutes le temps que tout se reconstruise, mais une fois les VPN reconnectés ceph et kubernetes retrouveront leurs petits.
Attendez vous également à des performances moindres qu'un véritable réseau dédié mais on fait avec le budget ;-)</p>
<p>En outre cette technique peut tout à fait être utilisée entre différents hébergeurs ou datacenters pour plus de résilience avec des performances très correctes.</p>
<h2 id="ceph">Ceph</h2>
<p>Une fois le serveur installé, on va commencer par installer <strong>ceph</strong>, qui sera ainsi prêt à recevoir kubernetes et ses provisionner (les outils kubernetes qui parlent au système de stockage).</p>
<p>Comme je suis un grand utilisateur de <strong>Ansible</strong>, j'ai décidé d'utiliser le projet *<a href="https://github.com/ceph/ceph-ansible">ceph-ansible</a> pour déployer ceph.
L'avantage est d'avoir un ensemble de playbook pour gérer le cluster et de pouvoir ainsi rajouter des serveurs de manière très simple. Là encore l'idée est de pouvoir jeter, remplacer et ajouter des serveurs le plus facilement possible.</p>
<p>Ici va se poser la question du type de stockage que vous souhaitez utiliser avec ceph. Les plus connus sont Rados Block Device (RBD) et Ceph FileSystem (cephfs).</p>
<p>Chacun ont des avantages et des inconvénients, mais dans kubernetes la principale différence est que RBD ne peut marcher qu'en ReadWriteOnce, c'est à dire qu'un stockage ne peut être monté que sur une seule node à la fois.
D'expérience ça pose quelques problèmes avec le fonctionnement de k8s, notamment en cas de soucis sur une node (crash, perte de réseau, ...) si elle n'a pas pu annoncer qu'elle relachait le RBD, votre pod qui l'utilise ne pourra jamais redémarrer ailleurs ûisque pour k8s le stockage sera toujours utilisé...</p>
<p>Cephfs de son côté présente l'avantage de permettre du ReadWriteMany et en outre comme tout filesystem on lui définit un quota plutôt quu'ne taille fixe, ce qui est pratique quand on a besoin d'un stockage extensible comme pour Peertube.
J'ai donc choisi <strong>Cephfs</strong> comme système de stockage via ceph.</p>
<p>Cela impose quelques subtilités lors du déploiement, notamment la création de pools ceph dédié à cephfs car il a besoin de stocker ses data et ses metadata.</p>
<p>Pour ce faire, on va ajouter dans les <strong>variables de déploiement</strong> de ceph-ansible les valeurs suivantes :
(on parle bien ici de variables ansible)</p>
<div class="highlight"><pre><span></span><code><span class="n">cephfs</span><span class="o">:</span> <span class="n">cephfs</span> <span class="err">#</span> <span class="n">nom</span> <span class="n">du</span> <span class="n">filesystem</span>
<span class="n">cephfs_data</span><span class="o">:</span> <span class="n">cephfs_data</span> <span class="err">#</span> <span class="n">nom</span> <span class="n">du</span> <span class="n">pool</span> <span class="n">de</span> <span class="n">données</span> <span class="n">du</span> <span class="n">cephfs</span>
<span class="n">cephfs_metadata</span><span class="o">:</span> <span class="n">cephfs_metadata</span> <span class="err">#</span> <span class="n">nom</span> <span class="n">du</span> <span class="n">pool</span> <span class="n">pour</span> <span class="n">les</span> <span class="n">metadata</span> <span class="n">du</span> <span class="n">cephfs</span>
</code></pre></div>
<p>Il vous faudra également créer les <strong>pools</strong> correspondants:</p>
<div class="highlight"><pre><span></span><code><span class="nl">cephfs_pools</span><span class="p">:</span><span class="w"></span>
<span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="err">{</span><span class="w"> </span><span class="nl">name</span><span class="p">:</span><span class="w"> </span><span class="ss">"{{ cephfs_data }}"</span><span class="p">,</span><span class="w"> </span><span class="nl">pgs</span><span class="p">:</span><span class="w"> </span><span class="ss">"{{ hostvars[groups[mon_group_name][0]]['osd_pool_default_pg_num'] }}"</span><span class="p">,</span><span class="w"> </span><span class="nl">pg_num</span><span class="p">:</span><span class="w"> </span><span class="ss">"{{ hostvars[groups[mon_group_name][0]]['osd_pool_default_pg_num'] }}"</span><span class="p">,</span><span class="w"> </span><span class="nl">pgp_num</span><span class="p">:</span><span class="w"> </span><span class="ss">"{{ hostvars[groups[mon_group_name][0]]['osd_pool_default_pg_num'] }}"</span><span class="w"> </span><span class="err">}</span><span class="w"></span>
<span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="err">{</span><span class="w"> </span><span class="nl">name</span><span class="p">:</span><span class="w"> </span><span class="ss">"{{ cephfs_metadata }}"</span><span class="p">,</span><span class="w"> </span><span class="nl">pgs</span><span class="p">:</span><span class="w"> </span><span class="ss">"{{ hostvars[groups[mon_group_name][0]]['osd_pool_default_pg_num'] }}"</span><span class="p">,</span><span class="w"> </span><span class="nl">pg_num</span><span class="p">:</span><span class="w"> </span><span class="ss">"{{ hostvars[groups[mon_group_name][0]]['osd_pool_default_pg_num'] }}"</span><span class="p">,</span><span class="w"> </span><span class="nl">pgp_num</span><span class="p">:</span><span class="w"> </span><span class="ss">"{{ hostvars[groups[mon_group_name][0]]['osd_pool_default_pg_num'] }}"</span><span class="w"> </span><span class="err">}</span><span class="w"></span>
</code></pre></div>
<p>Pour ce qui est du reste des variables, elles sont communes à un déploiement ceph, je vous renvoie vers la <a href="http://docs.ceph.com/ceph-ansible/master/">documentation de ceph-ansible</a></p>
<p>Le nombre de pg à définir notamment va grandement dépendre de la taille de votre cluster. Ceph propose un <a href="https://ceph.com/pgcalc/">outil</a> pour le calculer selon vos besoins.
A titre indicatif, pour le cluster avec 6 disques de 3To, j'utilise 64 pg par pool.</p>
<h2 id="kubernetes">Kubernetes</h2>
<p>Concernant kubernetes, j'ai décidé d'utiliser l'excellent <a href="https://github.com/kubernetes-sigs/kubespray">kubespray</a> qui permet de configurer et maintenir un cluster kubernetes avec Ansible.</p>
<p>La configuration par défaut est fonctionnelle, pensez à spécifier votre <code>bootstrap_os</code> pour coller à vos serveur (debian dans mon cas).</p>
<p>Concernant les variables à modifier, quelques bonnes pratiques de sécurités consistent à forcer tout le TLS possible, et à désactiver tout ce qui est authentification anonyme, que ce soit sur l'API du cluster ou sur l'API interne des nodes :</p>
<div class="highlight"><pre><span></span><code><span class="c">authorization_modes: ['Node', 'RBAC']</span>
<span class="c">kubelet_authentication_token_webhook: false</span>
<span class="c">kubelet_authorization_mode_webhook: false</span>
</code></pre></div>
<p>Pensez également à activer le <strong>provisionneur</strong> cephfs directement, puisque kubespray le supporte par le biais d'un <a href="https://github.com/kubernetes-incubator/external-storage/tree/master/ceph/cephfs">addons</a></p>
<div class="highlight"><pre><span></span><code><span class="err"># CephFS provisioner deployment</span>
<span class="c">cephfs_provisioner_enabled: true</span>
<span class="c">cephfs_provisioner_namespace: "cephfs-provisioner"</span>
<span class="c">cephfs_provisioner_cluster: ceph</span>
<span class="c">cephfs_provisioner_monitors: "10.8.0.1:6789,10.8.0.2:6789,10.8.0.3:6789"</span>
<span class="c">cephfs_provisioner_admin_id: admin</span>
<span class="c">cephfs_provisioner_secret: YourSecret</span>
<span class="c">cephfs_provisioner_storage_class: cephfs</span>
<span class="c">cephfs_provisioner_reclaim_policy: Delete</span>
<span class="c">cephfs_provisioner_claim_root: /volumes</span>
<span class="c">cephfs_provisioner_deterministic_names: true</span>
</code></pre></div>
<p><strong>Remplacez</strong> bien sur les IP des monitors avec vos propres IP, celles utilisées dans le réseau OpenVPN ;-)</p>
<p>Le secret ceph se retrouvera une fois le cluster ceph installé, il est généré par ceph lors de la création des pools pour l'utilisateur admin :</p>
<div class="highlight"><pre><span></span><code><span class="err"># ceph auth get client.admin</span>
</code></pre></div>
<p>A titre personnel, j'utilise également helm et le cert-manager proposé en tant qu'addons :</p>
<div class="highlight"><pre><span></span><code><span class="err"># Helm deployment</span>
<span class="c">helm_enabled: true</span>
<span class="err"># Cert manager deployment</span>
<span class="c">cert_manager_enabled: true</span>
<span class="c">cert_manager_namespace: "cert-manager"</span>
</code></pre></div>
<h1 id="ansible-et-deploiement">Ansible et déploiement</h1>
<p>Concernant l'inventaire ansible, il reste assez simple dans l'optique où les noeuds kubernetes seront les mêmes que les noeuds ceph.</p>
<p>Pour ma part, il ressemble à ça :</p>
<div class="highlight"><pre><span></span><code><span class="k">[k8s]</span>
<span class="na">node1.local osd_crush_location</span><span class="o">=</span><span class="s">"{ 'root': 'default', 'rack': 'cephfs_data', 'pod': 'pod1', 'host': 'node1.local' }"</span>
<span class="na">node2.local osd_crush_location</span><span class="o">=</span><span class="s">"{ 'root': 'default', 'rack': 'cephfs_data', 'pod': 'pod1', 'host': 'node2.local' }"</span>
<span class="na">node3.local osd_crush_location</span><span class="o">=</span><span class="s">"{ 'root': 'default', 'rack': 'cephfs_data', 'pod': 'pod1', 'host': 'node3.local' }"</span>
<span class="k">[kube-master:children]</span>
<span class="na">k8s</span>
<span class="k">[etcd:children]</span>
<span class="na">k8s</span>
<span class="k">[kube-node:children]</span>
<span class="na">k8s</span>
<span class="k">[k8s-cluster:children]</span>
<span class="na">kube-master</span>
<span class="na">kube-node</span>
<span class="k">[mons:children]</span>
<span class="na">k8s</span>
<span class="k">[osds:children]</span>
<span class="na">k8s</span>
<span class="k">[clients:children]</span>
<span class="na">k8s</span>
<span class="k">[mdss:children]</span>
<span class="na">k8s</span>
<span class="k">[mgrs:children]</span>
<span class="na">k8s</span>
</code></pre></div>
<p>Au final vous devriez avoir une arborescence de ce type pour l'inventaire ansible :</p>
<div class="highlight"><pre><span></span><code><span class="err">.</span>
<span class="err">├── ansible.cfg</span>
<span class="err">├── group_vars</span>
<span class="err">│ ├── all</span>
<span class="err">│ │ ├── ceph_pool.yml</span>
<span class="err">│ │ ├── ceph.yml</span>
<span class="err">│ │ ├── k8s-addons.yml</span>
<span class="err">│ │ ├── k8s-cluster.yml</span>
<span class="err">│ │ └── kubespray.yml</span>
<span class="err">│ ├── clients.yml</span>
<span class="err">│ ├── mons.yml</span>
<span class="err">│ └── osds.yml</span>
<span class="err">├── hosts</span>
<span class="err">├── host_vars</span>
<span class="err">│ ├── node1.local</span>
<span class="err">│ ├── node2.local</span>
<span class="err">│ └── node3.local</span>
</code></pre></div>
<p>Il ne vous reste alors plus qu'à déployer !</p>
<p>Comme kubernetes a besoin de ceph pour fonctionner, je vous conseille de commencer par ce dernier.
Attention à utiliser <strong>ansible 2.5</strong> pour ces déploiements (au 30/12/18, ceph-ansible ne supporte pas plus)</p>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">ceph-ansible</span><span class="o">]</span><span class="w"> </span><span class="err">±</span><span class="w"> </span><span class="n">cp</span><span class="w"> </span><span class="n">site</span><span class="p">.</span><span class="n">yml</span><span class="p">.</span><span class="n">sample</span><span class="w"> </span><span class="n">site</span><span class="p">.</span><span class="n">yml</span><span class="w"></span>
<span class="o">[</span><span class="n">ceph-ansible</span><span class="o">]</span><span class="w"> </span><span class="err">±</span><span class="w"> </span><span class="n">ansible</span><span class="o">-</span><span class="n">playbook</span><span class="w"> </span><span class="o">-</span><span class="n">i</span><span class="w"> </span><span class="p">..</span><span class="o">/</span><span class="n">your_inventory</span><span class="o">/</span><span class="n">hosts</span><span class="w"> </span><span class="n">site</span><span class="p">.</span><span class="n">yml</span><span class="w"></span>
<span class="o">[</span><span class="n">ceph-ansible</span><span class="o">]</span><span class="w"> </span><span class="err">±</span><span class="w"> </span><span class="n">cd</span><span class="w"> </span><span class="o">~/</span><span class="n">kubespray</span><span class="w"></span>
<span class="o">[</span><span class="n">kubespray</span><span class="o">]</span><span class="w"> </span><span class="n">master</span><span class="w"> </span><span class="err">±</span><span class="w"> </span><span class="n">ansible</span><span class="o">-</span><span class="n">playbook</span><span class="w"> </span><span class="o">-</span><span class="n">i</span><span class="w"> </span><span class="p">..</span><span class="o">/</span><span class="n">your_inventory</span><span class="o">/</span><span class="n">hosts</span><span class="w"> </span><span class="n">cluster</span><span class="p">.</span><span class="n">yml</span><span class="w"></span>
</code></pre></div>
<p>Les déploiements peuvent prendre un certain temps selon votre bande passante et le nombre de noeuds, parce qu'il y a quand même pas mal de chose à faire.</p>
<p>Si vous rencontrez des erreurs, les documentations sont en général suffisantes pour les corriger facilement, et les deux playbook sont <strong>idempotents</strong> (notamment kubespray) donc pas trop de problème pour les repasser en cas de crash.</p>
<p>Si vous rencontrez de gros soucis durant le déploiement de ceph, n'hésitez pas à purger le cluster pour recommencer, après tout vous n'avez pas de données dessus pour l'instant !</p>
<p><strong>Note :</strong> il s'agit ici d'utiliser ansible pour aider au déploiement. Vous pouvez tout à fait utiliser un autre outil ou déployer à la main si vous le préférez. <strong>Ne mettez pas en production un outil que vous ne maitrisez pas !</strong></p>
<p>Au final, vous disposez d'un cluster <strong>kubernetes</strong> fonctionnel avec une base ceph pour le stockage persistent ! Il va donc être temps de s'amuser avec ;-)</p>
<h1 id="securite">Sécurité</h1>
<p>D'un point de vue sécurité, il est très important que votre cluster ne soit accessible que sur les <strong>IP du VPN</strong>.
Bloquez les accès à l'API kubernetes sur le port <strong>6443</strong> car elle a tendance à écouter un peu n'importe où, utilisez exclusivement des certificats pour les utilisateurs !</p>
<p>Kubespray de base est plutôt sécurisé, ce qui est assez plaisant. Notamment il déploie des certificats pour sécuriser toutes les connexions (etc, api, kubelet, ...) mais cela n'empêche pas de limiter les accès pour éviter les angles d'attaques.</p>
<p>Concernant ceph, si vous lui avez fourni les bonnes IP VPN pour son déploiement, il ne devra jamais se retrouver exposé à l'extérieur.</p>
<p>Selon ce que vous souhaitez héberger dans votre cluster, les <strong>seuls ports</strong> à ouvrir devraient être ceux des services hébergés.</p>
<p>Par exemple dans mon cas pour pair2jeux, seuls les ports 80 et 443 sont exposés pour joindre Peertube et les outils web associés.</p>
<h1 id="conclusion">Conclusion</h1>
<p>Les clusters (ceph et kubernetes) proposés ici sont maintenables via les projets kubespray et ceph-ansible, que ce soit pour ajouter des nodes, en détruire ou pour mise à jour de l'infrastructure.</p>
<p>Il vous faudra choisir comment configurer vos accès aux services (j'utilise pour ma part <a href="https://github.com/jcmoraisjr/haproxy-ingress/">haproxy-ingress</a>.</p>
<p>Cette infrastructure me permet de faire tourner l'instance peertube de pair2jeux avec une assez confortable marge de stockage et d'y associer d'autres outils (wiki, ...) de manière fun.</p>
<p>Plusieurs améliorations peuvent être mises en place sur cette infrastructure, comme par exemple</p>
<ul>
<li>Un système de log centralisé (très utile pour les pods kubernetes)</li>
<li>Un monitoring des services kubernetes et des pods</li>
<li>Des sauvegardes des données ceph et de l'etcd</li>
<li>Un système d'IP virtuelle pour utiliser des entrées DNS qui tapent toujours dans le cluster fonctionnel en cas de panne</li>
<li>Intégrer l'espace disque restant au cluster ceph</li>
<li>Séparer les master kubernetes des nodes (quand le budget sera plus étendu)</li>
<li>Trouver des serveurs avec SSD pour faire tourner le système</li>
</ul>
<p>J'essaierai de traiter certains de ces points dans de futurs articles, en attendant j'espère que celui vous aura plu !</p>
<h3 id="remerciements">Remerciements</h3>
<p>Pour leur relecture :</p>
<ul>
<li>noskillbrain (<a href="https://noskillbrain.fr/">https://noskillbrain.fr/</a>)</li>
<li>Dryusdan (<a href="https://www.drycat.fr/">https://www.drycat.fr/</a>)</li>
<li>Nailyk</li>
</ul>Kubectl : forcer l'https pour utiliser can-i2018-09-14T18:32:00+02:002018-09-14T18:32:00+02:00Victortag:blog.victor-hery.com,2018-09-14:/2018/09/kubectl-https-can-i.html
<h1 id="le-bug-de-kubectl-auth-can-i-et-dimpersonate">Le bug de kubectl auth can-i et d'impersonate</h1>
<p>Si vous utilisez kubernetes, il est très probable que vous utilisez également kubectl pour gérer votre cluster en ligne de commande.</p>
<p>Dans ce cas, vous avez peut être eu besoin d'utiliser la commande <code>kubectl auth can-i</code> pour tester les différents accès de …</p>
<h1 id="le-bug-de-kubectl-auth-can-i-et-dimpersonate">Le bug de kubectl auth can-i et d'impersonate</h1>
<p>Si vous utilisez kubernetes, il est très probable que vous utilisez également kubectl pour gérer votre cluster en ligne de commande.</p>
<p>Dans ce cas, vous avez peut être eu besoin d'utiliser la commande <code>kubectl auth can-i</code> pour tester les différents accès de vos utilisateurs ou de vos services account.</p>
<p>Cette commande dispose en effet d'une option bien pratique, <strong>impersonate</strong>, que l'on peut appeller avec l'aide de <code>--as</code>, de cette façon :</p>
<div class="highlight"><pre><span></span><code>$ sudo kubectl auth can-i create networkpolicy --as system:serviceaccount:default:default
yes
</code></pre></div>
<p>Ici par exemple, on demande si le service account <em>default</em> du namespace <strong>default</strong>, possède le droit de créer des NetworkPolicy dans le cluster.
Sexy, n'est ce pas !</p>
<p>Et bien <strong>non</strong> !
En effet, si par malheur votre kubectl utilise http sur le port 8080 pour discuter avec l'API kubernetes, alors cette commande ne fonctionnera pas comme attendue.
Pire ! Elle vous renverra en permanence "yes", indiquant que le compte a les bons droits, alors qu'en fait il se peut tout à fait que non...</p>
<p>En effet, l'API en http ne supporte tout simplement pas l'impersonate. Sauf que kubectl, à cause d'un bug, ne gère pas le fait de vous le dire.</p>
<p>En tout simplicité, toutes les commandes que vous lancerez avec <code>--as</code> seront donc réellement lancées avec votre utilisateur admin actuel :-)</p>
<p>Ceci est donc un petit pense-bête avec contexte pour garder la manip sous le coude !</p>
<h1 id="kikekoi-quon-fait">kikekoi qu'on fait ?</h1>
<p>Pour régler ce problème, il devient donc nécessaire de parler à l'API de kubernetes en https, et heureusement ça peut se configurer !</p>
<p>Pour ce faire, on va assez simplement utiliser le fichier admin.conf qui est usuellement généré lors de l'installation du cluster.</p>
<p>Dans une configuration standard, le fichier devrait être placé dans <code>/etc/kubernetes/admin.conf</code>.
Il se peut également qu'il soit placé dans <code>/root/.kube/config</code>.</p>
<p>Dans tous les cas, vous pouvez l'appeler de la manière suivante :</p>
<div class="highlight"><pre><span></span><code><span class="err">sudo kubectl --kubeconfig /etc/kubernetes/admin.conf auth can-i create networkpolicy --as system:serviceaccount:default:default</span>
<span class="err">no</span>
</code></pre></div>
<p>Et voila, on obtient les bons droits avec un impersonate fonctionnel ;-)</p>Routeur 4G lvl 12018-01-31T10:00:00+01:002018-01-31T10:00:00+01:00Victortag:blog.victor-hery.com,2018-01-31:/2018/01/Routeur-4g-lvl1.html<p class="first last">Boostez votre connexion à la maison !</p>
<p>On veut tous avoir la connexion la plus rapide possible. Parce que les Mbps, ça fait paraitre plus grand, ça fait revenir l'être perdu, ça ramène l'amour à la maison.</p>
<p>Mais quand on est paumé dans une cambrousse qui dispose d'une connexion méritant à peine le A de ADSL, on souffre, chaque jour, en silence, dans une indifférence générale.
On ne reviendra donc pas sur le déploiement de la fibre en France, ce n'est pas le sujet du jour.</p>
<p>Aujourd'hui, on va voir comment pouvoir peut être gratter quelques octets de bande passante, ou multiplier votre connexion par 10, ça dépend du déploiement 4G dans votre cambrousse :-D</p>
<p>Merci à Fabien pour ses conseils sur le matériel et son expérience sur le sujet !</p>
<div class="section" id="materiel">
<h2><a class="toc-backref" href="#id2">Matériel</a></h2>
<p>Pour cet article, il va falloir du matériel physique, pas de miracle.</p>
<p>Il vous faudra au minimum :</p>
<ul class="simple">
<li>un routeur avec 2 ports RJ 45 (Un wan et un lan) et un port USB (pour la clef 4G). Je vous conseille d'en prendre 2 pour en avoir un en secours en cas de panne</li>
<li>une clef 4G. Il est conseillé de prendre une clef d'une marque faisant également des téléphones, ce afin de limiter les chances que votre opérateur détecte une utilisation en mode modem (souvent interdite par les CGU)</li>
<li>une carte SIM avec un forfait 4G</li>
<li>les câbles RJ 45 qui vont bien pour brancher le routeur</li>
</ul>
<p>Vous pouvez aussi prendre une antenne 4G pour renforcer votre signal si vous voulez, ça mange pas de pain.</p>
<div class="figure">
<img alt="antenne et routeurs" src="https://blog.victor-hery.com/images/routeur4G/routeur_antenne.jpg" style="width: 400px;"/>
<p class="caption">Les 2 routeurs et leur antenne</p>
</div>
<p>Dans ce tutoriel, voici le matériel que je vais utiliser. Il est minimaliste mais robuste et reconnu pour fonctionner, donc je me base dessus.</p>
<ul class="simple">
<li>Routeur <a class="reference external" href="https://wiki.openwrt.org/toh/nexx/wt3020">NEXX WT3020</a>.</li>
<li>Clef 4G <a class="reference external" href="http://consumer.huawei.com/en/mobile-broadband/e3372/specs/">Huawei E3372</a>. Pour ce modèle, je vous conseille ebay, on en trouve à des prix excellent, certains FAI les fournissant comme clef 4G officielle</li>
<li>Antenne <a class="reference external" href="http://www.lafalink.com/product_519.html">Lafalink ANT4G01</a>. Un peu massive, mais une bonne longueur de cable et qui fait bien le job</li>
</ul>
<p>Cela étant dit, comme on va utiliser <a class="reference external" href="https://fr.wikipedia.org/wiki/OpenWrt">OpenWRT</a> pour la partie logicielle, n'importe quel routeur qui le supporte devrait fonctionner ;-)</p>
</div>
<div class="section" id="installation-du-routeur">
<h2><a class="toc-backref" href="#id3">Installation du routeur</a></h2>
<div class="section" id="openwrt">
<h3><a class="toc-backref" href="#id4">OpenWRT</a></h3>
<p>Cette partie va concerner l'installation du routeur <a class="reference external" href="https://wiki.openwrt.org/toh/nexx/wt3020">NEXX WT3020</a> sous <a class="reference external" href="https://fr.wikipedia.org/wiki/OpenWrt">OpenWRT</a>. La procédure devrait être sensiblement la même pour la plupart des modèles de routeurs, mais n'hésitez pas à vous reporter à la documentation OpenWRT en cas de doute.</p>
<p>Je précise également qu'à ma connaissance, ce routeur ne dispose d'aucune backdoor matérielle connue, donc une fois OpenWRT installé, vous devriez être tranquille. Cependant, si jamais vous avez connaissance d'une telle faille, n'hésitez pas à me le faire savoir !</p>
<p>Connectez votre routeur à votre ordinateur de manière à ce que votre PC soit côté LAN du routeur, et branchez un câble relié à Internet sur la partie WAN. Le routeur doit avoir Internet, et vous devez pouvoir vous connecter au routeur :</p>
<div class="figure">
<img alt="Le WT3020 connecté" src="https://blog.victor-hery.com/images/routeur4G/IMG_20180117_101447.jpg" style="width: 400px;"/>
<p class="caption">Le WT3020 connecté</p>
</div>
<p>Dès que la connexion au WT3020 est établie, on peut se connecter en telnet. Par défaut, celui-ci vous donne une IP en 192.168.1.0/24, et lui-même est sur le 192.168.8.1.</p>
<p>Les identifiants par défaut sont ci-dessous :</p>
<div class="highlight"><pre><span></span>$ telnet <span class="m">192</span>.168.8.1
Trying <span class="m">192</span>.168.8.1...
Connected to <span class="m">192</span>.168.8.1.
Escape character is <span class="s1">'^]'</span>.
<span class="o">(</span>none<span class="o">)</span> login: nexxadmin
Password: y1n2inc.com0755
</pre></div>
<p>On va ensuite récupérer l'image openwrt. Pensez à aller vérifier si c'est bien la dernière en date ;-)</p>
<div class="highlight"><pre><span></span><span class="c1"># cd /tmp</span>
<span class="c1"># wget http://downloads.openwrt.org/chaos_calmer/15.05/ramips/mt7620/openwrt-15.05-ramips-mt7620-wt3020-8M-squashfs-sysupgrade.bin</span>
<span class="c1"># mtd_write -r write openwrt-15.05-ramips-mt7620-wt3020-8M-squashfs-sysupgrade.bin mtd3</span>
<span class="c1"># reboot</span>
</pre></div>
<p>Le routeur va redémarrer, et vous devriez tourner sur <a class="reference external" href="https://fr.wikipedia.org/wiki/OpenWrt">OpenWRT</a></p>
</div>
<div class="section" id="first-conf">
<h3><a class="toc-backref" href="#id5">First conf</a></h3>
<p>La première chose que l'on va faire, c'est dégager telnet et configurer ssh.</p>
<p>Pour cela, on va se reconnecter une dernière fois en telnet. <strong>Notez que OpenWRT par défaut utilise 192.168.1.0/24 comme réseau.</strong></p>
<div class="highlight"><pre><span></span>$ telnet <span class="m">192</span>.168.1.1
Trying <span class="m">192</span>.168.1.1...
Connected to openwrt.lan.
Escape character is <span class="s1">'^]'</span>.
<span class="o">===</span> <span class="nv">IMPORTANT</span> <span class="o">============================</span>
Use <span class="s1">'passwd'</span> to <span class="nb">set</span> your login password
this will disable telnet and <span class="nb">enable</span> SSH
------------------------------------------
</pre></div>
<p>Comme l'indique si gentiment le motd, il suffit de configurer un mot de passe à l'aide de <tt class="docutils literal">passwd</tt> pour activer le SSH et désactiver telnet, il n'y a plus qu'à :</p>
<div class="highlight"><pre><span></span>root@OpenWrt:/# passwd
Changing password <span class="k">for</span> root
New password:
Retype password:
Password <span class="k">for</span> root changed by root
root@OpenWrt:/#
</pre></div>
<p>A partir de là, telnet va être désactivé. C'est le moment de se connecter en SSH pour vérifier que vous n'avez pas d'erreurs dans le mot de passe !</p>
<p>Si tout est ok, vous pouvez également commencer à utiliser l'interface web LuCi via un navigateur, avec les accès root identiques au SSH.</p>
</div>
<div class="section" id="configuration-avancee">
<h3><a class="toc-backref" href="#id6">Configuration avancée</a></h3>
<p>Une fois le routeur installé, je vous inviteà vous connecter sur l'interafce web, via votre navigateur, en tapant son adresse IP : <a class="reference external" href="http://192.168.1.1">http://192.168.1.1</a></p>
<p>Les accès sont les même que ceux que vous avez rentrés pour configurer le SSH : utilisateur root, avec le mot de passe associé.</p>
<p>Le routeur est déjà plutôt fonctionnel à l'installation, néanmoins je vous propose quelques modifications qui permettent d'éviter les désagrément (type intrusion) en désactivant des services pas forcément utiles.</p>
<p>Onglet System :</p>
<ul class="simple">
<li>Configurez le NTP avec votre timezone dans le menu System</li>
<li>Dans le menu Administration, indiquez que vous souhaitez écouter en SSH uniquement sur l'interface LAN. Eventuellement vous pouvez indiquer une clef ssh publique si vous en avez une, ça peut faciliter les connexions ;-)</li>
</ul>
<p>Onglet Network</p>
<ul class="simple">
<li>Au niveau des Interfaces, vous devriez avoir une Interface LAN branchée (en vert), et une interface WAN débranchée (en rouge). Les couleurs indiquent les zones du pare-feu, le vert étant la zone "sécurisée", le rouge la zone "non sécurisée", c'est à dire Internet. On rajoutera plus tard une interface pour la clef 4G. C'est également ici (en éditant chaque interface) que vous pouvez modifier l'adresse du routeur si 192.168.1.1 ne vous convient pas.</li>
<li>Onglet wifi : choisissez si vous souhaitez ou non vous servir du wifi du routeur. Si vous voulez que vos matériels en wifi profitent de la 4G, il est préférable de l'activer. N'oubliez pas de mettre une clef de sécurité !</li>
</ul>
<p>Le reste est inutile pour l'instant, mais vous pouvez parcourir les menu pour jouer un peu si vous le souhaitez ;-)</p>
</div>
</div>
<div class="section" id="clef-4g">
<h2><a class="toc-backref" href="#id7">Clef 4G</a></h2>
<p>Il va donc être temps de brancher votre clef 4G et de la configurer. Bien entendu, mettez la carte SIM préalablement ^^</p>
<div class="section" id="drivers-openwrt">
<h3><a class="toc-backref" href="#id8">Drivers openwrt</a></h3>
<p>Openwrt n'a pas de base les drivers nécessaires pour reconnaître les périphériques réseaux en USB on va donc devoir installer les paquets qui vont bien.</p>
<p>Connectez vous en SSH au routeur et installez les paquets :</p>
<div class="highlight"><pre><span></span>opkg update
opkg install kmod-usb-net kmod-usb-net-rndis kmod-usb-net-cdc-ether usbutils udev
</pre></div>
<p>Note :
- le paquet kmod-usb-net-cdc-ether va permettre de reconnaître la majorité des clefs USB du marché
- le paquet kmod-usb-net-rndis de son côté est utile si vous souhaitez utiliser votre Smartphone en usb plutôt qu'une clef</p>
<p>Vous pourrez trouver plus d'information sur le tethering <a class="reference external" href="https://wiki.openwrt.org/doc/howto/usb.tethering">ici</a>.</p>
</div>
<div class="section" id="interface-reseau">
<h3><a class="toc-backref" href="#id9">Interface réseau</a></h3>
<p>Avant tout chose, il va falloir indiquer au routeur quoi faire de ce nouveau périphérique réseau.</p>
<p>Connectez votre clef 4G, puis connectez vous en ssh au routeur.</p>
<p>La commande</p>
<div class="highlight"><pre><span></span>ip a
</pre></div>
<p>devrait vous lister les interfaces réseaux disponibles. Il va falloir retrouver celles qui correspond à la clef.</p>
<p>Chez moi, j'ai eth0 qui correspond au lan, eth0.2 qui correspond au wan, et la clef est apapru en tant que eth1. Servez vous de l'IP pour la reconnaitre, traditionnellement les clefs 4G ont un DHCP sur le réseau 192.168.8.0/24 :-)</p>
<p>A défaut, reportez vous au mode d'emploi de la clef ou à son emballage pour récupérer l'adresse MAC.</p>
<p>Dans le cas d'un smartphone, l'interface est souvent vue comme <strong>usb0</strong>.</p>
<p>Une fois l'interface récupérée, on va aller la configurer sur le routeur. Retournez donc sur l'interface web du routeur !</p>
<p>Dans l'onglet Network -> Interfaces, on va créer une nouvelle interface grâce au bouton "Ajouter une interface" en dessous des interfaces existantes :</p>
<div class="figure">
<img alt="ajout d'une interface sur LuCi" src="https://blog.victor-hery.com/images/routeur4G/Add_Interfaces_4G.png" style="width: 400px;"/>
<p class="caption">Ajout de l'interface 4G0 sur LuCi</p>
</div>
<p>J'ai pour ma part nommée l'interface 4g0, mais vous pouvez choisir n'importe quel nom qui vous parle.</p>
<p>Une fois l'interface ajoutée, il va être important de l'éditer immédiatement, pour aller dans l'onglet "Pare-feu" de l'interface et la configurer comme étant dans la zone rouge "wan". De cette manière, le routeur considérera que c'est Internet qui est derrière, et bloquera la plupart des intrusions par défaut.</p>
<p>Je vous conseille également d'en profiter pour lui caler une IP fixe, histoire de faciliter la gestion.</p>
<p>Une fois ces configurations faites, vous pouvez débrancher et rebrancher la clef 4G pour lui faire redémarrer ses services et récupérer le réseau.</p>
</div>
<div class="section" id="configuration-de-la-clef">
<h3><a class="toc-backref" href="#id10">Configuration de la clef</a></h3>
<p>Pour cette deuxième partie, il est préférable que le routeur soit branché à votre PC directement (toujours via sa prise LAN), car la plupart des clefs 4G vont générer une popup vous permettant (entre autre) de rentrer le code PIN de votre SIM.</p>
<p>Si ce n'est pas le cas, il faudra se référer au mode d'emploi de la clef.</p>
<p>A défaut, vous devriez pouvoir vous connecter à la clef via votre navigateur, en rentrant son IP. Par exemple : <a class="reference external" href="http://192.168.1.1">http://192.168.1.1</a></p>
<p>Ici, la configuration va entièrement dépendre de votre clef, je vais donc parler de la clef <a class="reference external" href="http://consumer.huawei.com/en/mobile-broadband/e3372/specs/">Huawei E3372</a>, mais vous pouvez vous en servir comme liste de points à vérifier :</p>
<ul class="simple">
<li>Configurez le code PIN de votre carte SIM, en cochant la case permettant à la clef de s'en souvenir. Ainsi, même en cas de redémarrage du routeur, coupure electrique, etc, la carte sim sera automatiquement réactivée (et il reste peu probable qu'on vienne vous piquer le routeur avec le PIN enregistré dans votre salon)</li>
<li>Onglet Settings -> Mobile Connection : Vous devez "Turn ON" la connexion mobile, qui est désactivée par défaut. Je vous conseille cependant de laisser le roaming désactivée, sauf si vous avez un forfait en béton. N'oubliez pas de cliquer sur "Apply"</li>
<li>Onglet Settings -> Security -> DMZ Settings : Vous pouvez laisser le routeur OpenWRT gérer la partie pare-feu en indiquant ici son IP, pour que la clef redirige tout le traffic entrant vers lui. Principalement utile si vous souhaitez faire de l'hébergement de partie de jeu en ligne par exemple, même si vous n'aurez (sans doute) pas d'IP fixe via la 4G.</li>
<li>Onglet Settings -> Security -> UPnP : Je vous conseille de désactiver l'UPnP, qui est une source de faille trop importante et est très peu utile sur votre clef dans ce contexte</li>
</ul>
</div>
<div class="section" id="detection-du-tethering">
<h3><a class="toc-backref" href="#id11">Détection du tethering</a></h3>
<p>La plupart des FAI se servent d'une technique de détection du <a class="reference external" href="https://fr.wikipedia.org/wiki/Modem_affili%C3%A9">tethering</a> pour limiter les usages en mode modem de leurs forfaits. C'est au moins le cas de Free et Bouygues.</p>
<p>Cette détection est indépendante du type de matériel (je conseille ici encore de prendre une clef chez un constructeur faisant aussi des téléphones), mais leur permet d'ajouter des règles pour limiter le débit en cas de doute.</p>
<p>Typiquement, cela m'est arrivé avec la clef Huawei, qui se retrouvait limitée après 3 minutes de fonctionnement, et la limitation sautait si je la redémarrait (avant de revenir quelques minutes plus tard)</p>
<p>Cette technique se base sur le <a class="reference external" href="https://fr.wikipedia.org/wiki/Time_to_Live">Time To Live</a> (TTL) de vos paquets, en partant du principe que si vous êtes derrière un routeur 4G, alors celui-ci va décrémenter ce TTL (ce qui est normal), et donc le FAI verra arriver des paquets avec un TTL inférieur à celui par défaut.</p>
<p>Or, ce TTL est en général de 64 ou 127, selon les différents OS, il est donc aisé de se dire "ah, je vois le paquet arriver, le TTL est de 62 (ou 125), donc il y a eu 2 sauts entre le client et moi, il utilise un routeur 4G !".</p>
<p>On va donc faire en sorte que notre routeur remette ce TTL à une valeur acceptable avant d'envoyer les paquets au FAI :-)</p>
<p>Pour cela, iptables est notre ami !</p>
<p>Connectez vous sur l'interface web d'OpenWRT, et rendez-vous dans l'onglet Network -> firewall -> Custom rules</p>
<p>Rajoutez à la fin du fichier une règle iptables comme suit, en utilisant l'interface réseau de la clef 4G utilisée plus haut :</p>
<div class="highlight"><pre><span></span>iptables -t mangle -I POSTROUTING -o INTERFACE_4G -j TTL --ttl-set <span class="m">66</span>
</pre></div>
<p>Et bien sûr sauvegardez.</p>
<p>Cette règle va faire en sorte que chaque paquet sortant du routeur sur l'interface de la clef 4G verra son TTL forcé à 66, quelque soit sa valeur précédente. De fait, le FAI verra arriver un paquet avec un TTL plus grand que ce qu'il détecte, et ne devrait plus vous brider ;-)</p>
</div>
</div>
<div class="section" id="tests-et-sauvegardes">
<h2><a class="toc-backref" href="#id12">Tests et sauvegardes</a></h2>
<p>Une fois ces configurations appliquées, vous devriez pouvoir joindre Internet à travers la clef sans problème.</p>
<p>Déconnectez votre PC de toute autre sources de réseau (cables, wifi, ...) et testez de naviguer un peu. Lancez quelques <a class="reference external" href="http://www.speedtest.net/">Speed test</a> pour voir si la connexion à de la patate.</p>
<p>Si tout est ok, je vous conseille fortement d'aller sauvegarder les configurations du routeur <strong>et</strong> de la clef 4G via les menu backups correspondants.</p>
<p>Ainsi si le matériel décède, plante, ou quoique ce soit, vous serez bien content d'avoir ces fichiers à restaurer pour repartir rapidement avec du matériel neuf ;-)</p>
<p>Pour OpenWRT, la sauvegarde se trouve dans l'onglet System -> Backup</p>
<p>Pour la clef Huawei, la sauvegarde se trouve dans Settings -> System -> Backup</p>
</div>
<div class="section" id="conclusion">
<h2><a class="toc-backref" href="#id13">Conclusion</a></h2>
<p>Il ne vous reste plus qu'à brancher votre routeur là où vous le souhaitez pour profiter de la 4G !</p>
<p>Est ce que vous l'utilisez plutôt à la place de votre box ? Associé à la box ? Derrière un switch pour que toute la maison profite de la 4G ? N'hésitez pas à me laisser un petit commentaire pour partager votre configuration ! ;-)</p>
<p>Dans les prochains articles, nous verrons comment utiliser de manière fun votre connexion ADSL en plus de la 4G.</p>
<p>En outre, les réseaux 4G étant notoirement surveillés (encore plus que l'ADSL), voir non-neutres vers certains services (coucou Free vs Youtube), nous verrons comment rajouter un brin de VPN pour aider un peu.</p>
</div>
<div class="section" id="bilbiographie-et-liens">
<h2><a class="toc-backref" href="#id14">Bilbiographie et liens</a></h2>
<ul class="simple">
<li>Routeur <a class="reference external" href="https://wiki.openwrt.org/toh/nexx/wt3020">NEXX WT3020</a>.</li>
<li>Clef 4G <a class="reference external" href="http://consumer.huawei.com/en/mobile-broadband/e3372/specs/">Huawei E3372</a>.</li>
<li>Antenne <a class="reference external" href="http://www.lafalink.com/product_519.html">Lafalink ANT4G01</a>.</li>
<li><a class="reference external" href="http://www.securityskeptic.com/2016/01/how-to-turn-a-nexx-wt3020-router-into-a-tor-router.html">How To Turn a WT3020 into a TOR router</a>.</li>
<li>Le wiki <a class="reference external" href="https://github.com/openwrt/luci/wiki">OpenWRT LuCi</a>.</li>
<li>La documentation <a class="reference external" href="https://wiki.openwrt.org/doc/howto/mwan3">mwan3</a>.</li>
<li><a class="reference external" href="https://lafibre.info/4g-bytel/optim-ttl/">Comment modifier le TTL de sa connexion</a> pour limiter le tethering</li>
</ul>
</div>
Serveur Openvpn sous Debian 9 et systemd2017-12-12T10:25:00+01:002017-12-12T10:25:00+01:00Victortag:blog.victor-hery.com,2017-12-12:/2017/12/serveur-openvpn-sous-debian-9-et-systemd.html
<h1 id="openvpn-debian-9-et-systemd">Openvpn, Debian 9 et Systemd</h1>
<p>Pas mal de choses ont changées dans la configuration d'un serveur openvpn avec l'arrivée de Debian 9 et la "séparation" de easy-rsa et openvpn.</p>
<p>Entre les services systemd et le fait qu'Openvpn ne vient plus nativement avec easy-rsa, il me fallait une petite remise au …</p>
<h1 id="openvpn-debian-9-et-systemd">Openvpn, Debian 9 et Systemd</h1>
<p>Pas mal de choses ont changées dans la configuration d'un serveur openvpn avec l'arrivée de Debian 9 et la "séparation" de easy-rsa et openvpn.</p>
<p>Entre les services systemd et le fait qu'Openvpn ne vient plus nativement avec easy-rsa, il me fallait une petite remise au point sur le sujet !</p>
<p>C'est chose faite :-)</p>
<p>On va donc voir dans cet article comment configurer un serveur Openvpn sur Debian 9, puis comment faire en sorte qu'il se lance tout seul via les services systemd.<br/>
Normalement cette procédure devrait fonctionner pour toutes les versions de Debian supérieure à Debian 9 Stretch.</p>
<p>Je précise que je vais traiter la partie serveur VPN uniquement. Je pars donc du principe que vous disposez déjà d'un serveur sous Debian 9 (physique, VM, CT, ...), que ce serveur dispose d'une IP publique pour exposer le serveur Openvpn, et/ou que vous maitrisez le NAT de port pour faire en sorte qu'il le soit (exposé :-p)<br/>
J'assume totalement le fait que cet article est un bloc note pour garder les infos sous la mains en cas de besoin ! </p>
<p>D'un autre côté vous me connaissez, je suis obligé de détailler, donc comme d'habitude, si vous rencontrez des difficultés ou que vous avez besoin d'aide, faites moi signe dans les commentaires !</p>
<h1 id="preparation-du-serveur">Préparation du serveur</h1>
<h2 id="paquets-et-repertoires">Paquets et répertoires</h2>
<p>Sur Debian 9, il faut désormais installer 2 paquets pour gérer openvpn en mode serveur.<br/>
Ils sont disponibles par défaut, donc pas de tergiversations :</p>
<div class="highlight"><pre><span></span><code><span class="err">aptitude install openvpn easy-rsa</span>
</code></pre></div>
<p>Par convention, on va poser les fichiers dans <code>/etc/openvpn</code>, c'est parti :</p>
<div class="highlight"><pre><span></span><code>cd /etc/openvpn
YOURSERVER="yourserver"
make-cadir <span class="cp">${</span><span class="n">YOURSERVER</span><span class="cp">}</span>
</code></pre></div>
<p>Cela va permettre à easy-rsa d'initialiser un répertoire contenant tous les fichiers (binaires, configurations) pour générer et gérer les clefs, comptes et autre index qui vont servir à votre serveur openvpn.<br/>
Il faut également lui indiquer quel fichier de conf openssl on va utiliser, pas de chichi faites un lien vers le plus récent :</p>
<div class="highlight"><pre><span></span><code>cd /etc/openvpn/<span class="cp">${</span><span class="n">YOURSERVER</span><span class="cp">}</span>
ln -s openssl-1.0.0.cnf openssl.cnf
</code></pre></div>
<h2 id="variables">Variables</h2>
<p>Comme d'habitude avec Openvpn, on va utiliser le fichier vars qui contient les différentes variables utiles à la génération des clefs.</p>
<p>Editez donc le fichier <code>vars</code> et modifiez les valeurs suivantes pour gagner du temps par la suite :</p>
<div class="highlight"><pre><span></span><code>vim /etc/openvpn/<span class="cp">${</span><span class="n">YOURSERVER</span><span class="cp">}</span>/vars
# -----
export KEY_SIZE=4096 # Une clef de 4096 est le minimum actuellement pour un chiffrement correct
export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain
"
export KEY_OU="MyOrganizationalUnit"
export KEY_NAME="VPNServerName" # Choisissez un nom qui vous parlera, même dans 6 mois !
</code></pre></div>
<p>Bien entendu modifiez les différentes valeurs pour coller à vos propres souhaits. Cela vous permettra d'avoir une bonne configuration par défaut pour générer plus rapidement les différentes clefs.</p>
<h2 id="clefs-serveur">Clefs serveur</h2>
<p>On est désormais prêt pour générer toutes les clefs qui vont permettre au serveur de fonctionner, avec un maximum de sécurité.<br/>
Cette partie peut être longue, selon votre CPU et le niveau d'entropie de votre serveur. Plus le CPU est costaud et le serveur est physique, plus ça ira vite, mais dans le cas contraire prenez votre mal en patience, ça va se dépiler ;-) </p>
<p>Je vous invite d'ailleurs à aller jeter un oeil à mon article sur <a href="https://blog.victor-hery.com/2017/12/ameliorer-l-entropie-de-votre-serveur.html">l'amélioration de l'entropie pour votre serveur</a>. </p>
<p>Sinon, soit vous disposez d'un bon gros serveur physique des familles, soit vous avez 2 ou 3 thermos de café prêts pour passer le temps ^^</p>
<p>C'est parti !</p>
<div class="highlight"><pre><span></span><code>cd /etc/openvpn/<span class="cp">${</span><span class="n">YOURSERVER</span><span class="cp">}</span>
source ./vars # On export toutes les variables qu'on a editées
# ./clean-all ## ATTENTION ne lancez cette commande que la toute première fois ou vous initialiser votre serveur, car elle va effacer TOUTES les clefs du serveur !
./build-ca # Pour construire le certificat d'authorité de votre serveur
</code></pre></div>
<p>Notre autorité est prête, on va pouvoir passer aux clefs du serveur en tant que telles :</p>
<div class="highlight"><pre><span></span><code>cd /etc/openvpn/<span class="cp">${</span><span class="n">YOURSERVER</span><span class="cp">}</span>
./build-key-server <span class="cp">${</span><span class="n">YOURSERVER</span><span class="cp">}</span> # <span class="cp">${</span><span class="n">YOURSERVER</span><span class="cp">}</span> indique le nom de la clef générée, vous pouvez bien sûr l'adapter
</code></pre></div>
<p>On génère également une clef HMAC :</p>
<div class="highlight"><pre><span></span><code>openvpn --genkey --secret /etc/openvpn/<span class="cp">${</span><span class="n">YOURSERVER</span><span class="cp">}</span>/keys/ta.key
</code></pre></div>
<p>Attention, l'étape suivante est probablement la plus longue.<br/>
Il va falloir générer une clef <a href="https://fr.wikipedia.org/wiki/%C3%89change_de_cl%C3%A9s_Diffie-Hellman">Diffie Hellman</a> de 4096 bits. Cela peut assez facilement prendre des heures si votre CPU est faiblard (bonjour, Intel Atom !). N'hésitez pas à la lancer dans un tmux pour qu'elle tourne tranquillement, et continuez à dérouler la procédure pendant ce temps.</p>
<div class="highlight"><pre><span></span><code>cd /etc/openvpn/<span class="cp">${</span><span class="n">YOURSERVER</span><span class="cp">}</span>
openssl dhparam 4096 > keys/dh-4096.pem
</code></pre></div>
<p>On dispose de toutes nos clefs, il est temps d'attaquer la configuration !</p>
<h2 id="configuration-de-base-et-securite">Configuration de base et sécurité</h2>
<p>Openvpn vient sur Debian avec une configuration exemple que l'on va simplement réutiliser :</p>
<div class="highlight"><pre><span></span><code>gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > /etc/openvpn/<span class="cp">${</span><span class="n">YOURSERVER</span><span class="cp">}</span>.conf
</code></pre></div>
<p>Le fichier est auto-documenté de manière assez complète grâce à ses commentaires. Quelques variables sont bien entendus à changer pour que tout fonctionne, on va s'y intéresser de plus près :-)<br/>
Editez manuellement le fichier pour modifier les quelques variables qui nous intéressent</p>
<div class="highlight"><pre><span></span><code>vim /etc/openvpn/<span class="cp">${</span><span class="n">YOURSERVER</span><span class="cp">}</span>.conf
</code></pre></div>
<p>puis :</p>
<div class="highlight"><pre><span></span><code><span class="err">ca /etc/openvpn/YOURSERVER/keys/ca.crt</span>
<span class="err">cert /etc/openvpn/YOURSERVER/keys/server.crt</span>
<span class="err">key /etc/openvpn/YOURSERVER/keys/server.key # This file should be kept secret</span>
<span class="err">dh /etc/openvpn/YOURSERVER/keys/dh-4096.pem</span>
<span class="err">tls-auth /etc/openvpn/YOURSERVER/keys/ta.key 0 # This file is secret</span>
</code></pre></div>
<p><strong>Bien sûr, remplacez YOURSERVER par le chemin vers vos clefs !</strong><br/>
Les configuration suivantes vont permettre de relever un peu plus le niveau de sécurité du serveur, au prix d'une utilisation CPU un peu plus intensive. Mais vu l'époque, c'est nécessaire..</p>
<div class="highlight"><pre><span></span><code><span class="err">cipher AES-256-CBC</span>
<span class="err">auth SHA512</span>
<span class="err">tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA:TLS-DHE-RSA-WITH-AES-128-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA</span>
</code></pre></div>
<h2 id="utilisateur-openvpn">Utilisateur Openvpn</h2>
<p>Openvpn tourne en root par défaut, ce qui bien entendu est <strong>mal</strong>. Traditionnellement, on le configure donc pour utiliser l'utilisateur nobody ainsi que son groupe associé pour le lancer.<br/>
Cependant, pour limiter les risques de compromission, il est je pense préférable de le faire tourner avec son propre utilisateur. Après tout, nobody peut être utilisé par d'autres services à côté.</p>
<div class="highlight"><pre><span></span><code><span class="err">adduser --system --shell /usr/sbin/nologin --no-create-home openvpn</span>
</code></pre></div>
<p>Puis dans votre configuration openvpn :</p>
<div class="highlight"><pre><span></span><code><span class="err">user openvpn</span>
<span class="err">group nogroup</span>
</code></pre></div>
<h2 id="demarrer-le-serveur">Démarrer le serveur</h2>
<p>Enfin ! On arrive à la subtilité d'openvpn avec systemd : lancer le serveur :-) </p>
<p>Heureusement une fois qu'on a choppé le coup, le concept reste assez simple. En fait, openvpn propose une unit systemd, qui va permettre d'aller chercher votre fichier de configuration dans <code>/etc/openvpn</code> et de le gérer avec systemctl comme n'importe quel service :</p>
<div class="highlight"><pre><span></span><code>systemctl start openvpn
systemctl start openvpn@<span class="cp">${</span><span class="n">YOURSERVER</span><span class="cp">}</span>
</code></pre></div>
<p>Comme on le voit, il suffit de donner à systemctl le nom de votre fichier de conf (sans le .conf), et il va s'occuper de le démarrer.<br/>
Si vous disposez de plusieurs fichiers de configuration, il vous suffit de lancer autant de service @votrefichierdeconf que vous le souhaitez.</p>
<p>Vous pouvez vérifier qu'ils ont bien démarrés avec <code>systemctl status</code>, et je vous conseille également de les activer au démarrage :</p>
<div class="highlight"><pre><span></span><code>systemctl enable openvpn
systemctl enable openvpn@<span class="cp">${</span><span class="n">YOURSERVER</span><span class="cp">}</span>
</code></pre></div>
<p>Voila, côté serveur, on a finit !</p>
<p>PS : Si vous utilisez un container openvz, il peut y avoir quelques subtilités supplémentaires. Je vous invite à vérifier à la fin de l'article ;-)</p>
<h1 id="generation-des-clients">Génération des clients</h1>
<p>Comme pour le serveur, la génération d'un compte VPN client va se faire en deux phases : les clefs et le fichier de configuration.</p>
<h2 id="clefs-client">Clefs client</h2>
<p>On retourne dans le répertoire de votre serveur VPN :</p>
<div class="highlight"><pre><span></span><code>cd /etc/openvpn/<span class="cp">${</span><span class="n">YOURSERVER</span><span class="cp">}</span>
source ./vars
./build-key nom_du_client
</code></pre></div>
<p>De préférence, indiquez un mot de passe pour la clef, sauf si vous savez que votre client se connectera en mode automatique (par exemple au démarrage du PC client) </p>
<p>Voila, vous avez vos clefs pour votre premier compte client VPN.</p>
<h2 id="configuration-client">Configuration client</h2>
<p>On va là aussi récupérer la configuration exemple fournie par openvpn. Je vous conseille d'ailleurs de vous créer un petit répertoire où caler toutes vos configurations clients, ça sera plus pratique :</p>
<div class="highlight"><pre><span></span><code>mkdir /etc/openvpn/<span class="cp">${</span><span class="n">YOURSERVER</span><span class="cp">}</span>/clients
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/<span class="cp">${</span><span class="n">YOURSERVER</span><span class="cp">}</span>/clients/nom_du_client.ovpn
</code></pre></div>
<p>Quelques champs vont bien sûr devoir être édités !</p>
<div class="highlight"><pre><span></span><code><span class="err">remote 192.168.1.5 1194 # Mettez ici l'IP de votre serveur VPN et le port utilisé (par défaut 1194 en UDP)</span>
<span class="err">user nobody</span>
<span class="err">group nogroup</span>
<span class="err">ca ca.crt</span>
<span class="err">cert nom_du_client.crt</span>
<span class="err">key nom_du_client.key</span>
<span class="err">tls-auth ta.key 1</span>
<span class="err">cipher AES-256-CBC</span>
<span class="err">auth SHA512</span>
<span class="err">tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA:TLS-DHE-RSA-WITH-AES-128-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA</span>
</code></pre></div>
<p>Il faut bien sur remettre les options de chiffrement et d'authentification mise dans le serveur, sinon le client ne pourra pas lui parler :-)<br/>
Pensez également à bien mettre les noms de clefs correspondant au client (pas celles du serveur). Les deux champs ca.crt et ta.key sont des exceptions, ce sont bien les fichiers du serveurs qu'il faut indiquer ici.</p>
<p>Préparons ensuite le fichier à envoyer au client, avec tout ce qui va bien dedans :</p>
<div class="highlight"><pre><span></span><code># tar cJf /etc/openvpn/<span class="cp">${</span><span class="n">YOURSERVER</span><span class="cp">}</span>/clients/nom_du_client.tar.xz -C /etc/openvpn/<span class="cp">${</span><span class="n">YOURSERVER</span><span class="cp">}</span>/keys ca.crt nom_du_client.crt nom_du_client.key ta.key -C /etc/openvpn/<span class="cp">${</span><span class="n">YOURSERVER</span><span class="cp">}</span>/clients/ nom_du_client.ovpn
</code></pre></div>
<p>Et voila, vous avez votre compte client à transmettre à votre utilisateur.</p>
<p>Je vous conseille de le tester par vous même, par exemple depuis votre PC, pour être sûr que tout est OK.</p>
<h2 id="connexion-client-automatique">Connexion client automatique</h2>
<p>Si vous utilisez ce compte pour une machine qui doit se connecter de manière automatique à votre VPN, vous pouvez là encore utiliser systemd. Attention, sur la machine cliente !</p>
<p>Détarez votre archive dans le <code>/etc/openvz</code> de votre client (vous avez bien entendu installé openvpn dessus ;-) )</p>
<div class="highlight"><pre><span></span><code><span class="err">cd /etc/openvpn</span>
<span class="err">tar xJf /path/to/nom_du_client.tar.xz</span>
</code></pre></div>
<p>Il vous suffit ensuite d'activer le service openvpn, qui devrait lancer le fichier de conf.<br/>
<strong>Attention</strong>, selon les versions il faudra peut être renommer le fichier de configuration en .conf au lieu de .ovpn. Linux préfère les .conf, Windows les .ovpn.</p>
<div class="highlight"><pre><span></span><code><span class="err">systemctl start openvpn</span>
<span class="err">systemctl start openvpn@nom_du_client</span>
<span class="err">systemctl enable openvpn</span>
<span class="err">systemctl enable openvpn@nom_du_client</span>
</code></pre></div>
<p>Et voila votre connexion s'établit :-)</p>
<p>Vous devriez désormais posséder un serveur VPN parfaitement fonctionnel avec systemd, félicitations !</p>
<p>N'hésitez pas à approfondir le fonctionnement d'openvpn, de nombreuses configurations sont possibles, et laissez moi un commentaire si jamais vous souhaitez plus de détails sur quelque chose ;-)</p>
<h1 id="configuration-avancee">Configuration avancée</h1>
<p>On est parti ici de la configuration par défaut. Vous avez donc un serveur VPN qui écoute sur toutes les interfaces du serveur, sur le port standard openvpn 1194 en UDP, qui utilise tun et une plage d'ip en 10.8.0.0/24, etc, etc</p>
<p>Il est possible d'aller beaucoup plus loin dans la configuration, en modifiant les plages IP, en branchant le VPN sur un bridge pour étendre un réseau local à travers le VPN, pour lancer des scripts au démarrage du VPN, améliorer les logs, et pleins d'autres choses encore.</p>
<p>Personnellement je me sers d'openvpn pour étendre le LAN de mon chez moi sur tous mes serveurs virtuels, ce qui permet de les joindres comme s'ils étaient dans la maison.</p>
<p>Je ferai (probablement) d'autres articles à ce propos, si ça vous intéresse, n'hésitez pas à me laisser un petit commenaire !</p>
<h1 id="openvpn-et-openvz-7">Openvpn et Openvz (7)</h1>
<p>Si vous utilisez un container openvz pour faire tourner votre serveur VPN, il faut savoir qu'il y a quelques subtilités à mettre en place, sans quoi votre serveur refusera de démarrer, ou ne pourra pas atteindre les autres CT hébergés.</p>
<h2 id="activer-tuntap-dans-un-ct">Activer tun/tap dans un CT</h2>
<p>Sur les versions antérieures d'openvz, il fallait activer les capability admin ainsi que tun/tap sur le CT depuis l'hyperviseur pour que openvpn puisse démarrer. Pour plus d'information, veuillez vous référer au <a href="https://openvz.org/VPN_via_the_TUN/TAP_device">wiki</a></p>
<p>Sur <strong>openvz7</strong>, un CT doit toujours avoir ces options activées, MAIS les commandes vzctl n'ont plus aucun effet !<br/>
Il semble qu'à l'heure actuelle, l'activation ne marche pas. vzctl se termine avec succès, dit que tout est ok, mais rien n'est activé, et prlctl ne connait pas ces options...</p>
<p>Il est donc nécessaire d'activer directement ces options dans le fichier de conf du CT..</p>
<div class="highlight"><pre><span></span><code><span class="err">vim /etc/vz/conf/CTID.conf</span>
<span class="err">#Ajoutez les lignes suivantes :</span>
<span class="err">FEATURES="bridge:on"</span>
<span class="err">DEVNODES="net/tun:rw "</span>
<span class="err">DEVICES="c:10:200:rw "</span>
<span class="err">CAPABILITY=" NET_ADMIN:on"</span>
</code></pre></div>
<p>Il est ensuite nécessaire de redémarrer le CT</p>
<div class="highlight"><pre><span></span><code><span class="err">prlctl restart CTID</span>
</code></pre></div>
<h2 id="pas-de-communication-entre-client-vpn-et-les-autres-ct">Pas de communication entre client VPN et les autres CT</h2>
<p>Si vous utilisez votre VPN en tant que pont pour vous permettre d'accéder à d'autres CT hébergés, voir à des serveurs physiques présents derrière le VPN, par exemple via un VLAN ou une interface bridge, il faut savoir que à partir de openvz7, un <a href="https://fr.wikipedia.org/wiki/Usurpation_d%27adresse_IP">anti-spoofing</a> est présent par défaut quand on mets une interface réseau à un CT. Ce dernier ne peut donc pas sortir avec une IP que l'hyperviseur ne connait pas dans le cas d'un venet, ou dans le cas d'un veth avec une MAC que l'hyperviseur ne connait pas.</p>
<p>Ce qui bien evidemment pose souci si vous souhaitez utiliser des adresses IP derrière votre serveurs VPN. </p>
<p>Plutôt que monter un NAT, et si vous avez confiance dans votre réseau, vous pouvez désactiver cet anti-spoofing pour le CT qui contient votre serveur VPN.<br/>
Il va falloir supprimer son interface réseau et la recréer, à l'heure actuelle prlctl ne gère pas de "set" pour cette option, uniquement un "add" :</p>
<div class="highlight"><pre><span></span><code><span class="err">prlctl set CTID --device-del eth0</span>
<span class="err">prlctl set CTID --device-add net --network votre_reseau --macfilter no eth0</span>
</code></pre></div>
<h2 id="daemon-failed-or-unsupported-resource-temporarily-unavailable">daemon() failed or unsupported: Resource temporarily unavailable</h2>
<p>Vous obtenez cette erreur parfaitement cryptique au démarrage d'Openvpn ?</p>
<p>C'est normal ! :-D<br/>
Openvpn dans son unit systemd par défaut, limite le nombre de process à 10, sauf que dans un CT, vous n'avez pas les droits pour gérer ce genre d'option, qui sont gérées via l'hyperviseur et les limitations accordé au CT.</p>
<p>Pour ça pas le choix, il va falloir éditer cette ligne dans la configuration de l'unit systemd directement..</p>
<div class="highlight"><pre><span></span><code><span class="err">vim /lib/systemd/system/openvpn@.service</span>
<span class="err"># Commentez la ligne LimitNPROC=10</span>
<span class="err">LimitNPROC=10 => # LimitNPROC=10</span>
</code></pre></div>
<p>Puis reloadez les unit systemd :</p>
<div class="highlight"><pre><span></span><code><span class="err">systemctl daemon-reload</span>
</code></pre></div>
<p>Votre openvpn devrait ensuite fonctionner.</p>
<p>Cf ce <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=819919">bugreport</a></p>Ameliorer l'entropie de votre serveur2017-12-08T11:04:00+01:002017-12-08T11:04:00+01:00Victortag:blog.victor-hery.com,2017-12-08:/2017/12/ameliorer-l-entropie-de-votre-serveur.html
<h1 id="gimme-me-more-entropy">Gimme me more Entropy !</h1>
<p>La génération de clef privée sécurisée se sert de l'entropie dont dispose votre serveur.<br/>
Très grossièrement (pardon aux puristes), l'entropie représente la qualité de l'aléatoire du votre serveur, la prédictabilité des résultats de certaines commandes. Plus il y a d'entropie, plus vite et plus efficacement vous …</p>
<h1 id="gimme-me-more-entropy">Gimme me more Entropy !</h1>
<p>La génération de clef privée sécurisée se sert de l'entropie dont dispose votre serveur.<br/>
Très grossièrement (pardon aux puristes), l'entropie représente la qualité de l'aléatoire du votre serveur, la prédictabilité des résultats de certaines commandes. Plus il y a d'entropie, plus vite et plus efficacement vous pouvez générer des clefs (entre autres).</p>
<p>Sur un serveur physique avec un CPU récent, l'entropie est en générale assez élevée. Sur des VM ou si votre CPU est trop basique, elle peut être très faible, et cela augmente de manière assez exponentielle le temps de génération des clefs...<br/>
Vous pouvez voir l'entropie disponible sur votre serveur grâce à</p>
<div class="highlight"><pre><span></span><code><span class="err">cat /proc/sys/kernel/random/entropy_avail</span>
</code></pre></div>
<p>En général, une valeur inférieure à 1000 est assez mauvais signe. Attention sur un Containeur (openvz notamment), cela affiche directement l'entropie de l'hyperviseur, mais openssl sera extrêmement lent même si l'entropie est élevée...</p>
<p>Je vais ici m'inspirer de l'excellent article <a href="https://www.cyberciti.biz/open-source/debian-ubuntu-centos-linux-setup-additional-entropy-for-server-using-aveged-rng-tools-utils/">How to speed up OpenSSL/GnuPG Entropy</a> du tout autant excellent <a href="https://www.cyberciti.biz/">NixCraft</a>. Référez vous aux Sources en fin d'article pour plus de références :-)</p>
<h2 id="testez-votre-entropie">Testez votre entropie</h2>
<p>Il existe un outil qui permet de tester la qualité et la vitesse de génération de l'entropie de votre serveur.<br/>
Il s'agit de <strong>rng-tools</strong>.</p>
<p>Cet outil est disponible sous debian et centos :</p>
<div class="highlight"><pre><span></span><code><span class="n">apt</span><span class="o">-</span><span class="k">get</span> <span class="n">install</span> <span class="n">rng</span><span class="o">-</span><span class="n">tools</span>
<span class="n">systemctl</span> <span class="n">stop</span> <span class="n">rngd</span><span class="p">.</span><span class="n">service</span> <span class="o">#</span> <span class="n">Le</span> <span class="n">daemon</span> <span class="n">rngd</span> <span class="n">est</span> <span class="n">installé</span> <span class="n">avec</span> <span class="n">les</span> <span class="n">tools</span><span class="p">,</span> <span class="n">mais</span> <span class="k">on</span> <span class="n">le</span> <span class="n">coupe</span> <span class="n">sinon</span> <span class="err">ç</span><span class="n">a</span> <span class="n">fausse</span> <span class="n">les</span> <span class="n">tests</span> <span class="p">;</span><span class="o">-</span><span class="p">)</span>
<span class="n">yum</span> <span class="n">install</span> <span class="n">epel</span><span class="o">-</span><span class="n">release</span>
<span class="n">yum</span> <span class="n">install</span> <span class="n">rng</span><span class="o">-</span><span class="n">tools</span><span class="p">.</span><span class="n">x86_64</span>
<span class="n">systemctl</span> <span class="n">stop</span> <span class="n">rngd</span><span class="p">.</span><span class="n">service</span> <span class="o">#</span> <span class="n">Le</span> <span class="n">daemon</span> <span class="n">rngd</span> <span class="n">est</span> <span class="n">installé</span> <span class="n">avec</span> <span class="n">les</span> <span class="n">tools</span><span class="p">,</span> <span class="n">mais</span> <span class="k">on</span> <span class="n">le</span> <span class="n">coupe</span> <span class="n">sinon</span> <span class="err">ç</span><span class="n">a</span> <span class="n">fausse</span> <span class="n">les</span> <span class="n">tests</span> <span class="p">;</span><span class="o">-</span><span class="p">)</span>
</code></pre></div>
<p>Et il va vous permettre de tester le <code>/dev/random</code> de votre PC/serveur/VM/whatever pour faire quelques benchmark afin de vérifier si vous pouvez réellement améliorer la qualité de l'entropie.</p>
<p>Une fois l'outil installé, c'est très simple :</p>
<div class="highlight"><pre><span></span><code><span class="err">cat /dev/random | rngtest -c 1 # 1, parce que si votre entropie est mauvaise, avec plus vous êtes partis pour des heures...</span>
</code></pre></div>
<p>La commande peut prendre trèès longtemps selon la qualité actuelle de votre entropie, mais notez le résultat, ça servira pour comparer plus tard :-)<br/>
Notez particulièrement le "input channel speed" qui est vraiment très lent par défaut (de l'ordre du bit/s).</p>
<h2 id="quelques-exemples-pour-comparaison">Quelques exemples pour comparaison</h2>
<p>Parce que le nions pas, c'est toujours d'actualité de savoir qui a la plus grosse !<br/>
Par ordre de puissance :</p>
<p><strong> Xeon(R) E3-1241 v3 @ 3.50GHz </strong> : input channel speed: (min=90.908; avg=90.908; max=90.908)bits/s ---- Program run time: 220002767 microseconds<br/>
<strong> Core i7-3632QM @ 2.20GHz </strong> : input channel speed: (min=33.471; avg=33.471; max=33.471)bits/s ---- Program run time: 597524821 microseconds<br/>
<strong> Pentium(R) G3450 @ 3.40GHz </strong> : input channel speed: (min=25.983; avg=25.983; max=25.983)bits/s ---- Program run time: 769745403 microseconds<br/>
<strong> Atom(TM) N2800 @ 1.86GHz </strong> (à l'intérieur d'un containeur) : input channel speed: (min=37.391; avg=37.391; max=37.391)bits/s ---- Program run time: 534922002 microseconds </p>
<p>Je précise pour la science que ces tests sont fait sur des machines en production, donc avec le CPU fortement sollicité, difficile de déterminer exactement en quoi cela impacte l'entropie..<br/>
On voit d'ailleurs que ce n'est pas forcément le CPU le plus costaud qui est le plus efficace !</p>
<h1 id="lentropie-lunivers-et-le-reste-avec-rngd">L'entropie, l'univers et le reste avec RNGD</h1>
<p>Voyons maintenant comme on peut améliorer tout ça :-)</p>
<p>rng-tools vient par défaut avec rngd : un daemon dont l'unique rôle est de générer plus d'entropie à travers le matériel présent sur le serveur :-)</p>
<p>Si vous êtes sur un serveur physique, il ne devrait pas y avoir trop de souci. Le service rngd devrait démarrer sans douleur.<br/>
<strong> Debian : </strong></p>
<div class="highlight"><pre><span></span><code><span class="err">systemctl start rng-tools</span>
</code></pre></div>
<p><strong> Centos : </strong></p>
<div class="highlight"><pre><span></span><code><span class="err">systemctl start rngd.service</span>
</code></pre></div>
<p>Vous pouvez ensuite vérifier qu'il tourne bien avec le classique <code>systemctl status nom_du_service</code></p>
<p>Après ça, ça va dépoter fort !</p>
<div class="highlight"><pre><span></span><code><span class="err">cat /dev/random | rngtest -c 1</span>
</code></pre></div>
<p>Comparé à tout à l'heure : </p>
<p><strong> Xeon(R) E3-1241 v3 @ 3.50GHz </strong> : input channel speed: (min=327.959; avg=327.959; max=327.959)Kibits/s ---- Program run time: 59779 microseconds<br/>
<strong> Core i7-3632QM @ 2.20GHz </strong> : input channel speed: (min=744.473; avg=744.473; max=744.473)Kibits/s ---- Program run time: 26636 microseconds</p>
<p>On voit que le temps s'est incomparablement amélioré pour sortir 1 passe aléatoire. On peut même obtenir des temps bien plus raisonnables sur de très longues passe, 1000 par exemple :</p>
<div class="highlight"><pre><span></span><code><span class="err">cat /dev/random | rngtest -c 1000</span>
</code></pre></div>
<p>Nous donne :</p>
<div class="highlight"><pre><span></span><code><span class="n">rngtest</span><span class="o">:</span> <span class="n">input</span> <span class="n">channel</span> <span class="n">speed</span><span class="o">:</span> <span class="o">(</span><span class="n">min</span><span class="o">=</span><span class="mf">296.094</span><span class="o">;</span> <span class="n">avg</span><span class="o">=</span><span class="mf">520.690</span><span class="o">;</span> <span class="n">max</span><span class="o">=</span><span class="mf">1218.039</span><span class="o">)</span><span class="n">Kibits</span><span class="o">/</span><span class="n">s</span>
<span class="n">rngtest</span><span class="o">:</span> <span class="n">Program</span> <span class="n">run</span> <span class="n">time</span><span class="o">:</span> <span class="mi">37824064</span> <span class="n">microseconds</span>
</code></pre></div>
<p>On voit clairement l'amélioration.</p>
<p>Si par contre RNGD démarre pas correctement, les sections suivantes discutent de solutions possibles.</p>
<h1 id="pas-de-source-dentropie">Pas de source d'entropie ?</h1>
<p>Vous pouvez obtenir au démarrage les erreurs suivantes :</p>
<div class="highlight"><pre><span></span><code><span class="err">read error</span>
<span class="c">hwrng: no available rng</span>
<span class="err">Unable to open file: /dev/tpm0</span>
<span class="err">can't open any entropy source</span>
<span class="err">Maybe RNG device modules are not loaded</span>
</code></pre></div>
<p>Ou :</p>
<div class="highlight"><pre><span></span><code><span class="err">Starting Hardware RNG entropy gatherer daemon: (Hardware RNG device inode not found)</span>
<span class="err">/etc/init.d/rng-tools: Cannot find a hardware RNG device to use.</span>
</code></pre></div>
<p>Dans ces 2 cas, cela signifie que votre serveur ne dispose d'aucun composant matériel permettant de générer de l'entropie. Dit plus simplement, votre CPU est trop pourri...</p>
<p>Vous pouvez vérifier si rngd trouve un générateur d'entropie avec :</p>
<div class="highlight"><pre><span></span><code><span class="err"># rngd -v # Avec le -v sous Centos, ou sans le -v sous debian</span>
<span class="err">/dev/hwrng: No such device</span>
<span class="err">/dev/tpm0: No such file or directory</span>
<span class="err">Available entropy sources:</span>
<span class="err">DRNG</span>
</code></pre></div>
<p>(ici il a par exemple trouvé DRNG comme source)</p>
<h2 id="trick-avec-rngd-pour-la-culture-generale">Trick avec RNGD (Pour la culture générale)</h2>
<p>(va y avoir du <strong>gras</strong> dans le texte)<br/>
Une des solutions peut consister à configurer rngd pour se nourrir de <code>/dev/urandom</code>.</p>
<p><strong>MAIS</strong> (je mets un gros MAIS) cette solution n'est pas idéale, voir même dangereuse !<br/>
En effet, on se retrouve alors à nourrir <code>/dev/random</code> avec <code>/dev/urandom</code>, ce qui revient à tromper le système en lui faisant croire que ces 2 périphériques donnent des résultats aléatoires différents <strong>alors que ce sont les mêmes</strong>.</p>
<p>En conséquence, bien que le système pense que l'entropie augmente, elle est en fait de très mauvaise qualité, et dans certains cas elle peut même <strong>décroître</strong> en réalité.</p>
<p>Si vous comptez vous servir de votre entropie pour de la production (et notamment des clefs de chiffrement) cette technique est <strong>à éviter </strong> !</p>
<p>Mais comme je sais que vous êtes curieux, je vous la mets quand même pour la culture générale :-)</p>
<p>On va se servir de systemd pour modifier les options de lancement du daemon rngd et lui forcer <code>/dev/urandom</code> comme source d'entropie.</p>
<p><strong> Debian </strong></p>
<div class="highlight"><pre><span></span><code><span class="err">mkdir -p /etc/systemd/system/rng-tools.service.d</span>
<span class="err">vim /etc/systemd/system/rng-tools.service.d/customexec.conf</span>
</code></pre></div>
<p>Indiquez dans le fichier :</p>
<div class="highlight"><pre><span></span><code><span class="k">[Service]</span>
<span class="na">ExecStart</span><span class="o">=</span>
<span class="na">ExecStart</span><span class="o">=</span><span class="s">/usr/sbin/rngd -f -r /dev/urandom</span>
</code></pre></div>
<p><strong> Centos </strong></p>
<div class="highlight"><pre><span></span><code><span class="err">mkdir -p /etc/systemd/system/rngd.d/</span>
<span class="err">vim /etc/systemd/system/rngd.service.d/customexec.conf</span>
</code></pre></div>
<p>Indiquez dans le fichier :</p>
<div class="highlight"><pre><span></span><code><span class="k">[Service]</span>
<span class="na">ExecStart</span><span class="o">=</span>
<span class="na">ExecStart</span><span class="o">=</span><span class="s">/sbin/rngd -f -r /dev/urandom</span>
</code></pre></div>
<p>Et redémarrez ensuite le service (rng-tools sous Debian, rngd sous Centos).<br/>
<strong>Je le répète, cette méthode n'est pas à utiliser en production !</strong></p>
<p>On voit que les résultat d'un test d'entropie sont bien plus rapides, mais la qualité ne sera pas au rendez vous :</p>
<div class="highlight"><pre><span></span><code><span class="nt">cat</span> <span class="o">/</span><span class="nt">dev</span><span class="o">/</span><span class="nt">random</span> <span class="o">|</span> <span class="nt">rngtest</span> <span class="nt">-c</span> <span class="nt">1000</span>
<span class="nt">rngtest</span><span class="o">:</span> <span class="nt">input</span> <span class="nt">channel</span> <span class="nt">speed</span><span class="o">:</span> <span class="o">(</span><span class="nt">min</span><span class="o">=</span><span class="nt">2</span><span class="p">.</span><span class="nc">918</span><span class="o">;</span> <span class="nt">avg</span><span class="o">=</span><span class="nt">19</span><span class="p">.</span><span class="nc">656</span><span class="o">;</span> <span class="nt">max</span><span class="o">=</span><span class="nt">41</span><span class="p">.</span><span class="nc">374</span><span class="o">)</span><span class="nt">Mibits</span><span class="o">/</span><span class="nt">s</span>
<span class="nt">rngtest</span><span class="o">:</span> <span class="nt">Program</span> <span class="nt">run</span> <span class="nt">time</span><span class="o">:</span> <span class="nt">1110683</span> <span class="nt">microseconds</span>
</code></pre></div>
<h2 id="utilisation-de-haveged-bon-pour-la-production">Utilisation de Haveged (bon pour la production)</h2>
<p>La solution marrante mais moche étant vue, voyons comment s'en tirer sans générateur matériel, de manière réellement utilisable.</p>
<p>Ici, tant qu'à devoir utiliser du logiciel pour générer de l'aléatoire (c'était le concept de <code>/dev/urandom</code>), on va utiliser un algorithme qui est conçu pour et maitrisé :-)<br/>
Cet algorithme, c'est <a href="http://www.irisa.fr/caps/projects/hipsor/">HAVEGE</a>, et nous allons l'utiliser via le daemon <a href="http://issihosts.com/haveged/index.html">haveged</a>.</p>
<p>Il suffit donc d'installer le paquet et d'activer le service (désactivé par défaut) :</p>
<p><strong> Debian </strong></p>
<div class="highlight"><pre><span></span><code><span class="err">aptitude install haveged</span>
<span class="err">systemctl disable rng-tools.service # On désactive rngd pour être sûr de pas avoir de conflits</span>
<span class="err">systemctl start haveged</span>
<span class="err">systemctl enable haveged</span>
</code></pre></div>
<p>Dans le cas de Debian, allez modifier la configuration de <code>/etc/default/haveged</code> pour indiquer : <code>DAEMON_ARGS="-w 1024"</code>.</p>
<p><strong> Centos </strong></p>
<div class="highlight"><pre><span></span><code><span class="err">yum install haveged</span>
<span class="err">systemctl disable rngd.service # On désactive rngd pour être sûr de pas avoir de conflits</span>
<span class="err">systemctl start haveged</span>
<span class="err">systemctl enable haveged</span>
</code></pre></div>
<p>Vous pouvez aussi le laisser désactivé (systemctl disable) et ne le démarrer qu'en cas de besoin.</p>
<p>Avec Haveged, on obtiens également de très bon résultats lors des tests !<br/>
Pour 1000 passes :</p>
<p><strong> Pentium(R) G3450 @ 3.40GHz </strong> : input channel speed: (min=2.708; avg=19.129; max=34.553)Mibits/s ---- Program run time: 1196145 microseconds<br/>
<strong> Atom(TM) N2800 @ 1.86GHz </strong> (à l'intérieur d'un containeur) : input channel speed: (min=484.190; avg=5526.698; max=3906250.000)Kibits/s ---- Program run time: 4801478 microseconds</p>
<h2 id="le-cas-des-containeurs">Le cas des Containeurs</h2>
<p>Si vous utilisez des containeurs (Openvz, et très probablement LXC et Docker), c'est l'entropie de l'hyperviseur qui est directement utilisée.</p>
<p>Il est donc dans ce cas nécessaire d'installer rng ou haveged directement sur l'hyperviseur, de même que la configuration du service. Dans les résultats précédent lancés dans un containeur, le service tournait sur l'hyperviseur, mais le test était effectué depuis l'intérieur.</p>
<h1 id="sources">Sources</h1>
<p>Merci à ces différents articles qui m'ont été bien utiles !</p>
<ul>
<li><a href="https://www.cyberciti.biz/open-source/debian-ubuntu-centos-linux-setup-additional-entropy-for-server-using-aveged-rng-tools-utils/">How to speed up OpenSSL/GnuPG Entropy</a></li>
<li><a href="https://developers.redhat.com/blog/2017/10/05/entropy-rhel-based-cloud-instances/">Entropy on red hat</a></li>
<li><a href="https://wiki.archlinux.org/index.php/Systemd#Examples">Systemd : Arch Linux wiki Examples</a></li>
<li><a href="https://www.digitalocean.com/community/tutorials/how-to-setup-additional-entropy-for-cloud-servers-using-haveged">How to setup additionnal Entropy</a></li>
</ul>Installer Openvz 7 à distance2017-11-23T23:31:00+01:002017-11-23T23:31:00+01:00Victortag:blog.victor-hery.com,2017-11-23:/2017/11/installer-openvz7-a-distance.html
<p><strong>Edit 2022</strong>: Article mis à jour pour nettoyer les parties obsolètes : utilisation de sshd et du raid soft</p>
<h1 id="vous-navez-acces-a-rien">Vous n'avez accès à rien ?</h1>
<p>Pas d'ipmi, pas de KVM, pas de console ? Et pourtant vous voulez installer votre serveur openvz ?</p>
<p>C'est possible et dans cet article, on va voir comment vous …</p>
<p><strong>Edit 2022</strong>: Article mis à jour pour nettoyer les parties obsolètes : utilisation de sshd et du raid soft</p>
<h1 id="vous-navez-acces-a-rien">Vous n'avez accès à rien ?</h1>
<p>Pas d'ipmi, pas de KVM, pas de console ? Et pourtant vous voulez installer votre serveur openvz ?</p>
<p>C'est possible et dans cet article, on va voir comment vous pouvez vous en tirer !<br/>
En bonus, parce que sinon ce serait trop facile, on va également voir comment chiffrer le serveur et lancer un serveur SSH au boot pour entrer le mot de passe et déchiffrer le disque.</p>
<p>Vous aurez ainsi un serveur openvz entièrement chiffré pour faire tourner vos container ou vos VM, ce qui est très appréciable à notre époque où la confidentialité des données est un problème important.<br/>
Vous pouvez très bien faire confiance à votre hébergeur (ou à ceux qui pourraient lui demander d'accéder à vos données), mais personnellement je pense que si vous ne vous mettez pas dans la situation ou vous <strong>devez</strong> lui faire confiance, c'est encore plus simple ;-)</p>
<p>Je ne vais par contre pas vous mentir, sans accès visuel, le debug en cas de problèmes peut être trèèèèès relou.<br/>
Je vais ici décrire la procédure complète qui a fonctionné plusieurs fois chez moi, mais il a fallut de nombreux tests... Si jamais vous ne vous en sortez pas, n'hésitez pas à commenter, j'essaierai de vous aider au mieux !</p>
<p><strong>Attention !</strong> Cela va de soit, mais cette procédure va totalement effacer les données de votre serveur. S'il n'est pas neuf et que vous souhaitez récupérer des données dessus, pensez à les backuper ;-)</p>
<h1 id="prerequis">Prérequis</h1>
<p>Je le dis tout de suite, il va vous falloir quand même quelques trucs pour vous faciliter la vie et permettre l'installation.</p>
<ul>
<li>Un serveur HTTP (pas hébergé sur le serveur que vous installez !) accessible par le serveur que vous souhaitez installer. Voir ci-dessous.</li>
<li>Un client VNC. Je vous conseille <a href="http://www.remmina.org/wp/">Reminna</a> si vous utilisez Linux. Sous Windows, je ne peux pas vous aider.</li>
<li>Un client SSH. Openssh sous Linux, ou <a href="http://www.putty.org/">putty</a> sous Windows.</li>
<li>Il vous faut un mode rescue avec votre hébergeur... Même minimaliste, avec au moins un accès SSH, nécessaire pour le chroot.</li>
<li>Installer votre serveur sur votre OS préféré pour le préparer, j'utiliserai pour ma part Debian 11.</li>
</ul>
<h2 id="preparer-le-serveur-http">Préparer le serveur HTTP</h2>
<p>Pour permettre l'installation à distance, il va falloir faire en sorte que les fichiers de l'image ISO openvz7 soient accessibles en HTTP pour que votre serveur puisse récupérer les fichiers à distance lors de son démarrage.<br/>
<strong>Ces manipulations doivent donc avoir lieu sur un AUTRE serveur que celui que vous allez installer !</strong><br/>
Je partirai également du principe que vous avez un serveur HTTP. N'importe quel serveur web fera l'affaire, apache, nginx, IIS, c'est selon vos préférenes ou ce qui est disponible.</p>
<p>Téléchargez votre iso depuis les <a href="https://download.openvz.org/virtuozzo/releases/7.0/x86_64/iso/">mirroirs openvz</a>. Vous pouvez prendre l'image classique (pas la netinstall).<br/>
Il va vous falloir mettre à disposition les fichiers de l'image via HTTP. On va donc monter l'ISO sur votre serveur web, puis poser les fichiers dans un vhost pour qu'ils soient disponibles.</p>
<div class="highlight"><pre><span></span><code><span class="err">mount openvz-iso-7.0.5-netinstall.iso /votre_repertoire_web/</span>
</code></pre></div>
<p>Faites en sortes que ce répertoire soit accessible sur une adresse type http://votredomain.tld/vz. Il doit pointer directement dans le répertoire où est montée l'image.<br/>
Notez cette adresse dans un coin, ça va resservir. :-)</p>
<h2 id="preparer-le-serveur-pour-linstallation">Préparer le serveur pour l'installation</h2>
<h3 id="nettoyez-les-disques-en-mode-rescue">Nettoyez les disques en mode rescue</h3>
<p>Redémarrer votre serveur sur votre mode rescue, pour nettoyer à fond les disques dur de votre serveur avant l'installation.<br/>
Pour ça, on va utiliser l'outil <a href="https://fr.wikipedia.org/wiki/Shred_(commande_unix)">Shred</a>. En mode rescue, vous pouvez effacer vos disques tranquillement.<br/>
Je vous conseille d'utliser au moins 2 passes, tout en remplissant de zéro pour être carré : </p>
<div class="highlight"><pre><span></span><code><span class="err">shred -n 2 -z /dev/sda</span>
</code></pre></div>
<p>Ca peut prendre pas mal de temps selon la taille des disques, jusqu'à plusieurs heures... Lancez le de nuit si possible, mais pour que le chiffrement soit efficace, mieux vaut que le disque ne soit pas prédictible :-)</p>
<h3 id="poser-les-fichiers-dinstallation">Poser les fichiers d'installation</h3>
<p>Pour télécharger les fichiers nécessaires au lancement de l'installation, il vous faudra un OS installé sur votre serveur.<br/>
Vous aurez besoin de générer un grub et de poser quelques fichiers dans /boot donc un Linux selon votre préférence. Pour ma part, je part sur un debian.</p>
<p>Réinstallez donc votre serveur via le système d'installation de votre hébergeur, connectez vous en SSH, et go !</p>
<p>Récupérez via votre serveur HTTP (celui avec l'ISO montée) les 2 fichiers d'install PXE :</p>
<div class="highlight"><pre><span></span><code><span class="err">wget http://votredomaine.tld/vz/images/pxeboot/initrd.img -O /boot/initrd_ovz7.img</span>
<span class="err">wget http://votredomaine.tld/vz/images/pxeboot/vmlinuz -O /boot/vmlinuz_ovz7</span>
</code></pre></div>
<p>Notez la configuration réseau de votre serveur. Il vous faut adresse IP, passerelle, masque réseau et serveurs DNS :</p>
<div class="highlight"><pre><span></span><code><span class="err">ip address show</span>
<span class="err">cat /etc/resolv.conf</span>
</code></pre></div>
<p>Vérifiez quel driver grub utilise pour votre partition de boot, et l'id de la partition /boot au passage : </p>
<div class="highlight"><pre><span></span><code><span class="err">grep "hint" /boot/grub/grub.cfg</span>
<span class="err"># search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1' xxxx-xxxx-xxxx-xxxx-xxxx</span>
<span class="err"># Ici on veut récupérer l'info du --hint, ainsi que l'ID du disque xxxx-....</span>
</code></pre></div>
<p>On va ensuite éditer grub pour ajouter une entrée spécifique pour booter sur l'installeur :</p>
<div class="highlight"><pre><span></span><code><span class="err">vim /etc/grub.d/40_custom</span>
</code></pre></div>
<p>Et ajoutez après les commentaires le contenu suivant :<br/>
<strong>Attention à ne pas enlever le <code>exec tail -n +3 $0</code> dans le fichier</strong></p>
<div class="highlight"><pre><span></span><code><span class="err">menuentry 'NetInstall' {</span>
<span class="err"> load_video</span>
<span class="err"> set gfxpayload=keep</span>
<span class="err"> insmod gzio</span>
<span class="err"> insmod part_msdos</span>
<span class="err"> insmod ext2</span>
<span class="err"> set root='HINT'</span>
<span class="err"> if [ x$feature_platform_search_hint = xy ]; then</span>
<span class="err"> search --no-floppy --fs-uuid --set=root --hint='HINT' ID_DISQUE</span>
<span class="err"> else</span>
<span class="err"> search --no-floppy --fs-uuid --set=root ID_DISQUE</span>
<span class="err"> fi</span>
<span class="err"> linux /vmlinuz_ovz7 vnc vncpassword=guigui inst.vncpassword=guigui headless inst.repo=https://votredomaine.tld/vz/ ip=IP_SERVEUR netmask=MASQUE_SERVEUR gateway=PASSERELLE_SERVEUR dns=DNS_SERVEUR nameserver=DNS_SERVEUR biosdevname=0 net.ifnames=0 ksdevice= bootproto=static lang=en_US keymap=us text noipv6</span>
<span class="err"> initrd /initrd_ovz7.img</span>
<span class="err">}</span>
</code></pre></div>
<p>Cette configuration va permettre de redémarrer le serveur sur une console VNC pour permettre d'installer openvz7 en mode graphique à distance :-)<br/>
Editez bien entendu les valeurs ci dessous :</p>
<ul>
<li>ID_DISQUE : l'id de la partition récupérée plus tôt</li>
<li>HINT : le numéro de disque et la table de partition associé récupéré dans grub.cfg (ex : <code>hd0,msdos</code>, <code>hd1,gpt</code>, ...)</li>
<li>IP_SERVEUR : l'adresse IP du serveur</li>
<li>MASQUE_SERVEUR : le masque de sous réseau de votre serveur</li>
<li>PASSERELLE_SERVEUR : la passerelle par défaut de votre serveur</li>
<li>DNS_SERVEUR (x2) : l'IP du serveur DNS remontée plus tôt</li>
<li>mot de passe vnc : il doit faire entre 4 et 6 caractères, donc si vous le changez, restez dans ces critères</li>
</ul>
<p>Puis regénérez la configuration de grub :</p>
<div class="highlight"><pre><span></span><code><span class="err">grub-mkconfig -o /boot/grub/grub.cfg</span>
</code></pre></div>
<p>Et enfin, configurez votre serveur pour redémarrer sur votre installeur au prochain reboot. Cette option permettra de redémarrer sur l'entrée grub, mais une fois seulement.<br/>
Ainsi, si jamais il ne démarre pas ou que l'installation se passe mal (avant le formatage bien sûr), un simple redémarrage électrique le fera redémarrer sur son OS de base.</p>
<div class="highlight"><pre><span></span><code><span class="err">grub-reboot NetInstall</span>
</code></pre></div>
<p><strong>Attention</strong>, si votre serveur utilise une partition /boot sur un RAID soft, cette commande est durable. En cas de souci, il faudra passer par le rescue pour reconfigurer le démarrage sur le bon os.</p>
<p>On va maintenant pouvoir redémarrer et récupérer la console VNC.</p>
<h1 id="installation-dopenvz-7">Installation d'openvz 7 !</h1>
<p>Redémarrez votre serveur, et lancez un ping sur son adresse IP. Dès qu'il répond, lancez votre console VNC sur l'IP du serveur, avec le port <code>:5901</code> ou <code>:1</code>.<br/>
<strong>Attention</strong>, malgré pas mal de recherches et de tests, je n'ai pas réussi à monter une connexion chiffrée pour ce VNC... Sachez donc que tout ce que vous y entrerez sera potentiellement récupérable en clair sur Internet !<br/>
Préparez vous donc à utiliser des mots de passe temporaires pour le chiffrement des disques et les accès utilisateurs. Nous les changerons dès l'installation terminée via une connexion SSH un peu plus robuste :-)</p>
<p>Vous avez accès à la console VNC en mode graphique, donc rien de très compliqué pour l'installation. La <a href="https://docs.openvz.org/openvz_installation_guide.webhelp/_installing_openvz_in_graphics_mode.html">documentation officielle</a> est parfaite à ce niveau là.</p>
<p>Normalement, la configuration réseau est déjà faite grâce aux options de grub, donc rien à toucher.</p>
<p>Le partitionnement des disques par défaut est en théorie suffisant, <strong>mais</strong> c'est le moment de penser à cocher "Encrypt" !<br/>
Vous devez cocher la case pour toutes les partitions sauf /boot et la petite partition "BIOS Boot".</p>
<p>En sortant du menu de partionnement, l'installeur vous demandera les mots de passe pour le chiffrement. Il est important de mettre le même mot de passe pour toutes les partitions.<br/>
Attention là encore à ne pas mettre le mot de passe final, car la connexion à VNC n'est pas chiffrée !</p>
<p>Laissez ensuite l'installation se terminer tranquillement, puis passez à la suite.</p>
<h1 id="ssh-et-reseau-au-demarrage">SSH et réseau au démarrage</h1>
<p>Pour cette partie, il va falloir redémarrer votre serveur en mode rescue de nouveau.<br/>
En effet, votre serveur est désormais installé, ses disques sont chiffrés, mais vous n'avez pour l'instant aucun moyen de taper le mot de passe demandé au boot pour déchiffrer les disques !<br/>
On va donc modifier directement le initramfs pour y intégrer un petit serveur SSH qui se lancera au boot, et qui permettra ainsi de taper le mot de passe au démarrage en toute sécurité.</p>
<p>Une fois revenu en mode rescue, préparez vous à monter votre système en chroot. Je part ici du principe que vous avez gardé le partionnement par défaut, donc pensez à adapter le nom des partitions dans la suite si besoin.<br/>
On va commencer par changer les mots de passe bidon des partitions maintenant que nous sommes sur une connexion ssh sécurisée.</p>
<p>La manipulation change toutefois selon que vous ayez gardé du lvm monodisque, ou utilisé une configuration avec raid multidisque, choisissez celle qui vous convient le mieux !</p>
<h2 id="chroot-avec-lvm">chroot avec lvm</h2>
<details>
<summary>cliquez pour déplier</summary>
On va activer les volumes lvm, changer les mots de passe luks, puis activer la partition root et la monter pour entrer en chroot.
<div class="highlight"><pre><span></span><code><span class="err">vgchange -a y</span>
<span class="err">cryptsetup luksChangeKey /dev/sda3 # On change le mot de passe du swap</span>
<span class="err">cryptsetup luksChangeKey /dev/mapper/virtuozzo-root # On change le mot de passe du /</span>
<span class="err">cryptsetup luksChangeKey /dev/mapper/virtuozzo-vz # On change le mot de passe du vz</span>
<span class="err">cryptsetup luksOpen /dev/mapper/virtuozzo-root crypt_root</span>
<span class="err">mkdir -p /mount/openvz</span>
<span class="err">mount /dev/mapper/crypt_root /mount/openvz</span>
<span class="err">mount /dev/sda2 /mount/openvz/boot</span>
<span class="err">mount -o bind /dev/ /mount/openvz/dev/</span>
<span class="err">mount -o bind /sys/ /mount/openvz/sys</span>
<span class="err">mount -o bind /proc/ /mount/openvz/proc/</span>
<span class="err">chroot /mount/openvz</span>
</code></pre></div>
</details>
<h2 id="chroot-avec-raid-soft">chroot avec raid soft</h2>
<details>
<summary>cliquez pour déplier</summary>
l'objectif est de signaler au système l'existence de volumes raid avec les bonnes partitions, changer les mots de passe luks, puis activer la partition root et la monter pour entrer en chroot.
Pour commencer, récupérez les partitions qui correspondent entre-elles sur vos disques
<div class="highlight"><pre><span></span><code><span class="err">fdisk -l /dev/sda</span>
<span class="err"># Start End Size Type Name</span>
<span class="err"> 1 2048 4095 1M BIOS boot </span>
<span class="err"> 2 4096 2101247 1G Microsoft basic </span>
<span class="err"> 3 2101248 5760518143 2,7T Linux RAID </span>
<span class="err"> 4 5760518144 5827631103 32G Linux RAID </span>
<span class="err"> 5 5827631104 5860532223 15,7G Linux RAID </span>
<span class="err">fdisk -l /dev/sdb</span>
<span class="err"># Start End Size Type Name</span>
<span class="err"> 1 2048 5758418943 2,7T Linux RAID </span>
<span class="err"> 2 5758418944 5825531903 32G Linux RAID </span>
<span class="err"> 3 5825531904 5858433023 15,7G Linux RAID </span>
</code></pre></div>
L'objectif ici est de **rapprocher** les partitions qui "vont ensembles" en raid mdadm, en utilisant leur taille, puisque 2 partitions en raid doivent être identiques.
On observe par exemple que
- sda3 est liée à sdb1
- sda4 est liée à sdb2 # Au passage, cette partition est notre partition root, à repérer pour savoir quelle partition monter dans le chroot
- sda5 est liée à sdb3
Une fois cette correspondance faite, on va dire à mdadm d'activer les volumes raid.
On prends ici l'exemple d'un raid1 avec 2 disques, dans le cas de raid5, ou 6, ajoutez les partitions nécessaires.
<div class="highlight"><pre><span></span><code><span class="err"># Modifiez bien vos partitions si nécessaire !</span>
<span class="err">mdadm -A -R /dev/md1 /dev/sda3 /dev/sdb1</span>
<span class="err">mdadm -A -R /dev/md2 /dev/sda4 /dev/sdb2</span>
<span class="err">mdadm -A -R /dev/md3 /dev/sda5 /dev/sdb3</span>
<span class="err">cryptsetup luksChangeKey /dev/md1</span>
<span class="err">cryptsetup luksChangeKey /dev/md2</span>
<span class="err">cryptsetup luksChangeKey /dev/md3</span>
<span class="err">cryptsetup luksOpen /dev/md2 crypt_root</span>
<span class="err">mkdir -p /mount/openvz</span>
<span class="err">mount /dev/mapper/crypt_root /mount/openvz</span>
<span class="err">mount /dev/sda2 /mount/openvz/boot</span>
<span class="err">mount -o bind /dev/ /mount/openvz/dev/</span>
<span class="err">mount -o bind /sys/ /mount/openvz/sys</span>
<span class="err">mount -o bind /proc/ /mount/openvz/proc/</span>
<span class="err">chroot /mount/openvz</span>
</code></pre></div>
</details>
<h2 id="ssh-dans-le-initramfs">SSH dans le Initramfs</h2>
<p>Une fois dans le chroot, les choses marrantes reprennent ;-)</p>
<p>La connexion au boot se fera exclusivement avec une clef SSH. Si vous avez besoin de générer une clef SSH, vous pouvez vous référer à <a href="https://blog.victor-hery.com/2012/08/connexion-ssh-par-cle.html#generation-de-la-cle-les-choses-serieuses-commencent">cet article</a> .<br/>
Commencez donc par poser votre clef ssh dans le chroot directement, ainsi elle sera prête pour votre connexion une fois le serveur démarré.</p>
<div class="highlight"><pre><span></span><code><span class="err">mkdir -p /root/.ssh</span>
<span class="err">vim /root/.ssh/authorized_keys # Entrez votre clef SSH personnelle</span>
<span class="err">chmod 700 /root/.ssh</span>
<span class="err">chmod 600 /root/.ssh/authorized_keys</span>
</code></pre></div>
<p>J'utilisais précédemment <a href="https://github.com/dracut-crypt-ssh/dracut-crypt-ssh">dracut-crypt-ssh</a> qui implémentait DropbearSSH, mais après plusieurs années de bons et loyaux services, il n'est plus maintenu.<br/>
On peut avantageusement le remplacer désormais par <a href="https://github.com/gsauthof/dracut-sshd">dracut-sshd</a> qui utilise pour sa part openssh.</p>
<div class="highlight"><pre><span></span><code><span class="err">yum install yum-plugin-copr</span>
<span class="err">yum copr enable gsauthof/dracut-sshd/</span>
<span class="err">yum update</span>
<span class="err">yum install dracut-sshd</span>
<span class="err">mkdir /etc/dracut-sshd</span>
<span class="err">cp /root/.ssh/authorized_keys /etc/dracut-sshd/</span>
</code></pre></div>
<p><strong>Si vous utilisez un raid software</strong> il est nécessaire d'indiquer à dracut de charger le driver correspondant </p>
<div class="highlight"><pre><span></span><code><span class="err">vim /etc/dracut.conf</span>
<span class="err"># Modifier et décommentez l'entrée add_drivers</span>
<span class="err">add_drivers+="raid1" # Dans le cas d'un raid1, sinon raid5, raid6, raid0, ...</span>
</code></pre></div>
<p>Par défaut, dracut va générer un initramfs pour le noyau sur lequel le serveur est démarré, à savoir celui du rescue.<br/>
Pas très utile dans notre cas...</p>
<p>Récupérez donc le "vrai" noyau qu'utilise openvz, c'est à dire le dernier (classé par nom) disponible dans /boot : </p>
<div class="highlight"><pre><span></span><code><span class="err"># ls /boot/</span>
<span class="err">[...]</span>
<span class="err">vmlinuz-3.10.0-514.16.1.vz7.30.10</span>
</code></pre></div>
<p>On va ici générer l'image initramfs pour le noyau 3.10.0-514.16.1.vz7.30.10 :</p>
<div class="highlight"><pre><span></span><code><span class="err">dracut --force /boot/initramfs-3.10.0-514.16.1.vz7.30.10.img 3.10.0-514.16.1.vz7.30.10</span>
</code></pre></div>
<p>La commande dracut ne doit rien vous renvoyer mais peut être longue à exécuter... Si vous avez une erreur, vous devrez chercher la solution avant le prochain redémarrage, car votre initramfs risque d'être HS. Au pire, le mode rescue vous sera extrêmement utile !</p>
<p>Une fois que le initramfs a été généré sans erreur, on va s'occuper du réseau.</p>
<h2 id="configuration-de-grub-reseau">Configuration de grub : réseau</h2>
<p>Reprenez ici la configuration réseau que vous aviez noté plus haut pour le boot VNC, ça va resservir.</p>
<p>On va éditer le fichier <code>/etc/default/grub</code> pour demander à grub de monter le réseau au démarrage.</p>
<div class="highlight"><pre><span></span><code><span class="err"> GRUB_CMDLINE_LINUX="... rd.neednet=1 ip=IP_SERVEUR::PASSERELLE_SERVEUR:MASQUE_SERVEUR:centos:enp0s3:off dns=DNS_SERVEUR nameserver=DNS_SERVEUR"</span>
</code></pre></div>
<p>Ici on va réutiliser les paramètres réseaux, mais ce qu'il faut surtout noter, c'est la partie "enp0s3".<br/>
Il s'agit de votre interface réseau, nommée d'après les paramètres du Bios de votre serveur, les classiques ethX ayant été abandonnés depuis les derniers noyaux. Si jamais vous ne la connaissez pas, il est possible de forcer eth0, cf la section troubleshooting plus bas :-)</p>
<p>Une fois le fichier enregistré, regénérez la configuration grub :</p>
<div class="highlight"><pre><span></span><code><span class="err">grub2-mkconfig --output /etc/grub2.cfg</span>
</code></pre></div>
<h2 id="configuration-de-grub-luks">Configuration de grub : luks</h2>
<p>Sur les dernières versions d'openvz, j'ai noté que le grub n'est parfois configuré que pour déchiffrer que les partitions root et swap.</p>
<p>Cela nous pose problème, car il demande le mot de passe pour déchiffrer la partition /vz bien plus tard, <strong>après</strong> le process initramfs mais <strong>avant</strong> d'avoir lancé les services. Pas de ssh pour le déverrouiller donc !</p>
<p>Pour corriger cela, on va devoir vérifier la configuration du grub nous-même. </p>
<p>Tout se passe dans le fichier <code>/etc/default/grub</code>, à la section <code>GRUB_CMDLINE_LINUX</code>.</p>
<p>Tout d'abord, récupérez les noms des partitions luks :</p>
<div class="highlight"><pre><span></span><code><span class="err"># blkid |grep luks</span>
<span class="err">/dev/mapper/luks-c80672a4-6644-4c0a-bc11-2ab2674fd4ec: UUID="16609b0b-983e-4982-9dd0-972f66a0c115" TYPE="swap" </span>
<span class="err">/dev/mapper/luks-40bc8a84-7296-4df4-b872-6b67aa037174: UUID="51390ed2-dddf-4f61-8c29-19bd43022863" TYPE="ext4" </span>
<span class="err">/dev/mapper/luks-02313a5d-c3af-4372-9ea5-ead11f2ce244: UUID="5b63074f-c886-46bf-a1c9-1c43a0059667" TYPE="ext4" </span>
</code></pre></div>
<p>On récupère ce qui est après le <code>/dev/mapper</code>, par exemple <code>luks-c80672a4-6644-4c0a-bc11-2ab2674fd4ec</code></p>
<p>Pour chaque volume luks à déchiffrer au boot, vous devez avoir une section de type </p>
<div class="highlight"><pre><span></span><code><span class="err">rd.luks.uuid=luks-02313a5d-c3af-4372-9ea5-ead11f2ce244</span>
</code></pre></div>
<p>dans la <code>GRUB_CMDLINE_LINUX</code> du fichier `/etc/default/grub. (cf un exemple complet ci-dessous)</p>
<p>
<details>
<summary>Si vous utilisez en outre un raid soft, cliquez</summary>
Vous devez récupérer les volumes raid :
<div class="highlight"><pre><span></span><code><span class="err"># blkid | grep md</span>
<span class="err">/dev/md127: UUID="6f09377e-dda8-4d11-83b6-c3c3cc17b6b9" TYPE="crypto_LUKS" </span>
<span class="err">/dev/md126: UUID="03988b26-4004-4551-969b-461a7d2f37e6" TYPE="crypto_LUKS" </span>
<span class="err">/dev/md125: UUID="0d60f8ec-7167-4e07-a92a-8f58fe89c22a" TYPE="crypto_LUKS" </span>
</code></pre></div>
On va utiliser le paramètre `rd.md.uuid` de grub MAIS celui-ci prends un format bien précis d'uuid, séparé par des points.
Prenez donc l'UUID de vos disques, et tous les 8 caractères, enlevez le tiret et mettez un `:` à la place :
<div class="highlight"><pre><span></span><code><span class="err">6f09377e-dda8-4d11-83b6-c3c3cc17b6b9 => 6f09377e:dda84d11:83b6c3c3:cc17b6b9</span>
<span class="err">03988b26-4004-4551-969b-461a7d2f37e6 => 03988b26:40044551:969b461a:7d2f37e6</span>
<span class="err">...</span>
</code></pre></div>
Il faudra ensuite ajouter dans la ligne `GRUB_CMDLINE_LINUX` une option `rd.md.uuid=XXX` pour chaque partition raid. (cf exemple complet ci-dessous)
</details>
</p>
<p>Voici un exemple complet de la ligne finale avec un raid1 :</p>
<div class="highlight"><pre><span></span><code><span class="err"># cat /etc/default/grub</span>
<span class="err">GRUB_CMDLINE_LINUX="crashkernel=auto rd.luks.uuid=luks-03988b26-4004-4551-969b-461a7d2f37e6 rd.md.uuid=4e7537f2:97d36823:1495a4b6:5e02ee30 rd.luks.uuid=luks-6f09377e-dda8-4d11-83b6-c3c3cc17b6b9 rd.md.uuid=d57b1ed4:ea77ea71:27bcaadd:39321bd9 rd.luks.uuid=luks-0d60f8ec-7167-4e07-a92a-8f58fe89c22a rd.md.uuid=5e66072c:1ffb2033:ff97ca5a:6ab13de0 biosdevname=0 net.ifnames=0 quiet rd.neednet=1 ip=IP_SERVEUR::PASSERELLE_SERVEUR:MASQUE_SERVEUR:centos:enp0s3:off dns=DNS_SERVEUR nameserver=DNS_SERVEUR"</span>
</code></pre></div>
<p>Une fois le fichier enregistré, regénérez la configuration grub :</p>
<div class="highlight"><pre><span></span><code><span class="err">grub2-mkconfig --output /etc/grub2.cfg</span>
</code></pre></div>
<h2 id="sortir-du-chroot">Sortir du chroot</h2>
<p>Une fois la configuration regénérée sans erreurs, vous pouvez quitter le chroot, démonter les disques et préparer le redémarrage.</p>
<p>
<details>
<summary>Cliquez pour sortir du chroot avec lvm</summary>
<div class="highlight"><pre><span></span><code><span class="err">exit</span>
<span class="err">umount /mount/openvz/dev</span>
<span class="err">umount /mount/openvz/sys</span>
<span class="err">umount /mount/openvz/proc</span>
<span class="err">umount /mount/openvz/boot</span>
<span class="err">umount /mount/openvz</span>
<span class="err">cryptsetup luksClose crypt_root</span>
<span class="err">vgchange -a n</span>
</code></pre></div>
</details>
</p>
<p>
<details>
<summary>Cliquez pour sortir du chroot avec raid soft</summary>
<div class="highlight"><pre><span></span><code><span class="err">exit</span>
<span class="err">umount /mount/openvz/dev</span>
<span class="err">umount /mount/openvz/sys</span>
<span class="err">umount /mount/openvz/proc</span>
<span class="err">umount /mount/openvz/boot</span>
<span class="err">umount /mount/openvz</span>
<span class="err">cryptsetup luksClose crypt_root</span>
<span class="err">mdadm -S /dev/md3</span>
<span class="err">mdadm -S /dev/md2</span>
<span class="err">mdadm -S /dev/md1</span>
</code></pre></div>
</details>
</p>
<p>N'oubliez pas de désactiver le mode rescue de votre serveur, pour éviter qu'il ne démarre en mode rescue ! Puis redémarrez le serveur.</p>
<h1 id="last-reboot">Last reboot (?)</h1>
<p>Si tout s'est bien passé, au bout de quelques minutes (selon votre serveur), le réseau devrait se remettre à pinguer. Quelques instant plus tard, le SSH devrait être disponible. </p>
<div class="highlight"><pre><span></span><code><span class="c">% ssh root@IP_SERVEUR -p 22</span>
# <span class="n">Cette</span> <span class="n">commande</span> <span class="n">permet</span> <span class="n">de</span> <span class="n">passer</span> <span class="n">le</span> <span class="n">mot</span> <span class="n">de</span> <span class="n">passe</span> <span class="n">de</span> <span class="n">déchiffrement</span> à <span class="n">systemd</span>
# <span class="n">Sur</span> <span class="n">une</span> <span class="n">install</span> <span class="n">standard</span><span class="p">,</span> <span class="n">vous</span> <span class="n">avez</span> <span class="mi">3</span> <span class="n">disques</span> à <span class="n">déchiffrer</span> <span class="p">(</span><span class="o">/</span><span class="n">root</span><span class="p">,</span> <span class="o">/</span><span class="n">vz</span> <span class="n">et</span> <span class="n">swap</span><span class="p">),</span> <span class="n">il</span> <span class="n">faudra</span> <span class="n">donc</span> <span class="n">entrer</span> <span class="n">la</span> <span class="n">commande</span> <span class="mi">3</span> <span class="n">fois</span>
<span class="n">systemd</span><span class="o">-</span><span class="n">tty</span><span class="o">-</span><span class="n">ask</span><span class="o">-</span><span class="n">password</span><span class="o">-</span><span class="n">agent</span>
<span class="n">systemd</span><span class="o">-</span><span class="n">tty</span><span class="o">-</span><span class="n">ask</span><span class="o">-</span><span class="n">password</span><span class="o">-</span><span class="n">agent</span>
<span class="n">systemd</span><span class="o">-</span><span class="n">tty</span><span class="o">-</span><span class="n">ask</span><span class="o">-</span><span class="n">password</span><span class="o">-</span><span class="n">agent</span>
</code></pre></div>
<p>Si le mot de passe est correct, le boot va continuer, votre shell va se terminer et votre serveur terminer de démarrer tranquillement.<br/>
Vous devriez ensuite pouvoir vous connecter de manière tout à fait classique avec vos identifiants (le mot de passe root indiqué à l'installation).</p>
<p>Si jamais initramf ne continue pas, n'hésitez pas à utiliser la commande <code>systemd-tty-ask-password-agent --list</code> pour récupérer la liste des disques non débloqués et voir ce qui coince.</p>
<h1 id="troubleshooting">Troubleshooting</h1>
<p>Cette procédure est normalement fonctionnelle, mais pas mal de chose peuvent mal se passer malheureusement, sans accès console, c'est difficile à debuguer...<br/>
Personnellement, j'ai redémarré mon serveur en mode rescue/redémarrage classique plus de 90 fois pour rédiger cet article :-D<br/>
Je vais ici parler des problèmes que j'ai rencontré pendant mes tests.</p>
<h2 id="pas-de-vnc">Pas de VNC</h2>
<p>Si votre serveur ne démarre pas en VNC, il se peut que le réseau ne monte pas. Si vous avez suivi la consigne avec la commande <code>grub-reboot NetInstall</code>, il vous suffit de redémarrer le serveur via l'interface de votre hébergeur, et il repartira par défaut sur votre OS de préparation.</p>
<p>À partir de là, vérifiez votre configuration réseau et que votre grub contient le tout. Sous Debian, il est dans <code>/boot/grub/grub.cfg</code>.<br/>
Remettez un coup de <code>grub-reboot NetInstall</code> et on redémarre :-)</p>
<h2 id="linstalleur-virtuozzo-plante">L'installeur Virtuozzo plante</h2>
<p>J'ai rencontré plusieurs crash une fois la console VNC lancée. Ils étaient dû à des paramètres incorrects dans les paramètres de boot, comme l'id du disque dur de votre menu grub, ou le layout clavier.<br/>
Vérifiez que tout correspond bien, et notamment si vous avez tenté un <code>lang</code> différent de "en_US" ou un <code>keymap</code> différent de "us", laissez tomber et réessayez avec les bonnes options. Apparemment, l'installeur de Virtuozzo n'aime pas les autres options au démarrage... </p>
<p>Notez que vous pouvez quand même configurer un layout FR une fois l'installeur lancé via l'interface graphique.</p>
<h2 id="forcer-eth0">Forcer eth0</h2>
<p>Pour la configuration réseau de initramfs, déterminer le nom qu'aura l'interface réseau avec la prédiction Bios n'est pas forcément évident si votre OS de préparation ne l'utilise pas.<br/>
Pour forcer à revenir à eth0, il vous suffit d'ajouter les 2 options suivantes dans votre <code>GRUB_CMDLINE_LINUX</code>, via votre chroot en mode rescue :</p>
<div class="highlight"><pre><span></span><code><span class="err">... net.ifnames=0 biosdevname=0 ...</span>
</code></pre></div>
<p>N'oubliez pas de régnérer le grub une fois la ligne modifiée :-)</p>
<div class="highlight"><pre><span></span><code><span class="err">grub2-mkconfig --output /etc/grub2.cfg</span>
</code></pre></div>
<h2 id="rien-ne-boot-ca-marche-pas">Rien ne boot ça marche pas !</h2>
<p>Un conseil, si vraiment ça ne fonctionne pas et que tout parait correct, déroulez toute la procédure sur une VM locale, par exemple via virtualbox, pour disposer d'une console et voir les erreurs qui peuvent s'y afficher.</p>
<p>Si jamais, n'hésitez pas à me laisser un petit commentaire, si je peux aider ça sera avec plaisir !</p>
<p>Et bon courage ;-)</p>
<h1 id="sources-et-biblio">Sources et biblio</h1>
<p>Je remercie ces différents auteurs qui m'ont permis d'arriver à ce résultat et à écrire cet article !</p>
<ul>
<li><a href="https://blog.imirhil.fr/2017/07/22/stockage-chiffre-serveur.html">Stockage chiffré intégral sur serveur distant Debian</a></li>
<li><a href="https://docs.virtuozzo.com/virtuozzo_7_installation_guide/installing-virtuozzo/installing-virtuozzo-via-vnc.html">Install Virtuozzo via VNC</a></li>
<li><a href="http://roosbertl.blogspot.com/2012/12/centos6-disk-encryption-with-remote.html">Centos6 disk encryption with remote password</a></li>
<li><a href="https://bitbucket.org/bmearns/dracut-crypt-wait/src">crypt-wait for dracut</a></li>
<li><a href="https://github.com/gsauthof/dracut-sshd">Dracut sshd</a></li>
<li><a href="https://www.kernel.org/pub/linux/utils/boot/dracut/dracut.html">Dracut documentation</a></li>
</ul>Comment utiliser drone-ci pour tester vos images docker ?2017-07-30T08:20:00+02:002017-07-30T08:20:00+02:00Victortag:blog.victor-hery.com,2017-07-30:/2017/07/build-et-test-custom-image-drone-ci.html<p>Pouvoir tester vos images docker maison et lancer des tests dessus avec drone ? C'est possible !</p>
<h1 id="tester-docker-avec-docker">Tester Docker avec Docker ?</h1>
<p>Dernièrement, je me suis intéressé à <a href="https://github.com/drone/drone" title="drone continuous integration">Drone</a> qui est un sympathique logiciel d'<a href="https://fr.wikipedia.org/wiki/Int%C3%A9gration_continue" title="Wikipédia fr : intégration continue">intégration continue</a>.
Il permet de professionnaliser un peu le fonctionnement d'un dépôt git pour publier automatiquement du code, effectuer des tests divers et variés, envoyer le tout sur un dépot, etc.</p>
<p>Bref, ça permet de faire plus avancé et plus propre que de simples hooks git. Par exemple, pour publier automatiquement ce blog quand je pousse sur mon dépôt :-)</p>
<p>Et l'une des difficultés que j'ai rencontrée, c'est comment tester mes images Docker avec Drone, qui lui même tourne avec Docker.
En effet, ça me paraissait à la fois intéressant et fun de pouvoir oser dans un dépôt git mes images docker, puis lors d'un push construire l'image, vérifier qu'elle se lance, et surtout démarrer des tests sur un exemplaire de l'image elle-même pour être sûr qu'elle fait encore ce pour quoi elle est sensée être faite.</p>
<p>Or, entre la documentation de Drone qui est assez, disons variée, et le fait que le client Drone tourne dans une image docker (ce qui limite les intégrations avec docker lui-même), ça n'était pas si simple.</p>
<p>D'où l'idée de rédiger ce petit article histoire d'avoir une trace en français qui pourrai servir à d'autres personnes intéressées par ce sujet :-)</p>
<p>On va donc voir comment <strong>construire</strong> des images Docker avec Drone, et surtout comment les <strong>lancer</strong> pour les tester !</p>
<h1 id="build-and-test">Build and Test !</h1>
<h2 id="prerequis">Prérequis</h2>
<p>On va ici partir du principe que ce que vous voulez tester est une image docker.</p>
<ul>
<li>Votre dépot contient donc les fichiers habituels docker et notamment un DockerFile (ou équivalent)</li>
<li>Vous avez également Drone installé et configuré pour fonctionner avec votre service git préféré (github, gitlab, gitea et compagnie)</li>
<li>Vous avez bien entendu des choses à tester sur votre image ! ;-)</li>
<li>Optionnellement, si vous avez un registry Docker, nous verrons comment publier votre image dessus si les tests réussissent</li>
</ul>
<p>Pour nos tests, nous prendron une image postfix et nous vérifierons que le port 25 répond correctement avec un EHLO kivabien.</p>
<h2 id="configuration-de-drone">Configuration de Drone</h2>
<p>Côté Drone, la configuration est assez simple.</p>
<p>//!\<strong>Attention tout de même</strong>//!\ Pour faire tout cela votre drone agent va devoir accéder au socket docker de votre "hyperviseur" Docker.
Il pourra donc, outre construire des images, accéder à toutes les images existantes sur l'hyperviseur. Soit vous le posez dans un hyperviseur avec aucune autre image, soit vous faites très attention à ce que votre système Drone ne soit pas accessible depuis l'extérieur !</p>
<p>Il faut donc autoriser votre drone-agent à accéder au socket docker. Pour ce faire, on va passer par les volumes docker.
Indiquez donc à votre image drone-agent qu'elle peut accéder au socket en lui donnant l'accès, par défaut <code>/var/run/docker.sock</code> :</p>
<div class="highlight"><pre><span></span><code><span class="c">volumes: </span>
<span class="c"> - /var/run/docker.sock:/var/run/docker.sock</span>
</code></pre></div>
<p>Puis relancez votre drone-agent à coup de docker-compose.</p>
<p>Celui-ci pourra désormais utiliser les commandes docker pour construire et gérer des images.</p>
<h2 id="test-de-construction">Test de construction</h2>
<p>La première chose à vérifier dans la procédure de test est que votre image se construit correctement.</p>
<p>Pour cette phase, on va utiliser comme image Drone une image docker fournie par drone eux-même, et dédié à la construction d'image.
L'astuce va consister à spécifier à la main une commande de build, et ainsi à donner un tag à votre image maison.</p>
<p>Elle va ainsi se retrouver dans le cache local de votre serveur docker, et vous pourrez la réutiliser dans la suite de votre chaine de test pour effectuer des tests dessus !</p>
<p>Voici un exemple de la tache de build :</p>
<div class="highlight"><pre><span></span><code><span class="n">build</span><span class="o">:</span>
<span class="n">image</span><span class="o">:</span> <span class="n">docker</span><span class="o">:</span><span class="n">latest</span>
<span class="n">volumes</span><span class="o">:</span>
<span class="o">-</span> <span class="sr">/var/run/docker.sock:/var/run/</span><span class="n">docker</span><span class="o">.</span><span class="na">sock</span>
<span class="n">commands</span><span class="o">:</span>
<span class="o">-</span> <span class="n">docker</span> <span class="n">build</span> <span class="o">-</span><span class="n">t</span> <span class="n">test</span><span class="o">/</span><span class="n">postfix</span><span class="o">:</span><span class="n">latest</span> <span class="o">.</span>
</code></pre></div>
<p>Comme attendu, il faut que le pipeline puisse accéder au socket docker pour la construction de l'image, et ici on place l'image construite dans le dépôt local <em>test/postfix</em> avec le tag <em>latest</em>.</p>
<p>Vous avez ainsi 2 choses de réalisé :
* Votre image se construit correctement (c'est toujours ça de pris :-D )
* Vus disposez d'une version toute fraiche de votre image dans un dépot de test utilisable par Drone</p>
<h2 id="test-sur-limage">Test sur l'image</h2>
<p>Ensuite, c'est assez simple. Vous allez utiliser votre jolie image toute neuve comme image de base pour votre chaine de test !</p>
<p>Vous pourrez alors lancer tous les tests que vous souhaitez dessus.
Dans mon cas, j'installe quelques outils nécessaires et je lance un script qui va faire un telnet, envoyer un EHLO et vérifier que l'image répond correctement :</p>
<div class="highlight"><pre><span></span><code><span class="n">basic_test</span><span class="o">:</span>
<span class="n">image</span><span class="o">:</span> <span class="n">test</span><span class="o">/</span><span class="n">postfix</span><span class="o">:</span><span class="n">latest</span>
<span class="n">commands</span><span class="o">:</span>
<span class="o">-</span> <span class="n">apt</span><span class="o">-</span><span class="kd">get</span> <span class="n">update</span><span class="o">;</span><span class="n">apt</span><span class="o">-</span><span class="kd">get</span> <span class="n">install</span> <span class="o">-</span><span class="n">q</span> <span class="o">-</span><span class="n">y</span> <span class="n">expect</span> <span class="n">telnet</span>
<span class="o">-</span> <span class="n">service</span> <span class="n">postfix</span> <span class="n">start</span>
<span class="o">-</span> <span class="o">./</span><span class="n">basic</span><span class="o">-</span><span class="n">test</span><span class="o">.</span><span class="na">sh</span>
</code></pre></div>
<p>Vous remarquerez que j'ai spécifié pour <code>image:</code> le chemin de notre image juste construite.</p>
<p>Si ça vous intéresse, le contenu de <code>basic-test.sh</code> :</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
2
3
4
5
6
7
8
9
10</pre></div></td><td class="code"><div class="highlight"><pre><span></span><code><span class="o">#!/</span><span class="n">usr</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">expect</span> <span class="c1">--</span>
<span class="o">##</span> <span class="n">Basic</span> <span class="n">test</span> <span class="k">for</span> <span class="k">postfix</span>
<span class="k">set</span> <span class="n">timeout</span> <span class="mi">5</span>
<span class="n">spawn</span> <span class="n">telnet</span> <span class="n">localhost</span> <span class="mi">25</span>
<span class="n">expect</span> <span class="ss">"220 mail.victor-hery.com"</span>
<span class="n">send</span> <span class="c1">-- "EHLO example.com\r"</span>
<span class="n">expect</span> <span class="ss">"250-mail.victor-hery.com"</span>
<span class="n">send</span> <span class="c1">-- "quit\r"</span>
<span class="n">expect</span> <span class="ss">"Bye"</span>
</code></pre></div>
</td></tr></table>
<p>On peut ensuite imaginer toutes sortes de tests bien plus complexes, envoyer un courriel, vérifier qu'il arrive correctement, etc, etc.</p>
<p>On peut aussi utiliser le système de groupe de Drone pour construire plusieurs images simultanéments et faire des tests croisés (par exemple un proxy et un serveur web, une base de données, etc)</p>
<h2 id="publier-votre-image">Publier votre image</h2>
<p>Si tous vos tests passent avec succès et que vous disposez d'un registry, vous pouvez utiliser le système de publication de Drone à la fin de votre chaine de test :</p>
<div class="highlight"><pre><span></span><code><span class="n">publish</span><span class="o">:</span>
<span class="n">image</span><span class="o">:</span> <span class="n">plugins</span><span class="o">/</span><span class="n">docker</span>
<span class="n">tags</span><span class="o">:</span>
<span class="o">-</span> <span class="n">latest</span>
<span class="n">dockerfile</span><span class="o">:</span> <span class="n">Dockerfile</span>
<span class="n">volumes</span><span class="o">:</span>
<span class="o">-</span> <span class="sr">/var/run/docker.sock:/var/run/</span><span class="n">docker</span><span class="o">.</span><span class="na">sock</span>
<span class="o">-</span> <span class="sr">/data/storage/registry/certs/:/etc/ssl/</span><span class="n">certs</span>
<span class="n">insecure</span><span class="o">:</span> <span class="kc">true</span>
<span class="n">repo</span><span class="o">:</span> <span class="n">registry</span><span class="o">.</span><span class="na">local</span><span class="o">:</span><span class="mi">5000</span><span class="sr">/prod/</span><span class="n">postfix</span>
<span class="n">registry</span><span class="o">:</span> <span class="n">registry</span><span class="o">.</span><span class="na">local</span><span class="o">:</span><span class="mi">5000</span>
</code></pre></div>
<p>Pour ma part il s'agit d'un dépot local à mon serveur, avec un certificat autosigné pour l'instant, d'où les ports maison et le <code>insecure: true</code>.</p>
<h1 id="limitations">Limitations</h1>
<p>Pour l'instant, la principale limitation à ce genre de chaine de test que j'ai trouvé, c'est l'impossiblité de faire des tests depuis l'extérieur de l'image.</p>
<p>Pour ma part, j'aimerai bien lancer mon image postfix, la binder sur un port, puis m'y connecter pour vérifier comment elle réagit...
De manière plus fine que lancer un test depuis l'intérieur en tablant sur le fait que localhost fonctionnera à l'identique que le bind externe de docker.</p>
<p>J'espère que ce petit article vous plaira, n'hésitez pas à me laisser des commentaires si vous avez des questions, j'y répondrai avec plaisir !
Si vous avez des astuces de votre côté pour utiliser Drone, ce sera également avec grand plaisir que je les consulterai :-)</p>Passage à un système de blog statique2017-07-04T09:10:00+02:002017-07-04T09:10:00+02:00Victortag:blog.victor-hery.com,2017-07-04:/2017/07/passage-blog-statique.html<p>Aujourd'hui, c'est la mise en production du nouveau blog (ou du blog nouveau)</p>
<h1 id="un-blog-pardon-quoi">Un blog pardon quoi ?</h1>
<p>Bonjour à toutes et à a tous !</p>
<p>Un système de blog statique on vous dit !</p>
<p>C'est un concept où le blog (ou le site) n'est constitué que de fichiers entièrement statiques.<br/>
Plus de php, de bases de données ou autre scripts exécutés côté serveur, on est sur du 100% statique, servi par un serveur web, et c'est tout.</p>
<p>Des images, de l'html, du css et éventuellement un peu de javascript pour faire joli.</p>
<h1 id="mais-pourquoi">Mais pourquoi ?</h1>
<h2 id="de-labandon-de-pluxml">De l'abandon de PluXML</h2>
<p>Et oui, ça faisait un moment que je souhaitais mettre de côté mon ancien moteur de blog.<br/>
Il m'a fidèlement servi pendant des années, et je tiens à remercier la communauté <a href="http://pluxml.org/">PluXML</a> pour ce CMS très léger et parfaitement fonctionnel.</p>
<p>Néanmoins, le système de captcha pour les commentaires (et malgré les plugins) laissait à désirer et je passait trop de temps à virer les spams qui passaient dans les mailles du filet.</p>
<p>De plus, la gestion des mises à jour, bien que de mieux en mieux intégrée, reste comme pour tous les CMS assez critique. Les failles sont en général dangereuses (injection de script, réécriture d'articles ou de commentaires, ...) et jamais faciles à suivre, parfois pas simple à corriger. Elles peuvent générer des bugs difficile à repérer, etc...</p>
<p>En outre, il utilise php (comme la plupart des CMS), et bien qu'il n'utilise pas de bases de données au sens propre (stockage plat dans de l'xml), il reste mine de rien consommateur en IO et en ressources, surtout avec ma notoriété croissante (ahah)</p>
<p>Plus sérieusement, PluXML est très bien et ce sont principalement les arguments des spam commentaires et de la gestion des mises à jour qui ont fait pencher la balance.</p>
<h2 id="des-avantages-du-blog-statique">Des avantages du blog statique</h2>
<p>Le blog statique se démarque sur 2 points : </p>
<ul>
<li>Il est statique</li>
<li>Le moteur qui le génère n'est pas accessible pour un tiers.</li>
</ul>
<p>Le premier point parait trivial, mais en fait pas tant que ça.<br/>
Le 2eme point demande également plus d'explication</p>
<h3 id="pas-de-script-cote-serveur">Pas de script côté serveur</h3>
<p>En effet, le fait d'avoir un site entièrement statique rend l'hébergement ô combien plus simple. Mine de rien, la gestion de php (et de ses mises à jour) ou d'une base de donnée reste consommateur en temps, demande des downtime pour les maintenances, etc.</p>
<p>De plus, un site qui exécute des scripts (php notamment) sur le serveur consomme des ressources serveur, et surtout est un point d'entrée éventuel pour un hack.<br/>
Bien que ça se passe la plupart du temps très bien, si jamais quelqu'un arrive à exécuter un fichier de son cru sur le serveur (injection de fichier, faille, etc), il peut alors faire tout ce qu'il veut, de transformer le serveur en zombie de botnet à miner du <a href="https://fr.wikipedia.org/wiki/Bitcoin">bitoin</a> (ou des <a href="https://fr.wikipedia.org/wiki/Ethereum">Ether</a>, on commence à en voir), envoyer des spam, ou simplement surveiller ce qui s'y passe.</p>
<p>Dans tous ces cas, votre serveur est compromis, c'est mort, foutu, en général repartir de zéro est plus tranquillisant pour l'esprit.<br/>
Ca ne m'est jamais arrivé personnellement, mais dans mon boulot j'en vois régulièrement, et c'est suffisant pour que je ne tienne pas à le subir à la maison :-)</p>
<p><strong>Avec un blog statique, rien de tout ça.</strong> Il n'y a strictement rien d'exécuté côté serveur, les fichiers sont statiques (d'où le nom) et donc sont envoyés tels quels au navigateur du visiteur, dans l'idéal ils ne sont même pas lus par le serveur (autre que pour les envoyer of course), et encore moins interprétés.</p>
<p>Bien sûr ce n'est pas parfait, mais déjà il y a du mieux.</p>
<h3 id="le-moteur-est-exterieur-au-site">Le moteur est extérieur au site</h3>
<p>Générer ces fichiers statiques ne se fait pas par magie.</p>
<p>En effet, il est possible d'écrire soit même son CSS, son html, et remplir chaque page à la main. Soyons honnêtes, je ne suis pas développeur web et l'html/css, disons que ça me passionne pas.<br/>
Du coup, plusieurs moteurs existent qui permette de générer ces fichiers statiques à partir de templates, de choisir des thèmes, etc.</p>
<p>Et donc, le moteur qui génère tous ces fichiers est extérieur au site. C'est à dire qu'il n'est pas exposé publiquement.</p>
<p>Dans le cas de php par exemple, ce sont les visiteurs qui lancent les scripts php et provoquent la génération des pages, avec les inconvénients vu ci-dessus.<br/>
Dans le cas du site statique, c'est le rédacteur qui va générer les pages une fois, lorsqu'il le souhaite (on parle de compilation comme pour un logiciel) et ensuite elles ne bougent plus.</p>
<p>Le premier avantage est en terme de ressources, car le site est généré une fois et on peut le faire n'importe quand (la nuit, sur un serveur dédié à ça) pour que ça n'impacte pas le serveur exposé au public.</p>
<p>Le 2eme avantage touche aux mises à jour du moteur et aux failles associées. En effet, le moteur n'est plus exposé au public !<br/>
Donc, même si des failles apparaissent, leur exploitation est beaucoup plus difficile, voire impossible, pour un hacker puisqu'il n'a tout simplement pas accès au système.</p>
<p>Et en plus, comme le site statique vit sa vie indépendamment du moteur, les mises à jour de ce dernier n'impliquent pas de maintenance ou de coupure du site, ce qui est appréciable :-)</p>
<h1 id="ok-ca-rox-pourquoi-ces-sites-nont-pas-conquis-le-monde">Ok ça rox, pourquoi ces sites n'ont pas conquis le monde ??</h1>
<p>Alors ne mentons pas, il y a des désavantages.</p>
<p>Le principal étant que... le site est statique (Merci <a href="https://fr.wiktionary.org/wiki/Captain_Obvious">Capitaine Obvious</a> !)<br/>
Ça implique qu'il n'y a strictement rien pour interagir avec les visiteurs.</p>
<p>En effet, pas d'intéraction côté serveur, c'est pas de commentaires, pas de livre d'or, aucun moyen pour un visiteur de choisir ou configurer quelque chose qui serait enregistré dans une base de données et réutilisé plus tard (panier, compte, moyen de paiement, adresse courriel, ...)</p>
<p>On voit tout de suite que ça pose certains problèmes pour la plupart des sites du marchés, et notamment les sites qui fournissent un service (vente de produit, vente de vos informations privées et autres)</p>
<p>Pour un blog, par contre, c'est nickel. L'intéraction est minimale, et on peut gérer la plupart des problèmes en les contournant.</p>
<p><strong>Sauf sur un point.</strong></p>
<h2 id="de-la-gestion-des-commentaires">De la gestion des commentaires</h2>
<p>LES COMMENTAIRES. Tout bon blog sérieux se doit d'en avoir, sinon c'est trop la honte on a peur des retours des gens sur nos articles lolilol.</p>
<p>Non réellement, j'aime bien les commentaires parce que ça permet un échange avec mes lecteurs, et moi j'aime bien échanger, apprendre et transmettre, m'améliorer et améliorer.<br/>
C'est même pour ça que j'ai fais un blog, alors...</p>
<p>Et du coup les commentaires <strong>sont</strong> un problème sur un site statique, puisqu'il ne permet pas d'intéragir.</p>
<p>Des solutions existent, et la solution la plus répandue est l'utilisation de <a href="https://disqus.com/">disqus</a>, un site qui ne fait que des commentaires. (c'est présenté avec des fioritures autour mais en gros c'est ça)<br/>
Vous l'incluez dans votre site avec un peu de javascript, et il apparait bien intégré, le visiteur peut voir les commentaires, y répondre et en ajouter, c'est bô. </p>
<p>Sauf que ce n'est pas sur votre serveur, c'est le site de Disqus qui est affiché, votre navigateur parle à Disqus, et vos commentaires sont enregistrés chez Disqus.<br/>
Ça me dérangeait un peu, comme concept.</p>
<p>Alors, j'ai pris une autre solution, certes moins élégante et plus "brute de décoffrage".</p>
<p><strong>Pour commenter, envoyez moi un courriel.</strong></p>
<p>Alors je sais, vous allez me dire, "Queeeeouuuââââ ? Que raconte-t-il ce vil faquin ? Envoyer des courriels en 2017 ??"</p>
<p>Alors d'une part, vous devez dans tous les cas fournir une adresse de messagerie pour poster un commentaire, où que ce soit, envoyer un vrai courriel ne coute donc pas cher.</p>
<p>D'autre part, j'ai quand même fait en sorte de simplifier les choses, faut pas déconner.</p>
<p>En bas des articles, dans la section "Comments" (oui je travaille à la traduction), vous trouverez un espace de commentaire tout ce qu'il y a de plus classique.</p>
<p>Écrivez votre commentaire, comme vous le souhaitez, comme d'habitude. <strong>La seule différence</strong> c'est que quand vous cliquerez sur envoyer, ça vous fera un joli mailto:, qui ouvrira votre client de messagerie par défaut, et proposera d'envoyer le commentaire par courriel, tout bien formaté comme il faut. Si votre client est bien configuré, il suffira d'appuyer sur "Envoyer", et c'est tout !</p>
<p>Ensuite, je fais un peu de modération (parce qu'on est quand même pas à l'abri d'un robot un peu trop malin...), et hop votre commentaire sera publié.<br/>
Exactement comme sur mon ancien blog, et comme sur la majorité des sites présents sur Internet.</p>
<p>Et comme ça, votre commentaire restera chez moi, sur mon serveur, dans mon salon, de même que tout ce qui touche au blog.</p>
<p><strong>Elle est pas belle la vie ?</strong></p>
<h1 id="et-sinon-la-technique">Et sinon, la technique ?</h1>
<p>Ah oui, comme ce blog se veut quand même un peu technique, parlons tuyauterie.</p>
<p>Ce blog est désormais propulsé par <a href="https://blog.getpelican.com/">Pélican</a>, sur une base de python.</p>
<p>Le thème graphique du blog est inspiré par <a href="http://oncrashreboot.com/elegant-best-pelican-theme-features">Elegant</a> de <a href="http://oncrashreboot.com">http://oncrashreboot.com</a>.</p>
<p>Il est géré et versionné via <a href="https://git.lecygnenoir.info/LecygneNoir/blog.victor-hery.com">un dépôt git</a>. Un peu d'intégration continue maison pour publier automatiquement a été ajoutée par dessus.<br/>
Vous pouvez librement cloner le dépôt si vous voulez récupérer des morceaux de code, tout est sous licence <a href="https://creativecommons.org/licenses/?lang=fr">Creative Common</a>. Je vous demanderai juste de citer le site d'origine sous la forme : <a href="https://blog.victor-hery.com">https://blog.victor-hery.com</a></p>
<p>Vous pouvez aussi vous inscrire au dépôt (ou créer des tickets) si vous voulez envoyer des pull request, pour améliorer des articles ou corriger des fautes d'orthographe par exemple.</p>
<p>Le blog est rédigé en <a href="https://fr.wikipedia.org/wiki/Markdown">MarkDown</a></p>
<p>Bien sûr, tous les articles et leurs commentaires ont été importés.</p>
<p>Cet article se voulant une annonce, je reste volontairement flou sur la partie technique (ça fait déjà une sacrée annonce à lire)<br/>
Si vous voulez plus de détails, ou que je fasse un article pour détailler la couche technique que j'utilise, n'hésitez pas à commenter ;-)</p>
<p>Dites moi ce que vous pensez de ce nouveau fonctionnement, j'espère qu'il vous plaira, et à bientôt pour de nouveaux articles !</p>Culture et jardin potager en lasagne2016-08-08T10:27:00+02:002016-08-08T10:27:00+02:00Victortag:blog.victor-hery.com,2016-08-08:/2016/08/culture-jardin-potager-lasagnes.html
<h2 id="de-quoi-donc">De quoi donc ?</h2>
<p>Aujourd'hui pas de jeux de mots, nous allons réellement discuter jardin, et mettre la main dans la terre au sens propre :-)</p>
<p>Dans le sympathique nouveau coin ou j'habite, j'ai la chance d'avoir un jardin, et comme j'ai toujours eu envie d'avoir un jardin potager, je me suis …</p>
<h2 id="de-quoi-donc">De quoi donc ?</h2>
<p>Aujourd'hui pas de jeux de mots, nous allons réellement discuter jardin, et mettre la main dans la terre au sens propre :-)</p>
<p>Dans le sympathique nouveau coin ou j'habite, j'ai la chance d'avoir un jardin, et comme j'ai toujours eu envie d'avoir un jardin potager, je me suis intéressé aux différents types de cultures.</p>
<p>Là aussi il s'agit de do it yourself, et de l'auto production ^^</p>
<p>Parmi le jardinage classique et les culture en carré, une technique m'a bien plu et permet un rendement optimal, c'est la <a href="https://fr.wikipedia.org/wiki/Jardinage_en_lasagnes">culture en lasagne</a>.</p>
<p>Après m'y être essayé avec pas mal de succès l'année dernière, j'ai décidé d'augmenter ma surface cette année, et j'en ai profité pour faire quelques photos afin de rédiger un petit article, qui j'espère plaira !</p>
<h2 id="concept">Concept</h2>
<p>La culture en lasagne fonctionne de manière très simple, et présente plusieurs avantages, notamment par rapport au jardinage classique (et quelques un par rapport au jardinage en carré)</p>
<p>Vous pouvez jardiner en lasagne n'importe où, même sur du béton ou du bitume. Un balcon par exemple est tout à fait envisageable !</p>
<p>Si vous jardinez sur de l'herbe ou des mauvaise herbes, pas besoin de désherber, vous posez votre lasagne par dessus et les mauvaises herbes seront éttoufées toutes seules.</p>
<p>Les différentes couches de matières (d'où le nom lasagne) fournissent tout ce qu'il faut aux plantes pour pousser de manière très exubérante. Légumes et/ou fleurs, selon les gouts ;)</p>
<p>Aucun besoin de désherber même durant l'année, car vous amenez de la terre "propre" sans mauvaises herbes, et en paillant régulièrement la lasagne, peu de mauvaises herbes arriveront à prendre. En plus, le paillage nourrira la lasagne.</p>
<p>Les différentes couches permettent de retenir efficacement l'eau, et donc de diminuer l'arrosage par rapport à de la pleine terre.</p>
<p> </p>
<h2 id="ingredients-et-recette">Ingrédients et recette</h2>
<p>Il vous faut de la matière première de différente sorte.</p>
<p>Nécessaire :</p>
<p> - De quoi couvrir une surface de environ 1m sur 2m de carton d'emballage. <strong>Il faut du carton sans étiquettes, scotch, ou autre addictif chimiques de ce genre</strong>. Le carton ondulé est un must car il garde très bien l'humidité et réduit l'arrosage. Du carton duquel vous enlevez les étiquettes et le scotch fait très bien le job. Je vous conseille de planter vos tuteurs tout de suite, car une fois toutes les couches en place, c'est plus compliqué à enfoncer à travers ;-)</p>
<p><img alt="Lasagnes avec tuteurs" src="/images/Jardin/img_1303.jpg" style="width: 500px; height: 375px;"/></p>
<p> - Du résidu "brun" épais, qui permettra de faire une couche stable pour votre lasagne. Des copeaux de bois ou du branchage léger (type fagot) sont idéals</p>
<p> - Du résidu vert épais pour faire la première couche de vert. Des feuilles fraîches (je prends des feuilles de bambous) c'est parfait.</p>
<p><img alt="Lasagnes couches de gros" src="/images/Jardin/img_1306.jpg" style="width: 500px; height: 375px;"/></p>
<p> - Du résidu brun fin (par exemple du foin ou de la paille). Pas la peine de prendre du haut de gamme (en général assez cher) qui sert à nourrir les animaux. Ici, on veut plutôt du déchet :)</p>
<p> - Du résidu vert fin pour terminer vos couches. Ici, de l'herbe fraîchement coupée ou des déchets verts sont parfaits. <strong>Attention dans le cas de l'herbe coupée</strong>, elle composte à très haute température (jusqu'à 50°C), il faudra donc attendre au moins une semaine pour planter des légumes dans votre lasagne sinon les racines vont cramer et se dessécher. . . Par contre, la plupart des fruitiers s'en fichent (les fraisiers sont très content les pieds dans le chaud ;) )</p>
<p><img alt="" src="/images/Jardin/img_1312.jpg" style="width: 500px; height: 375px;"/></p>
<p> - Enfin, du compost bien avancé si vous en avez, sinon, du terreau pour plantation bio, ça s'achète par sac de 5 ou 10L en magasin et c'est parfait. Il permettra de planter vos plants dans quelques chose de solide, tout en évitant que les couches ne s'envolent avec le vent. Les couches quand à elles vont composter à différentes vitesses et apporter des nutriments en permanences à vos plantations.</p>
<p><img alt="" src="/images/Jardin/img_1310.jpg" style="width: 500px; height: 375px;"/></p>
<p> - Enfin, il est nécessaire d'arroser abondamment pour que la terre soit humide avant de planter, et également humidifier les différentes couches. L'avantage est que le carton retiendra l'eau, vous pouvez donc y aller sans problèmes.</p>
<h2 id="et-on-en-fait-quoi">Et on en fait quoi ?</h2>
<p>Et voila, vous pouvez planter ! Comme dit précedemment, mieux vaut attendre une petite semaine si vous avez utilisé de l'herbe fraiche le temps qu'elle composte. Sinon, vous pouvez directement planter !</p>
<p>Voici quelques conseils tirés de mon expérience (limitée je le précise). Si vous en avez d'autres ou souhaitez partager, n'hésitez pas à commenter !</p>
<p> - Si vous attendez avant de planter, n'oublier pas d'arroser abondamment juste après avoir planté pour aider vos plants à prendre leurs marques.</p>
<p> - Le type de plants dépendra de vos envies, et de la période de l'année. Avril-Juin est parfait pour les légumes d'été (courgettes, tomates, melon, concombres, etc). Les fruitiers peuvent être plantés à peu près n'importe quand (fraisier, framboises, ...). Idem pour certaines fleurs. Référez vous à vos plants pour en savoir plus !</p>
<p> - Pour la sélection, préférez des choses qui poussent en hauteur. Malheureusement l'inconvénient de la lasagne est que niveau profondeur, c'est pas trop ça. Du coup, tout ce qui est légumes à racines (poireau, radis, pommes de terres, ...) ne poussent pas idéalement. La racine a tendance à ramper plutôt que s'enfoncer, et c'est pas top.</p>
<p> - Si vous plantez des graines, mieux vaut laisser la terre exposée pour ne pas les stresser.</p>
<p> - Si par contre vous partez de plants déjà bien germés, vous pouvez recouvrir votre terre d'une nouvelle couche d'herbe ou de copeau pour limiter les arrivées de mauvaises herbes (notamment les graines volantes) et limiter encore l'arrosage (en limitant l'évaporation de la terre)</p>
<p> - Vous pouvez découper le carton qui dépasse pour faire plus joli, mais essayez de laisser au moins 3 à 5 cm autour de la lasagne, cela empêchera les mauvaises herbes grimpantes alentours de se reprendre dans la lasagne. Le carton disparaitra tout seul au bout de quelques mois, normalement d'ici là la lasagne sera bien posée.</p>
<p> - Il n'y a pas de miracles. La lasagne devrait permettre d'avoir un rendement très efficace (ça pousse très fort) et de limiter tout le travail de la terre (désherbage, creuser des trancher, etc) mais par contre, il faut entretenir ce qui pousse. De l'arrosage quotidien (ça dépend de ce qui est planté) et un entretien (tuteurage, enlever les gourmands des tomates, ...) est nécessaire ! Attention également aux maladies.</p>
<p>Et voila c'est tout. Je rajouterai des nouveaux conseils si j'en découvre d'autres :-)</p>
<p>N'hésitez pas à poster vos commentaires à propos de cette technique de jardinage et partagez vos expériences !</p>
<h2 id="le-resultat">Le résultat,</h2>
<p>Voici quelques photos du résultat 2 mois après avoir planté environ.</p>
<p>Au premier plan, 4 pieds de tomates, et derrières 2 pieds de concombre. On voit sur la droite une 2eme lasagne avec une courgette. On voit qu'ils ont pris leurs aises :-)</p>
<p>Je vous mets aussi une photo de la récolte (d'une journée !). Les tomates ont mal démarrées à cause des 5 semaines de pluie du printemps cette année (2016), mais les concombres ont adorés !</p>
<p><img alt="" src="/images/Jardin/img_1931.jpg" style="width: 400px; height: 300px;"/><img alt="" src="/images/Jardin/img_1932.jpg" style="width: 400px; height: 300px;"/></p>Sonde RIPE Atlas :2016-01-18T22:52:00+01:002016-01-18T22:52:00+01:00Victortag:blog.victor-hery.com,2016-01-18:/2016/01/sonde-ripe-atlas.clignote-ou-pas.html
<h2 id="la-sonde-ripe-atlas">La sonde RIPE Atlas</h2>
<p>Depuis quelques mois, je participe au programme <a href="https://atlas.ripe.net/">RIPE Atlas</a>, un programme extrêmement intéressant du RIPE NCC qui consiste à installer chez des particuliers ou des professionnels des petites sondes permettant de tester la qualité du réseau, effectuer des tests de connectivité, etc.</p>
<p>L'objectif est de construire …</p>
<h2 id="la-sonde-ripe-atlas">La sonde RIPE Atlas</h2>
<p>Depuis quelques mois, je participe au programme <a href="https://atlas.ripe.net/">RIPE Atlas</a>, un programme extrêmement intéressant du RIPE NCC qui consiste à installer chez des particuliers ou des professionnels des petites sondes permettant de tester la qualité du réseau, effectuer des tests de connectivité, etc.</p>
<p>L'objectif est de construire un réseau pour collecter des données sur la qualité de la connexion dans le monde entier, et ainsi avoir une carte détaillée à l'échelle de la planète de l'état du réseau Internet.</p>
<p>A peu près n'importe qui peut adhérer à ce programme, même si en France il devient difficile d'en avoir vu la quantité de participants...</p>
<p>Ici nous allons discuter de comment réparer une sonde Atlas de 3eme génération qui ne veut plus se connecter. Cette astuce me vient du support RIPE Atlas, et est publiée avec leur aimable accord :-)</p>
<h2 id="diagnostic">Diagnostic</h2>
<p>Il y a quelques temps, ma sonde s'est mise à refuser de se connecter sans raisons évidentes.</p>
<p>(Bon, réellement suite à une coupure de courant nocturne, mais bon, passons ^^)</p>
<p>Quoiqu'il en soit, un diagnostic basique montrait que la sonde démarrait, qu'elle récupérait bien une adresse IP en DHCP, IPv4 et IPv6, elle effectuait même des requêtes DNS.</p>
<p>Mais, elle ne se connectait pas jusqu'aux serveurs RIPE Atlas, qui la voyait comme absente, et le clignotement des diodes sur le dessus ne correspondait à aucun des schémas recensés dans la <a href="https://atlas.ripe.net/about/faq/#what-do-the-lights-on-the-side-of-the-probe-mean">FAC</a>.</p>
<p>A partir de là, n'ayant aucun accès possible à la sonde, il devient difficile d'aller plus loin, mais heureusement le support RIPE est là. Et il est très efficace, même en période de fêtes !</p>
<h2 id="lastuce">L'astuce</h2>
<p>L'astuce est en fait assez simple pour remettre à zéro la sonde et lui permettre de se reconnecter comme si rien ne s'était passé :</p>
<ol>
<li>Éteindre la sonde</li>
<li>Retirer le plug USB qui est enfiché dans la sonde</li>
<li>Démarrer la sonde et connectez là comme habituellement</li>
<li>Attendez pendant 5 à 6 minutes</li>
<li>Remettez en place le plug USB à chaud, sans éteindre la sonde</li>
<li>Au bout d'une dizaine de minute, la sonde a détecté de nouveau le plug et lancés les scripts adéquats.</li>
<li>Le clignotement revient à la normale, et la sonde se reconnecte</li>
<li>Et voila</li>
</ol>
<p>Simple et efficace.</p>
<p>Merci au RIPE pour ce projet et pour l'astuce !</p>Use Haproxy with Let's Encrypt2015-12-18T09:33:00+01:002015-12-18T09:33:00+01:00Victortag:blog.victor-hery.com,2015-12-18:/2015/12/use-letsencrypt-haproxy.html
<h2 id="first-what-are-we-talking-about">First: what are we talking about?</h2>
<p><strong>Note : </strong>Ceci est la version anglaise de l'article, pour la version française, voir <a href="/2015/12/utiliser-letsencrypt-haproxy.html">ici</a>.</p>
<h3 id="haproxy">Haproxy :</h3>
<p><a href="http://www.haproxy.org/">Haproxy </a>is a proxy software. It has many use, but here we will use its capacity to reverse proxying HTTP and HTTPS.</p>
<p>For this post, we will consider you …</p>
<h2 id="first-what-are-we-talking-about">First: what are we talking about?</h2>
<p><strong>Note : </strong>Ceci est la version anglaise de l'article, pour la version française, voir <a href="/2015/12/utiliser-letsencrypt-haproxy.html">ici</a>.</p>
<h3 id="haproxy">Haproxy :</h3>
<p><a href="http://www.haproxy.org/">Haproxy </a>is a proxy software. It has many use, but here we will use its capacity to reverse proxying HTTP and HTTPS.</p>
<p>For this post, we will consider you have a working Haproxy server and a working configuration.</p>
<h3 id="lets-encrypt">Let's Encrypt :</h3>
<p><a href="https://letsencrypt.org/">Let's Encrypt</a> is an open source project sponsored by Mozilla foundation and Cisco.</p>
<p>Idea is to create an free certificate authority in order to create SSL certificate and doing so, allowing to most people possible to use HTTPS and secure websites.</p>
<p>Regarding usual cost of SSL certificate, this a very interesting project!</p>
<p>In addition to that, Let's Encrypt is really easy to use, mainly thank to an API allowing to create certificate very easily.</p>
<p>We will use this API in this post through Let's Encrypt official python client.</p>
<p><strong>EDIT : </strong>04/04/16 : add note about case when you use redirect HTTP to HTTPS in your HTTP haproxy frontend</p>
<p><strong>EDIT</strong> : 09/16/16 : Update with new binary + add git repository with some scritps to automate LE management</p>
<h2 id="concept">Concept</h2>
<p>Let's Encrypt offers many option to create and validate certificate via its client.</p>
<p>If your Haproxy is localised on the same server than your web server, you can use the --webroot option, which allow Let's Encrypt to store a special file directly in the root directory of your website, in order to allow Let's Encrypt server to request the file and validate that you are the real owner of the domain.</p>
<p>If you want to use this option, you can read this <a href="https://blog.infomee.fr/p/letsencrypt-haproxy">blog post </a>about using webroot and haproxy, including using a dedicated apache webserver for validation.</p>
<p>For this post, we will use instead the --standalone option, which launch a mini-webserver. This webserver will be used for the validation process, as Let's Encrypt server will request it directly. Usually, this option has a big disadvantage: as the webserver bind on 80 network port, the real webserver needs to be temporally shutdown during the validation process.</p>
<p>In other word, your website(s) will be unavailable during all the process.</p>
<p>But we are going to use an option to change the default port, in coordination with haproxy frontend/backend capabilities, to allow validation without any downtime :-)</p>
<p>-- Many thanks to <a href="https://coolaj86.com/articles/lets-encrypt-with-haproxy/">coolaj86</a> as his post give me this idea to use haproxy and Let's Encrypt together ;-) --</p>
<h2 id="get-lets-encrypt-client">Get Let's Encrypt client</h2>
<p>As LE is now officially released, a new official binary is available, more advanced and more easy to use than the previous letsencrypt-auto</p>
<p>All information are available on the certbot <a href="https://certbot.eff.org/">official website</a>, but here are quick instructions how to use it.</p>
<p><code>cd /root/</code></p>
<p><code>mkdir letsencrypt</code></p>
<p><code>cd letsencrypt</code></p>
<p><code>wget https://dl.eff.org/certbot-auto</code></p>
<p><code>chmod a+x certbot-auto</code></p>
<p><br/>
You can next directly use the binary to get your new certificate (at least, once you have configured as this blog article describes it :-p)</p>
<p><code>./certbot-auto certonly --domains blog.victor-hery.com --renew-by-default --http-01-port 63443 --agree-tos</code></p>
<h2 id="configure-haproxy">Configure haproxy</h2>
<h3 id="frontend">Frontend</h3>
<p>To avoid any downtime, we will use your existing frontend.</p>
<p>Let's Encrypt will request the IP address which resolve your website, so if you have many frontends or many IPs, you need to configure each frontend according to your needs.</p>
<p>Main idea is : during the process, Let's Encrypt request the base website URL, following by <em>/.well-known/acme-challenge/a_unique_id.</em></p>
<p>So we are going to configure a haproxy ACL which match this path to redirect it to a specific backend!</p>
<div class="highlight"><pre><span></span><code><span class="err">frontend http-in</span>
<span class="err"> acl app_letsencrypt path_beg /.well-known/acme-challenge/</span>
<span class="err"> [...]</span>
<span class="err"> use_backend bk-letsencrypt if app_letsencrypt</span>
</code></pre></div>
<ul>
<li>path_beg: match the path (the part just after the first /) that begin by <em>.well-known/acme-challenge/</em></li>
</ul>
<p>Doing so, all Let's Encrypt requests will be redirected to the <em>bk-letsencrypt</em> backend.</p>
<p><strong>Warning : </strong>if you are using redirect from HTTP to HTTPS for your website, haproxy will also redirect Let's Encrypt request to your HTTPS frontend.</p>
<p>You will then need to add the acl and use_backend lines to your HTTPS frontend as well, or let's encrypt will get 404 not found answer.</p>
<h3 id="backend">Backend</h3>
<p>About the backend, we are going to configure it to redirect request to the server launched by Let's Encrypt client.</p>
<div class="highlight"><pre><span></span><code><span class="err">backend bk-letsencrypt</span>
<span class="err"> log global</span>
<span class="err"> mode http</span>
<span class="err"> server srv_letsencrypt 127.0.0.1:63443</span>
</code></pre></div>
<ul>
<li>mode http: allow to check the HTTP consistency of the request</li>
<li>server: this line redirect to the server that Let's Encrypt client will launch on localhost, port 63443</li>
</ul>
<p>The local server will not always be up, only when the client is running. Rest of the time, haproxy will return a 503 error if someone try to get an URL matching the ACL.</p>
<p>Of course, you need to reload haproxy after doing these modifications.</p>
<div class="highlight"><pre><span></span><code>systemctl reload haproxy.service```
## Configure and use of Let's Encrypt
#### Configuration :
<span class="nt"><p></span>To simplify the command line usage, we use a configuration file for Let's Encrypt client.<span class="nt"></p></span>
<span class="nt"><p></span>By default, the client uses the file <span class="nt"><em></span>/etc/letsencrypt/cli.ini<span class="nt"></em></span>. So this is the file we are going to edit.<span class="nt"></p></span>
</code></pre></div>
<p>rsa-key-size = 4096
email = your_admin_email
authenticator = standalone
standalone-supported-challenges = http-01</p>
<div class="highlight"><pre><span></span><code><span class="nt"><ul></span>
<span class="nt"><li></span>rsa-key-size: tell letsencrypt to direclty generate 4096 bits certificate, more strong that default 2048. You can downgrade to 2048 (but never less!) if your server is low performance to gain some generation time<span class="nt"></li></span>
<span class="nt"><li></span>email: use a valid email address, as it will be used if certificate recovery is needed through the Let's Encrypt website.<span class="nt"></li></span>
<span class="nt"><li></span>authenticator: as seen before, we will use <span class="nt"><em></span>standalone<span class="nt"></em></span> mode<span class="nt"></li></span>
<span class="nt"><li></span>standalone-supported-challenges: this option is specific to standalone mode, and allow to choose the method used for the verification process, between <span class="nt"><em></span>http-01<span class="nt"></em></span> and <span class="nt"><em></span>tls-sni-01<span class="nt"></em></span>. Here we use http-01 as our website has no valid certificate (the first time), and so haproxy will not have valid SSL certificate to use in its frontend for Let's Encrypt server request.<span class="nt"></li></span>
<span class="nt"></ul></span>
<span class="nt"><p></span>Using HTTP for the verification process is safe, as only the verification request will be send in clear, and it has no secret inside.<span class="nt"></p></span>
### Generate the certificate
<span class="nt"><p></span>The command line to use to generate your certificate is the following:<span class="nt"></p></span>
</code></pre></div>
<p>/root/letsencrypt/certbot-auto certonly --domains yourdomain.tld --renew-by-default --http-01-port 63443 --agree-tos```</p>
<ul>
<li>certonly: tell the client that we only want to generate the certificate, not using some installation plugin to install certificate somewhere.</li>
<li>domains: the domain or subdomain for which you want your certificate</li>
<li>renew-by-default: tell letsencrypt that, if the certificate already exist, it should renew it. If it does not exist, it will create it.</li>
<li>http-01-port: tell the network port to use for the temporary validation server launched. This is the port used in the haproxy backend we have configured before.</li>
<li>agree-tos: tell the client to automatically accept the therm of service of Let's Encrpt (If you are here, you have read it and agree, right ?)</li>
</ul>
<h3 id="installing-the-certificate">Installing the certificate</h3>
<p>Certificates are created in a directory called <em>/etc/letsencrypt/live/yourdomain.tld/</em> by the client during the generation process.</p>
<p>You will find multiple files inside:</p>
<ul>
<li>cert.pem : the certificate public part (crt)</li>
<li>chain.pem : the authority chain (ca of authorities)</li>
<li>fullchain.pem : a concatenation of cert.pem and chain.pem</li>
<li>privkey.pem : the certificat private key</li>
</ul>
<p>In order to use with haproxy, you need to concatenate fullchain.pem and privkey.pem, and store it where haproxy read its certificates.</p>
<div class="highlight"><pre><span></span><code>cat fullchain.pem privkey.pem <span class="ni">&gt;</span> domain.tld.pem```
<span class="nt"><p></span>For example for the following HTTPS frontend:<span class="nt"></p></span>
</code></pre></div>
<p>frontend https-in
bind IP:443 ssl crt /etc/haproxy/cert/</p>
<div class="highlight"><pre><span></span><code><span class="nt"><p></span>Here we need to store the domain.tld.pem file in <span class="nt"><em></span>/etc/haproxy/cert/<span class="nt"></em></p></span>
<span class="nt"><p></span>Once your certificate is stored in the right place, reload haproxy for it to re-read certificate, and everything should be OK.<span class="nt"></p></span>
<span class="nt"><p></span>Of course do not forget to configure an HTTPS frontend with correct ACL for your website in haproxy!<span class="nt"></p></span>
<span class="nt"><p></span>Usually, simply copy/paste of your HTTP frontend changing port to 443 (and adding ssl and crt option) will do the job.<span class="nt"></p></span>
## Limitations
### Renew the certificate
<span class="nt"><p></span>Even from the end of beta time, LE has taken decision to provide certificate for 90 days duration max. It allow them to avoid abuse usage and to make the project alive by forcing regular renew.<span class="nt"></p></span>
<span class="nt"><p></span>Note that unlilke the beta client, certbot-auto is capable to use all your available certificates (thanks to the directory<span class="nt"><em></span>/etc/letsencrypt/renewal/<span class="nt"></em></span>) to allow automatic renewal .<span class="nt"></p></span>
<span class="nt"><p></span>So remember to configure a cron job on your server to renew certificate:<span class="nt"></p></span>
</code></pre></div>
<p>crontab -e</p>
<div class="highlight"><pre><span></span><code>
</code></pre></div>
<h1 id="renew-certificate">renew certificate</h1>
<p>30 01 01,10,20,30 * * /root/letsencrypt/certbot-auto renew```</p>
<p>This cron task will launch the renew command each 10 days to be sure your certificates will stay valids.</p>
<p>Do not forget that you still need to create the .pem from fullchain.pem and .key to give it to haproxy. See below for some automation about this task!</p>
<h3 id="rate-limit-of-certificate-by-domain">Rate limit of certificate by domain</h3>
<p>Because of its free use Let's Encrypt use a rate-limit sysytem to avoid generation of too many certificate for the same domain.</p>
<p>You will get an error if you try to generate too quickly or too often certificates for the same domain</p>
<p><strong>Be careful:</strong> the limitation take into account subdomain as well! All certificates finishing with domain.tld will be count.</p>
<h3 id="ins">iNS :</h3>
<p>For the moment, Let's Encrypt does not allow certificate for international Domain Name.</p>
<p>This is impossible to generate a certificate for a domain or subdomain containing accent or special characters.</p>
<p>For example, impossible to generate certificate for https://blog.héry.com unfortunately.</p>
<p>There is currently a <a href="https://github.com/letsencrypt/boulder/issues/597">boulder</a> on Let's Encrypt github, but it is still no available. If you are willing to help or need the function, does not hesitate to join :-)</p>
<h2 id="bonus-some-scripts">Bonus: some scripts</h2>
<p>In order to make the process easier, I have written some scripts to allo generation and renewal of certificate, and haproxy interactions, easier.</p>
<p>They are available in my <a href="https://git.lecygnenoir.info/LecygneNoir/letsencrypt-haproxy">git repository</a>, so you can easily clone them in your server:</p>
<p><code>git clone https://git.lecygnenoir.info/LecygneNoir/letsencrypt-haproxy.git</code></p>
<p>README simply describes how to use them, it pretty simple.</p>
<p>create-certificate allow you to create a certificate for the domain you pass to the script, then it creates the .pem for haproxy, store it in the given directory and reload haproxy.</p>
<p>renew-certificates only renew all certificates that need to be renewed, creates as well haproxy pem files, en reload haproxy. You can use renew-certificate in our cron task as explained before if you want.</p>
<p><strong>Do not forget to check path in scripts, mainly where to store certificates for haproxy, and path to certbot binary</strong></p>
<p>And voila, with all of that, you should be able to create all certificates you need, and use them directly in haproxy, without any downtime! So, welcome in the HTTPS world :-)</p>Utiliser Let's Encrypt avec Haproxy2015-12-18T09:33:00+01:002015-12-18T09:33:00+01:00Victortag:blog.victor-hery.com,2015-12-18:/2015/12/utiliser-letsencrypt-haproxy.html
<h2 id="de-quoi-parle-t-on-donc">De quoi parle-t-on donc ?</h2>
<p><strong>Note: </strong>This is the French version of the post. English version <a href="/2015/12/use-letsencrypt-haproxy.html">here.</a></p>
<h3 id="haproxy">Haproxy :</h3>
<p><a href="http://www.haproxy.org/">Haproxy </a>est un logiciel de proxy. Il peut servir à beaucoup de chose, ici nous l'utiliserons pour de l'https et de l'http. Je vous invite à lire <a href="http://blog.victor-hery.com/article21/configurer-un-reverse-proxy-sous-haproxy">mon article à ce sujet</a> si …</p>
<h2 id="de-quoi-parle-t-on-donc">De quoi parle-t-on donc ?</h2>
<p><strong>Note: </strong>This is the French version of the post. English version <a href="/2015/12/use-letsencrypt-haproxy.html">here.</a></p>
<h3 id="haproxy">Haproxy :</h3>
<p><a href="http://www.haproxy.org/">Haproxy </a>est un logiciel de proxy. Il peut servir à beaucoup de chose, ici nous l'utiliserons pour de l'https et de l'http. Je vous invite à lire <a href="http://blog.victor-hery.com/article21/configurer-un-reverse-proxy-sous-haproxy">mon article à ce sujet</a> si vous voulez en savoir plus.</p>
<p>Dans cet article, nous considérerons que vous avez un serveur avec Haproxy fonctionnel pour les tests.</p>
<h3 id="lets-encrypt">Let's Encrypt :</h3>
<p><a href="https://letsencrypt.org/">Let's Encrypt</a> est un projet soutenu entre autre par la fondation Mozilla et Cisco.</p>
<p>L'idée est de mettre en place une autorité de certification gratuite pour créer des certificats SSL et permettre au plus grand nombre de personne de sécuriser leurs sites web.</p>
<p>Au regard du prix habituel d'un certificat, c'est un projet vraiment très intéressant !</p>
<p>D'autant plus qu'il est vraiment axé sur la facilité d'utilisation, avec notamment une API permettant de créer des certificats de manière simple.</p>
<p>Nous nous appuierons ici sur cette API, à travers un client créé par Let's Encrypt.</p>
<p><strong>EDIT : </strong>04/04/16 : ajout d'une note si vous utilisez des redirect de l'http vers l'https, pour permettre le renouvellement auto de letsencrypt</p>
<p><strong>EDIT</strong> : 16/09/16 : Mise à jour avec les nouveaux binaires suite à la sortie de bêta de LE + amélioration et versionning des Scripts</p>
<h2 id="concept">Concept</h2>
<p>Let's Encrypt propose plusieurs options via le client pour télécharger et valider un certificat SSL.</p>
<p>Si votre haproxy est sur le même serveur que le serveur web, vous pouvez utiliser l'option --webroot, qui permet de placer un fichier à la racine de votre site, que le site letsencrypt ira vérifier pour valider que vous possédez bien le site web. Si vous souhaitez utiliser cette technique, cet <a href="https://blog.infomee.fr/p/letsencrypt-haproxy">article de blog</a> explique très bien comment le faire interagir en utilisant un serveur apache dédié.</p>
<p>Dans cet article, nous utiliserons l'option --standalone qui permet de lancer un mini serveur web, qui contiendra le fichier de vérification et qui sera utilisé par le site letsencrypt. Cette option présente à première vue l'inconvénient de devoir utiliser le port 80 ou 443 pour lancer le serveur web, ce qui demande evidemment de faire sauter le serveur web principal, et donc de couper les sites pendant la vérification.</p>
<p>Mais nous allons utiliser une option du client qui permet d'utiliser un autre port que ceux par défaut, allié aux capacité frontend/backend de haproxy, pour effectuer la vérification sans aucune coupure de vos sites :-)</p>
<p>Merci à <a href="https://coolaj86.com/articles/lets-encrypt-with-haproxy/">coolaj86</a> dont l'article m'a donné cette idée d'utiliser haproxy et Let's Encrypt ensembles ;-)</p>
<p>-- Many thanks to <a href="https://coolaj86.com/articles/lets-encrypt-with-haproxy/">coolaj86</a> as his post give me this idea to use haproxy and Let's Encrypt together ;-) --</p>
<p> </p>
<h2 id="recuperer-le-client-lets-encrypt">Récupérer le client Let's Encrypt</h2>
<p>Maintenent que LE est officiellement sorti un binaire plus carré est disponible, et beaucoup plus simple à installer que le précédent letsencrypt-auto.</p>
<p>Toutes les info sont présente sur le <a href="https://certbot.eff.org/">site officiel</a> de certbot, mais voici les instructions rapides pour l'installer.</p>
<p><code>cd /root/</code></p>
<p><code>mkdir letsencrypt</code></p>
<p><code>cd letsencrypt</code></p>
<p><code>wget https://dl.eff.org/certbot-auto</code></p>
<p><code>chmod a+x certbot-auto</code></p>
<p><br/>
Vous pouvez ensuite directement utiliser le binaire pour activer vos certificats</p>
<p><code>./certbot-auto certonly --domains blog.victor-hery.com --renew-by-default --http-01-port 63443 --agree-tos</code></p>
<h2 id="configurer-haproxy">Configurer haproxy</h2>
<h3 id="frontend">Frontend</h3>
<p>Pour éviter toute coupure, nous allons utiliser votre (vos) frontend existant.</p>
<p>La requête de Let's Encrypt se fera sur l'adresse IP à laquelle répond le site web pour lequel vous générez le certificat, donc si vous avez plusieurs frontend ou plusieurs IP, il faudra configurer chaque frontend selon vos besoins.</p>
<p>L'idée est la suivante : lors de sa requête, Let's Encrypt interrogera l'url du site, suivi simplement de <em>/.well-known/acme-challenge/un-id_unique.</em></p>
<p>Nous allons donc configurer une acl qui cherchera cette chaine pour la rediriger vers un backend spécifique !</p>
<div class="highlight"><pre><span></span><code><span class="err">frontend http-in</span>
<span class="err"> acl app_letsencrypt path_beg /.well-known/acme-challenge/</span>
<span class="err"> [...]</span>
<span class="err"> use_backend bk-letsencrypt if app_letsencrypt</span>
</code></pre></div>
<ul>
<li>path_beg : cherche les URL dont le path (ce qui est après le premier / de l'url) commence par <em>.well-known/acme-challenge/</em></li>
</ul>
<p>Ainsi, toutes les requêtes de vérification de Let's Encrypt seront redirigées vers le backend <em>bk-letsencrypt</em>.</p>
<p><strong>Attention :</strong> Si vous redirigez de manière forcée vos sites en HTTP vers l'HTTPS, alors haproxy va rediriger aussi les requêtes let's encrypt vers votre frontend HTTS.</p>
<p>Il faut alors ajouter l'acl et le use_backend bk-letsencrypt <strong>dans votre frontend https !</strong></p>
<h3 id="backend">Backend</h3>
<p>Concernant le backend, nous allons le configurer pour rediriger les requêtes vers le serveur qui sera lancé en local par le client Let's Encrypt.</p>
<div class="highlight"><pre><span></span><code><span class="err">backend bk-letsencrypt</span>
<span class="err"> log global</span>
<span class="err"> mode http</span>
<span class="err"> server srv_letsencrypt 127.0.0.1:63443</span>
</code></pre></div>
<ul>
<li>mode http : permet, tant qu'à faire, de vérifier qu'il s'agit bien d'une requête http qui passe par ce backend</li>
<li>server : la ligne redirige vers le serveur que le client Let's Encrypt aura lancé sur localhost, sur le port 63443</li>
</ul>
<p>Ce serveur ne tournera pas en permanence, uniquement lorsque le client Let's Encrypt est en attente de vérification, en temps normal haproxy renverra donc une erreur 503 si quelqu'un tente d'accéder à une URL qui correspond à l'acl du frontend.</p>
<p>Bien sûr, rechargez haproxy après ces modifications.</p>
<div class="highlight"><pre><span></span><code><span class="err">systemctl reload haproxy.service</span>
</code></pre></div>
<h2 id="configurer-et-utiliser-lets-encrypt">Configurer et utiliser Let's Encrypt</h2>
<h3 id="configuration">Configuration :</h3>
<p>Pour simplifier la ligne de commande et faciliter l'automatisation, nous allons directement configurer un fichier pour Let's Encrypt.</p>
<p>Let's Encrypt utilise par défaut le fichier <em>/etc/letsencrypt/cli.ini</em><em>. </em>Nous allons donc taper dedans directement.</p>
<div class="highlight"><pre><span></span><code><span class="err">rsa-key-size = 4096</span>
<span class="err">email = your_admin_email</span>
<span class="err">authenticator = standalone</span>
<span class="err">standalone-supported-challenges = http-01</span>
</code></pre></div>
<ul>
<li>rsa-key-size ; permet de générer directement des certificats de 4096 bit, plus robustes que le 2048 par défaut. Vous pouvez redescendre à 2048 (mais pas en dessous !) si votre serveur est peu puissant pour gagner du temps de génération.</li>
<li>email : utilisez une adresse valide, car ce sera l'adresse utilisée pour récupérer le certificat sur le site web de Let's Encrypt si jamais le besoin s'en faisait sentir</li>
<li>authenticator : comme vu plus haut, nous utilisons le mode <em>standalone</em></li>
<li>standalone-supported-challenges : Cette option est spécifique au mode standalone, et permet de spécifier la méthode à utiliser pour la vérification, parmi <em>http-01</em> ou <em>tls-sni-01</em>. Nous utilisons http-01 car notre site n'a pas (forcément) encore de certificat, et donc lors d'un appel sur 403 haproxy n'aura pas de certificat valide à présenter.</li>
</ul>
<p>Utiliser http pour la vérification ne pose pas de problème, car seule la requête de validation passe en clair, et elle n'a rien de secrète.</p>
<h3 id="generation-du-certificat">Génération du certificat</h3>
<p>La ligne de commande à utiliser pour générer votre certificat est la suivante :</p>
<div class="highlight"><pre><span></span><code><span class="err">/root/letsencrypt/certbot-auto certonly --domains yourdomain.tld --renew-by-default --http-01-port 63443 --agree-tos</span>
</code></pre></div>
<ul>
<li>certonly : précise que l'on souhaite simplement générer le certificat, et pas utiliser un plugin d'installation pour stocker les certificats quelque part</li>
<li>domains : le domaine ou sous domaine pour lequel vous voulez générer ce certificat</li>
<li>renew-by-default : indique que si le certificat existe déjà, il faut le renouveler. S'il n'existe pas, il sera créé dans la base de Let's Encrypt</li>
<li>http-01-port : permet de spécifier le port à utiliser pour le serveur de validation temporaire. C'est le port utilisé dans le backend haproxy plus haut</li>
<li>agree-tos : indique d'accepter les conditions d'utilisation de Let's Encrypt (vous les avez lues et êtes ok pour les accepter, pas vrai ?)</li>
</ul>
<h3 id="mettre-en-place-le-certificat">Mettre en place le certificat</h3>
<p>Les certificats sont mis en place dans le répertoire <em>/etc/letsencrypt/live/yourdomain.tld/</em> par le client lors de la génération.</p>
<p>Vous y trouverez plusieurs fichiers :</p>
<ul>
<li>cert.pem : le certificat (le crt)</li>
<li>chain.pem : la chaine de confiance (les certificats de l'authorité)</li>
<li>fullchain.pem : une concaténation des 2 premiers</li>
<li>privkey.pem : la clef privée du certificat</li>
</ul>
<p>Pour haproxy, vous devez concaténer fullchain.pem et privkey.pem dans un seul fichier, et le placer là ou votre haproxy lit ses certificats.</p>
<div class="highlight"><pre><span></span><code><span class="err">cat fullchain.pem privkey.pem &gt; domain.tld.pem</span>
</code></pre></div>
<p>Un exemple :</p>
<div class="highlight"><pre><span></span><code><span class="err">frontend https-in</span>
<span class="err"> bind IP:443 ssl crt /etc/haproxy/cert/</span>
</code></pre></div>
<p>Ici, nous devons mettre notre fichier.pem dans le répertoire <em>/etc/haproxy/cert/</em></p>
<p>Une fois le certificat placé là, rechargez haproxy pour qu'il le lise, et ça y est tout sera Ok.</p>
<p>N'oubliez pas que pour que votre site fonctionne en HTTPS, il faudra un frontend https dans haproxy, avec les acl qui vont bien.</p>
<p>En général, un copier/coller de votre frontend HTTP classique en changeant le port vers 443 fait l'affaire.</p>
<h2 id="limitations">Limitations</h2>
<h3 id="renouveler-le-certificat">Renouveler le certificat</h3>
<p>Même sorti de bêta, LE a pris la décision de ne fournir des certificat valides que 3 mois (90 jours), ce afin d'éviter les abus et faire "vivre" le certificat.</p>
<p>Notez que contrairement au binaire de bêta, certbot-auto peut scanner vos certificats disponibles (via le répertoire <em>/etc/letsencrypt/renewal/</em>) pour les renouveller automatiquement.</p>
<p>Pensez donc à configurer une tache cron sur votre serveur pour renouveler le certificat régulièrement</p>
<div class="highlight"><pre><span></span><code><span class="err">crontab -e</span>
<span class="err">#renew certificate</span>
<span class="err">30 01 01,10,20,30 * * /root/letsencrypt/certbot-auto renew</span>
</code></pre></div>
<p>Cette tâche permettra de lancer la commande tous les 10 jours, afin d'être sur d'avoir des certificats à jour.</p>
<p>N'oubliez pas qu'il faudra quand même aller récupérer le fullchain.pem et le .key pour aller les mettre dans haproxy. Voyez plus bas pour un peu d'automatisation sur cette tâche !</p>
<h3 id="nombre-de-certificat-par-domaine">Nombre de certificat par domaine</h3>
<p>A cause de sa gratuité, Let's Encrypt dispose d'un système évitant de générer trop violemment des certificats pour le même domaine.</p>
<p>Vous aurez donc une erreur si vous tentez de générer trop vite ou trop souvent des certificats avec le même domaine.</p>
<p><strong>Attention</strong>, c'est valable également pour les sous-domaine ! La limitation prend en compte tout ce qui se termine par domain.tld.</p>
<h3 id="idn">iDN :</h3>
<p>Actuellement Let's Encrypt ne gère pas les noms de domaines internationaux.</p>
<p>Il est donc impossible de générer un certificat pour un domaine ou un sous-domaine contenant des accents ou des caractères spéciaux.</p>
<p>Impossible par exemple de générer pour l'instant un certificat pour blog.héry.com malheureusement.</p>
<p>Une <a href="https://github.com/letsencrypt/boulder/issues/597">requête</a> existe actuellement à ce sujet sur le github de Let's Encrypt, mais plusieurs mois après le passage en stable, ce n'est toujours pas prêt malheureusement. Affaire à suivre (et à aider dans la mesure de ses moyens ;-) )</p>
<h2 id="bonus-des-scripts">Bonus : des scripts</h2>
<p>Histoire de faciliter la génération et la mise en place sur haproxy, j'ai écris quelques petits scripts maison permettant de générer le certificat et le placer dans le bon répertoire, ainsi que gérer proprement le renouvellement.</p>
<p>Ceux-ci sont disponibles sur <a href="https://git.lecygnenoir.info/LecygneNoir/letsencrypt-haproxy">mon dépôt git</a>, vous pouvez donc directement les cloner sur votre serveur :</p>
<p><code>git clone https://git.lecygnenoir.info/LecygneNoir/letsencrypt-haproxy.git</code></p>
<p>Le README décrit rapidement comment utiliser les scripts, c'est globalement assez simple.</p>
<p>create_certificate permet de créer un certificat pour le domaine passé en paramètre, génère le .pem pour haproxy, le place dans l'arborescence haproxy et reload haproxy.</p>
<p>renew-certificates se contente de renouveler tous les certificats, de générer les fichiers pour haproxy et de reload ce dernier. Vous pouvez utiliser renew-certificates dans une tâche cron comme indiqué plus haut.</p>
<p><strong>Vérifiez les chemins dans les scripts, notamment où placer les certificats et le chemin vers le binaire certbot</strong></p>
<p> </p>
<p>Voila, avec tout ça vous devriez pouvoir générer autant de certificat que vous le souhaitez, et les utiliser directement dans haproxy, alors bienvenue dans le monde de l'HTTPS !</p>Configurer un reverse proxy avec haproxy2015-12-11T09:16:00+01:002015-12-11T09:16:00+01:00Victortag:blog.victor-hery.com,2015-12-11:/2015/12/configurer-reverse-proxy-haproxy.html
<h2 id="ou-utilisons-un-logiciel-dont-cest-le-taf-de-proxyfier-">Ou : utilisons un logiciel dont c'est le taf de proxyfier :-)</h2>
<p>(Oui, j'assume le verbe proxyfier, na)</p>
<p>Il y a quelques temps, j'avais fait un article pour configurer <a href="/2012/10/configurer-reverse-proxy-apache.html">apache en mode reverse proxy</a>.</p>
<p>Je vous invite à le relire rapidement (au moins le chapô ;-) ) pour savoir de quoi l'on parle avec …</p>
<h2 id="ou-utilisons-un-logiciel-dont-cest-le-taf-de-proxyfier-">Ou : utilisons un logiciel dont c'est le taf de proxyfier :-)</h2>
<p>(Oui, j'assume le verbe proxyfier, na)</p>
<p>Il y a quelques temps, j'avais fait un article pour configurer <a href="/2012/10/configurer-reverse-proxy-apache.html">apache en mode reverse proxy</a>.</p>
<p>Je vous invite à le relire rapidement (au moins le chapô ;-) ) pour savoir de quoi l'on parle avec le terme reverse proxy.</p>
<p>Bien que ça fonctionne très bien, il existe des logiciels dédiés à la mise en place d'un reverse proxy, à mettre devant le serveur web.</p>
<p>Le logiciel auquel nous allons nous intéresser aujourd'hui est <a href="http://www.haproxy.org/">haproxy</a> et est justement dédié à cet usage.</p>
<p>À noter que nous allons l'utiliser ici en tant que proxy HTTP/HTTPS, mais que haproxy peut servir de proxy pour n'importe quoi, du serveur de messagerie à un serveur mysql, et globalement à tout ce qui utilise TCP.</p>
<h2 id="pourquoi-que-donc">Pourquoi que donc ?</h2>
<p>Avoir un reverse proxy devant son serveur web présente plusieurs avantages.</p>
<ul>
<li> Ne pas avoir le serveur web publiquement accessible (par exemple pour sa protection)</li>
<li> Faire des pré-traitement sur les requêtes (nombre de sessions, limitation de bande passante, etc)</li>
<li> Balancer les requêtes entre plusieurs serveurs web</li>
<li> Centraliser les accès publics (pour n'utiliser qu'une IP publique avec différents serveurs web derrière)</li>
</ul>
<p>Une fois n'est pas coutume, attaquons le concret :)</p>
<h2 id="pre-requis">Pré-requis</h2>
<p>Pour que cela fonctionne, il vous faut au minimum un serveur web fonctionnel. Il peut être sous apache, nginx, ou même IIS pourquoi pas.</p>
<p>C'est vers lui que nous redirigerons les requêtes.</p>
<p>Il vous faut également un serveur où installer haproxy.</p>
<p>Dans cet exemple, nous prendrons un serveur dédié à cet usage. Cependant, il est aussi possible d'installer haproxy SUR le serveur hébergeant le serveur web (s'il est sous Linux). Ce n'est pas le sujet ici :-)</p>
<p> </p>
<p>Nous allons donc partir sur un serveur web, et un serveur "passerelle" qui possédera l'adresse publique de votre site, et sur lequel nous installerons haproxy.</p>
<p>Dans notre exemple, ce serveur passerelle sera sous debian 8.</p>
<p>Soit vous avez des serveurs physiques, soit vous les virtualisez.</p>
<p>Si vous vous auto-hébergez, vous ne pourrez pas utiliser votre adresse publique sur votre serveur passerelle. Dans ce cas, mettez en place une redirection de port vers votre serveur passerelle sur votre machinbox (ou routeur). Les ports 80 et 443 suffiront :-)</p>
<h2 id="terminologie">Terminologie</h2>
<p>Haproxy utilise des termes assez classiques dans sa configuration, mais que nous allons tout de même revoir ici afin de bien savoir de quoi l'on parle dans la suite.</p>
<ul>
<li>bind : <em>attacher </em>en Anglais, permet de dire sur quelle IP et quel port haproxy va écouter. Par exemple, 192.168.1.1 sur le port 80</li>
<li>frontend : c'est un bloc de configuration qui permet de définir toutes les règles qui s'appliqueront (domaines écoutés, limitations, etc). Un frontend peut s'appliquer à un ou plusieurs bind.</li>
<li>backend : c'est un autre bloc de configuration, que l'on place derrière un frontend. Si le frontend gère ce qui est publique (à "l"avant" du serveur), le backend gère "l'arrière". C'est là que vous définirez les serveurs web vers lesquels envoyer les requêtes.</li>
<li>acl : une "access control list" permet de définir des conditions dans un bloc, par exemple "si le domaine contient site1, alors faire cela, si la requête est en https, alors faire ceci"</li>
</ul>
<h2 id="aller-go-le-cambouis-cest-pas-si-salissant">Aller go : le cambouis c'est pas si salissant</h2>
<h3 id="installation">Installation</h3>
<p>On commence par installer haproxy. Il est de base dans debian (depuis la version 6)</p>
<p>Si vous voulez faire de l'https, il vous faudra la version au moins 1.5 de haproxy. (disponible dans les backports debian 7 ou nativement sous debian 8)</p>
<p>Si vous voulez plus de détails sur les versions à installer, rendez vous sur <a href="http://haproxy.debian.net/">http://haproxy.debian.net/</a></p>
<div class="highlight"><pre><span></span><code><span class="err">aptitude update</span>
<span class="err">aptitude install haproxy</span>
</code></pre></div>
<h3 id="global-et-default">Global et default</h3>
<p>Les 2 sections global et default permettent de définir des variables qui seront appliquées à tout le reste de la configuration (sauf redéfinition plus précise dans un sous bloc).</p>
<p>Les paramètres définit à l'installation sont corrects, vous pouvez donc laisser ces sections ainsi pour l'instant.</p>
<h3 id="ou-configurer">Où configurer</h3>
<p>Le fichier de configuration de haproxy est placé dans<em> /etc/haproxy/haproxy.cfg. </em>Néanmoins, pour que cela soit plus pratique à configurer, vous pouvez écrire vos configurations personnalisées dans un fichier <em>/etc/haproxy/haproxy.local</em>, cela évitera d'avoir à modifier le fichier par défaut.</p>
<h3 id="configuration-du-frontend">Configuration du frontend</h3>
<p>Nous allons voir ici une configuration de frontend basique. Il est possible de faire des choses très compliquées, mais on va rester simple pour l'instant :-)</p>
<div class="highlight"><pre><span></span><code><span class="err">frontend http-in</span>
<span class="err"> bind IP_PUBLIQUE:80</span>
<span class="err"> mode http</span>
<span class="err"> option httplog</span>
<span class="err"> acl your_acl hdr(host) votresiteweb.tld</span>
<span class="err"> use_backend backend1 if your_acl</span>
</code></pre></div>
<p>Attention, l'indentation est importante !</p>
<p>Tous les paramètres du bloc doivent être décalés en dessous pour que haproxy voit que ces paramètres font parti du bloc. En général, une tabulation ou X espaces, selon les préférences.</p>
<p>Vous définissez :</p>
<ul>
<li>frontend http-in : le mot clef <em>frontend</em> indique la présence d'un bloc de configuration frontend. ici,<strong> http-in</strong> est un nom pour ce frontend, choisi arbitrairement. Vous pouvez nommer le frontend comme vous le souhaitez, une bonne pratique est de prendre un nom clair et pas trop à rallonge :-)</li>
<li>IP_PUBLIQUE : l'adresse IP sur laquelle haproxy va écouter. Vous pouvez préciser une IP précise, ou bien 0.0.0.0 pour écouter sur toutes les IP présentes sur le serveur. Vous pouvez aussi mettre plusieurs lignes l'une en dessous de l'autre pour ajouter des IP précises</li>
<li>mode http : on définit que ce frontend va traiter uniquement le protocole HTTP (et donc aussi HTTPS). Cela permet déjà à haproxy d'analyser les requêtes, et de rejeter tout ce qui n'est pas formaté correctement vis à vis des RFC</li>
<li>option httplog : permet de logguer le détail des requêtes http. Cela permet d'avoir plus d'informations dans les logs haproxy (headers, session http, ...).</li>
<li>acl : on définit une ACL, qui sera reconnue si la partie HOST de la requête http correspond <strong>exactement</strong> à <em>votresiteweb.tld</em>. Il est aussi possible de chercher l<strong>a fin</strong> d'un host (tout ce qui termine par votresiteweb.tld), <strong>commence par</strong>, <strong>contient</strong> tel mot, etc. Ici si ça correspond, l'acl se nommera <em>your_acl</em>, nous pourrons la réutiliser dans la suite du bloc.</li>
<li>use_backend : on définit ici qu'on va utiliser le backend <em>backend1</em> SI l'acl <em>your_acl</em> est active. Donc dans notre cas, si la requête traitée contient <strong>exactement</strong> <em>votresiteweb.tld</em> dans la partie HOST, l'acl est active. Tout se recoupe !</li>
</ul>
<p>Et voila, en 5 lignes, vous avez configuré un premier frontend pour rediriger votresiteweb.tld vers un backend (qu'il reste à écrire)</p>
<p>On voit déjà que la syntaxe est très simple par rapport à apache (plus de ProxyPass avec des paramètres pas toujours clairs).</p>
<p>On a ici une configuration très simpliste. Je présenterai quelques options montrant la puissance d'haproxy à la fin de cet article.</p>
<h3 id="configuration-du-backend">Configuration du backend</h3>
<p>Maintenant que notre frontend est prêt à recevoir les requêtes publiques, il faut créer le backend qui sera à même de savoir <strong>où</strong> envoyer ces requêtes.</p>
<div class="highlight"><pre><span></span><code><span class="err">backend backend1</span>
<span class="err"> mode http</span>
<span class="err"> option httpchk</span>
<span class="err"> option forwardfor except 127.0.0.1</span>
<span class="err"> http-request add-header X-Forwarded-Proto https if { ssl_fc }</span>
<span class="err"> server web-server1 IP_SERVEUR_WEB:80 maxconn 32</span>
</code></pre></div>
<p>De la même manière que pour le frontend, attention à l'indentation pour que les paramètres soient décalés en dessous du mot clef <em>backend</em></p>
<p>Ici vous définissez :</p>
<ul>
<li>backend backend1 : le mot clef <em>backend</em> permet d'indiquer le début d'un bloc de backend. Le nom <strong>backend1</strong> est au choix, comme pour le nom du frontend. Il sera celui à utiliser dans le frontend au moment d'écrire le <em>use_backend</em></li>
<li>mode http : comme pour le frontend, cela indique que ce backend s'occupera d'http, et permet d'utiliser diverses options pratiques (réécriture de header notamment)</li>
<li>option httpchk : le httpchk permet de faire en sorte que haproxy vérifie à tout moment l'état des serveurs web derrière lui. Il peut ainsi savoir si le serveur est prêt à recevoir des requêtes, basculer vers un serveur de secours, afficher une page d'erreur en cas de panne, etc. De base, c'est un simple check HTTP sur le / qui est effectué, mais il est possible par exemple de spécifier un script ou un chemin précis</li>
<li>forwardfor except 127.0.0.1 : cette option va permettre d'ajouter un en tête <strong>xforwardfor</strong> dans les requêtes qui passent par le backend, en tête contenant la véritable adresse IP du visiteur. En effet, les requêtes passant par le proxy, c'est son IP qui sera vu niveau réseau par le serveur web ce qui peut être gênant pour faire des statistiques de visites par exemple, car vous auriez l'impression que toutes les visites viennent du serveur proxy... Le <strong>except 127.0.0.1</strong> permet d'éviter d'ajouter cet en tête si c'est 127.0.0.1 qui a généré la requête.</li>
<li>server web-server1 : cette définition va permettre d'indiquer le serveur vers lequel transmettre les requêtes. IP_SERVEUR_WEB est bien sûr l'adresse IP du serveur web. :80 permet d'indiquer le port ou transmettre. Il est possible d'indiquer plusieurs lignes pour définir plusieurs serveur web et faire de la répartition de charge.</li>
<li>maxconn 32 : permet de limiter le nombre maximum de connexions gérées par ce serveur, ici 32. Cela permet d'éviter de surcharger le serveur web au dessus de sa capacité par exemple, et de mitiger directement et à peu de coût une attaque.</li>
</ul>
<p>A partir de là, c'est tout bon. Vous avez une configuration, certes basique, qui vous permettra de recevoir des requêtes pour votre site, et les transmettre vers votre serveur web :-)</p>
<p>Bien sûr, redémarrez haproxy pour appliquer la configuration.</p>
<div class="highlight"><pre><span></span><code><span class="err">systemctl restart haproxy</span>
</code></pre></div>
<h2 id="un-peu-plus-loin-https">Un peu plus loin : https</h2>
<h3 id="frontend">frontend</h3>
<p>Jusqu'ici, le frontend était uniquement http, pas de certificat.</p>
<p>Mettre en place un frontend https est tout ce qu'il y a de plus simple. On va tout simplement créer un deuxième frontend, cette fois bindé sur le port 443</p>
<div class="highlight"><pre><span></span><code><span class="err">frontend https-in</span>
<span class="err"> bind IP_PUBLIQUE:443 ssl crt /etc/haproxy/cert/ no-sslv3</span>
<span class="err"> mode http</span>
<span class="err"> option httplog</span>
<span class="err"> acl your_acl hdr(host) votresiteweb.tld</span>
<span class="err"> use_backend backend1 if your_acl</span>
</code></pre></div>
<p>On voit quelques différences par rapport à la configuration définie plus haut.</p>
<ul>
<li>https-in : le nom est là encore au choix, mais il faut qu'il soit différent du premier, sinon haproxy renverra une erreur au démarrage.</li>
<li>bind : la ligne bind change. On voit qu'on va cette fois se mettre sur le port 443 au lieu de 80, l'HTTPS étant par défaut sur le port 443. Rien ne vous empêche de mettre un autre port selon vos besoins.</li>
<li>ssl : ce mot clef (utilisable sur la même ligne que bind) permet d'indiquer à haproxy qu'il va devoir faire du SSL sur ce bind</li>
<li>crt /etc/haproxy/cert/ : définit le répertoire dans lequel vous mettre vos certificats. haproxy gère les certificats au format pem, que vous pouvez simplement créer de la façon suivante en mergeant le .crt et le .key :</li>
</ul>
<div class="highlight"><pre><span></span><code><span class="err">cat domain.tld.crt domain.tld.key &gt; domain.tld.pem</span>
</code></pre></div>
<ul>
<li>no-sslv3 : cela permet de spécifier à haproxy de refuser d'utiliser le protocole sslv3, considéré désormais comme non sécurisé.</li>
</ul>
<p>Toutes les autres options sont les même que pour le frontend HTTP (acl, use_backend, ...)</p>
<h3 id="note-sur-le-dossier-des-certificats">Note sur le dossier des certificats</h3>
<p>haproxy gère de manière très efficace les certificats. Vous pouvez les mettre en vrac dans le répertoire, haproxy les parse au démarrage et utilise les certificat de la manière la plus précise possible.</p>
<p>Si par exemple vous possédez un certificat wildcard (*.domain.tld) et un certificat plus précis (sous.domain.tld)</p>
<ul>
<li>Les visites sur <em>sous.domain.tld</em> utiliseront le certificat de <em>sous.domain.tld</em></li>
<li>Les visites sur domain.tld utiliseront le certificat wildcard</li>
<li>Les visites sur toto.domain.tld utiliseront le certificat wildcard</li>
<li>etc :-)</li>
</ul>
<h3 id="backend">Backend</h3>
<p>Comme c'est le frontend qui gère la partie HTTPS, vous pouvez utiliser exactement les même backend pour le frontend http et le frontend https. Rien à faire à ce niveau là donc, tout est déjà bon dans la configuration.</p>
<p>Redémarrez haproxy, et votre site est prêt à fonctionner en HTTPS !</p>
<h2 id="encore-plus-loin-options-sympathiques">Encore plus loin : options sympathiques</h2>
<p>Cette liste n'est clairement pas exhaustive, haproxy disposant d'une foison incroyable de possibilités. Je ne liste ici que celles qui me semblent les plus utiles de manière générales (en gros, celles que j'utilise moi :-D )</p>
<p>Pour une liste complète, je vous invite à vous référer à la <a href="http://cbonte.github.io/haproxy-dconv/configuration-1.5.html">documentation haproxy</a> qui est vraiment très claire et détaillée avec tous les exemples nécessaires à la compréhension.</p>
<h3 id="plusieurs-sites-dans-un-frontend">Plusieurs sites dans un frontend</h3>
<p>Comme vous ne pouvez créer qu'un seul frontend écoutant sur le port 80 (ou 443) sur une adresse IP, il va falloir utiliser le même frontend pour gérer plusieurs sites.</p>
<p>Cela se fait très simplement, en utilisant plusieurs acl dans le frontend, par exemple :</p>
<div class="highlight"><pre><span></span><code><span class="err">acl site1 hdr(host) site1.tld</span>
<span class="err">acl sous-domaine hdr(host) sousdomain.site1.tld</span>
<span class="err">acl toto-site2 hdr(host) toto.site2.tld</span>
</code></pre></div>
<p>Vous pouvez ensuite utiliser un ou plusieurs backend selon les acl :</p>
<div class="highlight"><pre><span></span><code><span class="err">use_backend backend1 if site1 or sous-domaine or toto-site2</span>
</code></pre></div>
<p>Ou encore :</p>
<div class="highlight"><pre><span></span><code><span class="err">use_backend backend1 if site1 or sous-domaine</span>
<span class="err">use_backend backend2 if toto-site2</span>
</code></pre></div>
<h3 id="test-de-domaine-dans-un-frontend">Test de domaine dans un frontend</h3>
<p>Dans mes exemples, j'ai à chaque fois utilisé hdr(host) dans mes acl, qui permet de chercher le contenu exact de la variable HOST de la requête HTTP.</p>
<p>Néanmoins, il est possible de faire plus général, comme par exemple créer des acl en se basant sur la fin du HOST, le début, voir chercher si HOST contient telle ou telle chaîne de caractère.</p>
<p>Cela peut permettre de créer une acl qui gérera tout ce qui se termine par site.tdl, tout ce qui contient www., etc</p>
<div class="highlight"><pre><span></span><code><span class="err">acl test1 hdr_beg(host) www. #On match ce qui commence par www.</span>
<span class="err">acl test2 hdr_end(host) domain.tld #On match tout ce qui termine par domain.tld</span>
<span class="err">acl test3 hdr_reg(host) REGEX #On match tout ce qui correspond à l'expression régulière REGEX</span>
</code></pre></div>
<p>Vous êtes ensuite libre d'utiliser ces acl dans les backend que vous voulez.</p>
<h3 id="backend-par-defaut-aussi-nomme-la-poubelle">Backend par défaut, aussi nommé la poubelle</h3>
<p>Une fonctionnalité que je trouve assez intéressante est de prévoir un backend par défaut qui servira de poubelle. Toutes les visites arrivant sur votre serveur et qui ne matchent pas une acl peuvent être considérées comme de la poubelle, voire comme une attaque potentielle, et donc autant ne pas les rediriger vers un site par défaut (comme le fait par exemple de base le vhost apache default)</p>
<p>Pour cela, il suffit d'ajouter dans le frontend le mot clef <em>default_backend</em> qui permet de définir un backend qui sera utilisé pour les requêtes n'ayant matché aucune acl dans le frontend, et de créer un backend qui renverra par exemple une erreur 403 "accès interdit" :</p>
<div class="highlight"><pre><span></span><code><span class="n">frontend</span> <span class="n">http</span><span class="o">-</span><span class="k">in</span>
<span class="p">[...]</span>
<span class="n">default_backend</span> <span class="n">poubelle</span>
<span class="n">backend</span> <span class="n">poubelle</span>
<span class="k">mode</span> <span class="n">http</span>
<span class="n">http</span><span class="o">-</span><span class="n">request</span> <span class="n">deny</span>
</code></pre></div>
<h3 id="repartition-de-charge-avec-un-backend">Répartition de charge avec un backend</h3>
<p>Si vous définissez plusieurs lignes de <em>server </em>dans un backend, alors haproxy va automatiquement répartir (via le protocole round robin) les requêtes entrantes de manière équitables entre les serveurs.</p>
<p>Mais il est également possible de définir des poids pour ces serveurs, si par exemple l'un d'eux est plus puissant, plus à même de recevoir des requêtes</p>
<div class="highlight"><pre><span></span><code><span class="err">backend backend1</span>
<span class="err"> [...]</span>
<span class="err"> server server1 ip1:80 weight 1</span>
<span class="err"> server server2 ip2:80 weight 2</span>
</code></pre></div>
<p>Ici server2 encaissera 2 fois plus de requêtes que server1</p>
<p>Vous pouvez utiliser le mot clef backup :</p>
<div class="highlight"><pre><span></span><code><span class="err">backend backend1</span>
<span class="err"> [...]</span>
<span class="err"> server server1 ip1:80</span>
<span class="err"> server server2 ip2:80 backup</span>
</code></pre></div>
<p>Ici, server1 recevra <strong>toutes</strong> les requêtes, <strong>mais</strong> si haproxy détecte qu'il n'est plus accessible, alors il enverra automatiquement toutes les requêtes vers server2</p>
<p>Il est possible aussi de combiner ces 2 techniques, faire de la répartition de charge entre plusieurs serveurs tout en ayant d'autres disponibles en backup.</p>
<h3 id="forcer-lhttps">Forcer l'https</h3>
<p>Il est possible de dire à haproxy, dans votre frontend sur le port 80, que tel site doit absolument utiliser l'HTTPS. Auquel cas, si haproxy reçoit une requête en HTTP, alors il redirigera immédiatement le visiteur vers exactement la même requête mais en HTTPS :</p>
<div class="highlight"><pre><span></span><code><span class="n">frontend</span> <span class="n">http</span><span class="o">-</span><span class="k">in</span>
<span class="p">[...]</span>
<span class="o">#</span> <span class="k">On</span> <span class="n">a</span> <span class="n">plusieurs</span> <span class="n">acl</span>
<span class="n">acl</span> <span class="n">site1</span> <span class="n">hdr</span><span class="p">(</span><span class="k">host</span><span class="p">)</span> <span class="n">site1</span><span class="p">.</span><span class="n">tld</span>
<span class="n">acl</span> <span class="n">sous</span><span class="o">-</span><span class="n">domaine</span> <span class="n">hdr</span><span class="p">(</span><span class="k">host</span><span class="p">)</span> <span class="n">sousdomaine</span><span class="p">.</span><span class="n">site1</span><span class="p">.</span><span class="n">tld</span>
<span class="n">acl</span> <span class="n">toto</span><span class="o">-</span><span class="n">site2</span> <span class="n">hdr</span><span class="p">(</span><span class="k">host</span><span class="p">)</span> <span class="n">toto</span><span class="p">.</span><span class="n">site2</span><span class="p">.</span><span class="n">tld</span>
<span class="n">redirect</span> <span class="n">scheme</span> <span class="n">https</span> <span class="n">code</span> <span class="mi">301</span> <span class="k">if</span> <span class="o">!</span><span class="err">{</span> <span class="n">ssl_fc</span> <span class="err">}</span> <span class="n">site1</span><span class="p">.</span><span class="n">tld</span> <span class="k">or</span> <span class="n">sous</span><span class="o">-</span><span class="n">domaine</span>
<span class="n">use_backend</span> <span class="n">backend2</span> <span class="k">if</span> <span class="n">toto</span><span class="o">-</span><span class="n">site2</span>
</code></pre></div>
<p>Ici, on va forcer via un code 301 (redirection permanente) la redirection vers l'HTTPS (on détecte que le protocole ssl n'est pas utilisé) pour les accès sur site1.tld et sousdomaine.site1.tld, mais on reste en HTTP et on utilise backend2 si la visite est sur toto.site2.tld</p>
<h3 id="reecrire-des-en-tetes-dans-le-backend">Réécrire des en-têtes dans le backend</h3>
<p>On a vu un exemple de réécriture d'en tête dans la partie sur les backend avec le xForwarFor.</p>
<p>Il est possible dans un backend d'écrire tous les en têtes que vous voulez.</p>
<p>Par exemple, si le frontend devant le backend est en https, vous pouvez ajouter un en-tête qui indiquera au serveur web derrière qu'il y a eu traitement https, ce même si le serveur web ne voit jamais le certificat puisque c'est haproxy qui s'en occupe :</p>
<div class="highlight"><pre><span></span><code><span class="err">backend backend1</span>
<span class="err"> [...]</span>
<span class="err"> http-request add-header X-Forwarded-Proto https if { ssl_fc }</span>
</code></pre></div>
<p>Vous pouvez ainsi écrire (ou réécrire) n'importe quel en-tête.</p>
<p>Par exemple pour réécrire l'en tête serveur :</p>
<div class="highlight"><pre><span></span><code><span class="err">backend backend1</span>
<span class="err"> [...]</span>
<span class="err"> rspidel ^server #On commence par effacer l'en tête serveur déjà présent</span>
<span class="err"> rspadd Server:\ Vous\ utilisez\ mon\ super\ serveur\ ! #On rajoute un nouvel en-tete Server (attention à bien protéger les espaces par des \)</span>
</code></pre></div>
<p> </p>
<p>Voila pour ce tour d'horizon (pas si) rapide sur haproxy !</p>
<p>J'espère que cela vous permettra de vous familiariser avec ce logiciel, qui n'a été ici qu'à peine effleuré :-)</p>
<p>Comme toujours, n'hésitez pas à poser vos questions dans les commentaires !</p>Non le blog n'est pas mort :)2015-07-12T09:17:00+02:002015-07-12T09:17:00+02:00Victortag:blog.victor-hery.com,2015-07-12:/2015/07/le-blog-nest-pas-mort.html<p>Bonjour à tous,</p>
<p> </p>
<p>Comme le dit si bien le titre, non le blog n'est pas mort.</p>
<p>Bon, il est pas non plus hyper vivant je me fais pas d'illusions...</p>
<p>J'ai malheureusement (à ma grande honte) disposé et débloqué très peu de temps pour m'en occuper.</p>
<p>Du coup, il y a …</p><p>Bonjour à tous,</p>
<p> </p>
<p>Comme le dit si bien le titre, non le blog n'est pas mort.</p>
<p>Bon, il est pas non plus hyper vivant je me fais pas d'illusions...</p>
<p>J'ai malheureusement (à ma grande honte) disposé et débloqué très peu de temps pour m'en occuper.</p>
<p>Du coup, il y a plusieurs brouillons dans les tuyaux, pas mal d'idées, des articles pas finis, ...</p>
<p> </p>
<p>J'ai conscience que c'est un peu frustrant, et je vois régulièrement des commentaires qui montrent que le blog est toujours lu.</p>
<p>En attendant d'avoir le temps de faire plus (j'y compte bien, sisi !), je vous annonce la mise en place d'une page "Contact".</p>
<p>Disponible en haut du blog parmi les sections (Articles, Présentation, ...), cela vous permettra de m'envoyer directement un courriel si vous souhaitez discuter d'un article, poser une question, avancer de votre côté sur un quelconque problème levé par un article, etc.</p>
<p> </p>
<p>L'idée étant principalement que le système de commentaire est assez vite limité pour les échanges vraiment constructifs et les questions qui y sont parfois posées sont compliquées à répondre dans un si petit espace.</p>
<p>Un courriel permettra d'initier un vrai dialogue ! ;)</p>
<p>N'hésitez donc pas à me contacter sur ce formulaire de contact (avec une adresse valable si vous souhaitez que je vous réponde \o/ ) et je reviendrai vers vous avec grand plaisir !</p>
<p>A très bientôt à tous, merci pour votre soutien et vos différents commentaires sur mes articles !</p>
<p>Victor</p>Construction du cluster (openvpn)2013-02-02T13:35:00+01:002013-02-02T13:35:00+01:00Victortag:blog.victor-hery.com,2013-02-02:/2013/02/cluster-proxmox-distant-2.4-construction-cluster.html
<h2 id="commencons">Commençons</h2>
<p>Bien, cet article est la partie 2 de ma série d'articles sur la mise en place d'un cluster Proxmox.</p>
<p>Dans cet article, je vais partir du début et parler de l'installation des 3 serveurs Proxmox dont nous allons avoir besoin.</p>
<p>Pour rappel : </p>
<ul>
<li>Un serveur principal, chargé de faire tourner …</li></ul>
<h2 id="commencons">Commençons</h2>
<p>Bien, cet article est la partie 2 de ma série d'articles sur la mise en place d'un cluster Proxmox.</p>
<p>Dans cet article, je vais partir du début et parler de l'installation des 3 serveurs Proxmox dont nous allons avoir besoin.</p>
<p>Pour rappel : </p>
<ul>
<li>Un serveur principal, chargé de faire tourner les principaux services sous forme de machines virtuelles</li>
<li>Un serveur de secours, moins costaud mais suffisant pour faire tourner les services que vous considérez comme vitaux</li>
<li>Un 3ème serveur, pas forcément très performant, qui va principalement servir à assurer le quorum, afin que 3 machines soient dans le cluster</li>
</ul>
<p>Vous trouverez tous les détails dans la partie 1 de cette série, <a href="/2013/01/cluster-proxmox-distant-1.4-concept.html">Cluster Proxmox distant (1/4) : le concept</a></p>
<p> </p>
<p>Le petit schéma pour rappeler l'infrastructure et les noms des machines :</p>
<p><img alt="" src="/images/schemaHA(1).png" style="width: 612px; height: 353px;"/></p>
<p> </p>
<h2 id="materiel-serveurs-specificites-et-autres-joyeusetes">Matériel, serveurs, spécificités et autres joyeusetés</h2>
<p>Comme dit plus haut, vous allez avoir besoin de 3 serveurs. Les 2 principaux, je conseille qu'ils soient physiques. De vrais serveurs avec les perfomances dont vous avez besoin.</p>
<p>Le 3eme serveur, servant uniquement pour le quorum, peut être une simple machine virtuelle dans un coin. L'important est que vous puissiez installer proxmox dessus. (Pour ma part, c'est une KVM avec proxmox à l'intérieur, qui tourne sur une autre architecture Proxmox chez moi :) )</p>
<p><strong>Par contre, ne montez pas votre Arbitre sur une KVM dans l'un des 2 premiers serveurs. Sinon vous perdez tout l'intérêt d'avoir un 3eme système indépendant des 2 autres pour assurer le quorum !</strong></p>
<p> </p>
<p>Vous allez également avoir besoin d'installer Proxmox sur vos serveurs. Dans ces articles, je me baserai sur l'installation de <a href="http://www.proxmox.com/downloads/proxmox-ve">Proxmox 2.X standard</a>, fournie par Proxmox et donc basée sur Debian Squeeze (actuellement Proxmox 2.2).</p>
<p>L'installation de base présente l'avantage de proposer un partionnement des disques dur via <a href="http://fr.wikipedia.org/wiki/LVM">LVM</a>, qui est très pratique pour redimensionner les partitions et utiliser DRBD par la suite. Cependant, je détaillerai le partionnement nécessaire, afin que vous puissiez vous en tirer si vous souhaitez installer Proxmox par dessus une autre distribution Linux.</p>
<p>OVH et Online proposent la distribution Proxmox à l'installation. OVH vous permet de choisir le partionnement via leur interface web, ce qui est assez pratique. Online par contre part sur un partionnement sans LVM qui ne vous permettra pas d'utiliser simplement DRBD par la suite. <strong>Attention donc chez Online, mieux vaut passer par leurs cartes ILO/iDrac pour installer Proxmox depuis l'ISO.</strong></p>
<p> </p>
<p>Enfin, vous allez avoir besoin d'un PC supportant le SSH pour vous connecter aux différents serveurs. Je vous conseillerai bien un Linux, parce que vous allez passer pas mal de temps connecté, donc un système supprotant bien le bash (et notamment l'encodage de caractère et les couleurs) est préférable. Cependant, Windows avec putty fonctionne aussi, donc à vous de voir.</p>
<p><strong>Une dernière recommandation : pour monter le cluster, il est important qu'AUCUNE machine virtuelle ne soit présente sur les serveurs (pour éviter les conflits de VMID)</strong>. Si vous récupérez des serveurs existants, il va donc falloir basculer vos machines de droite à gauche pendant la mise en place du cluster. Si vous partez d'une installation neuve, attendez d'avoir monté le cluster pour réimporter vos machines virtuelles.</p>
<p> </p>
<h2 id="installation-et-partionnement">Installation et partionnement</h2>
<p>L'installation de l'ISO proxmox se fait toute seule, sans besoin d'intervention. Insérez le disque (ou la clef USB, maintenant supportée), bootez dessus et procédez à l'installation.</p>
<p>Le partionnement de proxmox utilise LVM, et se décompose de la manière suivante :</p>
<ul>
<li>Une partition physique dédiée au boot, /dev/sda1, d'environ 500Mo</li>
<li>Une parition physique entièrement formatée en LVM, avec le reste du disque</li>
</ul>
<p>C'est cette deuxième partition qui nous intéresse. Elle utilise LVM, et peut donc être redimensionné par nos soins plus tard. En prenant bien sûr les précautions nécessaires :-)</p>
<ul>
<li>Un disque logique d'environ 30Go pour /. </li>
<li>Un disque logique servant de Swap, calculé à partir de la taille de votre RAM</li>
<li>Un disque logique utilisant tout le reste du disque (moins 4Mo), qui sera monté comme /var/lib/vz et qui servira à stocker vos VM, les backups, etc</li>
</ul>
<p>Pour être plus confortable, notamment au niveau du système, vous pouvez utiliser la technique suivante :</p>
<ul>
<li>Lors du prompt au boot sur le CD, tapez "debug"</li>
<li>tapez : <span style="background-color:#000000;"><span style="color:#ffffff;">linux maxroot=100</span></span></li>
</ul>
<p>Cela va configurer la partition système pour utiliser 100Go. Il existe d'autre options, pour plus de détails, voyez <a href="http://pve.proxmox.com/wiki/Debugging_Installation">Debugging Installation</a>.</p>
<p>Pour le reste, c'est correct.</p>
<p>Si vous faites votre partionnement vous-même, veillez à utiliser LVM pour au moins /var/lib/vz. Cela nous permettra d'utiliser les snapshot LVM et de gérer l'espace facilement pour DRBD.</p>
<h2 id="personnalisation-et-astuces">Personnalisation et astuces</h2>
<p>Bon, votre système est installé.</p>
<p>Avant d'attaquer le vif du sujet, je vous propose quelques petits trucs pour faciliter la suite.</p>
<h3 id="bash-et-couleurs">Bash et couleurs</h3>
<p>Pour faciliter la gestion de vos 3 serveurs, vous pouvez personnaliser votre bash pour utiliser plusieurs couleurs dans votre connexion SSH.</p>
<p>Pour ce faire, vous pouvez éditer /etc/bash.bashrc</p>
<p><span style="background-color:#000000;"><span style="color:#ffffff;"># nano /etc/bash.bashrc</span></span></p>
<p>Pour ajouter des couleurs, ajoutez ceci à la fin du fichier :</p>
<p style="margin-left: 40px;"># couleurs<br/>
<strong><em>C_RED="\[\e[1;31m\]"<br/>
C_BLUE="\[\e[1;34m\]"<br/>
C_GRAY="\[\e[1;30m\]"<br/>
C_WHITE="\[\e[1;37m\]"<br/>
C_YELLOW="\[\e[1;33m\]"</em></strong><br/>
C_DEF="\[\033[0m\]"<br/>
<br/>
mUID=`id -u`<br/>
MACHINE=`hostname -f`<br/>
<br/>
if [ "$mUID" = "0" ] ; then<br/>
PS1="${<strong>C_RED</strong>}\u${C_DEF}@${<strong>C_RED</strong>}${MACHINE}${C_DEF}:\w${<strong>C_RED</strong>}#${C_DEF} "<br/>
PS2="${<strong>C_RED</strong>}>${C_DEF} "<br/>
else<br/>
PS1="${C_BLUE}\u${C_DEF}@${MACHINE}:\w${C_BLUE}\$ ${C_DEF}"<br/>
PS2="${C_BLUE}>${C_DEF} "<br/>
fi<br/>
<br/>
export PS2<br/>
export PS1<br/>
<br/>
case $TERM in<br/>
xterm*)<br/>
PROMPT_COMMAND='echo -ne "\033]0;${USER}@${MACHINE}: ${PWD}\007"'<br/>
echo -ne "\033]0;${USER}@${MACHINE}: ${PWD}\007"<br/>
;;<br/>
*)<br/>
setterm -blength 0<br/>
;;<br/>
esac</p>
<p>Ce fichier va automatiquement colorer votre nom d'utilisateur et le nom de la machine dans votre connexion SSH.</p>
<p>Si vous êtes connectés avec un autre utilisateur que root, la couleur sera bleue.</p>
<p>Il va également modifier dynamiquement le nom de votre fenêtre SSH selon le dossier où vous êtes. Le but est de ne pas se perdre pour éviter les bêtises ;-)</p>
<p>Je vous conseille de changer les parties en <strong>gras</strong> (C_RED) selon les machines (avec les couleurs disponibles en <em><strong>gras italique</strong></em> au dessus)</p>
<p>N'hésitez pas à vous amuser pour trouver les combinaisons de couleurs qui vous plaisent.</p>
<p>Une fois le fichier sauvegardé, vous pouvez activer les modifications pour tester les couleurs avec un :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># exec bash</span></span></p>
<p>Vous pouvez également ajouter à la fin du fichier ces alias, qui peuvent être utiles :</p>
<p style="margin-left: 40px;">alias l='ls -ahlF --color=yes --full-time --time-style=long-iso | more'<br/>
alias ll='ls -alhF --color=yes --full-time --time-style=long-iso'<br/>
alias cpav='cp -av'</p>
<p>Une fois tout cela configuré selon votre souhait, faites une petite mise à jour de la machine, et redémarrez si nécessaire.</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># aptitude update && aptitude safe-upgrade -y</span></span></p>
<h2 id="configuration-des-interfaces-reseaux">Configuration des interfaces réseaux</h2>
<p>Pour utiliser openVPN et simplifier la gestion des adresses IP publiques entre les serveurs (toujours sympathique), nous allons créer diverses interfaces supplémentaires sur chacun de nos serveurs.</p>
<h3 id="architecture-interne-des-serveurs">Architecture interne des serveurs</h3>
<p>Après une installation de Proxmox, vous devez disposer d'un bridge virtuel <strong>vmbr0.</strong></p>
<p>Nous allons créer les interfaces suivantes :</p>
<ul>
<li><strong>vmbr1</strong> : ce bridge permettra la communication en interne au serveur, notamment entre VM. Toutes vos VM devront avoir une interface dans vmbr1 pour discuter entre elles. C'est également cette interface qui permettra la liaison VPN, afin que vos VM puissent discuter entre serveurs, dès fois que vous ayiez plusieurs VM sur chacun de vos serveurs</li>
<li><strong>vmbr2</strong> : ce bridge un peu particulier permettra la discussion entre les machines "passerelles", qui portent les IP publiques, et les machines ayant besoin d'une connexion entrante ou sortante vers Internet. Ces machines, par exemple en HA, pourront avoir une carte réseau sur vmbr2 et une interface sur vmbr1. Avec une architecture identique sur les 2 serveurs principaux au niveau des VM publiques, les machines basculant en HA retrouveront directement leur connexion</li>
<li><strong>dummy1</strong> : cette interface "bidon" va permettre d'avoir une interface fixe pour "brancher" openvpn, qui a besoin d'une interface réseau physique pour se lancer correctement au démarrage du serveur</li>
</ul>
<p>Pour que cela soit plus clair, un schéma (le retour) est le bienvenu :</p>
<p><img alt="" src="/images/SchemaInterneVM.png" style="height: 383px; width: 633px;"/><br/>
Les adresses IP sont indicatives, mais il est important que le réseau sur vmbr1 soit différent du réseau sur vmbr2. Il est également important que le réseau utilisé sur vmbr2 soit identique sur les 2 serveurs. Cela va permettre de basculer les machines en HA d'un serveur à l'autre sans changer aucune de leurs configurations internes. Il faut également que les passerelles soient équivalentes (sauf l'IP publique bien sûr).</p>
<p>Si vous configurez des routages de ports entre votre passerelle et les machines en HA, il faudra avoir les même sur la passerelle du PRA, même s'ils pointent dans le vide tant que les machines HA ne sont pas sur le PRA.</p>
<h3 id="configuration-de-dummy">Configuration de dummy</h3>
<p>Nous allons commencer par créer l'interface dummy nécessaire à OpenVPN. De base, Proxmox peut utiliser une interface dummy pour des usages internes, nous allons donc utiliser une deuxième par précaution :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># echo "options dummy numdummies=2" > /etc/modprobe.d/dummy.conf</span></span></p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># modprobe dummy</span></span></p>
<p>Pour vérifier que les interfaces ont bien été créées, tapez la commande suivante :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># ifconfig -a | grep Link | grep -v inet6</span></span></p>
<p>Qui doit vous renvoyer quelque chose comme ça :</p>
<p style="margin-left: 40px;">dummy0 : Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx<br/>
dummy1 : Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx<br/>
eth0 : Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx<br/>
lo : Link encap:Local Loopback<br/>
vmbr0 : Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx</p>
<h3 id="configuration-des-interfaces">Configuration des interfaces</h3>
<p>Nous allons aller toucher au fichier /etc/network/interfaces.</p>
<p>Avant ça, sauvegardez le fichier :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># cpav /etc/network/interfaces /etc/network/interfaces.original</span></span></p>
<p>Puis éditez le :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># nano /etc/network/interfaces</span></span></p>
<p>Ajoutez vmbr1 :</p>
<p style="margin-left: 40px;">auto vmbr1<br/>
iface vmbr1 inet static<br/>
address XXX.XXX.XXX.XXX<br/>
netmask 255.255.255.0<br/>
bridge_ports dummy1<br/>
bridge_stp off<br/>
bridge_fd 0<br/>
post-up route add -net 224.0.0.0 netmask 240.0.0.0 dev vmbr1</p>
<p>Dans le schéma de mon exemple, j'utilise 192.168.11.1 pour le serveur principal, 192.168.11.2 pour le PRA, et 192.168.11.3 pour l'arbitre.</p>
<p>Ajoutez vmbr2 : </p>
<p style="margin-left: 40px;">auto vmbr2<br/>
iface vmbr2 inet static<br/>
address XXX.XXX.XXX.XXX<br/>
netmask 255.255.255.0<br/>
bridge_ports none<br/>
bridge_stp off<br/>
bridge_fd 0</p>
<p>Dans le schéma de mon exemple, je prends 192.168.10.253. La passerelle portera par exemple 192.168.10.254.</p>
<p>Pour appliquer les modifications, effectuez un :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># /etc/init.d/networking restart</span></span></p>
<p>Pour vérifier que les nouvelles interfaces fonctionnent correctement, vous pouvez les pinguer :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># ping 192.168.10.253</span></span></p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># ping 192.168.11.1</span></span></p>
<h3 id="configuration-des-services">Configuration des services</h3>
<p>Pour désactiver l'IPv6, si vous n'en avez pas besoin (pas de troll :-))</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># echo "options ipv6 disable=1" > /etc/modprobe.d/disable-ipv6.conf</span></span></p>
<p>Il faut configurer Proxmox pour écouter sur l'interface OpenVPN :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># nano /etc/hosts</span></span></p>
<p>Vérifiez que c'est bien l'adresse de vmbr1 qui est configurée :</p>
<p style="margin-left: 40px;">127.0.0.1 localhost.localdomain localhost<br/>
xxx.xxx.xxx.xxx serveurprincipal.mon-cluster.vpn pra pvelocalhost<br/>
[...]</p>
<p>Où xxx.xxx.xxx.xxx est l'adresse que vous avez indiquée pour <strong>vmbr1</strong> (pour moi 192.168.11.1)</p>
<p>Pour avoir des logs propres au démarrage (on sait jamais)</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># nano /etc/default/bootlogd </span></span></p>
<p>Et modifiez :</p>
<p style="margin-left: 40px;">BOOTLOGD_ENABLE=Yes</p>
<h2 id="installation-dopenvpn">Installation d'OpenVPN</h2>
<p>On est parti ! Tout ce qui était avant va vous servir :-)</p>
<p>Installons OpenVPN pour commencer :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># aptitude install openvpn</span></span></p>
<p>Faites ceci sur tous vos serveurs.</p>
<h3 id="preparation-des-certificats">Préparation des certificats</h3>
<p>Sur le serveur PRA, le serveur principal d'OpenVPN, nous allons générer les certificats serveurs et clients.</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># cpav /usr/share/doc/openvpn/examples/easy-rsa/2.0/ /etc/openvpn/easy-rsa/<br/>
<br/>
# cd /etc/openvpn/easy-rsa/<br/>
<br/>
# cpav vars vars.original</span></span></p>
<p>Editez le fichier vars, tout à la fin du fichier, pour modifier les variables globales. Ainsi votre génération de clef se fera automatiquement. Sinon, vous devrez indiquer les informations à chaque génération.</p>
<p>Puis :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># source ./vars</span></span></p>
<p style="margin-left: 40px;">NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/keys</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># ./clean-all</span><br/>
<span style="background-color:#000000;"># ./build-dh</span></span></p>
<p style="margin-left: 40px;">Generating DH parameters, 1024 bit long safe prime, generator 2<br/>
This is going to take a long time<br/>
........................................................+......<br/>
..+............+...............................................<br/>
...............................................................<br/>
...+............................................++*++*++*</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># ./pkitool --initca</span></span></p>
<p style="margin-left: 40px;">Using CA Common Name: Mon organisation CA<br/>
Generating a 1024 bit RSA private key<br/>
...++++++<br/>
................++++++<br/>
writing new private key to 'ca.key'<br/>
-----</p>
<h3 id="generez-la-clef-serveur">Générez la clef serveur</h3>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># ./pkitool --server server</span></span></p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># openvpn --genkey --secret ./keys/ta.key</span></span></p>
<h3 id="generez-les-clefs-clients">Générez les clefs clients</h3>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># ./pkitool clientPrincipal</span></span></p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># ./pkitool clientArbitre</span></span></p>
<p>Vous pouvez également en profiter pour générer d'autres clefs clients si vous souhaitez vous connecter vous-même au VPN, pour sécuriser à fond vos accès SSH par exemple.</p>
<h3 id="sauvegarde-des-clefs">Sauvegarde des clefs</h3>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># cd /etc/openvpn/easy-rsa/keys/</span><br/>
<br/>
<span style="background-color:#000000;"># tar cvzf /root/server-keys.tar.gz server.crt server.key ca.crt dh1024.pem ta.key</span><br/>
<br/>
<span style="background-color:#000000;"># tar cvzf /root/clientPrincipal-keys.tar.gz clientPrincipal.crt clientPrincipal.key ca.crt ta.key</span></span></p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># tar cvzf /root/clientArbitre-keys.tar.gz clientArbitre.crt clientPrincipal.key ca.crt ta.key</span></span></p>
<h3 id="configuration-des-serveurs">Configuration des serveurs</h3>
<p>Pour mettre en place le fameux triangle OpenVPN permettant un quorum solide, nous allons devoir configurer à la fois le serveur principal ET le serveur PRA comme serveurs OpenVPN.</p>
<p>La différence se jouera dans les fichiers de configurations des clients.</p>
<p>Sur chacune des machines, importez le fichier de configuration par défaut :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># cd /etc/openvpn/<br/>
<br/>
# zcat /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > server.conf<br/>
<br/>
# cpav server.conf server.conf.original</span></span></p>
<p>Pour une configuration idéale (d'après mes tests de robustesse personnels), le fichier doit ressemble à ça sans ses commentaires :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># cat server.conf | grep -v -e '^;' | grep -v -e '^#' | grep -v -e '^$'</span></span></p>
<p style="margin-left: 40px;"><strong>local IP_PUBLIQUE_SERVEUR</strong><br/>
<strong>port 4450</strong><br/>
proto tcp<br/>
dev tap0<br/>
ca ca.crt<br/>
cert server.crt<br/>
key server.key # This file should be kept secret<br/>
dh dh1024.pem<br/>
<strong>server-bridge XXX.XXX.XXX.XXX 255.255.255.0 YYY.YYY.YYY.YYY TTT.TTT.TTT.TTT</strong><br/>
client-to-client<br/>
duplicate-cn<br/>
keepalive 10 120<br/>
tls-auth /etc/openvpn/ta.key 0 # This file is secret<br/>
comp-lzo<br/>
max-clients 4<br/>
user nobody<br/>
group nogroup<br/>
persist-key<br/>
persist-tun<br/>
status openvpn-status.log<br/>
log-append openvpn.log<br/>
verb 3<br/>
mode server<br/>
tls-server<br/>
script-security 2<br/>
up "/etc/openvpn/up.sh"<br/>
down "/etc/openvpn/down.sh"</p>
<p>Les choses à modifier selon le serveur sont en gras :</p>
<ul>
<li>local IP_PUBLIQUE_SERVEUR : remplacez par l'adresse IP publique de votre serveur, pour écouter en VPN sur cette adresse. Cette adresse est a priori différente selon le serveur ! ;-)</li>
<li>Le port d'écoute. Par défaut 1194, mais il est conseillé de le changer pour éviter d'être reconnu direct comme un VPN</li>
<li>XXX.XXX.XXX.XXX : remplacez par l'adresse privée du <strong>vmbr1</strong> du serveur. Attention à ne pas vous tromper !</li>
<li>YYY.YYY.YYY.YYY : cette IP est le début de la plage allouée pour OpenVPN. Pour ma part, je prend 4 clients possibles. Les 2 serveurs et 2 autres (pour vos connexions de gestion par exemple)</li>
<li>TTT.TTT.TTT.TTT : Cette IP est la fin de la plage allouée commencée par YYY.YYY.YYY.YYY. Cette plage doit contenir les IP de vos serveurs, mais comme ceux-ci sont en IP fixe, pas de risque d'allocation se marchant dessus.</li>
</ul>
<h3 id="scripts-upsh-et-downsh-pour-les-serveurs">Scripts up.sh et down.sh (pour les serveurs)</h3>
<p>Ces scripts vont permettre d'ajouter l'interface OpenVPN (tap0) au bridge vmbr1 à chaque démarrage du serveur VPN. Et bien sûr de le retirer à l'arrêt du serveur VPN (faisons les choses bien :-))</p>
<p>Ces scripts seront sensiblement différents pour les clients, nous verrons ça plus bas.</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># nano /etc/openvpn/up.sh</span></span></p>
<p style="margin-left: 40px;">#!/bin/bash<br/>
/sbin/ifconfig vmbr1 promisc<br/>
/sbin/ifconfig tap0 up promisc<br/>
/usr/sbin/brctl addif vmbr1 tap0</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># nano /etc/openvpn/down.sh</span></span></p>
<p style="margin-left: 40px;">#!/bin/bash<br/>
/usr/sbin/brctl delif vmbr1 tap0<br/>
/sbin/ifconfig tap0 down -promisc<br/>
#/sbin/ifconfig vmbr1 -promisc</p>
<h3 id="installation-des-clefs-serveurs">Installation des clefs serveurs</h3>
<p>Chacun des serveur devra disposer du set de clef serveur que nous avons généré plus haut. Sans quoi, ils n'accepteront pas les connexions du client.</p>
<p>Physiquement, le client ne sera connecté qu'à un serveur à la fois, mais il faut que les 2 serveurs tournent en permanence pour que le client puisse basculer facilement en cas de souci sur le PRA.</p>
<p>Sur le PRA, où vous avez généré les clefs, il suffit de les placer dans le dossier openVPN puis de les extraire :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># cd /etc/openvpn</span></span></p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># tar xvzf /root/</span></span><span style="color:#ffffff;"><span style="background-color:#000000;">server-keys.tar.gz</span></span></p>
<p>Sur le serveur principal, il va d'abord falloir envoyer les clefs via scp :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># scp </span></span><span style="color:#ffffff;"><span style="background-color:#000000;">/root/</span></span><span style="color:#ffffff;"><span style="background-color:#000000;">server-keys.tar.gz root@IP_PUBLIQUE_SERVEUR:</span></span></p>
<p><strong>Note : il n'est pas très propre d'utiliser root pour le transfert, mais c'est malheureusement la technique la plus simple sur Proxmox, où quasi-tout doit se faire en root. Vous pouvez cependant créer un autre utilisateur qui ne servira que pour les transferts. De toute façon, le cluster discute avec le compte root, donc le SSH sur le port 22 en root devra au moins être autorisé dans le tunnel OpenVPN. Je vous laisse gérer votre niveau de sécurité :-)</strong></p>
<p>Puis extraire les clefs :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># cd /etc/openvpn</span></span></p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># tar xvzf /root/</span></span><span style="color:#ffffff;"><span style="background-color:#000000;">server-keys.tar.gz</span></span></p>
<p>Une fois ceci fait, vous pouvez redémarrer OpenVPN sur les 2 serveurs :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># /etc/init.d/openvpn restart</span></span></p>
<p>Normalement, il doit démarrer sans erreurs des deux côtés. Les logs s'écrivent dans /etc/openvpn/openvpn.log</p>
<p>Un démarrage réussit doit se terminer par </p>
<p style="margin-left: 40px;">Initialization sequence completed</p>
<p>Sinon, vérifiez bien les adresses IP que vous avez indiquée (problème de bind) et la synthaxe des paramètres dans le fichier de conf (problème de "unknown parameter")</p>
<h3 id="configuration-des-clients">Configuration des clients</h3>
<p>A ce stade, nous avons uniquement les serveurs VPN qui tournent. Il va vous falloir configurer les clients qui s'y connectent.</p>
<p>Au nombre des clients, nous avons donc l'arbitre, et le serveur principal qui je le rappelle est à la fois client ET serveur.</p>
<p>Nous allons configurer l'arbitre pour qu'il tente en premier lieu de se connecter au PRA, et s'il échoue qu'il tente de se connecter au serveur principal. Nous allons également indiquer dans sa configuration que si sa connexion saute, il doit réessayer immédiatement de se reconnecter.</p>
<p>Par contre, le serveur principal n'essaiera de se connecter qu'au PRA.</p>
<p>Voici le fichier de configuration. La spécificité de l'arbitre est en <span style="color:#ff0000;">rouge</span> :</p>
<p style="margin-left: 40px;">client<br/>
<strong>dev tap1</strong><br/>
proto tcp<br/>
<strong>remote IP_PUBLIQUE_PRA PORT_VPN<br/>
<span style="color:#ff0000;">remote IP_PUBLIQUE_SERVEUR_PRINCIPAL PORT_VPN</span></strong><br/>
resolv-retry infinite<br/>
nobind<br/>
persist-key<br/>
persist-tun<br/>
ca ca.crt<br/>
<strong>cert CLIENT.crt<br/>
key CLIENT.key</strong><br/>
ns-cert-type server<br/>
tls-auth ta.key 1<br/>
comp-lzo<br/>
verb 3<br/>
<strong>log-append openvpnclient.log</strong><br/>
script-security 2<br/>
<strong>up "/etc/openvpn/upclient.sh"<br/>
down "/etc/openvpn/downclient.sh</strong>"<br/>
<strong>keepalive 30 120</strong><br/>
float</p>
<p>Les paramètres à adapter sont en <strong>gras</strong> :</p>
<ul>
<li>dev tapX : c'est l'interface que crééra openvpn pour sa connexion. Il est important de ne pas mettre tap0, qui est déjà utilisé pour le serveur VPN sur le serveur principal. Pour uniformiser, mieux vaut utiliser la même interface sur les 2 clients</li>
<li>remote .... : c'est là que vous indiquez sur quel serveur se connecter. Indiquez l'adresse IP du PRA ainsi que le port que vous avez choisi. Sur l'arbitre, rajoutez une ligne avec l'adresse IP du serveur principal. OpenVPN essaiera toujours la première ligne, puis si elle échoue il passera à la deuxième.</li>
<li>cert, key : c'est là que vous définirez les certificats et les clefs à utiliser pour la connexion client (clientPrincipale ou clientArbitre) que nous allons rapatrier via scp.</li>
<li>log-append : indique le fichier dans lequel les logs de connexion seront écrits. Indiquez un nom de fichier différent de celui du serveur pour avoir des logs bien séparés</li>
<li>up, down : les fichiers up.sh et down.sh sont différents entre les serveurs et les clients, donc indiquez là aussi des noms différents ce ceux dans le fichier de conf du serveur</li>
<li>keepalive 30 120 : cette directive va indiquer aux clients qu'il doivent tenter de relancer leur connexion si jamais elle tombe (On ping toutes les 30s, on redémarre au bout de 120s si pas de réponse). Dans le cas du serveur principal, il essaiera en boucle de se reconnecter sur le PRA. Dans le cas de l'arbitre, il alternera entre le PRA et le serveur principal jusqu'à ce qu'une connexion réussisse</li>
</ul>
<h3 id="scripts-upclient-et-downclient">Scripts upclient et downclient</h3>
<p>Les fichiers up.sh et down.sh sont différents pour les clients. Comme le serveur principal possède déjà up.sh et down.sh, on les nomme upclient.sh et downclient.sh pour qu'ils ne se marchent pas dessus (quelle imagination ! \o/)</p>
<p>Donc, upclient.sh :</p>
<p style="margin-left: 40px;">#!/bin/bash<br/>
/sbin/ifconfig vmbr1 promisc<br/>
/sbin/ifconfig tap1 up promisc<br/>
/usr/sbin/brctl addif vmbr1 tap1<br/>
/sbin/ifconfig tap1 0</p>
<p>Et downclient.sh :</p>
<p style="margin-left: 40px;">#!/bin/bash<br/>
/sbin/ifconfig vmbr1 -promisc</p>
<p>La principale différence est le nom des interfaces à bridger (tap1 dans mon cas). Le down client ne doit également pas sortir le tap1 du bridge, sinon il risque de générer une erreur qui va bloquer la tentative de connexion en boucle du client. Et donc rendre inefficace le mode de secours. (Un petit souci de gestion de bridge avec OpenVPN vis à vis de tous les bridges/tap qu'on utilise ici...)</p>
<h3 id="recuperation-des-clefs-clients">Récupération des clefs clients</h3>
<p>Bien, il ne reste plus qu'à transmettre les clefs openvpn à qui de droit. Depuis le PRA qui les a générées, envoyez les tar.gz grâce à scp :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># scp /root/clientPrincipal-keys.tar.gz root@IP_PUBLIQUE_SERVEURPRINCIPAL:</span></span></p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># scp /root/clientArbitre-keys.tar.gz root@IP_PUBLIQUE_ARBITRE:</span></span></p>
<p>Puis sur chaque serveur, extrayez les clefs dans /etc/openvpn :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># cd /etc/openvpn</span></span></p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># tar xvzf /root/client{Principal,Arbitre}-keys.tar.gz</span></span></p>
<p>Et enfin, redémarrez openvpn.</p>
<p>La connexion va s'établir. Là encore, les logs s'écrivent dans /etc/openvpn, dans le fichier openvpnclient.log spécifé dans le fichier de configuration.</p>
<p>Si tout se passe bien, vous pourrez y voir apparaitre un "Initialization sequence completed".</p>
<p>C'est également dans ce fichier que vous pouvez vérifier si la reconnexion se fait bien.</p>
<h2 id="tests-du-triangle-openvpn">Tests du triangle openvpn</h2>
<p>Il est important de tester votre système de connexion/reconnexion.</p>
<p>A l'étape précédente, la connexion de base a dû bien fonctionner. Sinon, faites en sorte que ce soit le cas. Si jamais vous avez des soucis particuliers, faites m'en part dans les commentaires :-)</p>
<p>Pour tester, effectuez quelques ping sur les adresse vmbr1 de chaque serveur :</p>
<ul>
<li>Sur le serveur principal, pinguez le vmbr1 du PRA et de l'arbitre</li>
<li>Sur le PRA, pinguez le vmbr1 du serveur principal et de l'arbitre</li>
<li>sur l'arbitre, pinguez le vmbr1 du serveur principal et du PRA</li>
</ul>
<p> </p>
<p>Pour tester que la reconnexion fonctionne bien, nous allons essayer de couper le serveur VPN du PRA et voir comment tout cela se comporte.</p>
<p>Ouvrez 3 connexions SSH, une par serveur.</p>
<ul>
<li>Sur l'arbitre et le serveur principal, lancez une surveillance du client OpenVPN :</li>
</ul>
<p style="margin-left: 40px;"><span style="color:#ffffff;"><span style="background-color:#000000;"># less /etc/openvpn/openvpnclient.log</span></span></p>
<p style="margin-left: 40px;">Puis effectuez la combinaison de touche "maj + F" qui va permettre une mise à jour en temps réel du fichier. Vous verrez ainsi tout ce qui s'y écrit</p>
<ul>
<li>Sur le PRA, coupez openvpn avec un </li>
</ul>
<p style="margin-left: 40px;"><span style="color:#ffffff;"><span style="background-color:#000000;"># /etc/init.d/openvpn stop</span></span></p>
<p>Normalement, vous devriez rapidement voir dans les fichiers de log que la connexion s'est interrompue. Sur le serveur Principal, la connexion va tenter en boucle de s'établir à nouveau.</p>
<p>Sur l'arbitre, vous devriez voir rapidement une tentative de connexion sur le serveur principal, qui doit réussir.</p>
<p>Là encore, vous pouvez vérifier avec quelques ping que tout va bien.</p>
<p>Relancez ensuite le serveur VPN sur le PRA. Vous devez observer que le serveur principal revient s'y connecter.</p>
<p><strong>A ce moment là, l'arbitre est connecté sur le serveur principal. Il ne va pas essayer de se reconnecter sur le PRA sauf si le serveur principal tombe.</strong></p>
<p>Pour achever nos tests, coupez le serveur VPN sur le serveur principal, ce qui devrait provoquer la reconnexion de l'arbitre sur le PRA.</p>
<p>Si tout ça fonctionne, on commence à être vraiment bon ! :-)</p>
<h2 id="mise-en-place-du-cluster">Mise en place du cluster</h2>
<p>Avant de mettre en place le cluster, nous allons vérifier que le multicast passe bien dans le VPN.</p>
<p>Pour ce faire, sur chaque machine, installez l'outil suivant :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># aptitude install ssmping</span></span></p>
<p>Ensuite, nous allons tester les serveurs 2 par 2. L'un essaiera de joindre l'autre en multicast, pendant que la cible écoutera les connexions.</p>
<p>Bon je vais pas écrire toutes les combinaisons possibles pour les tests. Sachez qu'il vous faut lancer sur un serveur pour le mettre en écoute :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># ssmpingd</span></span></p>
<p>Puis depuis un autre, lancez le test :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># asmping 224.0.2.1 IP_SERVEUR_TEST</span></span></p>
<p>Vous devez voir passer sur le serveur en écoute des messages de ce type :</p>
<p style="margin-left: 40px;">asmping joined (S,G) = (*,224.0.2.234)<br/>
pinging IP_SERVEUR_TEST from IP_SERVEUR_SOURCE<br/>
unicast from IP_SERVEUR_TEST, seq=1 dist=0 time=38.699 ms<br/>
multicast from IP_SERVEUR_TEST, seq=1 dist=0 time=76.405 ms<br/>
unicast from IP_SERVEUR_TEST, seq=2 dist=0 time=38.802 ms<br/>
multicast from IP_SERVEUR_TEST, seq=2 dist=0 time=76.238 ms</p>
<p>Les lignes importantes à repérer sont celles du multicast, <strong>que vous devez impérativement constater pour le bon fonctionnement du cluster !</strong></p>
<p>C'est également le bon moment pour vérifier le fichier /etc/hosts.</p>
<p>Vous devez avoir indiqué l'adresse IP du vmbr1. C'est l'adresse dont se sert Proxmox comme information lors du contact avec les autres membres du cluster.</p>
<h3 id="creation-du-cluster">Création du cluster</h3>
<p>Pour le cluster, nous allons effectuer sa création depuis le PRA, puis nous allons y ajouter les 2 autres serveurs.</p>
<p><strong>Je vous rappelle qu'il ne doit y avoir aucune VM sur le serveur principal et sur l'arbitre ! </strong>Si votre système a déjà des VM en fonctionnement, migrez les temporairement sur le PRA le temps de créer le cluster. Cette limitation a pour but de s'assurer qu'aucun VMID ne sera en conflit au sein du cluster.</p>
<p>Le nom du cluster est important, dans le sens où une fois le cluster créé, vous ne pourrez plus changer ce nom. Choisissez le bien !</p>
<p>Sur le PRA : </p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># pvecm create NOM_DU_CLUSTER</span></span></p>
<p>qui doit vous renvoyer :</p>
<p style="margin-left: 40px;"><br/>
Generating public/private rsa key pair.<br/>
Your identification has been saved in /root/.ssh/id_rsa.<br/>
Your public key has been saved in /root/.ssh/id_rsa.pub.<br/>
The key fingerprint is:<br/>
xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx root@proxmox-server-1<br/>
The key's randomart image is:<br/>
+--[ RSA 2048]----+<br/>
| |<br/>
| |<br/>
| |<br/>
| | <br/>
| . So o |<br/>
| . .. .O o |<br/>
<br/>
| .. . o* = |<br/>
| +o o.=.. |<br/>
| . +E * o o . |<br/>
+----------------------+<br/>
Restarting pve cluster filesystem: pve-cluster[dcdb] crit: unable to read cluster config file '/etc/cluster/cluster.conf' - Failed to open file '/etc/cluster/cluster.conf': No such file or directory<br/>
[dcdb] notice: wrote new cluster config '/etc/cluster/cluster.conf'<br/>
[dcdb] crit: cman_tool version failed with exit code 1#010<br/>
.<br/>
Starting cluster:<br/>
Checking if cluster has been disabled at boot... [ OK ]<br/>
Checking Network Manager... [ OK ]<br/>
Global setup... [ OK ]<br/>
Loading kernel modules... [ OK ]<br/>
Mounting configfs... [ OK ]<br/>
Starting cman... [ OK ]<br/>
Waiting for quorum... [ OK ]<br/>
Starting fenced... [ OK ]<br/>
Starting dlm_controld... [ OK ]<br/>
Unfencing self... [ OK ]</p>
<p>Puis, sur chacun des autres serveurs :</p>
<p># pvecm add IP_VMBR1_PRA</p>
<p>qui doit vous renvoyer à peu près la même chose qu'au dessus.</p>
<h3 id="etat-du-cluster">Etat du cluster</h3>
<p>La commande pvecm vous permettra d'avoir plusieurs infos sur le cluster.</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># pvecm n</span></span></p>
<p>vous donnera un aperçu des nodes (date de connexion, état, etc)</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;"># pvecm s</span></span></p>
<p>vous donnera des informations sur le cluster lui-même (état du qorum, nombre de node, nombre de vote, etc)</p>
<p>Nous verrons plus tard des commandes plus spécifiques au HA.</p>
<h2 id="bon-je-crois-que-jai-rien-oublie">Bon, je crois que j'ai rien oublié</h2>
<p>Et bien voila qui conclut la création de notre système de cluster !</p>
<p>A la fin de ce tutoriel, vous avez normalement un cluster de 3 nodes, donc avec un quorum qui fonctionne, et des paritions manipulables facilement.</p>
<p>Vous êtes prêts à mettre en place le système de disque répliqué, puis le HA lui-même.</p>
<p>Ces deux étapes seront le sujet des prochains articles.</p>
<p>En attendant, n'hésitez pas à me poser des questions dans les commentaires !</p>
<p> </p>Construisez un tunnel (ssh) de vos propres mains !!2013-01-17T20:58:00+01:002013-01-17T20:58:00+01:00Victortag:blog.victor-hery.com,2013-01-17:/2013/01/construisez-tunnel-ssh.html
<h2 id="un-tunnel-sans-pelle">Un tunnel sans pelle</h2>
<p>Et sans terre sur les mains. Classe non ?</p>
<p>Et bien, c'est possible grâce à SSH. (entre autre hein, tunnel est un terme plutôt répandu en informatique, mais bon ça fait une bonne accroche)</p>
<p>Pour parler plus directement, un tunnel ssh va vous permettre de communiquer via …</p>
<h2 id="un-tunnel-sans-pelle">Un tunnel sans pelle</h2>
<p>Et sans terre sur les mains. Classe non ?</p>
<p>Et bien, c'est possible grâce à SSH. (entre autre hein, tunnel est un terme plutôt répandu en informatique, mais bon ça fait une bonne accroche)</p>
<p>Pour parler plus directement, un tunnel ssh va vous permettre de communiquer via SSH avec un serveur distant, et plus pécisément de rediriger certains ports locaux vers ce serveur, qui en fera ce que vous voulez.</p>
<p> </p>
<p>Typiquement, rediriger un port VNC dans un tunnel SSH permet de se connecter sur une machine distante de manière sécurisée. Alors que VNC de base, c'est quand même tout en clair à l'arrache.</p>
<p>Ce système permet de sécuriser la plupart des routages de ports sales que l'on peut faire sur une box pour rentrer dans son réseau. Bien sûr, il y a aussi des applications techniques plus intéressantes au niveau entreprise :-)</p>
<p>L'un des gros intérêts également, c'est que ça peut être utilisé sur un smartphone (<a href="https://fr.wikipedia.org/wiki/Smartphone">ordiphone</a>) sans aucun hack (ou rootage, ou jailbreak), contrairement à OpenVPN par exemple.</p>
<h2 id="il-faut-pas-le-dire">Il faut pas le dire</h2>
<p>Avec cette technique, vous pouvez également (ouh, c'est mal) passer certaines protections ou proxy, par exemple en redirigeant toutes vos connexion HTTP (port 80) sur un tunnel ssh sur le port 443 (HTTPS très rarement filtré) vers votre serveur, qui ensuite vous redirigera vers le site que vous vouliez.</p>
<p>Inconvenient : vous profitez de votre bande passante potentiellement pourrie, surtout si vous vous auto-hébergez (c'est le bien !), puisque où que vous soyiez, toutes vos requêtes Internet passeront par chez vous.</p>
<p>Avantage : vous mettez un doigt dans l'os à tout ces "filtrages" pseudo sécurité qui en fait font chier que les gens honnêtes. (Dont vous faites bien sûr partie)</p>
<p>Ce besoin qu'on a tous connu (ou qu'on imagine au moins) servira de contexte pour ce tuto.</p>
<p> </p>
<h2 id="le-principe">Le principe</h2>
<p>Comme d'habitude, un petit rappel du principe technique de la chose.</p>
<p>Nous allons mettre en place sur un serveur, placé où bon vous semble, ce qu'on appelle un shell SSH qui attendra des connexions extérieures.</p>
<p>Ce système est sensé permettre un accès SSH à votre serveur. Comme ce n'est pas le but ici, nous allons détourner le problème en mettant en place un shell hyper restreint. De cette façon vous pourrez fournir la connexion à qui vous voulez, en étant sûr qu'ils ne feront pas de mauvaises choses avec votre serveur. (On ne sait jamais :-) )</p>
<p>La connexion se fera grâce à un couple clef/mot de passe, pour une sécurité maximum. La connexion au tunnel sera interdite par tout autre moyen, ce qui permet de limiter les attaques par brute force notamment.</p>
<p>Chaque personne voulant se connecter devra donc posséder un couple clef/mot de passe fourni par vous. Dans cette optique et pour suivre plus simplement qui a quoi, nous allons créer pour chaque compte un utilisateur du système, qui aura le droit d'utiliser le tunnel. Ces utilisateurs appartiendront tous au groupe tunnelssh.</p>
<p>Ce système, même s'il peut créer beaucoup d'utilisateur, présente l'avantage d'être à la fois clair et d'avoir des logs faciles à lire (chaque tentative de connexion étant loggué par utilisateur)</p>
<p>Le système de redirection de port sera à votre convenance. Comme dit plus haut, j'utiliserais pour ma part le port 443, le plus communément ouvert même dans des lieux "limitatifs" sur des wifi "ouverts".</p>
<p> </p>
<h2 id="materiels-connaissances-besoins-divers">Matériels, connaissances, besoins divers</h2>
<p>Comme toujours quand on est un gros hacker barbu, plusieurs choses s'imposent.</p>
<p>Tout d'abord, il va vous falloir un serveur sous Linux, qui permettra d'installer la sortie du tunnel. Vous vous connecterez avec votre machine sur lui, qui se chargera de rediriger ce que vous voulez où vous voulez.</p>
<p>Pour ma part, j'utilise debian, mais SSH étant plutôt répandu, ça ne posera pas de problème à transcrire ailleurs.</p>
<p>Il vous faudra aussi une autre machine servant de client pour les tests (Ordiphone Android/Iphone, PC fixe, PC portable, tablette, ...)</p>
<p>Il est conseillé de disposer d'un minimum de connaissances dans la ligne de commande, et connaître un peu le réseau (notamment les ports) est un plus apprécié. Cependant, il est possible de copier-coller les commandes, donc pas la peine de trembler si vous ne maitrisez pas le bousin :-)</p>
<p> </p>
<p>Enfin, comme l'objectif est de travailler honnêtement pour promouvoir un Internet plus libre, une bonne bière n'est pas de refus !</p>
<p> </p>
<h2 id="bien-on-est-parti">Bien. On est parti.</h2>
<h3 id="configuration-du-tunnel">configuration du tunnel</h3>
<p>Pour commencer, connectez vous sur votre serveur, via un SSH classique. Si vous utilisez directement un écran/clavier/souris, il faudra vérifier qu'openSSH est correctement installé :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;">$ sudo aptitude install openssh-server</span></span></p>
<p>Une fois cela fait, nous allons créer une deuxième instance d'OpenSSH server, qui va écouter sur le port 443 et qui servira exclusivement pour le tunnel. Pour ce faire, créez un fichier sshd_config_tunnel, placé dans /etc/ssh :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;">$ sudo nano /etc/ssh/sshd_config_tunnel</span></span></p>
<p>A l'intérieur, copiez-collez ce qui suit : </p>
<p style="margin-left: 40px;">Port <strong>443</strong><br/>
<br/>
#ListenAddress ::<br/>
#ListenAddress 0.0.0.0<br/>
Protocol 2<br/>
# HostKeys for protocol version 2<br/>
HostKey /etc/ssh/ssh_host_rsa_key<br/>
HostKey /etc/ssh/ssh_host_dsa_key<br/>
#Privilege Separation is turned on for security<br/>
UsePrivilegeSeparation yes<br/>
<br/>
KeyRegenerationInterval 3600<br/>
ServerKeyBits 768<br/>
<br/>
# Logging<br/>
SyslogFacility AUTH<br/>
LogLevel INFO<br/>
<br/>
# Authentication:<br/>
LoginGraceTime 120<br/>
<strong>PermitRootLogin no<br/>
AllowGroups tunnelssh</strong><br/>
StrictModes yes<br/>
<br/>
<strong>AllowTcpForwarding yes</strong><br/>
<strong>#PermitOpen IP_LOCALE:PORT_LOCAL</strong><br/>
AllowAgentForwarding no<br/>
<br/>
RSAAuthentication yes<br/>
PubkeyAuthentication yes<br/>
AuthorizedKeysFile %h/.ssh/authorized_keys<br/>
<br/>
IgnoreRhosts yes<br/>
RhostsRSAAuthentication no<br/>
<br/>
HostbasedAuthentication no<br/>
#IgnoreUserKnownHosts yes<br/>
<br/>
PermitEmptyPasswords no<br/>
<br/>
ChallengeResponseAuthentication no<br/>
<strong>PasswordAuthentication no</strong><br/>
<br/>
# Kerberos options<br/>
#KerberosAuthentication no<br/>
#KerberosGetAFSToken no<br/>
#KerberosOrLocalPasswd yes<br/>
#KerberosTicketCleanup yes<br/>
<br/>
# GSSAPI options<br/>
#GSSAPIAuthentication no<br/>
#GSSAPICleanupCredentials yes<br/>
<br/>
X11Forwarding no<br/>
X11DisplayOffset 10<br/>
PrintMotd no<br/>
PrintLastLog yes<br/>
TCPKeepAlive yes<br/>
#UseLogin no<br/>
<br/>
#MaxStartups 10:30:60<br/>
#Banner /etc/issue.net<br/>
<br/>
AcceptEnv LANG LC_*<br/>
<br/>
Subsystem sftp /usr/lib/openssh/sftp-server<br/>
<br/>
UsePAM yes</p>
<p>C'est en fait un fichier de configuration ssh classique modifié pour notre usage. Je l'ai épuré des commentaires pour qu'il ne soit pas trop lourd, et j'ai mis en gras les morceaux importants :</p>
<ul>
<li>Port 443 : c'est ici que vous allez définir sur quel port écoute votre serveur. Comme dit précedemment, j'utilise le port 443, mais vous mettez ce que vous voulez.</li>
<li>PermitRootLogin no : cette directive va interdire toute connexion au serveur avec l'utilisateur root.</li>
<li>AllowGroups tunnelssh : cela permet d'autoriser uniquement les utilisateurs appartenant au groupe tunnelssh de se connecter.</li>
<li>AllowTcpForwarding yes : cette directive va autoriser votre serveur SSH à transmettre ce qui lui arrive dessus vers une autre machine (typiquement vos requêtes Internet)</li>
<li>#PermitOpen IP_LOCALE:PORT_LOCAL : cette directive (ici commenté) peut vous servir si vous voulez utiliser votre tunnel pour accéder à une seule machine de votre réseau local. Par exemple, pour vous connecter sur votre PC avec VNC. Si vous désirez utilisez votre tunnel pour accéder à Internet, laissez cette ligne commentée.</li>
<li>PasswordAuthentication no : cette directive va imposer l'utilisation d'une clef SSH pour vous connecter au serveur.</li>
</ul>
<p> </p>
<p>Il va également vous falloir lancer ce serveur en parallèle du vrai serveur SSH (que je vous conseille de laisser pour les accès "administratifs" dont vous pourriez avoir besoin).</p>
<p>Pour ce faire, il suffit de créer dans le dossier /etc/init.d/ un nouveau fichier de lancement ssh :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;">$ sudo nano /etc/init.d/ssh_tunnel</span></span></p>
<p>Dans lequel vous pouvez copiez-collez :</p>
<p style="margin-left: 40px;">#! /bin/sh<br/>
<br/>
### BEGIN INIT INFO<br/>
# Provides: sshd_tunnel<br/>
# Required-Start: $remote_fs $syslog<br/>
# Required-Stop: $remote_fs $syslog<br/>
# Default-Start: 2 3 4 5<br/>
# Default-Stop: 0 1 6<br/>
# Short-Description: OpenBSD Secure Shell server<br/>
### END INIT INFO<br/>
<br/>
set -e<br/>
<br/>
# /etc/init.d/ssh: start and stop the OpenBSD "secure shell(tm)" daemon<br/>
<br/>
test -x /usr/sbin/sshd || exit 0<br/>
( /usr/sbin/sshd -\? 2>&1 | grep -q OpenSSH ) 2>/dev/null || exit 0<br/>
<br/>
umask 022<br/>
<br/>
if test -f /etc/default/ssh; then<br/>
. /etc/default/ssh<br/>
fi<br/>
<br/>
. /lib/lsb/init-functions<br/>
<br/>
if [ -n "$2" ]; then<br/>
SSHD_OPTS="$SSHD_OPTS $2"<br/>
fi<br/>
<br/>
SSHD_OPTS="$SSHD_OPTS -f<strong> /etc/ssh/sshd_config_tunnel"</strong><br/>
<br/>
# Are we running from init?<br/>
run_by_init() {<br/>
([ "$previous" ] && [ "$runlevel" ]) || [ "$runlevel" = S ]<br/>
}<br/>
<br/>
check_for_no_start() {<br/>
# forget it if we're trying to start, and /etc/ssh/sshd_not_to_be_run exists<br/>
if [ -e /etc/ssh/sshd_not_to_be_run ]; then<br/>
if [ "$1" = log_end_msg ]; then<br/>
log_end_msg 0<br/>
fi<br/>
if ! run_by_init; then<br/>
log_action_msg "OpenBSD Secure Shell server not in use (/etc/ssh/sshd_not_to_be_run)"<br/>
fi<br/>
exit 0<br/>
fi<br/>
}<br/>
<br/>
check_dev_null() {<br/>
if [ ! -c /dev/null ]; then<br/>
if [ "$1" = log_end_msg ]; then<br/>
log_end_msg 1 || true<br/>
fi<br/>
if ! run_by_init; then<br/>
log_action_msg "/dev/null is not a character device!"<br/>
fi<br/>
exit 1<br/>
fi<br/>
}<br/>
<br/>
check_privsep_dir() {<br/>
# Create the PrivSep empty dir if necessary<br/>
if [ ! -d /var/run/<strong>sshd_tunnel</strong> ]; then<br/>
mkdir /var/run/<strong>sshd_tunnel</strong><br/>
chmod 0755 /var/run/<strong>sshd_tunnel</strong><br/>
fi<br/>
}<br/>
<br/>
check_config() {<br/>
if [ ! -e /etc/ssh/sshd_not_to_be_run ]; then<br/>
/usr/sbin/sshd $SSHD_OPTS -t || exit 1<br/>
fi<br/>
}<br/>
<br/>
export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"<br/>
<br/>
case "$1" in<br/>
start)<br/>
check_privsep_dir<br/>
check_for_no_start<br/>
check_dev_null<br/>
log_daemon_msg "Starting OpenBSD Secure Shell server" <strong>"sshd_tunnel"</strong><br/>
if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/<strong>sshd_tunnel.pid</strong> --exec /usr/sbin/sshd -- $SSHD_OPTS; then<br/>
log_end_msg 0<br/>
else<br/>
log_end_msg 1<br/>
fi<br/>
;;<br/>
stop)<br/>
log_daemon_msg "Stopping OpenBSD Secure Shell server" <strong>"sshd_tunnel"</strong><br/>
if start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/<strong>sshd_tunnel.pid</strong>; then<br/>
log_end_msg 0<br/>
else<br/>
log_end_msg 1<br/>
fi<br/>
;;<br/>
<br/>
reload|force-reload)<br/>
check_for_no_start<br/>
check_config<br/>
log_daemon_msg "Reloading OpenBSD Secure Shell server's configuration" <strong>"sshd_tunnel"</strong><br/>
if start-stop-daemon --stop --signal 1 --quiet --oknodo --pidfile /var/run/<strong>sshd_tunnel.pid</strong> --exec /usr/sbin/sshd; then<br/>
log_end_msg 0<br/>
else<br/>
log_end_msg 1<br/>
fi<br/>
;;<br/>
<br/>
restart)<br/>
check_privsep_dir<br/>
check_config<br/>
log_daemon_msg "Restarting OpenBSD Secure Shell server" "sshd"<br/>
start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile /var/run/<strong>sshd_tunnel.pid</strong><br/>
check_for_no_start log_end_msg<br/>
check_dev_null log_end_msg<br/>
if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/<strong>sshd_tunnel.pid</strong> --exec /usr/sbin/sshd -- $SSHD_OPTS; then<br/>
log_end_msg 0<br/>
else<br/>
log_end_msg 1<br/>
fi<br/>
;;<br/>
<br/>
try-restart)<br/>
check_privsep_dir<br/>
check_config<br/>
log_daemon_msg "Restarting OpenBSD Secure Shell server" "sshd"<br/>
set +e<br/>
start-stop-daemon --stop --quiet --retry 30 --pidfile /var/run/<strong>sshd_tunnel.pid</strong><br/>
RET="$?"<br/>
set -e<br/>
case $RET in<br/>
0)<br/>
# old daemon stopped<br/>
check_for_no_start log_end_msg<br/>
check_dev_null log_end_msg<br/>
if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/<strong>sshd_tunnel.pid</strong> --exec /usr/sbin/sshd -- $SSHD_OPTS; then<br/>
log_end_msg 0<br/>
else<br/>
log_end_msg 1<br/>
fi<br/>
;;<br/>
1)<br/>
# daemon not running<br/>
log_progress_msg "(not running)"<br/>
log_end_msg 0<br/>
;;<br/>
*)<br/>
# failed to stop<br/>
log_progress_msg "(failed to stop)"<br/>
log_end_msg 1<br/>
;;<br/>
esac<br/>
;;<br/>
<br/>
status)<br/>
status_of_proc -p /var/run/<strong>sshd_tunnel.pid</strong> /usr/sbin/sshd sshd && exit 0 || exit $?<br/>
;;<br/>
<br/>
*)<br/>
log_action_msg "Usage: /etc/init.d/<strong>ssh_tunne</strong>l {start|stop|reload|force-reload|restart|try-restart|status}"<br/>
exit 1<br/>
esac<br/>
<br/>
exit 0</p>
<p>Ce fichier est une copie du fichier /etc/init.d/ssh classique, mais modifié pour lancer le bon fichier de configuration et pour tourner en parallèle du serveur classique (notamment avec son propre pid)</p>
<p>Les parties modifiées sont en gras.</p>
<p>Enregistrez le fichier puis rendez-le exécutable.</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;">$ sudo chmod 755 /etc/init.d/ssh_tunnel</span></span></p>
<p>Si vous le souhaitez, vous pouvez configurer le tunnel pour se lancer au démarrage :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;">$ sudo update-rc.d ssh_tunnel defaults</span></span></p>
<h3 id="configuration-du-groupe-dutilisateur">Configuration du groupe d'utilisateur</h3>
<p>Nous allons ensuite créer le groupe tunnelssh, qui sera utilisé pour toutes les connexions.</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;">$ sudo groupadd tunnelssh</span></span></p>
<p>Il suffira ensuite de créer vos utilisateurs comme appartenant à ce groupe pour leur donner l'autorisation de se connecter au tunnel. Nous allons voir un script permettant de faire ça tout seul. :-)</p>
<h3 id="configuration-du-shell">Configuration du shell</h3>
<p>Afin que vos utilisateurs ne puissent pas se balader dans votre serveur via l'accès SSH du tunnel, nous allons créer un shell bidon. Cela permettra en plus d'afficher une jolie bannière pour l'utilisation du tunnel.</p>
<p>En avant. Créez un fichier dans /usr/bin :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;">$ sudo nano /usr/bin/tunnelshell</span></span></p>
<p>Qui contient quelque chose dans ce genre là :</p>
<p style="margin-left: 40px;">#!/bin/bash<br/>
echo "Connexion limitée au tunnel SSH."<br/>
read -p "Appuyez sur ENTREE pour vous déconnecter..."</p>
<p>Ainsi, toute personne se connectant sur votre tunnel verra apparaître ce message :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;">Connexion limitée au tunnel SSH.</span></span></p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;">Appuyez sur ENTREE pour vous déconnecter...</span></span></p>
<p>Comme indiqué, une pression de la touche entrée provoque la déconnexion immédiate du tunnel.<br/>
Vous êtes bien sûr libre de changer le message ! ;-)</p>
<h3 id="on-y-est">On y est !</h3>
<p>A ce stade, votre tunnel ssh est prêt à être utilisé. Il suffit de créer un utilisateur appartenant au groupe tunnelssh, de lui configurer comme shell /usr/bin/tunnelshell, puis de lui créer son couple clef/mot de passe.</p>
<p>Comme je suis super sympa (mouahahah), je vous propose un petit script qui fait tout ça tout seul.</p>
<p>Je vous conseille de le placer dans le dossier /root, ou à défaut dans un dossier à accès limité, puisqu'il contiendra tous les certificats de tous vos utilisateurs.</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;">$ sudo mkdir /root/tunnelSSH</span></span></p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;">$ sudo nano /root/tunnelSSH/Addsshtunneluser.sh</span></span></p>
<p>Dans celui-ci, vous pouvez mettre : </p>
<p style="margin-left: 40px;">#!/bin/bash<br/>
<br/>
if [ "$1" = "" ]; then<br/>
echo "Usage : Addsshtunneluser.sh name passphrase<br/>
fi<br/>
<br/>
if [ "$2" = "" ]; then<br/>
echo "Usage : Addsshtunneluser.sh name passphrase<br/>
fi<br/>
<br/>
mkdir /home/$1<br/>
mkdir /home/$1/.ssh<br/>
useradd $1 --home-dir /home/$1 --groups tunnelssh --no-user-group --shell /usr/bin/tunnelshell<br/>
ssh-keygen -t dsa -b 1024 -N $2 -f /home/$1/.ssh/id_dsa<br/>
cp /home/$1/.ssh/id_dsa.pub /home/$1/.ssh/authorized_keys<br/>
chmod 700 /home/$1/.ssh<br/>
chmod 600 /home/$1/.ssh/authorized_keys<br/>
chown -R $1:tunnelssh /home/$1<br/>
cp /home/$1/.ssh/id_dsa tunnelssh-$1</p>
<p>Ce script s'exécute de la manière suivante :</p>
<p><span style="color:#ffffff;"><span style="background-color:#000000;">$ sudo bash /root/tunnelSSH/Addsshtunneluser.sh UTILISATEUR MOTDEPASSE</span></span></p>
<ul>
<li>UTILISATEUR est le nom du nouvel utilisateur à créer</li>
<li>MOTDEPASSE est le mot de passe à donner à l'utilisateur</li>
</ul>
<p>Le script va alors créer un utilisateur portant ce nom. L'utilisateur appartiendra au groupe tunnelssh, et disposera de son répertorie /home/UTILISATEUR</p>
<p>Le script va ensuite créer la clef SSH à l'aide du MOTDEPASSE (on parle bien sûr d'un couple clef privée/clef publique). Il va ensuite copier la dite clef dans le dossier /root/tunnelSSH/ avec un nom du type tunnelssh-UTILISATEUR, ce qui va vous permettre de la récupérer facilement pour la transmettre à l'utilisateur concerné.</p>
<p>Il lui faudra alors utiliser cette clef pour configurer son tunnel ssh de la manière suivante :</p>
<ul>
<li>Adresse : l'adresse IP ou FQDN de votre serveur</li>
<li>Port : le port d'écoute de votre tunnel (ici 443)</li>
<li>Utilisateur : son nom d'utilisateur</li>
<li>Connexion par clef : avec la clef que vous lui avez transmis ainsi que le mot de passe associé</li>
</ul>
<p>Normalement, tout doit baigner !</p>
<h2 id="voila-cest-creuse">Voila, c'est creusé</h2>
<p>Avec tout ça, vous devriez être à même de vous connecter depuis n'importe où sur votre serveur.</p>
<p>A titre informatif, pour mettre en place le tunnel côté client :</p>
<ul>
<li>Windows : utilisez <a href="http://www.putty.org/">Putty</a> (allié à PuttyGen pour transformer votre clef en format Putty)</li>
<li>Linux/MacOSX : utilisez simplement openssh :-)</li>
<li>Android : utilisez <a href="https://play.google.com/store/apps/details?id=org.connectbot">ConnectBot</a></li>
<li>iPhone : Payez... Mais vous l'avez choisi avec un tel téléphone !</li>
</ul>
<p>Si jamais j'ai des demandes, je me lancerai dans un petit tuto pour l'une ou l'autre des plateformes :-)</p>
<p>Si vous avez des soucis, posez la question dans les commentaires !</p>Le concept du cluster2013-01-16T19:00:00+01:002013-01-16T19:00:00+01:00Victortag:blog.victor-hery.com,2013-01-16:/2013/01/cluster-proxmox-distant-1.4-concept.html
<h2 id="commencons-par-le-debut">Commençons par le début</h2>
<p>Oui, car ça fait un petit moment que je souhaite écrire une série d'articles sur Proxmox, articles présentant la mise en place de A à Z d'un <a href="http://fr.wikipedia.org/wiki/Grappe_de_serveurs">cluster</a>.</p>
<p>En effet, Proxmox depuis sa version 2 propose un système de clustering basé sur Red Hat, qui présente …</p>
<h2 id="commencons-par-le-debut">Commençons par le début</h2>
<p>Oui, car ça fait un petit moment que je souhaite écrire une série d'articles sur Proxmox, articles présentant la mise en place de A à Z d'un <a href="http://fr.wikipedia.org/wiki/Grappe_de_serveurs">cluster</a>.</p>
<p>En effet, Proxmox depuis sa version 2 propose un système de clustering basé sur Red Hat, qui présente un potentiel très intéressant de fonctionnalités pour parvenir à un système très stable.</p>
<p>Accessoirement, ça présente également un potentiel de problèmes clairement non négligeables. Mais bon.</p>
<p>Dans cette série d'articles, je vais donc tâcher de présenter sous le biais de tutoriel, la mise en place d'un tel cluster. Cependant, comme il est difficile de couvrir tous les cas possibles, je vais me permettre de me placer dans un cas précis et défini, adaptable et qui correspond à une problématique assez difficile.</p>
<p><strong>L'idée va être de configurer 3 serveurs distants géographiquement en cluster proxmox, avec un système de haute disponibilité.</strong></p>
<p>Dans ce premier article, je vais donc présenter la problématique du système, ainsi que le vocabulaire et les concepts importants à comprendre et à retenir. Les prochains articles seront plus techniques, promis !</p>
<p>Néanmoins, je partirais du principe que vous avez déjà une petite expérience de Proxmox (au moins savoir l'installer !), et que vous maitrisez SSH tout en ayant des bases de réseaux. J'essaierai quand même de rendre le plus compréhensible possible les problématiques techniques !</p>
<p>Je m'excuse d'avance pour la longueur des articles, mais la réalisation est quand même assez complexe ;-)</p>
<p>Pour ces articles, je m'appuie principalement sur les 3 liens suivants (merci beaucoup à eux pour leur travail !)</p>
<ul>
<li>Blog du développeur neurasthénique; <a href="http://blog.developpeur-neurasthenique.fr/auto-hebergement-configurer-un-cluster-proxmox-2-sans-multicast.html">cluster proxmox via OpenVPN</a></li>
<li>NedProduction : <a href="http://www.nedproductions.biz/wiki/configuring-a-proxmox-ve-2.x-cluster-running-over-an-openvpn-intranet">Configuring a Proxmox VE 2.x cluster running over an OpenVPN intranet</a> (notamment la partie 3)</li>
<li><a href="https://alteeve.ca/w/2-Node_Red_Hat_KVM_Cluster_Tutorial">Red Hat cluster tutorial</a> (extrêmement complet si vous lisez l'anglais. Une mine !)</li>
</ul>
<p>Je me suis également servi du <a href="http://forum.proxmox.com/forum.php">forum</a> et du <a href="http://pve.proxmox.com/wiki/Main_Page">wiki</a> proxmox.</p>
<h2 id="vocabulaire">Vocabulaire</h2>
<ul>
<li><a href="http://fr.wikipedia.org/wiki/Grappe_de_serveurs">Cluster</a> : comme le dit wikipédia, un cluster est un ensemble de serveurs regroupés artificiellement ensemble pour permettre la gestion globale de ceux-ci, et éventuellement la mise en place d'un système de haute disponibilité.</li>
<li>Node : une node est le nom donné à un serveur à l'intérieur d'un cluster. Un cluster est constitué de nodes, indépendantes ou non les unes des autres.</li>
<li><a href="http://fr.wikipedia.org/wiki/Haute_disponibilité">Haute disponibilité</a> : la haute disponibilité (High Availability, ou HA en anglais) consiste à assurer un service continu à vos utilisateurs/clients, même en cas de panne matérielle. Cela devient une vraie problématique dans les systèmes informatiques actuels, ou la simple indisponibilité pendant quelques heures d'un site web (le temps de changer un disque dur défectueux par exemple), peut rapidement se chiffrer en pertes financières importantes. La haute disponibilité permet donc de détecter automatiquement une panne et d'y réagir rapidement pour proposer une continuité de service. Cette continuité de service peut éventuellement être dépréciée, selon les standards recherchés. Par exemple le site web accessible, mais la plate-forme de paiement en ligne coupée temporairement.</li>
<li><a href="http://fr.wikipedia.org/wiki/Plan_de_reprise_d'activité">Plan de Reprise d'Activité</a> : Le Plan de Reprise d'Activité (PRA) est la procédure mise en place justement pour permettre une continuité de service. Cette procédure doit donc permettre de remettre en route tout ou partie des services en cas de panne du service principal, dans un délai prévu d'avance. Le PRA doit faire l'objet de tests réguliers et être bien assimilé par tout le monde, notamment dans le cas où les services remontés en cas de panne sont dépréciés. Le PRA peut également être le nom donné affectueusement au(x) serveur(s) qui servent à remonter les services :-)</li>
<li><br/>
Sauvegardes : les sauvegardes consistent à garder une trace régulièrement des machines virtuelles ou des dossiers importants sur un serveur. Elles font en général partie intégrante d'un PRA, et elles doivent être gardées dans différents endroits physiques pour pallier à tout risque de perte en cas d'incendie ou autre problème grave. <strong>Attention, mettre en place un système de HA ne doit pas dispenser de faire des sauvegardes !</strong></li>
<li><a href="http://fr.wikipedia.org/wiki/Quorum">Quorum</a> : le quorum est un concept assez difficile à appréhender, et pourtant il est absolument nécessaire à comprendre pour travailler sur un cluster en HA. Je vais donc m'arrêter un peu dessus pour expliquer le principe. D'après la page wikipédia, un quorum est le nombre minimal de personnes nécessaires pour prendre une décision dans un groupe. C'est un terme utilisé en droit habituellement, et un quorum représente en général la majorité, si tout le monde vote pour une voix. En informatique, le quorum est le nombre minimal de <em>votes</em> à atteindre pour prendre une décision <em>automatiquement</em>, comprendre sans intervention humaine.</li>
</ul>
<p style="margin-left: 40px;">Dans le cas d'un cluster, on peut donner à chaque serveur du cluster un poids différent ou identique, qui va influencer sur les choix que va prendre l'intelligence du cluster en cas de besoin. Par exemple, tous les serveurs ont un poids de un. S'il y a 5 serveurs, le quorum va être de 3. Il faut être au moins 3 pour prendre une décision. Dans ce cas, en cas de panne par exemple sur la liaison réseau entre les serveurs, ceux-ci prendront des décisions en fonction de leur quorum. Prenons un exemple :</p>
<p style="margin-left: 40px;">Nous avons 5 serveurs, montés en HA, avec un poids de 1 chacun. Une panne réseau survient, qui isole 3 serveurs d'un côté et 2 de l'autre. Chaque serveur va vérifier la connectivité avec les autres. Les serveurs ayant le quorum (le groupe de 3), se trouvant en majorité, peuvent prendre la décision de démarrer chez eux les services précédemment hébergés chez les 2 serveurs manquants. Les serveurs n'ayant plus le quorum (le groupe de 2) vont par contre décider qu'ils ne sont plus en majorité, et donc déduire que d'autres ayant le quorum vont prendre leur place. Ils vont donc prendre la décision de couper leurs services, voire de s'éteindre en attendant une intervention extérieure.</p>
<p style="margin-left: 40px;">Ce système permet d'éviter que des services tournent en même temps à deux endroits différents. Imaginez par exemple que la connexion entre les 2 groupes saute, mais que la connectivité Internet de chaque groupe fonctionne encore. Sans quorum, alors les utilisateurs seraient dirigés sur le site web de gauche ou de droite, rendant ingérable la restauration. En effet, si le site est un forum, alors les utilisateurs ont postés des messages à droite ET à gauche, il faudrait donc les fusionner pour revenir à un état stable sans perdre de données ! C'est un casse-tête qui a été réglé par la notion de Quorum.</p>
<p style="margin-left: 40px;">Bien sûr, ce système n'est pas parfait. Pour reprendre notre exemple, si le problème de connectivité fait que nous avons deux groupes de 2 serveurs et un groupe de 1, aucun des groupes n'a le quorum et tous risquent de s'éteindre. De la même façon, si nous avons un nombre pair de serveurs (Par exemple 4), le quorum est exactement la moitié, ce qui fait qu'en cas de répartition égale des groupes de serveurs, chacun va décider de démarrer les services de l'autre groupe !</p>
<p style="margin-left: 40px;">En conséquence, il est très important de bien comprendre cette notion. Dans l'idéal, vous devez <strong>toujours</strong> monter des clusters avec un nombre impair de serveurs, quitte à ce que l'un deux soit juste une machine virtuelle dans un coin servant 'd'arbitre'. Monter un cluster pair est possible, mais vous acceptez alors le risque de créer des situations qui seront difficilement gérables.</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Fencing_(computing)">Fencing</a> : le fencing n'a pas vraiment d'équivalent en français. C'est une notion liée à la haute disponibilité de la même façon que le quorum, et qui sert principalement à éviter des situations où les services tournent sur deux parties du cluster indépendantes. Le fencing consiste à pouvoir isoler chaque node du cluster pour être sûr qu'elle ne reviendra pas inopinément.</li>
</ul>
<p style="margin-left: 40px;">Par exemple, si un serveur redémarre par accident, le cluster se voyant en majorité va démarrer les services de la node défaillante. Sauf que une fois la node redémarrée, elle va rentrer de nouveau dans le cluster, donc avoir la majorité, et donc décider de lancer ses services. Ce qui va provoquer de nouveau une situation de doublon.</p>
<p style="margin-left: 40px;">Le rôle du fencing est donc d'autoriser le groupe du cluster ayant le quorum (ayant la majorité) à isoler artificiellement la ou les nodes défaillantes. Cela peut se faire en coupant le courant de la node (via un onduleur pilotable en réseau, via une carte DRAC ou ILO, ...), en coupant son réseau (via un switch manageable), en lui envoyant en boucle des ordres d'exctinction en ssh, ... Plusieurs techniques sont disponibles. Ce concept est important, et en général le plus compliqué et le plus lourd à mettre en place techniquement. Accepter de s'en passer peut poser un certains nombre de problème à l'administrateur, nous en parlerons plus loin. Dans Proxmox, le système de HA ne fonctionne pas si le fencing n'est pas configuré correctement.</p>
<p>Globalement, le quorum sert à pallier à une panne <strong>sur la liaison</strong> entre les machines, alors que le fencing sert à pallier à une panne <strong>matérielle</strong> de la machine. Ces deux concepts fonctionnent donc côte à côte.</p>
<ul>
<li><a href="http://fr.wikipedia.org/wiki/Fail_over">Fail-over</a> : le principe du Fail-Over s'applique en majorité aux adresses IP publiques d'un serveur (parfois à son adresse MAC). Le principe d'IP fail-over est que dans le cas où un de vos serveurs tombe en panne, votre hébergeur est capable de router votre IP vers un nouveau serveur. Techniquement, chacun des serveurs est une copie de l'autre, et chacun des serveurs porte l'IP publique. Cependant, un seul des serveurs est joignable à un instant T, ce qui permet de manière bien pratique de ne pas avoir à changer tous les enregistrements DNS en cas de panne du serveur principal (les DNS pouvant mettre jusqu'à 48h à se rafraichir, on imagine bien qu'une telle technique est utile pour éviter que son site soit innacessible pendant 2 jours).</li>
</ul>
<p>Voila pour le vocabulaire. Si d'autres mots vous posent problèmes durant la lecture d'un des articles, indiquez le dans les commentaires, je le rajouterai ici.</p>
<p> </p>
<h2 id="problematique">Problématique</h2>
<p>Dans le cadre de la mise en place d'un <a href="http://fr.wikipedia.org/wiki/Grappe_de_serveurs">cluster</a>, le principe basique consiste à mettre plusieurs serveurs identiques dans une baie, et à se servir d'eux pour augmenter la disponibilité de ceux-ci.</p>
<p>Par exemple, vous avez 3 serveurs, si l'un d'eux tombe, vous basculez tous ses services quasiment instantanément sur les deux autres, vous permettant d'avoir une disponibilité des services continue, même en cas de panne matérielle.</p>
<p>De plus le cluster vous permet de gérer, depuis une seule interface, tous vos serveurs.</p>
<p>C'est ce que propose Proxmox V2. En montant différents serveurs en cluster, vous pouvez en vous connectant à l'interface web de n'importe quel serveur créer des machines virtuelles sur le serveur de votre choix, gérer les sauvegardes de manière globale, créer des droits d'accès, bref, faire tout ce qui est possible d'habitude, mais sur tous vos serveurs d'un coup !</p>
<p>En fait, la vraie problématique qui se pose est la suivante :</p>
<p><strong>Quid si vous voulez également une redondance géographique ?</strong></p>
<p>Là, ça devient plus compliqué. Se posent directement les problèmes de communication entre les serveurs (qui doit être sécurisée !), le temps de basculement en cas de panne (qui doit être réduit, sinon sans intérêt), la détection de panne, le basculement des IP publiques, la gestion des serveurs qui ne sont pas identiques, etc, etc.</p>
<p>Rare sont les hébergeurs (en fait, inexistant à moins de payer 3 bras par mois, et encore) qui proposent ce genre de service, à savoir notamment une communication cryptée et des serveurs identiques dans deux lieux géographiquement redondés. A la rigueur, dans deux salles différentes ça peut être possible, et vous leur déléguez tout l'aspect sécurité/redondance/basculement, en leur faisant confiance. (Voir cet <a href="http://blog.héry.com/article12/on-rale-marre-du-filtrage-securite-des-hebergeurs">article</a>...)</p>
<p>Bon, la question ne se pose pas, je voulais tout faire moi-même, pour la gloire (et aussi pour mon porte monnaie, et également avoir une redondance de fournisseur, ça mange pas de pain).</p>
<h2 id="architecture">Architecture</h2>
<p>Mon système de serveur est assez simple. Je dispose d'un serveur principal, assez costaud, permettant de faire tourner la majorité des services. Certains de ces services sont importants et devront donc faire partie du HA. D'autres le sont moins et il est acceptable de s'en passer en cas de panne matérielle</p>
<p>En secours, je dispose également d'un deuxième serveur, chez un hébergeur différent, bien moins costaud mais à même de faire tourner les quelques services importants dans un mode déprécié.</p>
<p>Ces deux serveurs n'ont aucune liaison locale (étant chez deux hébergeurs différents), présentent des composants matériels différents (ils ne sont pas identiques) et dont donc placés à des endroits géographiquement différents, dans des réseaux différents. Ils ont également leurs propres IP publiques chez chacun des hébergeurs, rendant tout fail over impossible.</p>
<p>Chacun de ces serveurs utilise Proxmox comme système d'exploitation, et tous ces fameux services sont en fait placés dans des machines virtuelles, l'hyperviseur assurant un service minimum (en gros du routage et du NAT).</p>
<p>L'idée va donc consister à mettre en place un système de haute disponibilité pour les services souhaités, entre les deux serveurs, afin qu'une panne du serveur principal ne soit pas handicapante.</p>
<h3 id="quorum">Quorum</h3>
<p>Comme il est important de disposer d'un nombre impair de nodes pour permettre le fonctionnement du quorum, je rajoute à cette infrastructure un troisième serveur, qui n'héberge aucun service et sert uniquement d'arbitre. En fait, c'est une simple machine virtuelle avec Proxmox d'installé, hébergée chez moi.</p>
<h3 id="fencing">Fencing</h3>
<p>Malheureusement, peu d'hébergeurs proposent un système permettant la mise un place d'un fencing. Encore moins à travers Internet. J'ai donc du choisir de me passer de fencing. <strong>Ceci est un choix qui vous attirera les foudres de la communauté Proxmox/Red Hat, et qui risque de transformer toutes vos demandes sur les forums officiels en chasse à l'homme. J'en ai pleinement conscience.</strong> Cependant, la problématique technique imposée ne me laisse pas d'autres choix. Je proposerai donc dans ces articles un moyen de "tromper" le fencing pour permettre le bon fonctionnement du HA.</p>
<p>Il est important de comprendre que c'est un choix qui peut amener un certain nombres de problématiques techniques importantes, notamment pour remonter les services après une panne. Cependant, rien d'insurmontable. Mais c'est quand même très moche. Nécessité fait loi...</p>
<h3 id="multicast">Multicast</h3>
<p>Le système de cluster Proxmox nécessite une liaison multicast entre toutes les nodes. En effet, le cluster communique via ce biais entre les différentes nodes. Ce système présente l'avantage de supprimer la notion de maître/esclave présent dans Proxmox v1.X, mais est une problématique importante dans le sens qu'AUCUN réseau public n'autorise le multicast. Et surtout pas le réseau Internet.</p>
<p>Pour résoudre ce problème, j'utilise une liaison OpenVPN entre les nodes, et le cluster est construit via ce tunnel. Cela présente le double avantage de permettre facilement le Multicast sur Internet et de crypter la communication entre les nodes.</p>
<p>Cela présente le double inconvénient de remettre en place une notion de maitre/esclave (il faut un serveur VPN et des clients qui s'y connectent) et de rajouter un point de panne dans le système (si OpenVPN tombe, tout le cluster tombe). Nous verrons comment limiter ces deux problèmes.</p>
<h3 id="disque-commun-et-replication">Disque commun et réplication</h3>
<p>Un autre point important dans un cluster HA est que les services HA doivent être répliqués. En effet, si vous voulez que votre serveur de secours puisse redémarrer les machines virtuelles en cas de panne du serveur principal, et bien il faut qu'il ait les données de ces machines à disposition. De plus dans un système HA, ces données doivent être temporellement les plus proches possibles entre le serveur principal et son serveur de secours, sinon vous risquez de perdre pas mal de données lors du démarrage du serveur de secours.</p>
<p>Comme il est couteux d'avoir à disposition un disque réseau supplémentaire à partager entre les serveurs (et qu'il est de plus impossible de le faire via Internet entre deux hébergeurs différents), j'ai fait le choix d'utiliser <a href="http://fr.wikipedia.org/wiki/DRBD">DRBD</a>, un système permettant de mettre en place un RAID 1 via un réseau. Chaque action faite sur le disque du serveur principal est donc immédiatement répliquée sur le serveur de secours.</p>
<p>Ce système est plutôt robuste, mais est dépendant de la connexion entre vos serveurs. Plus votre liaison sera lente, plus le serveur de secours sera en retard par rapport au serveur principal, ce qui pose notamment problème dans le cas de base de données SQL. Cependant, la latence est minimale dans le cas d'hébergement proposant souvent au minimum 100Mo/s de bande passante.</p>
<p>Sachez tout de même qu'être trop grourmand sur le nombre de services répliqués peut entrainer des lenteurs sur vos machines virtuelles, le disque DRBD pouvant mettre en pause certains processus le temps d'écrire toutes ces données (Comme un disque classique d'ailleurs, bienvenue dans le monde des <a href="http://blog.developpeur-neurasthenique.fr/auto-hebergement-iowait-ma-tuer-1-2-vmstat-mpstat-atop-pidstat.html">I/O Wait</a>)</p>
<p>La synchronisation DRBD se fait via le tunnel Openvpn de la même façon que la communication inter-cluster.</p>
<p>Pour ma part, avec une base de données accessible à plusieurs dizaines d'utilisateurs plus une dizaine de serveurs écrivant leurs logs, je n'ai pas eu de soucis à ce niveau-là.</p>
<p><strong>Edit : Attention, et c'est une contrainte importante, utiliser DRBD impose d'avoir des KVM comme uniques machines virtuelles HA. Je n'ai pas réussi à avoir de manière satisfaisante de l'OpenVZ sur du DRBD.</strong> Il reste possible d'utiliser OpenVZ pour toutes vos autres machines non HA.</p>
<h3 id="terminologie">Terminologie</h3>
<p>Pour simplifier la suite, j'utiliserai les terminologies suivantes :</p>
<ul>
<li>Serveur principal : <strong>Serveur principal</strong></li>
<li>Serveur de secours : <strong>PRA</strong></li>
<li>Serveur "Arbitre" : <strong>Arbitre</strong></li>
<li>Haute Disponiblité : <strong>HA</strong></li>
</ul>
<h3 id="schema">Schéma</h3>
<p>Parce que c'est toujours plus visible sur un bô schéma :)</p>
<p><img alt="Schema infrastructure HA" src="/images/schemaHA%281%29.png" style="width: 612px; height: 353px;"/></p>
<p>Le PRA fera serveur VPN principal, pour une raison simple : c'est lui qui est sensé tourner en permanence.</p>
<ol>
<li>Si le serveur principal tombe, l'arbitre sera connecté en VPN sur le serveur de secours, qui aura donc le quorum immédiatement et pourra lancer le mode de secours</li>
<li>Si l'arbitre tombe, le serveur principal aura le quorum (étant connecté au PRA), les services tourneront donc normalement</li>
<li>Si le PRA tombe, le serveur principal devient serveur VPN secondaire. Le système de backup OpenVPN fait que l'arbitre revient se connecter sur lui plutôt rapidement. Le serveur principal retrouve donc le quorum rapidement et les services tournent normalement</li>
</ol>
<p> </p>
<h2 id="bon-on-commence-quand">Bon, on commence quand ?</h2>
<p>Et bien voila, je crois avoir fait le tour de présentation du système que je vais vous apprendre à monter.</p>
<p>Les tutoriels suivants expliqueront comment mettre en place le cluster via OpenVPN, comment monter la réplication DRBD et comment mettre en place le HA en lui-même.</p>
<p>Normalement, tout cela devrait tenir en 4 articles.</p>
<p>Si vous avez des questions sur ce concept ou avez besoin de détails, n'hésitez pas à me laisser un commentaire !</p>
<p> </p>
<p>EDIT : un petit sommaire pour avoir une idée de ce que devrait parler les prochaines articles</p>
<ul>
<li>1/4 : Le concept, que vous venez de lire</li>
<li><a href="http://blog.héry.com/article6/cluster-proxmox-distant-construction-du-cluster-openvpn">2/4 : Construction du cluster (openvpn), où on parlera installation, OpenVPN, personnalisation des serveurs et sécurité</a></li>
<li>3/4 : Réplication disque (DRBD), où on parlera de l'installation de DRBD et des diverses configurations qui en découlent</li>
<li>4/4 : Haute Disponibilité (HA), où on parlera de la configuration du HA, sa mise en place, sa gestion et l'ajout de VM à l'intérieur (fencing, cluster.conf, ...)</li>
</ul>
<p>A bientôt :-)</p>Configurer un reverse proxy Apache2012-10-16T20:06:00+02:002012-10-16T20:06:00+02:00Victortag:blog.victor-hery.com,2012-10-16:/2012/10/configurer-reverse-proxy-apache.html
<h2 id="ou-routage-entre-serveurs-par-nom-de-domaine">Ou : routage entre serveurs par nom de domaine</h2>
<p>Et oui, c'est ce dont on va parler ici. Comme ce n'est peut être pas très clair pour tout le monde, je vais me permettre une toute petite digression pour expliquer ce qu'est le routage, et plus précisément ce que j'appelle le …</p>
<h2 id="ou-routage-entre-serveurs-par-nom-de-domaine">Ou : routage entre serveurs par nom de domaine</h2>
<p>Et oui, c'est ce dont on va parler ici. Comme ce n'est peut être pas très clair pour tout le monde, je vais me permettre une toute petite digression pour expliquer ce qu'est le routage, et plus précisément ce que j'appelle le routage par noms de domaine.</p>
<h2 id="merci-pour-cette-digression">Merci pour cette digression.</h2>
<p>Mais de rien.</p>
<p>Qu'est ce que le <a href="http://fr.wikipedia.org/wiki/Routage">routage</a> ? Ca consiste à se servir d'une unique machine (comunément appelée "le routeur") pour diriger des flux réseau vers différents autres matériels.</p>
<p>Ca sert le plus simplement du monde sur Internet, pour router les différents sous réseaux. Vous voulez joindre truc.truc.truc.truc, mais vous avez comme IP machin.machin.machin.machin, alors un routeur va pouvoir vous dire :</p>
<p>"Pour aller vers truc, c'est à gauche, mais si c'est pour aller vers bidule, c'est à droite. Quand à toi machin, tu es au milieu".</p>
<p>Ok, c'est résumé très vite pour les puristes, mais l'idée est là :-)</p>
<p>Il existe différents autres types de routage. On utilise ce terme parce que l'idée de donner des routes (ou des chemins) pour diriger des flux reste la même.</p>
<p>Une machine (routeur, PC, serveur, ...) reçoit un flux, et à partir de différents critères choisit de rediriger ce flux vers un autre matériel du réseau, l'objectif final étant bien sûr que ce flux arrive à destination de manière sûre.</p>
<h2 id="ca-suffit-oui">Ca suffit oui ?</h2>
<p>On y arrive. ;-)</p>
<p><strong>EDIT décembre 2015 : </strong>j'ai écris un <a href="/2015/12/configurer-reverse-proxy-haproxy.html">nouvel article</a> pour utiliser haproxy en tant que reverse-proxy, logiciel plus léger et plus adapté qu'apache à cet usage.</p>
<p>Or donc, si vous avez plusieurs serveurs web mais une seule connexion Internet, alors vous avez sans doute déjà eu cette problématique.</p>
<p><em>Comment joindre plusieurs sites web sur différents serveurs depuis les Internet ?</em></p>
<p>La solution qui s'impose directement, c'est du routage de port.</p>
<p>Ce routage particulier consiste à router différents flux reçus depuis Internet vers des machines à l'intérieur de votre réseau local en se basant sur les ports réseaux utilisés. Ce n'est pas le lieu pour décrire un port réseau. Voyez ça comme une porte. Vous rentrez dans la même maison, mais selon que vous utilisiez la porte d'entrée ou la véranda, vous êtes "redirigés" vers une pièce différente de la maison.</p>
<p> </p>
<p>Ce type de routage présente un inconvénient certain : chacun de vos utilisateurs doit spécifier la porte qu'il veut utiliser pour joindre le bon serveur.</p>
<p>En général, ça consiste à taper <em>nomdedomaine.tld:port </em>dans votre navigateur, ce qui n'est pas très pratique, et difficile à expliquer à vos clients. (Et oubliez de suite expliquer ça à Google and co)</p>
<p>C'est là qu'intervient ce super outil, le <a href="http://fr.wikipedia.org/wiki/Reverse_proxy">reverse proxy, ou mandataire inverse</a>. Nous allons voir ici comment l'utiliser avec <a href="http://www.apache.org/">Apache</a>, un serveur web populaire. Il est sans doute possible de le faire également avec NGinX ou lightHTTPD, mais ce n'est pas le sujet :-D</p>
<p>Le mandataire inverse va regarder le site que vous voulez joindre, et vous rediriger vers le bon serveur directement. Il servira ensuite d'intermédiaire sur le réseau entre vous et le serveur.</p>
<h2 id="on-veut-du-concret">On veut du concret !</h2>
<p>Voila voila !</p>
<h3 id="pre-requis-materiel">Pré-requis matériel</h3>
<p>Pour commencer, il va falloir définir un serveur mandataire. C'est sur ce serveur que nous allons configurer le mandataire inverse.</p>
<p>Il peut héberger lui-même des sites Internet, ou vous pouvez l'utiliser uniquement comme mandataire, ça n'a pas d'importance. Si vous utilisez cette solution à des vues industrielles, mieux vaut prévoir un serveur robuste, puisqu'il supportera toutes les requêtes vers tous vos sites web.</p>
<p>Ensuite, il vous faut configurer votre routeur/machinbox© pour rediriger tout le flux web (port 80) vers le serveur mandataire. Ceci se fait grâce à un routage de port classique. Toutes les requêtes web arriveront maintenant sur ce serveur, qui va décider quoi en faire.</p>
<p>En théorie on devrait pouvoir faire la même chose pour l'HTTPS, mais vu qu'il y a quand même des contraintes de certificats et que je n'ai pas testé, je préfère ne pas dire de bêtises ici.</p>
<h3 id="prerequis-logiciel">Prérequis logiciel</h3>
<p>Là, c'est simple. Il vous faut un serveur Apache installé et fonctionnel sur votre serveur mandataire. C'est tout. Un système de pare-feu ne serait également pas de trop (ce serveur est l'unique point d'entrée d'Internet, rappelons le :-) )</p>
<p>Il vous faut également (bien evidemment ?) une connexion ssh vers votre serveur, ou à défaut un écran-clavier-souris.</p>
<h2 id="plongeons-dans-le-cambouis">Plongeons dans le cambouis</h2>
<h3 id="activation-du-module-proxy-apache">Activation du module proxy Apache</h3>
<p>Connectez vous sur votre serveur (mandataire), puis tapez :</p>
<div class="highlight"><pre><span></span><code>$ sudo a2enmod proxy
$ sudo a2enmod proxy_http
</code></pre></div>
<p> </p>
<p>Redémarrez ensuite Apache un petit coup</p>
<div class="highlight"><pre><span></span><code><span class="err">$sudo /etc/init.d/apache restart</span>
</code></pre></div>
<p> </p>
<p>Voila, c'est fait !</p>
<h3 id="configuration-du-routage">Configuration du routage</h3>
<p>Ici, tout va se faire grâce au système d'hôte virtuel Apache.</p>
<p>Editez un fichier dans /etc/apache2/site-available/</p>
<div class="highlight"><pre><span></span><code>$ sudo nano /etc/apache2/sites-available/monsite
</code></pre></div>
<p> </p>
<p>Puis configurez votre hôte comme suit :</p>
<div class="highlight"><pre><span></span><code><span class="nt"><VirtualHost</span> <span class="err">*:80</span><span class="nt">></span>
#
ServerName nomdedomaine.tld #
ProxyPreserveHost On
ProxyRequests off
ProxyPass / http://IPSERVEURWEBINTERNE/
ProxyPassReverse / http://IPSERVEURWEBINTERNE/
#
<span class="nt"></VirtualHost></span>
</code></pre></div>
<p> </p>
<p>Cela va permettre de rediriger toutes les requêtes sur nomdedomaine.tld en http vers le serveur IPSERVEURWEBINTERNE</p>
<p> </p>
<p>C'est simple et efficace. Vous pouvez créer toutes vos autres redirections dans ce fichier, ou créer un fichier par redirection (plus propre mais plus contraignant). A vous de voir.</p>
<p>Une fois ces fichier créés, il vous faut activer les hôtes virtuels.</p>
<p>Faites</p>
<div class="highlight"><pre><span></span><code>$ sudo a2ensite monsite
</code></pre></div>
<p>pour chaque fichier que vous avez créé.</p>
<p> </p>
<p>Ensuite, rechargez la configuration Apache (pas besoin de redémarrer)</p>
<div class="highlight"><pre><span></span><code>$ sudo /etc/init.d/apache2 reload
</code></pre></div>
<p> </p>
<h2 id="tadam">Tadam !</h2>
<p>Il ne vous reste plus qu'à tester. De l'exterieur, essayez de joindre nomdedomaine.tld, tout doit fonctionner :-)</p>
<p>Et voila, vous avez économisé plein d'adresses IP publiques ! Mais pourquoi utiliser plusieurs serveurs Web derrière une seule IP petits coquinous ? Ça, ça vous regarde...</p>
<p>Si jamais j'ai la problématique un jour, je configurerai ça pour de l'HTTPS (mais honnêtement j'espère jamais :-D )</p>
<p> </p>
<p><s>Et dans ce cas je rajouterai ça sur le blog, promis ! </s> Voir juste au dessous !</p>
<h2 id="edit-comme-promis-la-version-https">Edit : Comme promis, la version https</h2>
<p>Et oui, car finalement j'ai du m'y mettre :)</p>
<p>Tout d'abord, les limitations. Je n'ai réussit jusqu'alors qu'à configurer une connexion HTTPS entre le client et le reverse proxy.</p>
<p>Je n'ai pas réussit à avoir ensuite de l'HTTPS entre le reverse proxy et le vrai serveur web, ce qui veut dire que, au moins sur le réseau local, les données transitent en clair.</p>
<p>De mon point de vue ce n'est qu'un problème conceptuel, étant donné que le "réseau local" est en fait une liaison directe entre machines virtuelles sur le même hyperviseur, donc bon. Mais quand même, ce n'est pas très propre. Si jamais quelqu'un a une suggestion à ce sujet, qu'il me fasse signe :)</p>
<p> </p>
<p>L'idée donc du reverse proxy en HTTPS, c'est que c'est le proxy qui va contenir les certificats https. Celui-ci va alors répondre à la place du serveur web, avec la bonne URL puique c'est un proxy, et transmettre ensuite les requêtes vers le serveur.</p>
<p>On a donc un schéma dans cette idée :</p>
<div class="highlight"><pre><span></span><code><span class="err"><Client>====https====<Proxy>----http----<serveur web></span>
</code></pre></div>
<p>Et en plus, c'est assez simple en fait.</p>
<p><strong>On considérera ici que vous avez déja généré des certificats propres pour votre site (éventuellement auto-signés).</strong></p>
<p>Il vous faudra activer le SSL sur votre reverse proxy : </p>
<div class="highlight"><pre><span></span><code>$ sudo a2enmod ssl
$ sudo /etc/init.d/apache2 restart
</code></pre></div>
<p>Ensuite, placez vos certificats (clef publique, clef privée) dans le dossier /etc/apache2/ssl/.</p>
<div class="highlight"><pre><span></span><code>$ sudo cp moncertificat.* /etc/apache2/ssl/
</code></pre></div>
<p>Créez l'hôte virtuel qui servira pour votre redirection :</p>
<div class="highlight"><pre><span></span><code><span class="err">sudo nano /etc/apache2/site-available/monproxySSL</span>
</code></pre></div>
<p>Et remplissez le avec ceci :</p>
<div class="highlight"><pre><span></span><code><span class="w"> </span><span class="o"><</span><span class="n">VirtualHost</span><span class="w"> </span><span class="o">*</span><span class="err">:</span><span class="mi">443</span><span class="o">></span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">Décommentez</span><span class="w"> </span><span class="n">cette</span><span class="w"> </span><span class="n">ligne</span><span class="w"> </span><span class="n">et</span><span class="w"> </span><span class="n">indiquez</span><span class="o">-</span><span class="n">y</span><span class="w"> </span><span class="n">l</span><span class="s1">'adresse courriel de l'</span><span class="n">administrateur</span><span class="w"> </span><span class="n">du</span><span class="w"> </span><span class="n">site</span><span class="w"></span>
<span class="w"> </span><span class="n">#ServerAdmin</span><span class="w"> </span><span class="n">webmaster</span><span class="nv">@my</span><span class="o">-</span><span class="k">domain</span><span class="p">.</span><span class="n">com</span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">Classique</span><span class="p">,</span><span class="w"> </span><span class="n">votre</span><span class="w"> </span><span class="n">nom</span><span class="w"> </span><span class="n">de</span><span class="w"> </span><span class="n">domaine</span><span class="w"></span>
<span class="w"> </span><span class="n">ServerName</span><span class="w"> </span><span class="n">monsite</span><span class="p">.</span><span class="n">tld</span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">Si</span><span class="w"> </span><span class="n">jamais</span><span class="w"> </span><span class="n">vous</span><span class="w"> </span><span class="n">avez</span><span class="w"> </span><span class="n">d</span><span class="s1">'autres domaines renvoyant sur ce site, utilisez la dircetive ServerAlias</span>
<span class="s1"> # Vous pouvez utiliser le joker * pour prendre en compte tout les sous-domaines</span>
<span class="s1"> #ServerAlias www2.my-domain.com www.my-other-domain.com *.yet-another-domain.com</span>
<span class="s1"> # L'</span><span class="n">emplacement</span><span class="w"> </span><span class="n">des</span><span class="w"> </span><span class="n">logs</span><span class="p">.</span><span class="w"></span>
<span class="w"> </span><span class="n">ErrorLog</span><span class="w"> </span><span class="o">/</span><span class="nf">var</span><span class="o">/</span><span class="nf">log</span><span class="o">/</span><span class="n">apache2</span><span class="o">/</span><span class="n">monsite</span><span class="p">.</span><span class="n">tld</span><span class="o">-</span><span class="n">error</span><span class="p">.</span><span class="nf">log</span><span class="w"></span>
<span class="w"> </span><span class="n">LogLevel</span><span class="w"> </span><span class="n">warn</span><span class="w"></span>
<span class="w"> </span><span class="n">CustomLog</span><span class="w"> </span><span class="o">/</span><span class="nf">var</span><span class="o">/</span><span class="nf">log</span><span class="o">/</span><span class="n">apache2</span><span class="o">/</span><span class="n">monsite</span><span class="p">.</span><span class="n">tld</span><span class="o">-</span><span class="n">access</span><span class="p">.</span><span class="nf">log</span><span class="w"> </span><span class="n">combined</span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">SSL</span><span class="w"> </span><span class="n">magic</span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">Il</span><span class="w"> </span><span class="n">est</span><span class="w"> </span><span class="n">nécessaire</span><span class="w"> </span><span class="n">d</span><span class="s1">'activer SSL, sinon c'</span><span class="n">est</span><span class="w"> </span><span class="n">http</span><span class="w"> </span><span class="n">qui</span><span class="w"> </span><span class="n">sera</span><span class="w"> </span><span class="n">utilisé</span><span class="w"></span>
<span class="w"> </span><span class="n">SSLEngine</span><span class="w"> </span><span class="k">On</span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="k">On</span><span class="w"> </span><span class="n">autorise</span><span class="w"> </span><span class="n">uniquement</span><span class="w"> </span><span class="n">les</span><span class="w"> </span><span class="n">clefs</span><span class="w"> </span><span class="n">de</span><span class="w"> </span><span class="n">cryptage</span><span class="w"> </span><span class="n">longue</span><span class="w"> </span><span class="p">(</span><span class="n">high</span><span class="p">)</span><span class="w"> </span><span class="n">et</span><span class="w"> </span><span class="n">moyenne</span><span class="w"> </span><span class="p">(</span><span class="n">medium</span><span class="p">)</span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">SSLCipherSuite</span><span class="w"> </span><span class="nl">HIGH</span><span class="p">:</span><span class="n">MEDIUM</span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="k">On</span><span class="w"> </span><span class="n">autorise</span><span class="w"> </span><span class="n">SSLV3</span><span class="w"> </span><span class="n">et</span><span class="w"> </span><span class="n">TLSv1</span><span class="p">,</span><span class="w"> </span><span class="k">on</span><span class="w"> </span><span class="n">rejette</span><span class="w"> </span><span class="n">le</span><span class="w"> </span><span class="n">vieux</span><span class="w"> </span><span class="n">SSLv2</span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">SSLProtocol</span><span class="w"> </span><span class="ow">all</span><span class="w"> </span><span class="o">-</span><span class="n">SSLv2</span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">La</span><span class="w"> </span><span class="n">clef</span><span class="w"> </span><span class="n">publique</span><span class="w"> </span><span class="n">du</span><span class="w"> </span><span class="n">serveur</span><span class="w"> </span><span class="err">:</span><span class="w"></span>
<span class="w"> </span><span class="n">SSLCertificateFile</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">apache2</span><span class="o">/</span><span class="n">ssl</span><span class="o">/</span><span class="n">moncertificat</span><span class="o">-</span><span class="n">cert</span><span class="p">.</span><span class="n">pem</span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">La</span><span class="w"> </span><span class="n">clef</span><span class="w"> </span><span class="n">privée</span><span class="w"> </span><span class="n">du</span><span class="w"> </span><span class="nl">serveur</span><span class="p">:</span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">SSLCertificateKeyFile</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">apache2</span><span class="o">/</span><span class="n">ssl</span><span class="o">/</span><span class="n">moncertificat</span><span class="o">-</span><span class="k">key</span><span class="p">.</span><span class="n">pem</span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">Theses</span><span class="w"> </span><span class="n">lines</span><span class="w"> </span><span class="k">only</span><span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">rewrite</span><span class="w"> </span><span class="k">module</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">enabled</span><span class="p">.</span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">This</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">security</span><span class="w"> </span><span class="n">enhancement</span><span class="w"> </span><span class="n">recommanded</span><span class="w"> </span><span class="k">by</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">nessus</span><span class="w"> </span><span class="n">tool</span><span class="p">.</span><span class="w"></span>
<span class="w"> </span><span class="o"><</span><span class="n">IfModule</span><span class="w"> </span><span class="n">mod_rewrite</span><span class="p">.</span><span class="n">c</span><span class="o">></span><span class="w"></span>
<span class="w"> </span><span class="n">RewriteEngine</span><span class="w"> </span><span class="k">on</span><span class="w"></span>
<span class="w"> </span><span class="n">RewriteCond</span><span class="w"> </span><span class="o">%</span><span class="err">{</span><span class="n">REQUEST_METHOD</span><span class="err">}</span><span class="w"> </span><span class="o">^</span><span class="p">(</span><span class="n">TRACE</span><span class="o">|</span><span class="n">TRACK</span><span class="p">)</span><span class="w"></span>
<span class="w"> </span><span class="n">RewriteRule</span><span class="w"> </span><span class="p">.</span><span class="o">*</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="o">[</span><span class="n">F</span><span class="o">]</span><span class="w"></span>
<span class="w"> </span><span class="o"></</span><span class="n">IfModule</span><span class="o">></span><span class="w"></span>
<span class="w"> </span><span class="o"><</span><span class="n">IfModule</span><span class="w"> </span><span class="n">mod_rewrite</span><span class="p">.</span><span class="n">c</span><span class="o">></span><span class="w"></span>
<span class="w"> </span><span class="o"><</span><span class="n">IfModule</span><span class="w"> </span><span class="n">mod_proxy</span><span class="p">.</span><span class="n">c</span><span class="o">></span><span class="w"></span>
<span class="w"> </span><span class="n">#Ne</span><span class="w"> </span><span class="n">commentez</span><span class="w"> </span><span class="n">jamais</span><span class="w"> </span><span class="n">cette</span><span class="w"> </span><span class="n">ligne</span><span class="p">,</span><span class="w"> </span><span class="n">elle</span><span class="w"> </span><span class="n">évite</span><span class="w"> </span><span class="n">que</span><span class="w"> </span><span class="n">votre</span><span class="w"> </span><span class="n">serveur</span><span class="w"> </span><span class="n">soit</span><span class="w"> </span><span class="n">utilisé</span><span class="w"> </span><span class="n">comme</span><span class="w"> </span><span class="n">proxy</span><span class="w"> </span><span class="n">par</span><span class="w"> </span><span class="n">des</span><span class="w"> </span><span class="n">gens</span><span class="w"> </span><span class="n">mal</span><span class="o">-</span><span class="n">intentionnés</span><span class="p">.</span><span class="w"></span>
<span class="w"> </span><span class="n">ProxyRequests</span><span class="w"> </span><span class="k">Off</span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">Cetet</span><span class="w"> </span><span class="k">option</span><span class="w"> </span><span class="n">passe</span><span class="w"> </span><span class="n">les</span><span class="w"> </span><span class="n">nom</span><span class="w"> </span><span class="n">d</span><span class="s1">'hôte au serveur, ce qui vous permet d'</span><span class="n">utiliser</span><span class="w"> </span><span class="n">également</span><span class="w"> </span><span class="n">des</span><span class="w"> </span><span class="n">hôtes</span><span class="w"> </span><span class="n">virtuels</span><span class="w"> </span><span class="n">sur</span><span class="w"> </span><span class="n">le</span><span class="w"> </span><span class="n">serveur</span><span class="w"> </span><span class="n">principal</span><span class="p">.</span><span class="w"></span>
<span class="w"> </span><span class="n">ProxyPreserveHost</span><span class="w"> </span><span class="k">On</span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">Les</span><span class="w"> </span><span class="n">lignes</span><span class="w"> </span><span class="n">classiques</span><span class="w"> </span><span class="n">de</span><span class="w"> </span><span class="n">proxy</span><span class="p">.</span><span class="w"> </span><span class="n">Comme</span><span class="w"> </span><span class="n">dit</span><span class="w"> </span><span class="n">au</span><span class="w"> </span><span class="n">dessus</span><span class="p">,</span><span class="w"> </span><span class="k">on</span><span class="w"> </span><span class="n">passe</span><span class="w"> </span><span class="n">le</span><span class="w"> </span><span class="n">flux</span><span class="w"> </span><span class="n">en</span><span class="w"> </span><span class="n">http</span><span class="p">.</span><span class="w"></span>
<span class="w"> </span><span class="n">ProxyPassReverse</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="n">IPSERVEURWEB</span><span class="o">/</span><span class="w"></span>
<span class="w"> </span><span class="n">RewriteRule</span><span class="w"> </span><span class="o">^/</span><span class="p">(.</span><span class="o">*</span><span class="p">)</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="n">IPSERVERUWEB</span><span class="o">/</span><span class="err">$</span><span class="mi">1</span><span class="w"> </span><span class="o">[</span><span class="n">P,L</span><span class="o">]</span><span class="w"></span>
<span class="w"> </span><span class="o"></</span><span class="n">IfModule</span><span class="o">&</span><span class="n">gt</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="o"></</span><span class="n">IfModule</span><span class="o">&</span><span class="n">gt</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">Autoriser</span><span class="w"> </span><span class="n">l</span><span class="s1">'accès au contenu à travers le proxy.</span>
<span class="s1"> #Ne l'</span><span class="n">enlevez</span><span class="w"> </span><span class="n">pas</span><span class="w"> </span><span class="n">si</span><span class="w"> </span><span class="n">vous</span><span class="w"> </span><span class="n">voulez</span><span class="w"> </span><span class="n">que</span><span class="w"> </span><span class="n">le</span><span class="w"> </span><span class="n">site</span><span class="w"> </span><span class="n">fonctionne</span><span class="w"> </span><span class="err">!</span><span class="w"></span>
<span class="w"> </span><span class="o"><</span><span class="n">Location</span><span class="w"> </span><span class="o">/&</span><span class="n">gt</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="k">Order</span><span class="w"> </span><span class="k">deny</span><span class="p">,</span><span class="n">allow</span><span class="w"></span>
<span class="w"> </span><span class="n">Allow</span><span class="w"> </span><span class="k">from</span><span class="w"> </span><span class="ow">all</span><span class="w"></span>
<span class="w"> </span><span class="o"></</span><span class="n">Location</span><span class="o">&</span><span class="n">gt</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="o"></</span><span class="n">VirtualHost</span><span class="o">&</span><span class="n">gt</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="o"><</span><span class="n">VirtualHost</span><span class="w"> </span><span class="o">*</span><span class="err">:</span><span class="mi">80</span><span class="o">&</span><span class="n">gt</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">Cette</span><span class="w"> </span><span class="n">partie</span><span class="w"> </span><span class="n">va</span><span class="w"> </span><span class="n">permettre</span><span class="w"> </span><span class="n">de</span><span class="w"> </span><span class="n">rediriger</span><span class="w"> </span><span class="n">d</span><span class="s1">'éventuelles requêtes en HTTP vers l'</span><span class="n">HTTPS</span><span class="w"></span>
<span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">Vous</span><span class="w"> </span><span class="n">pouvez</span><span class="w"> </span><span class="n">également</span><span class="w"> </span><span class="n">configurer</span><span class="w"> </span><span class="n">le</span><span class="w"> </span><span class="n">proxy</span><span class="w"> </span><span class="n">à</span><span class="w"> </span><span class="n">la</span><span class="w"> </span><span class="n">place</span><span class="w"> </span><span class="n">de</span><span class="w"> </span><span class="n">la</span><span class="w"> </span><span class="n">règle</span><span class="w"> </span><span class="n">de</span><span class="w"> </span><span class="n">réécriture</span><span class="w"> </span><span class="n">si</span><span class="w"> </span><span class="n">vous</span><span class="w"> </span><span class="n">voulez</span><span class="w"> </span><span class="n">autoriser</span><span class="w"> </span><span class="n">l</span><span class="s1">'accès en HTTP</span>
<span class="s1"> ServerName monsite.tld</span>
<span class="s1"> #ServerAlias www2.my-domain.com www.my-other-domain.com *.yet-another-domain.com</span>
<span class="s1"> # Theses lines only apply of the rewrite module is enabled.</span>
<span class="s1"> # This is a security enhancement recommanded by the nessus tool.</span>
<span class="s1"> <IfModule mod_rewrite.c&gt;</span>
<span class="s1"> RewriteEngine on</span>
<span class="s1"> RewriteCond %{REQUEST_METHOD} ^{TRACE|TRACK}</span>
<span class="s1"> RewriteRule .* - [F]</span>
<span class="s1"> </IfModule></span>
<span class="s1"> # On renvoit toutes les requêtes HTTP vers l'</span><span class="n">HTTPS</span><span class="p">.</span><span class="w"></span>
<span class="w"> </span><span class="n">Redirect</span><span class="w"> </span><span class="n">permanent</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nl">https</span><span class="p">:</span><span class="o">//</span><span class="n">monsite</span><span class="p">.</span><span class="n">tld</span><span class="o">/</span><span class="w"></span>
<span class="w"> </span><span class="o"></</span><span class="n">VirtualHost</span><span class="o">></span><span class="w"></span>
</code></pre></div>
<p>N'oubliez pas bien sûr d'activer votre nouvel hôte virtuel :</p>
<div class="highlight"><pre><span></span><code>$ sudo a2ensite monproxyssl
$ sudo /etc/init.d/apache2 reload
</code></pre></div>
<p>Et voila, votre reverse proxy doit fonctionner en HTTPS :)</p>
<p> </p>Lan au sein d'une dedibox Online2012-09-12T20:30:00+02:002012-09-12T20:30:00+02:00Victortag:blog.victor-hery.com,2012-09-12:/2012/09/proxmox-lan-au-sein-d-une-dedibox-online.html
<h2 id="problematique-faut-quca-cause">Problématique : faut qu'ça cause</h2>
<p><p>
Ce tutoriel a été rédigé sur le modèle d'un serveur dédié "dedibox" loué par <a href="http://www.online.net">Online.net</a>.</p>
<p>
<em>Nota : cet article est la transcription un peu plus détaillée et technique d'un post de moi-même sur le forum d'Online. Il n'y a donc pas de probème de droits :)</em></p>
<p>
Cependant …</p></p>
<h2 id="problematique-faut-quca-cause">Problématique : faut qu'ça cause</h2>
<p><p>
Ce tutoriel a été rédigé sur le modèle d'un serveur dédié "dedibox" loué par <a href="http://www.online.net">Online.net</a>.</p>
<p>
<em>Nota : cet article est la transcription un peu plus détaillée et technique d'un post de moi-même sur le forum d'Online. Il n'y a donc pas de probème de droits :)</em></p>
<p>
Cependant, il peut s'adapter à n'importe quel serveur ayant une distribution proxmox d'installée, au prix du changement de nom de quelques interfaces.</p>
<p>
Globalement le problème se résume ainsi :</p>
<ul>
<li>
Votre proxmox est installé sur un serveur dédié</li>
<li>
Vous avez plusieurs machines virtuelles, qui ont besoin de causer entre elles, ou mieux avec l'extérieur (mises à jour, tout ça...)</li>
<li>
Votre herbergeur<a href="http://blog.héry.com/article12/on-rale-marre-du-filtrage-securite-des-hebergeurs"> <strike>est un gros extrémiste</strike> sécurise son réseau</a> et il coupe tout accès à votre serveur si vous avez le malheur de sortir sur le réseau avec une adresse IP/MAC privée</li>
</ul>
<p>
</p>
<p>
Il va donc falloir mettre en place un réseau virtuel interne à votre proxmox, et le cas échéant un système de NAT efficace pour permettre à vos VM avec adresses IP privées de sortir sur Internet.</p>
<p>
<strong>Que ce soit clair, ces règles de pare-feu ne sécurisent en rien votre serveur, elles se contentent uniquement de permettre à vos machines virtuelles de causer entre elles.</strong></p></p>
<h2 id="posons-les-termes-de-quoi-on-parle">Posons les termes : de quoi on parle</h2>
<p><p>
Pour rendre plus simples les explications suivantes, je vais poser dès maintenant la configuration que l'on va utiliser.</p>
<p>
Le tutoriel se base sur proxmox V2, configuré juste après installation.</p>
<p>
Dans ce cadre :</p>
<ol>
<li>
On utilise une distribution Proxmox, donc basée sur Debian</li>
<li>
vmbr0 est l'interface bridge créée par proxmox, normalement liée à eth0</li>
<li>
vmbr1 est une interface bridge supplémentaire créé par nos soins, sans nécessité d'être liée à une interface physique (éventuellement créée depuis l'interface web proxmox)</li>
<li>
Le pare-feu que nous utiliserons sera iptables</li>
<li>
Nous configurerons des containeurs OpenVZ (mais la configuration fonctionne avec des KVM en réseau bridgé)</li>
<li>
Une machine VMID OpenVZ existe déjà, et elle dispose d'une interface publique avec une adresse MAC générée via l'interface web Online. (hors cadre de ce tuto)</li>
<li>
Vos VM utilisent la plage d'adresse IP privées 192.168.0.0/16</li>
<li>
Vous possédez déjà quelques connaissances en ligne de commande/iptables</li>
</ol></p>
<h2 id="les-mains-dans-le-cambouis">Les mains dans le cambouis</h2>
<p><p>
Première chose à faire, se connecter en SSH sur votre hyperviseur proxmox.</p>
<p>
Utilisez Putty si vous êtes sous Windows, ou le shell via une applet java dans l'interface Proxmox en alternative.</p>
<p>
Dans tous les cas, continuez une fois que vous avez un shell d'ouvert sur votre hyperviseur :-)</p></p>
<h3 id="evitons-les-blocages-intempestifs">Evitons les blocages intempestifs</h3>
<p><p>
La première manip va être de mettre en place un NAT sur l'interface physique qui sert à l'hyperviseur pour joindre Internet. Ceci permettra tout de suite d'éviter la moindre fuite d'un paquet venant d'une VM vers l'extérieur.</p>
<p>
En effet, cette fuite pourrait entrainer la coupure de l'accès à votre serveur pour une durée indéterminée, évitons donc tout de suite ce cas là.</p>
<p>
Un effet de bord intéressant est que vos futures VM pourront accéder à Internet à l'aide de ce NAT à l'aide d'un peu de routage ! Pratique pour les mises à jour.</p>
<p>
Pour mettre en place ce NAT, utilisez les lignes suivantes (à utiliser en root, ou alternativement avec sudo) :</p>
<p></p>
<pre class="brush:bash;">
$ iptables -t nat -A POSTROUTING -o vmbr0 -s 192.168.0.0/16 ! -d 192.168.0.0/16 -j MASQUERADE
$ echo 1 > /proc/sys/net/ipv4/ip_forward
</pre>
<p>
Cela va permettre d'activer l'ip forwarding sur votre interface, et va faire en sorte que toutes vos VM en 192.168.0.0/16 seront nattées lorsqu'elles essaieront de joindre une machine qui n'est pas en 192.168.0.0/16.</p>
<p>
<strong>Attention, changez les adresses IP selon votre configuration.</strong></p>
<p>
Cette configuration est temporaire, elle n'aura plus d'effet au prochain redémarrage. Nous verrons dans la <a href="#Modifications permanentes">dernière partie</a> comment les rendre permanentes, mais vérifiez que tout fonctionne avant de faire ça.</p>
<p>
(Si vous vous plantez et que vous bloquez l'accès à votre système, au moins un redémarrage règle le problème. Une fois les règles permanentes, vous êtes obligés de tout formater...)</p>
<h3 id="configuration-openvz">Configuration OpenVZ</h3>
<p><p>
Nous allons rajouter à la VM une interface réseau qui va bien. C'est également possible de le faire via l'interface web, mais comme on est en SSH on va pas s'embêter à ouvrir un navigateur !</p>
<p>
<pre class="brush:bash;">
vzctl set VMID --netif_add eth1,,,,vmbr1 --save
</pre></p>
<p>
Ceci va permettre de rajouter à la machine VMID une interface eth1, branchée sur vmbr1. L'adresse MAC sera générée automatiquement. Le --save rend la modification permanente même après redémarrage de la VM.</p>
<p>
Pour faire plus simple, vous pouvez mettre à vmbr1 une adresse IP dans la même plage que les VM (ici 192.168.0.0/16), histoire que l'hyperviseur puisse leur causer aussi. Ce n'est pas obligatoire ceci dit.</p>
<p>
Pour faire ça, il suffit de modifier le fichier /etc/network/interfaces -> Voir dans la section "<a href="#Modifications permanentes">Modification permamentes</a>"</p>
<p>
Ensuite, il vous suffit de créer autant de VM que vous le souhaitez en réseau local. La seule contrainte est de leur mettre une interface réseau branchée sur vmbr1 à la création, puis une adresse IP dans la plage qui va bien.</p>
<p>
De cette façon vous êtes parés.</p>
<h2 id="modifications-permanentes"><a name="Modifications permanentes">Modifications permanentes</a></h2>
<p><p>
Bon aller, pour que tout cela soit permanent même après redémarrage, voici les choses à rajouter.</p>
<p>
Les modifications sont à faire sur l'hyperviseur.</p>
<p>
Dans /etc/network/interfaces, rajoutez sous la section vmbr0 les lignes suivantes :</p>
<p>
<pre class="brush:bash;">
echo 1 > /proc/sys/net/ipv4/ip_forward
post-up iptables -t nat -A POSTROUTING -o vmbr0 -s 192.168.0.0/16 ! -d 192.168.0.0/16 -j MASQUERADE
post-down iptables -t nat -D POSTROUTING -o vmbr0 -s 192.168.0.0/16 ! -d 192.168.0.0/16 -j MASQUERADE
</pre></p>
<p>
De cette façon, le NAT sera configuré au démarrage sur vmbr0.</p>
<p>
Pour avoir une adresse IP privée sur vmbr1, soit vous passez par l'interface web, soit vous retournez dans /etc/network/interfaces et vous rajouter dans vmbr1 les lignes qui vont bien (en vous basant sur vmbr0 par exemple)</p>
<p>
<pre class="brush:bash;">
addresse 192.168.0.1
netmask 255.255.0.0
broadcast 192.168.0.255
</pre>
<p>
</p>
<p>
Voila, j'espère que ce petit tuto vous aura été utile. Si vous avez des questions particulières, n'hésitez pas :-)</p>
<p>
</p></p></p></p></p>Utiliser un DNS dynamique chez OVH avec un WRT54GL sur tomato2012-09-11T21:16:00+02:002012-09-11T21:16:00+02:00Victortag:blog.victor-hery.com,2012-09-11:/2012/09/dns-dynamique-ovh-avec-wrt54gl.html
<h2 id="oui-le-titre-est-long-et-alors">Oui, le titre est long, et alors ?</h2>
<p>Si on faisait toujours des titres courts, ça serait pas référencés sur Google ! (#oupas)</p>
<p>Bon, cet article est sérieux, attaquons.</p>
<p> </p>
<p>Dernièrement, j'ai vu que OVH, en tant que <a href="http://fr.wikipedia.org/wiki/Registre_de_noms_de_domaine">registrer</a> (chez qui on achète ses noms de domaine), proposait de configurer directement des entrées …</p>
<h2 id="oui-le-titre-est-long-et-alors">Oui, le titre est long, et alors ?</h2>
<p>Si on faisait toujours des titres courts, ça serait pas référencés sur Google ! (#oupas)</p>
<p>Bon, cet article est sérieux, attaquons.</p>
<p> </p>
<p>Dernièrement, j'ai vu que OVH, en tant que <a href="http://fr.wikipedia.org/wiki/Registre_de_noms_de_domaine">registrer</a> (chez qui on achète ses noms de domaine), proposait de configurer directement des entrées DNS Dynamique.</p>
<p>Option plutôt sympathique il faut l'avouer, ça permet de gérer facilement ses noms de domaine avec IP dynamique. Quelques limitations sont à prévoir, notamment au niveau de la mise à jour de l'enregistrement. On est là pour en parler :-)</p>
<p> </p>
<h2 id="cest-quoi-un-dns-dynamique">C'est quoi un DNS Dynamique ?</h2>
<p>Un DNS dynamique, c'est en fait un DNS classique, mais avec un temps de réplication et de cache (<a href="http://fr.wikipedia.org/wiki/Time_to_Live">TTL</a>) très court.</p>
<p>Ceci, associé à un logiciel spécifique installé chez le client, permet d'avoir un nom de domaine qui se met à jour très rapidement à l'échelle mondiale. Cela permet notamment de gérer facilement lorsque vous avez besoin de joindre quelque chose chez vous (NAS, PC en VNC, auto-hébergement, ...) et que vous avez un FAI qui ne vous donne qu'une IP dynamique, c'est à dire qui change régulièrement.</p>
<p>En mettant à jour votre nom de domaine en DNS Dynamique dès que votre adresse IP change, cela permet d'avoir un temps d'indisponibilité assez court, à n'importe quel moment. En plus, ça se fait souvent en automatique.</p>
<p>C'est un système un peu batard né de l'utilisation du NAT et des IP privées, et nécessaire à cause des FAI trouvant plus simple de vous changer d'IP plutôt que de vous en filer une fixe. (On se demandera à jamais pourquoi)</p>
<h2 id="une-bonne-idee-mais">Une bonne idée, mais...</h2>
<p>Bon, les définitions étant posées, parlons maintenant plus particulièrement du service d'OVH.</p>
<p>Proposer des DNS dynamiques, c'est bien, mais comme vu plus haut, ça nécessite une interaction côté client pour mettre à jour en temps réel (idéalement) l'entrée DNS.</p>
<p>Pour cela, OVH propose dans sa documentation divers logiciels à installer chez vous qui se chargent du boulot. Windows et Linux sont au rendez vous, mais malheureusement, la plupart de ces logiciels sont fait pour être installés sur votre PC perso, voir un serveur maison.</p>
<p>De plus, ils sont pour la plupart basés sur le fait que votre PC perso/votre serveur porte l'IP publique dynamique, ce qui est quand même très rare. (BiduleBox powaa !)</p>
<p>On peut s'en sortir avec un vérificateur d'adresse IP externe.</p>
<p>Mais la grosse limitation intervient lorsque l'on veut configurer cette mise à jour directement sur un routeur (accessoirement une BiduleBox). Ce qui est plus logique, puisque ce sont souvent eux qui portent l'IP publique dynamique.</p>
<p>Or, à moins que votre routeur propose directement de profiter du service OVH, vous allez devoir utiliser une URL HTTP pour faire cette mise à jour. Et ça, point de trace sur la documentation OVH, ni sur les forum, malgré quelques post courageux de personnes bien intentionnées.</p>
<p> </p>
<h2 id="lexemple-du-wrt54gl-tomato">L'exemple du WRT54GL Tomato</h2>
<p>J'utilise pour ma part un routeur <a href="http://fr.wikipedia.org/wiki/WRT54GL">Linksys WRT54GL</a>, excellent produit, avec le firmware <a href="http://www.polarcloud.com/firmware">tomato</a>. Bien qu'assez riche en option pour configurer le DNS dynamique, ce firmware ne propose pas par défaut OVH. (Ni d'ailleurs aucun firmware WRT54GL à ma connaissance)</p>
<p>Ce firmware propose toutefois d'entrer une URL personnalisée pour aller mettre à jour votre enregistrement DNS. Plutôt sympathique, encore faut-il connaitre cette URL. Comme OVH n'en parle pas, il faut chercher.</p>
<p>Pour ma part, j'ai du regrouper plusieurs sites/blog en parlant pour réussir à obtenir une URL utilisable, je vous la fournit donc, après tout c'est l'info que vous cherchiez en venant ici ;-)</p>
<p>Donc, dans le menu Basic -> DDNS -> Dynamic DNS 1 :</p>
<ul>
<li>Choisir dans le menu déroulant Custom URL</li>
<li>Entrer l'URL suivante : <u><strong>http://IDENTIFIANT:MOTDEPASSE@www.ovh.com/nic/update?system=dyndns&hostname=NOMDEDOMAINE&myip=@IP</strong></u></li>
</ul>
<p>Où : </p>
<ol>
<li>IDENTIFIANT est l'identifiant de gestion du DNS dynamique configuré dans l'interface OVH</li>
<li>MOTDEPASSE est le mot de passe de cet identifiant</li>
<li>NOMDEDOMAINE est le nom de domaine à mettre à jour</li>
<li>@IP est le mot clé de tomato pour récupérer la nouvelle IP publique</li>
</ol>
<p>N'oubliez pas de modifier dans le premier menu déroulant l'option que vous souhaitez :</p>
<ul>
<li>WAN IP si votre routeur porte l'IP publique</li>
<li>External IP checker si votre routeur est derrière une BiduleBox</li>
<li>Custom IP si vous êtes en IP fixe, mais là l'intérêt est quand même moindre...</li>
</ul>
<p>Cochez "Force next update" pour que la mise à jour se fasse tout de suite, puis cliquez sur "Save".</p>
<p>La mise à jour va s'effectuer, et si tout va bien mettre à jour le DNS sans erreurs.</p>
<p>Voila, en espérant que ça serve à quelqu'un dans le meilleur des mondes </p>Marre du filtrage "sécurité" des hébergeurs !2012-09-05T18:57:00+02:002012-09-05T18:57:00+02:00Victortag:blog.victor-hery.com,2012-09-05:/2012/09/marre-filtrage-securite-hebergeurs.html
<h2 id="votre-hebergeur-roxx">Votre hébergeur roxx !</h2>
<p>Auneffet, ses serveurs HP et DELL vous donne accès à une carte ILO ou DRAC, qui permet de faire plein de choses sympas pour gérer votre serveur à un niveau supérieur. </p>
<p>Entre autre, grâce à ces cartes, vous pouvez décider de booter votre serveur sur une iso …</p>
<h2 id="votre-hebergeur-roxx">Votre hébergeur roxx !</h2>
<p>Auneffet, ses serveurs HP et DELL vous donne accès à une carte ILO ou DRAC, qui permet de faire plein de choses sympas pour gérer votre serveur à un niveau supérieur. </p>
<p>Entre autre, grâce à ces cartes, vous pouvez décider de booter votre serveur sur une iso de votre cru, qui est bien sûr votre distribution Linux préférée trop bien que vous pouvez plus vous en passer.</p>
<p>(Ou alors, vous voulez juste installer un système en gérant correctement le partitionnement, ce qui est pas encore gagné via les interfaces web...).</p>
<p> </p>
<p>Sauf que bon, charger une image iso de 600Mo depuis chez vous, avec votre ADSL de merde by "******", ça rend tout de suite le truc moins sexy.</p>
<p>C'est alors que tout frétillant vous vous dites "Mais oui" !</p>
<p>Car oui ! vous avez un autre serveur dédié chez le même hébergeur (car décidément vous le kiffez à mort).</p>
<p>Quoi de plus simple alors que d'installer une petite machine virtuelle sur le deuxième serveur, avec une interface graphique pour lancer la magnifique applet (<a href="http://fr.wikipedia.org/wiki/Appliquette">appliquette</a>) java permettant de faire votre bonheur ?</p>
<h2 id="et-ouais-sauf-que-non">Et ouais. Sauf que non</h2>
<p>[MODE GROGNE : ON]</p>
<p>Car, pour des raisons plus ou moins fallacieuses, vous allez vite déchanter.</p>
<p>Votre hébergeur, dans un souci constant de pourvoyer à votre sécurité (Ca fait partie du contrat ??) applique un filtrage sur ce qui se passe dans son réseau.</p>
<p>Manque de bol, il considère ses propres adresses IP comme pas de confiance, et donc bloque tout accès à sa propre console depuis une machine de son propre réseau. (On croit rêver...)</p>
<p>Comment font les techniciens pour intervenir ? Mystère... Sans doute un VPN/proxy installé chez un concurrent est-il le seul moyen pour les pauvres hères de travailler dans des conditions décentes.</p>
<p>Quoiqu'il en soit, après avoir installé votre distribution GNU/Linux avec une interface graphique GNU/Linux, avoir fait la configuration de NAT qui va bien (car votre hébergeur <strike>est toujours un gros extrémiste</strike> sécurise son réseau, <a href="#Et en plus...">voir plus bas</a>) vous chargez votre navigateur libre préféré, et vous vous mangez un méchant "403, Forbidden". Autrement nommé "Mais c'est pas vrai, y'a une erreur ! WTF ?"</p>
<p>Sauf que, forum à l'appui, d'erreur il n'y a point.</p>
<p>Pour éviter tout système de rebond (Entendez un méchant qui a piraté un serveur et qui voudrait accéder à la console pour en acheter un autre), on bloque, sans possibilité de rémission. Sans se poser de questions. Et tant qu'à faire, sans même un message un peu verbeux (403 Forbidden Apache powaa!)</p>
<p><strong>Résultat des courses : </strong>Vous vous résignez finalement à charger votre iso via votre machine locale, avec votre connexion ADSL à l'upload plus que douteux. Si en plus vous êtes en entreprise et que tout le reste de la boîte utilise la même connexion pour powner du FTP ou télécharger des contenus sous licence Creative Commons, préparez vous à avoir des remontées violentes. Mais bon vous bossez, c'pas d'votre faute hein.</p>
<p> </p>
<p><strong>Résultat des courses, 2eme vue : </strong>Vous avez perdu 1h à installer votre machine virtuelle, pour rien. Vous perdez ensuite 5h de votre journée à regarder avancer une jauge à la con. Bah oui, parce que comme c'est sécurisé, il y a un timeout, donc si jamais vous êtes pas là à cliquer régulièrement sur votre applet java pour lui dire que sisi, ça bosse toujours, vous êtes bons pour recommencer.</p>
<p>Accessoirement, avec un upload moyen de 70Kb/s, vous allez encore moins vite qu'un lecteur CD 1x. Croyez moi, s'pas gagné.</p>
<h2 id="et-en-plus"><a name="Et en plus...">Et en plus...</a></h2>
<p>Et en plus, comme votre hébergeur <strike>est toujours un gros extremiste</strike> sécurise son réseau, pendant que vous configuriez votre petite machine virtuelle (avant de vous rendre compte que ça servait à rien, j'entends) vous avez commencé par la lancer avec une IP privée, comme ça à l'arrache.</p>
<p>Sauf que, ni une, ni deux, elle a envoyé quelques paquets innocent avec son adresse privée et sa MAC bidon sur le réseau de votre hébergeur (bah oui, pas eu le temps de configurer un NAT, ou même d'y penser). Celui-ci, malin, va bloquer ces paquets rapidement.</p>
<p>Mais aussi, parce que ça ne mange pas de pain, il va également bloquer tout accès à votre serveur ! Plus de SSH, plus d'interface web, même plus de console en ligne ! (Sans parler d'ILO ou de DRAC)</p>
<p>Pendant un temps plus ou moins variable, vous ne pouvez plus rien faire. Sans même savoir pourquoi d'ailleurs, puisque vous avez juste droit à un gros message rouge vous disant que "c'est con hein, mais c'est bloqué. C'est votre faute z'aviez qu'à pas <Insert blank here>".</p>
<p>Pour peu que à peine le réseau revenu vous refassiez la même erreur 2, 3, 4 fois avant de comprendre ?</p>
<p>Pour peu que vous ayiez lancé un ping sur votre VM pour tester la connexion, et qu'au fur et à mesure que le réseau soit débloqué, la VM continue son ping et vous rebloque de nouveau...</p>
<p>Vous avez perdu encore une petite heure, au bas mot. (Soyons large, on est des pros ici, on comprends vite d'où ça peut venir ces petites erreurs là.)</p>
<p> </p>
<h2 id="mais-au-final">Mais au final</h2>
<p>Au final, vous avez déjà perdu 7h, vous êtes plus à ça près, s'pas ?</p>
<p>Et puis, ça vous laisse plein de temps pour chercher avec votre connexion surchargée le nom d'un autre hébergeur chez qui migrer au plus vite... Pour vous rendre compte qu'en fait, ils sont tous hors de prix tout en étant pire dans leur gestion réseau.</p>
<p> </p>
<p><strong>Conclusion : </strong>L'auto-hébergement, c'est le bien !</p>
<p>[MODE GROGNE : OFF]</p>
<p><em>Nota : bien sûr, personne ne doit se sentir insulté ou calomnié par ce texte, résultat de mon cerveau brouillon et sans prétention devant tant de capacités techniques employées pour faire le bien.</em></p>La virtualisation open source qui roxx2012-09-04T20:00:00+02:002012-09-04T20:00:00+02:00Victortag:blog.victor-hery.com,2012-09-04:/2012/09/virtualisation-opensource-qui-roxx-proxmox.html
<h2 id="proxmox-kesaco">Proxmox, kesaco ?</h2>
<p>Comme je l'ai dit dans un précédent <a href="http://blog.héry.com/article7/la-virtualisation-ou-l-un-des-seul-bienfait-du-cloud">article sur la virtualisation</a>, je trouve cette manière de fonctionner sur un serveur particulièrement intéressante.</p>
<p>Comme je l'ai également dit à la fin de cet article, j'utilise pour ma part un outil de virtualisation open source nommé <a href="http://www.proxmox.com/">proxmox</a>.</p>
<p><img alt="Logo Proxmox" src="/images/proxmox_logo.png" style="width: 195px; height: 28px"/></p>
<p> </p>
<p>Proxmox est un …</p>
<h2 id="proxmox-kesaco">Proxmox, kesaco ?</h2>
<p>Comme je l'ai dit dans un précédent <a href="http://blog.héry.com/article7/la-virtualisation-ou-l-un-des-seul-bienfait-du-cloud">article sur la virtualisation</a>, je trouve cette manière de fonctionner sur un serveur particulièrement intéressante.</p>
<p>Comme je l'ai également dit à la fin de cet article, j'utilise pour ma part un outil de virtualisation open source nommé <a href="http://www.proxmox.com/">proxmox</a>.</p>
<p><img alt="Logo Proxmox" src="/images/proxmox_logo.png" style="width: 195px; height: 28px"/></p>
<p> </p>
<p>Proxmox est un packaging disponibles pour de nombreuses versions de linux/unix, mais il existe une distribution basée sur debian et maintenue par Proxmox, que j'utilise pour sa simplicité et sa compatibilité. (Au moins, pas besoin de se demander si tel ou tel module noyau fonctionnera ou pas une fois installé le package proxmox...)</p>
<p>Donc, la distribution debian Proxmox vous permet, une fois installée, de virtualiser via 2 techniques, OpenVZ et KVM, et de gérer toutes vos machines simplement via une interface web, de les sauvegarder en masse de manière programmée, tout en ayant un panel d'outils en ligne de commande sympathiques pour faire tout et n'importe quoi.</p>
<p>Il est également possible de mettre en place un cluster entre plusieurs Proxmox, d'accéder aux VM via l'interface web avec une applet Java, etc etc.</p>
<p> </p>
<p>Je vais donc détailler dans cet articles les fonctionnalités de Proxmox, parce que j'ai bien envie d'en parler :)</p>
<h2 id="proxmox-reseau-bridge">Proxmox, réseau bridgé</h2>
<p>Avec proxmox, vous êtes automatiquement lié à différentes interfaces "bridgées". Ou plutôt, des <a href="http://fr.wikipedia.org/wiki/Pont_(informatique)">interfaces de pont</a> en français. En gros, un switch virtuel dans le serveur.</p>
<p>C'est assez classique des hyperviseur, mais ça vaut le coup de le rappeller. Ca permet de lier les interfaces réseau des VM aux interfaces réseau physiques de l'hyperviseur, pour par exemple leur donner accès à Internet.</p>
<p>Ca permet également de créer des interfaces bridgés pour créer un réseau interne dans le serveur, permettant de joindre en interne toutes les VM. Totalement étanche à l'extérieur, ça ouvre des possibilités intéressantes en matière de service sécurisés :-)</p>
<p>L'utilisation de ce service permet vraiment de configurer tout et n'importe quoi de manière très simple. En effet vous pouvez ajouter de nombreuses interfaces à un bridge, par exemple des tap/tun pour openVPN, des interfaces dummy ou même d'autre bridges !</p>
<p>De plus, vous pouvez grâce à iptables créer des règles spécifique sur cette interface, pour la rendre totalement étanche, comme un vrai switch physique.</p>
<p>C'est sur ce principe qu'est basé le système réseau de proxmox, et il est vraiment très simple à utiliser et à exploiter.</p>
<p> </p>
<h2 id="containeurs-openvz-ou-chroot-en-force">Containeurs OpenVZ, ou chroot en force</h2>
<p><a href="http://openvz.org"><img alt="Logo OpenVZ" src="/images/800px-openvz-logo.png" style="width: 200px; height: 50px"/></a></p>
<h3 id="quoique-cest">Quoique c'est ?</h3>
<p>Bon, soit vous êtes admin système et vous avez compris le titre, soit non. Dans mon métier, on aime les trucs binaires !</p>
<p>La virtualisation Open VZ va en fait consister à se servir du noyau système de l'hyperviseur pour faire fonctionner les machines virtuelles.</p>
<p>Cela a plusieurs effets, positifs comme négatifs.</p>
<p>En fait, vos machines virtuelles vont tourner en utilisant les ressources de base de l'hyperviseur. Contrairement à d'autres type de virtualisation, un OpenVZ va ainsi partager ses ressources directement avec l'hyperviseur.</p>
<p>Concrètement, si cela permet d'utiliser différentes distributions linux dans vos machines virtuelles, vous ne pourrez pas utiliser de Windows. Toutes vos distributions seront basées sur le noyau de l'hyperviseur, c'est à dire un noyau linux.</p>
<p>Installer un système Open VZ revient à choisir un "template", sorte d'image d'un véritable système d'exploitation, qui va être utilisé pour simuler ce système à destination de la machine virtuelle. De cette façon, du point de vue de la machine, le système sera correct et normal.</p>
<p>Ensuite, en se basant sur ce template, l'hyperviseur va réaliser un gros "<a href="http://fr.wikipedia.org/wiki/Chroot">Chroot</a>". Pour les néophytes ayant la flemme de lire wikipédia, l'hyperviseur va créer un dossier ayant une arborescence linux classique, puis va lancer la VM comme un processus classique en lui disant que son dossier racine / va être l'arborescence précedemment créée.</p>
<p>En conséquence, tout les processus lancées dans la VM seront vus depuis l'hyperviseur, alors que la VM sera une machine à part entière.</p>
<h3 id="osef-non">osef non ?</h3>
<p>Ben non, ça amène pas mal d'avantages intéressants.</p>
<ul>
<li>La VM a un nouveau nom. On appelle ça un containeur (CT), et c'est plus classe</li>
<li>Le CT n'a pas vriament besoin de démarrer ou redémarrer, vu que c'est un processus. Donc, quand on démarre ou redémarre un containeur, ça dure approximativement 10 secondes. (Sans SSD !!)</li>
<li>Le CT partage pas mal de configuration noyau avec l'hyperviseur. La gestion du swap ou de la RAM par exemple</li>
<li>Le CT n'a pas besoin d'un certain nombre de service (jamais de client NTP dans un CT !)</li>
<li>Le CT consomme extrêmement peu de ressource, même avec de l'apache, du mysql et autre (à charge raisonnable bien sûr...)</li>
<li>Le CT peut utiliser du réseau bridgé, ou entièrement virtualisé (plus d'adresse MAC nécessaire)</li>
<li>On peut facilement imaginer plusieurs centaines de CT sur un serveur sans trop de problème.</li>
<li>Comme l'intérieur des CT sont des dossier de l'hyperviseur, on peut modifier, sauvegarder et récupérer très simplement le contenu des CT.</li>
<li>On peut à n'importe quel moment augmenter en temps réel la taille du disque dur allouée au CT, même si celui est en fonctionnement.</li>
</ul>
<p>Il y a surement plein d'autres choses, mais globalement c'est déjà des points très intéressants, selon les usages qu'on en a.</p>
<p>Par contre, comme d'habitude, il y a aussi quelques inconvénients. Le noyaux étant émulé, il y a des choses qui ne fonctionnent pas dans le CT.</p>
<ul>
<li>N'essayez jamais d'installer un client NTP. Le CT fonctionne avec celui de l'hyperviseur, et il peut y avoir méchant conflit</li>
<li>Au revoir certains modules noyaux particulier, notamment IPSec...</li>
<li>Les machines virtuelles java n'aiment pas trop OpenVZ (sauf l'obscure machine d'IBM) Donc, pas de java sur OpenVZ (<troll>Des failles de sécurité en moins ! </troll>)</li>
<li>Il faut activer des choses depuis l'hyperviseur pour utiliser OpenVPN dans un CT (mais une fois fait, ça marche nickel)</li>
<li>La gestion du swap, de la RAM sont basés sur la configuration de l'hyperviseur. Enfin, ce n'est pas forcément un inconvénient</li>
<li>Il y a souvent des manip' un peu particulière à faire pour utiliser des services touchant au matériel ou au noyau, mais là encore on s'en tire</li>
</ul>
<p> </p>
<p>Bref, il y a du pour et du contre. Perso, sauf pour certains usages très précis (IPSec ou tomcat avec Java...), je n'utilise que des CT sous OpenVZ. Optimisées et ultra rapides, ça serait vraiment dommage de s'en passer.</p>
<p> </p>
<h2 id="kvm-le-mode-de-secours">KVM, le mode de secours</h2>
<p><img alt="Logo KVM" src="/images/kvmbanner-logo2.png" style="width: 200px; height: 62px"/></p>
<p>Bon, si vous tenez vraiment à faire tourner tomcat, à utiliser IPSec, voir à installer un client NTP. Ou pire, que vous n'aimez pas OpenVZ ou que vous tenez à utiliser Windows (ouh ! Haro !), proxmox n'a pas mis tous les oeufs dans le même panier et propose un deuxième système de virtualisation open source, j'ai nommé <a href="http://www.linux-kvm.org/page/Main_Page">KVM</a>.</p>
<p>Une machine KVM est cette fois une véritable machine virtuelle, complètement indépendante de l'hyperviseur. Elle possède son propre noyau, ses propres interfaces réseaux et sa carte graphique, un disque dur bien défini, etc.</p>
<p>Vous pouvez donc tout à fait l'utiliser pour faire tourner un système Windows si vous le souhaitez.</p>
<p>Cette technique de virtualisation est robuste, mais aucun des avantages d'OpenVZ ne peut être appliqué à elle. En contrepartie, la plupart des inconvénients d'OpenVZ n'a pas de prise sur une KVM :-)</p>
<p>Etant une "vraie" machine, une KVM va pouvoir utiliser ses propres modules noyaux (bonjour, IPSec), ainsi qu'une machine virtuelle java. On l'installe depuis une image iso classique, comme n'importe quel système d'exploitation.</p>
<p>Pour ma part, je ne m'éteindrai pas trop dessus, car je n'utilise les KVM que si mon besoin ne peut vraiment pas se poser sur OpenVZ.</p>
<p>KVM est certes plus complet, mais par rapport à OpenVZ, le fait d'avoir une vraie machine à émuler est aussi beaucoup plus lourd. Ca demande plus de ressource à l'hyperviseur, c'est bien plus long à éteindre et démarrer qu'un containeur, on est obligé d'y accéder via SSH ou avec les outils proxmox, ...</p>
<p>Bref :-)</p>
<p> </p>
<h2 id="interface-web-le-bonus-qui-en-jette">Interface web, le bonus qui en jette</h2>
<p>Bon, je ne vous ferait pas plein de screens super bô de l'interface web de gestion proxmox.</p>
<p>Accessible nativement en https (c'est le bien), elle permet de quasiment tout gérer pour vos tâches quotidienne.</p>
<ul>
<li>Création de machines virtuelles en 3 clics (OpenVZ et KVM)</li>
<li>Modifications des ressources allouées à ces machines (RAM, disques, nombres d'interfaces réseau, ...)</li>
<li>Gestion des stockages (disques dur machines, images iso, templates OpenVZ, ...)</li>
<li>Management des machines (éteindre, démarrer, couper à chaud ou à froid, accès à une console VNC ou un shell)</li>
<li>Création de cluster entre différents serveurs proxmox</li>
<li>Mise en place de <a href="http://fr.wikipedia.org/wiki/Haute_disponibilité">Haute Disponibilité</a> (un peu de ligne de commande nécessaire selon les configurations)</li>
<li>Gestion de TOUTES les machins d'un cluster depuis UNE seule interface web (trop le pied !)</li>
<li>Gestion d'utilisateurs, de groupes d'utilisateurs, de droits d'accès à des machines (qui a dit "Vendons du <a href="http://blogvps.kicou.org/">VPS</a> !")</li>
<li>Gestion de l'hyperviseur lui-même (redémarrage, accès shell, monitoring du traffic réseau, de la charge processeur, de la RAM, du SWAP, du...)</li>
<li>Gestion des sauvegardes, journalières, mensuelles, incrémentales, ...</li>
<li>Gestion du stockage réseau, du stockage local, de l'iscsi</li>
<li>...</li>
</ul>
<p>GLobalement, avec simplement l'interface web, vous faites tourner tout un tas de machines virtuelles seulement en cliquant 2 ou 3 fois, depuis une interface web sécurisée.</p>
<p>En rajoutant un peu de ssh et de ligne de commande, vous avez un service pro, redondé, sécurisé, permettant de lancer votre propre service de VPS dans votre salon si vous avez envie ! Après bien sûr, à vous de négocier votre bande passante avec votre FAI (ainsi qu'avec ses <a href="http://wiki.auto-hebergement.fr/fournisseurs/fai">Conditions Générales de Vente</a>)</p>
<p> </p>
<p>A plus petite échelle (la mienne par exemple) vous pouvez simplement sauvegarder et redémarrer votre serveur web que vous avez pris 3 jours de temps libre à configurer aux petits oignons. (Enfin, surtout le serveur courriel en fait...), et ce même si votre serveur maison claque brusquement.</p>
<p> </p>
<h2 id="moi-je-suis-convaincu-sinon-jen-ferai-pas-la-pub">Moi, je suis convaincu (sinon j'en ferai pas la pub)</h2>
<p>Auneffet, ce en quoi je crois, j'en parle. Simple et efficace :-)</p>
<p>Maintenant, ce long article servant d'introduction à d'autres prévus sur la configuration de proxmox, j'espère que vous l'aurez apprécié.</p>
<p>Désolé, c'est long. Mais c'est bon aussi ;-)</p>
<p> </p>La virtualisation, ou l'un des (seul ?) bienfait du cloud2012-08-15T17:51:00+02:002012-08-15T17:51:00+02:00Victortag:blog.victor-hery.com,2012-08-15:/2012/08/virtualisation-bienfait-du-cloud.html
<h2 id="la-virtualisation-quest-ce-que-cest">La virtualisation, qu'est ce que c'est ?</h2>
<p>La virtualisation de serveur, ça consiste à se servir d'une machine physique pour émuler plusieurs machines dites 'virtuelles'. La machine physique, autrement nommée <a href="http://fr.wikipedia.org/wiki/Hyperviseur">Hyperviseur</a>, va permettre de gérer de A à Z les machines virtuelles hébergées.</p>
<p>Gestion processeur, RAM, espace disque, réseau, extinction, ... l'hyperviseur …</p>
<h2 id="la-virtualisation-quest-ce-que-cest">La virtualisation, qu'est ce que c'est ?</h2>
<p>La virtualisation de serveur, ça consiste à se servir d'une machine physique pour émuler plusieurs machines dites 'virtuelles'. La machine physique, autrement nommée <a href="http://fr.wikipedia.org/wiki/Hyperviseur">Hyperviseur</a>, va permettre de gérer de A à Z les machines virtuelles hébergées.</p>
<p>Gestion processeur, RAM, espace disque, réseau, extinction, ... l'hyperviseur à la main sur tout ce qui à trait à ses machines virtuelles (VM pour Virtual Machine)</p>
<p>Chaque machine virtuelle par contre, vu de l'intérieur, est autonome. On la démarre, et le système à l'intérieur fonctionne tout seul, sans intervention extérieure. De son point de vue, elle est une machine physique. Elle dispose d'une configuration propre (définie par l'hyperviseur, vous suivez ?), et elle n'a pas "conscience" d'être en fait un sous ensemble d'une plus grosse machine physique.</p>
<p>Bien sûr, chaque hyperviseur a ses limites, il n'est pas possible d'installer trop de machines sur un serveur physique. La RAM que vous allouez par exemple à vos VM ne peut pas dépasser la RAM totale de l'hyperviseur, etc.</p>
<p> </p>
<p>Bref, ça a l'air super sexy, mais enfin bon, quelle utilité ?</p>
<p> </p>
<h2 id="de-lutilite-de-la-virtualisation">De l'utilité de la virtualisation</h2>
<p>D'abord, une constatation évidente. De nos jours, le moindre serveur dédié que vous pouvez louer est surdimensionné (à moins que vous ne souhaitiez vraiment faire tourner 70 sites web à vous tout seul, associé à 10000 adresses courriels et une 30aine de serveurs Counter Strike<sup>©</sup></p>
<p>Tout ça tournant bien sûr en vrac sur le serveur. Et si tout plante, et ben c'est con, mais y'a plus rien dis donc.</p>
<p>Sinon, vous avez une machine énorme pour faire tourner votre site web, et si vous voulez partager un peu vos services, ben vous achetez une deuxième machine énorme pour faire tourner votre serveur Teamspeak et votre Counter Strike<sup>©</sup></p>
<h3 id="separons-les-services-tous-les-oeufs-ne-vont-pas-dans-le-meme-panier">Séparons les services ! Tous les oeufs ne vont pas dans le même panier</h3>
<p>Le premier avantage à virtualiser, c'est que vous pouvez créer autant de machine virtuelle que de services que vous souhaitez faire tourner, par exemple.</p>
<p>Ainsi, une machine pour vos sites web, une machine pour votre serveur courriel, une machine pour les serveurs de jeu, etc. De cette façon, vous capitalisez un seul serveur physique pour tous vos services, sans que ceux-ci ne se marchent dessus !</p>
<p>Et en plus, ça vous permet de répartir exactement quelle ressource physique (processeur, RAM, ...) vous voulez allouer à vos services.</p>
<p>Un pirate attaque votre serveur web en saturant la RAM ? Pas grave, seul les petits 512Mo que vous lui aviez alloué vont se remplir. La VM va planter, les sites web devenir inaccessibles, mais pendant ce temps tout le reste continuera à tourner.</p>
<p>D'ailleurs, parlons sécurité.</p>
<h3 id="separons-les-services-bis-le-panier-il-fuit-pas">Séparons les services ! bis. Le panier, il fuit pas</h3>
<p>Et oui, l'un des autres gros avantages, c'est que si la machine qui contient votre serveur web (imaginons une faille dans apache par exemple), est compromise par un pirate, et bien, seule cette machine est compromise.</p>
<p>Comme de son point de vue elle est une machine physique à part entière, elle n'a pas de moyen "physique" de joindre les autres machines virtuelles, sauf par le réseau classique.</p>
<p>Du coup, le pirate peut effectivement s'amuser avec les sites web (ça, on ne peut malheureusement rien y faire), mais même s'il sature la mémoire, remplit le disque dur, surcharge le processeur, attaque la base mysql ou que sais-je d'autre, ça restera confiné à cette machine. Et les limitations mises en place par l'hyperviseur feront que ces dommages resteront minimes du point de vue des autres machines.</p>
<p>De plus, dans l'idéal le pirate n'a aucun moyen de savoir que cette machine est en réalité une machine virtuelle, il n'est donc pas tenté d'attaquer le reste des services. (Enfin, à la limitation que ces services ne soient pas visibles sur Internet. Sinon à moins d'être débile, notre pirate aura au moins des doutes.)</p>
<p> </p>
<h3 id="limitons-les-services-moins-ya-de-portes-plus-cest-dur-dentrer">Limitons les services : moins y'a de portes, plus c'est dur d'entrer</h3>
<p>Bien sûr, l'hyperviseur lui-même est le gros maillon faible de l'infrastructure. Si lui se trouvait être compromis, alors toutes les machines virtuelles seraient potentiellement en danger. Mais en y réfléchissant, ça serait pareil si tout tournait sur le serveur physique. S'il était compromis, tout serait compromis. Et en plus, il y aurait plus de porte pour y entrer.</p>
<p>En effet, chaque service (courriel, web, serveur de jeu) ouvert sur Internet est une porte potentielle pour un pirate, qui peut essayer de la forcer pour entrer sur votre serveur et mettre la pagaille.</p>
<p>Là, comme en théorie l'hyperviseur ne fait tourner aucun service dit sensible, il peut très bien être complètement invisible depuis Internet ! Et moins il y a de portes, plus c'est facile de les surveiller. Chaque machine peut avoir un bon gros pare-feu qui n'autorise que son service, limitant ainsi beaucoup les effets de bord.</p>
<p>Pour que ça soit encore plus cool, la plupart des hyperviseur implémentent un moyen de se connecter sur ses machines virtuelles. En gros, connectez vous sur l'hyperviseur, vous pourrez vous connecter sur toutes les machines. Ca peut sembler evident, mais ça permet du coup de se passer de tout accès SSH, telnet, rdp, ... sur les machines. Donc, d'autant de services offrant des opportunités d'entrer pour un pirate :-) </p>
<p> </p>
<h3 id="groupons-les-sauvegardes-et-migrons-les-machines">Groupons les sauvegardes et migrons les machines</h3>
<p>Un autre point sympathique de la virtualisation, c'est la gestion des sauvegardes. Tout hyperviseur digne de ce nom vous permet de sauvegarder l'intégralité d'une VM. </p>
<p>Il est ainsi extremement simple de sauvegarder toutes vos machines virtuelles, et de redonder ces sauvegardes pour que même en cas de coupure de courant, de disque qui lâche ou de guerre nucléaire, vous ayez tout ce qu'il faut sous le tapis.</p>
<p>Et en plus, les machines virtuelles ont le bon goût de ne pas trop se soucier de l'hyperviseur qui les fait tourner. C'est à dire que en cas de coupure de courant, de disque qui lâche ou de guerre nucléaire, vous prenez votre petite sauvegarde, un autre serveur avec l'hyperviseur installé, et hop, toutes vos machines redémarrent !</p>
<p>Au prix éventuellement d'une petite reconfiguration d'adresses IP et de serveurs DNS, tous vos services peuvent être disponible de nouveau en un temps très court. Et plus court encore si vous avez prévu le coup et avez déjà une copie de votre hyperviseur prête à l'emploi à tout moment.</p>
<p> </p>
<h2 id="jy-crois-pas-ya-forcement-un-mais">J'y crois pas, y'a forcément un mais</h2>
<p>Oui bon ok, il y a aussi des points négatifs.</p>
<h3 id="acces-a-lhyperviseur">Accès à l'hyperviseur</h3>
<p>L'un d'eux, c'est que si vous voulez accéder à votre hyperviseur pour ensuite accéder à vos machines (et ainsi vous affranchir de l'accès à vos machines une par une), il faut ouvrir ce service sur l'hyperviseur. Eventuellement depuis Internet.</p>
<p>Bon, dans le cas d'un serveur sous Windows, je ne vous cacherai pas qu'un vieux Remote Desktop Server bien pas sécurisé, bien moche et bien connu du moindre bébé pirate sorti du ventre de sa mère, ça pue. Ca pue vraiment. Laisser votre hyperviseur avec "ça" ouvert sur le net, c'est se tirer une balle dans la tête (non non, même pas dans le pied, dans la tête)</p>
<p>Après, si vous êtes quelqu'un de sérieux (troll inside) et que vous faites vos serveurs sous Linux/Unix, laisser un accès SSH ouvert, c'est acceptable. SSH est bien connu, très régulièrement mis à jour, facile à sécuriser. Je peux d'ailleurs vous conseiller un petit <a href="http://www.fail2ban.org/wiki/index.php/Main_Page">fail2ban</a> à cet effet, simple et très efficace.</p>
<p>Là, on est propre, et on peut se connecter assez sereinement à notre hyperviseur.</p>
<p> </p>
<h3 id="la-taille-des-sauvegarde">La taille des sauvegarde</h3>
<p>Malheureusement ça, c'est un fait. Sauvegarder des machines entières, ça prend de la place. Là où avant vous sauvegardiez un dossier avec vos sites, deux ou trois fichier de conf et une base de données, vous devez maintenant sauvegarder plusieurs serveurs. Chacun embarquant son système d'exploitation à lui. Et là, ça peut vite faire mal niveau espace disque nécessaire pour tout sauvegarder.</p>
<p>Mais bon, au moins vos machine sauvegardées peuvent repartir à tout moment. C'est déjà ça, hein ?</p>
<p> </p>
<h3 id="les-mises-a-jour-aie">Les mises à jour - Aie !</h3>
<p>Mais le vrai gros point noir de la virtualisation d'après moi, c'est la gestion des mises à jour.</p>
<p>En effet, si vos machines sont accessibles depuis le net, elles DOIVENT être à jour. On ne reviendra pas là dessus.</p>
<p>Cependant, avoir 4 machines qui tournent, c'est devoir mettre 4 machines à jour. L'hyperviseur, la VM du serveur web, la VM du serveur courriel et la VM de votre serveur de jeu doivent être mise à jour séparement.</p>
<p>Et ça, ça fait mal. C'est chronophage. C'est redondant. Ca pique. Et ça ennuie...</p>
<p>On peut tenter du script de mise à jour automatique, toutes les nuits. On lance la mise à jour, on répond automatiquement oui à toutes les questions, et c'est finit. Oui, jusqu'à ce qu'un fichier de conf soit changé durant la mise à jour, jusqu'à ce qu'un nouveau paramètre fasse son apparition, jusqu'à ce que... Bref, c'est prendre le risque qu'en vous levant un matin, plus rien ne fonctionne, et que vous deviez restaurer une sauvegarde de la veille faute de trouver qu'est ce qui a exactement été changé...</p>
<p>Donc non, mise à jour à la main, et une par une.</p>
<p>Et ça, malgré mes diverses recherches, je n'ai pas encore réussit à m'en affranchir dans le monde de la virtualisation...</p>
<p> </p>
<h2 id="mais-bon-cest-trop-bien-quand-meme">Mais bon, c'est trop bien quand même !</h2>
<p>Oui, parce qu'avec tous les avantages, ça serait quand même dommage de finir sur une note négative !</p>
<p>Pour ma part, je virtualise exclusivement sous debian, et j'utilise un outil nommé <a href="http://www.proxmox.com/">proxmox</a>. D'ailleurs, je prévoie un petit article à ce sujet bientôt :-)</p>
<p>EDIT : article rédigé <a href="/2012/09/virtualisation-opensource-qui-roxx-proxmox.html">ici</a>.</p>Connexion SSH par clé2012-08-15T10:20:00+02:002012-08-15T19:30:00+02:00Victortag:blog.victor-hery.com,2012-08-15:/2012/08/connexion-ssh-par-cle.html
<h2 id="pourquoi-se-connecter-par-cle">Pourquoi se connecter par clé ?</h2>
<p><p>
Si vous êtes comme moi et que vous faites des scripts sous linux, notamment de backup, vous avez sans doute le problème d'exécuter des commandes à distance automatiquement.</p>
<p>
Pour cela, le ssh est l'idéal; sécurisé, crypté, facilement configurable et utilisable.</p>
<p></p>
<p>
Cependant, l'un des gros problèmes …</p></p>
<h2 id="pourquoi-se-connecter-par-cle">Pourquoi se connecter par clé ?</h2>
<p><p>
Si vous êtes comme moi et que vous faites des scripts sous linux, notamment de backup, vous avez sans doute le problème d'exécuter des commandes à distance automatiquement.</p>
<p>
Pour cela, le ssh est l'idéal; sécurisé, crypté, facilement configurable et utilisable.</p>
<p></p>
<p>
Cependant, l'un des gros problèmes d'un script automatique, c'est qu'un mot de passe, il a un peu de mal à le taper. Alors, on peut bidouiller me direz-vous :</p></p>
<div class="highlight"><pre><span></span><code><span class="err">echo "motdepasse" ssh root@serveurIP</span>
</code></pre></div>
<p>
Pourquoi pas. Mais bon, ça oblige à mettre le mot de passe en clair, ça ne marche pas toujours selon la configuration de votre serveur ssh, et la connexion en root, c'est mal.</p>
<p></p>
<p>
C'est là qu'intervient un système sympa de ssh : <strong>la connexion par clé...</strong></p>
<h2 id="le-principe-rapidement">Le principe : rapidement</h2>
<p><p>
Pour ceux qui ne sont pas trop au fait de quoi que c'est que ça, je vais rapidement rappeller le principe de se connecter à l'aide d'une clé.</p>
<p>
En ssh, la connexion se fait en trois temps :</p>
<ul>
<li>
On fait une demande de connexion, le serveur renvoie une clé unique lié à sa configuration, qui va permettre de l'identifier et de chiffrer le flux (Cette demande n'est faite qu'à la première connexion)</li>
<li>
On accepte (ou non) cette clé. Elle permet notamment de voir si le serveur a été changé depuis la dernière connexion (si oui, attention ! potentielle attaque d'homme dans le milieu :-) )</li>
<li>
Ensuite, on rentre son mot de passe et la connexion s'établit</li>
</ul>
<p>
En fait, il y a l'identification du serveur (clé du serveur), puis notre identification (via le mot de passe)</p>
<p>
Avec une connexion par clé, c'est quasi la même chose, sauf qu'on va nous aussi utiliser une clé pour s'identifier ! De cette façon, une fois la clé installée sur le serveur, elle ne sera plus demandée et il n'y aura plus besoin de mot de passe. (trop la classe)</p>
<p>
<em>Notez qu'on peut assortir la connexion par clé d'une phrase de sécurité, à rentrer lors de la connexion et qui sécurise encore le processus. Cependant, ce n'est pas intéressant pour une connexion auto donc on ne s'en servira pas ici</em></p>
<p></p></p>
<h2 id="generation-de-la-cle-les-choses-serieuses-commencent">Génération de la clé : les choses sérieuses commencent</h2>
<p><p>
Sur votre machine cliente, il va d'abord falloir générer la fameuse clé. Ou plutôt, le couple de clé, la clé publique et la clé privée. <a href="http://fr.wikipedia.org/wiki/Cryptographie_asymétrique">(Voir la cryptographie asymétrique)</a></p>
<p>
Si ce n'est pas déjà fait, installez donc le client openssh :</p></p>
<div class="highlight"><pre><span></span><code>$ sudo aptitude update <span class="p">&</span>amp<span class="p">;&</span>amp<span class="p">;</span> sudo aptitude install openssh-client
</code></pre></div>
<p>
(Bien sûr, openssh serveur est installé sur votre machine distante)</p>
<p>
Ensuite, générez la clé pour votre client :</p>
<div class="highlight"><pre><span></span><code>$ ssh-keygen -t rsa -b <span class="m">4096</span>
Generating public/private rsa key pair.
</code></pre></div>
<p>
Il vous faut ensuite répondre à plusieurs questions. La valeur par défaut est correcte, il suffit donc d'appuyer sur Entrée à chaque fois. Pour la passphrase, laissez vide pour qu'elle ne soit pas utilisée (c'est ce que l'on veut pour la connexion automatique)</p>
<p>
Une fois la clé générée, un petit resumé est affiché :</p>
<div class="highlight"><pre><span></span><code><span class="err">Your identification has been saved in /home/utilisateur/.ssh/id_rsa.</span>
<span class="err">Your public key has been saved in /home/utilisateur/.ssh/id_rsa.pub.</span>
<span class="err">The key fingerprint is:</span>
<span class="c">XX:8a:XX:91:XX:ae:XX:23:XX:2e:XX:ed:XX:4e:XX:b8 utilisateur@machinecliente</span>
</code></pre></div>
<p>
Les deux clés (publique et privée) sont donc stockées directement dans votre dossier home, dans un dossier caché nommé .ssh/</p>
<h2 id="envoi-de-la-cle-au-serveur-tuyau-crypte">Envoi de la clé au serveur : tuyau crypté</h2>
<p><p>
Le moment délicat est arrivé. Il vous faut transmettre votre clé au serveur, de préférence via un moyen crypté. (Bah oui, envoyer la clé en clair via ftp par exemple vous expose à vous la faire piquer, et donc potentiellement pirater...)</p>
<p>
Pour ça, le meilleur moyen reste encore ssh ! Il va vous falloir une dernière fois votre mot de passe pour vous connecter au serveur. Grâce aux outils ssh, il suffit de faire :</p></p>
<div class="highlight"><pre><span></span><code>$ ssh-copy-id -i /home/login/.ssh/id_rsa.pub login@machineserveur
Password :
</code></pre></div>
<p>
Entrez votre mot de passe, et la clé sera directement copiée dans le dossier .ssh/authorized_keys de votre serveur. Ce dossier est dans le home de l'utilisateur du serveur (pas root hein ??)</p>
<div class="highlight"><pre><span></span><code><span class="err">Now try logging into the machine, with "ssh 'login@machineserveur'", and check in:</span>
<span class="err"> .ssh/authorized_keys</span>
<span class="err">to make sure we haven't added extra keys that you weren't expecting.</span>
</code></pre></div>
<p>
Une fois celà fait, vous pouvez maintenant vous connecter à votre serveur sans avoir besoin d'aucun mot de passe.</p>
<p>
Pour testez, faites donc un petit :</p>
<div class="highlight"><pre><span></span><code><span class="err">ssh login@machineserveur</span>
</code></pre></div>
<p>
La connexion doit s'effectuer sans mot de passe ! Vous pouvez maintenant utiliser à loisir ssh, scp, rsync, ... dans vos scripts !</p>
<h2 id="problemes-eventuels-il-peut-arriver-que">Problèmes éventuels : il peut arriver que...</h2>
<p><p>
Jusqu'ici, je n'ai quasiment jamais rencontré de problèmes avec l'authentification par clé.</p>
<p>
Cependant, si ça devait vous arriver, l'une des premières choses à vérifier est que les droits Unix sur le serveur sont corrects.</p></p>
<h3 id="le-serveur-continue-a-me-demander-mon-mot-de-passe">... Le serveur continue à me demander mon mot de passe !</h3>
<p><p>
C'est balot. Logguez vous sur votre serveur avec le mot de passe, et vérifiez que :</p>
<ol>
<li>
Les droits du dossier personnel de votre utilisateur sont corrects : </li></ol></p>
<div class="highlight"><pre><span></span><code>$ ls -l /home
drwxr-xr-x <span class="m">5</span> login login <span class="m">4096</span> <span class="m">3</span> jui. <span class="m">2012</span> login
</code></pre></div>
<div class="highlight"><pre><span></span><code><span class="err"> Les droits doivent être identiques à l'exemple, c'est à dire en 755. Pour eventuellement corriger ça, faites&nbsp;</span>
</code></pre></div>
<div class="highlight"><pre><span></span><code>$ chmod <span class="m">755</span> /home/login
</code></pre></div>
<div class="highlight"><pre><span></span><code> <span class="nt"><p></p></span>
<span class="nt"></li></span>
<span class="nt"><li></span>
Les droits du dossier .ssh sont corrects :
</code></pre></div>
<div class="highlight"><pre><span></span><code>$ ls -l /home/login
drwx------ <span class="m">2</span> login login <span class="m">4096</span> <span class="m">9</span> sept. <span class="m">2011</span> .ssh
</code></pre></div>
<div class="highlight"><pre><span></span><code><span class="err"> De même que précedemment, si les droits ne sont pas corrects, faites&nbsp;</span>
</code></pre></div>
<div class="highlight"><pre><span></span><code>$ chmod <span class="m">700</span> /home/login/.ssh
</code></pre></div>
<div class="highlight"><pre><span></span><code> <span class="nt"><p></p></span>
<span class="nt"></li></span>
<span class="nt"><li></span>
Les droits du fichier authorized_keys sont corrects :
</code></pre></div>
<div class="highlight"><pre><span></span><code>$ ls -l /home/login/.ssh/authorized_keys
-rw------- <span class="m">2</span> login login <span class="m">4096</span> <span class="m">9</span> sept. <span class="m">2011</span> authorized_keys
</code></pre></div>
<div class="highlight"><pre><span></span><code><span class="err"> Si ce n'est pas correct, un petit :</span>
</code></pre></div>
<div class="highlight"><pre><span></span><code>$ chmod <span class="m">600</span> /home/login/.ssh/authorized_keys
</code></pre></div>
<div class="highlight"><pre><span></span><code><span class="err"> devrait faire l'affaire</span>
<span class="err"></li></span>
</code></pre></div>
<h3 id="je-dois-utiliser-un-autre-port-que-le-port-22">... Je dois utiliser un autre port que le port 22 !</h3>
<p><p>
Il peut arriver que vous deviez utiliser la commande ssh-copy-id et que votre serveur utilise un port différent du port 22.</p>
<p>
Dans ce cas, vous remarquerez que ssh-copy-id ne prend pas l'option "-p" habituellement utilisé avec ssh.</p>
<p>
La solution est assez simple, il faut lui passer en tant qu'option ssh, de la manière suivante : </p>
<p></p></p>
<div class="highlight"><pre><span></span><code>$ ssh-copy-id -i /home/login/.ssh/id_dsa.pub <span class="s1">'-pPORT login@machineserveur'</span>
</code></pre></div>
<p>
En fait vous pouvez même passer toutes les options propres à ssh en mettant ça entre ''. (Par exemple l'algorithme de chiffrement, ...)</p>
<p></p>
<h3 id="et-si-cest-pas-ca">Et si c'est pas ça ?</h3>
<p><p>
C'est jusqu'ici les seuls problèmes que j'ai eu en utilisant correctement tous les outils ssh. Posez la question dans les commentaires :)</p></p>Installation d'un seagate dockstar 2/22012-08-13T21:54:00+02:002012-08-13T21:54:00+02:00Victortag:blog.victor-hery.com,2012-08-13:/2012/08/installation-dockstar-22.html
<h1 id="installation-de-debian-sur-le-dockstar">Installation de debian sur le dockstar</h1>
<p>Dans la première partie, nous avons déballé et branché le dockstar.</p>
<p>Nous avons également vu comment nous connecter au dockstar, bloquer ses mises à jour constructeur, etc... Pour lire la première partie, rendez vous <a href="https://blog.victor-hery.com/2012/08/installation-dockstar-12.html">ici</a></p>
<p>Maintenant, passons aux choses sérieuses : l'installation de debian sur …</p>
<h1 id="installation-de-debian-sur-le-dockstar">Installation de debian sur le dockstar</h1>
<p>Dans la première partie, nous avons déballé et branché le dockstar.</p>
<p>Nous avons également vu comment nous connecter au dockstar, bloquer ses mises à jour constructeur, etc... Pour lire la première partie, rendez vous <a href="https://blog.victor-hery.com/2012/08/installation-dockstar-12.html">ici</a></p>
<p>Maintenant, passons aux choses sérieuses : l'installation de debian sur notre dockstar ! Et pour commencer voyons un peu à quoi nous pouvons nous attendre...</p>
<h2 id="decouvrons-en-un-peu-plus">Découvrons-en un peu plus</h2>
<p>Quelques commandes de base de tout système linux vont nous permettre de découvrir un peu les capacités de ce dockstar. </p>
<p>Par exemple,</p>
<div class="highlight"><pre><span></span><code><span class="err"> uname -a</span>
</code></pre></div>
<p>nous donne :</p>
<div class="highlight"><pre><span></span><code><span class="err"> Linux Pogoplug 2.6.22.18 #57 Mon Aug 31 16:31:01 PDT 2009 armv5tejl unknown</span>
</code></pre></div>
<p>Notre dockstar tourne donc avec un linux pogoplug, plutôt minimaliste. Il est cependant possible d'en faire quelque chose :)<br/>
Nous pouvons également voir que le dockstar est monté sur une architecture ARM (comment ça on le savait déjà ?). Il nous faudra y penser lorsque nous installerons des logiciels. En effet, les architectures ARM sont inhabituelles, et certains paquets debian ne seront pas compatibles. Une recompilation à partir des sources pourra s'avérer nécessaire, mais nous en reparlerons. </p>
<p>Si nous effectuons dans la foulée un</p>
<div class="highlight"><pre><span></span><code><span class="err">cat /proc/cpuinfo</span>
</code></pre></div>
<p>nous obtenons toutes les informations sur le processeur de la bête. Architecture ARM, puissance, ... </p>
<p>Pour avoir des informations sur la mémoire RAM : </p>
<div class="highlight"><pre><span></span><code><span class="err">free -m</span>
</code></pre></div>
<p>Bien. Attaquons nous à Débian lui-même maintenant ! </p>
<h2 id="installation-de-debian">Installation de debian</h2>
<h3 id="partionnement">Partionnement</h3>
<p>Pour installer debian, il vous faut une clé USB. N'importe laquelle fonctionnera, mais je vous conseille de prendre une clé d'au moins 2Go, afin d'avoir assez d'espace pour installer diverses choses, tout en ayant de la place pour une mémoire swap. (si vous ne savez pas ce qu'est une mémoire swap, rendez-vous ici) </p>
<p>Sachez également que plus votre clé USB est de qualité et rapide, plus le système sera réactif. </p>
<p>Pour permettre l'utilisation du système, il va vous falloir brancher votre clé sur le port usb à gauche quand vous regardez votre dockstar de derrière. Sinon, il risque d'y avoir des conflits avec le périphérique USB qui sera éventuellement branché sur cette prise. En effet, ce port est considéré comme sda par le système pogoplug, et donc prioritaire.<br/>
Branchez donc votre clé sur ce port. </p>
<p>Vérifiez grâce à</p>
<div class="highlight"><pre><span></span><code><span class="err">/sbin/fdisk -l</span>
</code></pre></div>
<p>si votre clé est bien détectée sur sda. Nous allons maintenant la formater proprement avant installation. </p>
<p>Lancez</p>
<div class="highlight"><pre><span></span><code><span class="err">/sbin/fdisk /dev/sda</span>
</code></pre></div>
<p>Vous êtes maintenant dans l'interface de configuration de ce magnifique utilisaire qu'est fdisk. Très puissant, mais il faut l'avouer un peu frustre. Qu'importe, allons-y :) </p>
<p>Tapez d pour effacer les éventuelles partitions déjà existantes. Validez par Enter. </p>
<p>Ensuite, tapez n pour créer une nouvelle partition. Choisissez primary, puis le numéro 1 pour cette partition. Décidez de votre taille, variable selon la capacité de votre clé. N'oubliez pas de garder un peu d'espace pour le swap. Je vous conseille un swap de 512Mo, pour compenser le peu de RAM que possède le dockstar.<br/>
Une fois cette partition créée, tapez de nouveau n, puis créez la deuxième partition pour le swap (primary, partition n°2). Bien sûr, vous pouvez créer autant de partitions que vous voulez, mais une partition primaire et une autre pour le swap sont suffisantes. </p>
<p>Une fois votre partionnage terminé, tapez t, puis entrez le numéro de partition swap (2 dans notre exemple). Entrez ensuite 82 pour définir cette partition comme swap linux.<br/>
Il ne reste plus qu'à taper w pour écrire les partitions et enregistrer les modifications. </p>
<h3 id="telechargement">Téléchargement</h3>
<p>Maintenant que notre clé est prête, nous allons commence le téléchargement et l'installation de Debian. </p>
<p>Tapez</p>
<div class="highlight"><pre><span></span><code><span class="err">cd /tmp</span>
</code></pre></div>
<p>pour aller dans la partie temporaire du système. Tout ce qui est placé dans ce dossier est supprimé à chaque reboot. C'est fort pratique pour télécharger des fichiers temporaires, comme des sources par exemple, qui seront supprimées une fois le logiciel installé. </p>
<p>On télécharge debian squeeze :</p>
<div class="highlight"><pre><span></span><code><span class="err">wget http://jeff.doozan.com/debian/dockstar.debian-squeeze.sh</span>
<span class="err">chmod +x dockstar.debian-squeeze.sh</span>
<span class="err">export PATH=$PATH:/usr/sbin:/sbin</span>
<span class="err">./dockstar.debian-squeeze.sh</span>
</code></pre></div>
<p>Répondez "Ok" à la première question. Surtout, ne débranchez pas le dockstar pendant le téléchargement, au risque de le rendre hors d'état.<br/>
Le script d'installation va installer uBoot, pour permettre de booter sur une clé USB, ce que par défaut le dockstar ne permet pas. </p>
<p>Les mises à jour automatiques du pogoplug sont désactivées, puis l'installation commence. Il y en a pour 15-20 minutes selon votre connexion. Chaque package est téléchargé et validé, vous pouvez regarder les différents modules installés pour en apprendre plus sur une distribution linux si vous le souhaitez :-) </p>
<p>Enfin, le script vous informe que le mot de passe root par défaut sera root. Assez peu sécurisé, nous le changerons dès la connexion. Tapez Y quand le script vous demande de redémarrer. </p>
<p>Il n'y a plus qu'à attendre que le dockstar ne redémarre. Il met environ une 30aine de secondes, mais vous pouvez décider de le pinguer jsuqu'à ce qu'il réponde pour gagner du temps. Il reprendra la même IP qu'au début, sauf si vous avez un serveur DHCP, auquel cas il risque de lui donner une autre adresse. Utilisez netdiscover ou nmap pour le découvrir si vous n'arrivez pas à vous connecter. </p>
<h3 id="configuration-de-debian">Configuration de Debian</h3>
<p>Connectez vous en ssh sur le dockstar avec le login <code>root</code>, mot de passe <code>root</code>.</p>
<p>Utilisez tout de suite</p>
<div class="highlight"><pre><span></span><code><span class="err">passwd</span>
</code></pre></div>
<p>pour changer le mot de passe root. Choisissez le mot de passe qui vous convient. </p>
<p>L'installation de tous les services que vous désirez se passe maintenant comme dans un système debian classique, avec apt-get et apt-cache. </p>
<p>Pour ce qui est de la configuration en elle-même du dockstar, il est probable que vous souhaitiez installer un serveur FTP pour accéder à vos disque dur externe, ainsi que le système de partage de fichier windows Samba. </p>
<p>Pour cela :</p>
<div class="highlight"><pre><span></span><code><span class="err">apt-get install pure-ftpd samba</span>
</code></pre></div>
<p>J'utilise pure-ftp comme serveur ftp car il permet une gestion simple des utilisateurs, mais vous pouvez bien sûr utiliser le serveur qui vous sied le mieux. </p>
<p>Je vous conseille également à titre personnel d'installer aptitude pour mieux gérer les paquets, nano pour faire de l'édition de texte plus simple qu'avec vi, ntp pour maintenir le système à l'heure, et screen pour utiliser plusieurs terminals sur le même écran. </p>
<div class="highlight"><pre><span></span><code><span class="err">apt-get install aptitude screen nano ntp</span>
</code></pre></div>
<h2 id="et-voila">Et voila !</h2>
<p>Et voila, votre dockstar est completement fonctionnel sous debian ! Si jamais votre clé USB plante, il vous suffira de réinstaller tout ça sur une nouvelle clé. Vous pouvez également faire un backup de votre clé sur votre PC personnel, surtout si vous avez mis en place une configuration pointue. </p>
<p>Pour ma part, j'utilise mon dockstar 24/24 comme serveur FTP, serveur de backup avec rsync, partage de fichier samba et serveur de version type Dropbox grâce à <a href="sparkleshare.org/">sparkleshare</a>. Il faut avouer qu'il marche parfaitement, et ce depuis plus de 7 mois maintenant :) </p>
<p>Attention par contre à ne pas trop lui en demander. Il peut héberger un serveur web, mais préférez un serveur léger type <a href="nginx.net/">Nginx</a> à apache.<br/>
Sachez également qu'un serveur de mail postfix/dovecot peut tourner, mais après tests, installer les applications qui s'imposent à côté (type spamassassin) a eu pour résultat de saturer la mémoire RAM et de planter le dockstar. Il peut être intéressant de se servir du dockstar comme test pour vous amuser si vous voulez :)<br/>
Puis de vous construire un petit serveur personnel ensuite ! S'auto-héberger reste une solution viable et intéressante pour s'amuser ! Référez vous aux articles sur Dovecot, postfix et autre de ce site si vous avez apprécié cet article. </p>
<h2 id="sources">Sources</h2>
<p><a href="blog.crifo.org/post/2010/10/02/Seagate-DockStar-deballage-et-installation-de-debian">Installation et déballage d'un Seagate Dockstar</a></p>
<p><a href="www.debianaddict.org/article71.html">Installation et utilisation de pure ftp</a></p>
<p><a href="nginx.net/">Nginx</a></p>
<p><a href="blog.crifo.org/post/2010/10/09/Partager-ses-donnees-avec-samba-depuis-Linux">Installation de samba sur Linux</a></p>
<p><a href="www.commentcamarche.net/faq/9773-my-sql-reinitialiser-le-mot-de-passe-root">Si vous oubliez votre mdp root mysql</a> ;)</p>Installation d'un seagate dockstar 1/22012-08-12T21:54:00+02:002012-08-12T21:54:00+02:00Victortag:blog.victor-hery.com,2012-08-12:/2012/08/installation-dockstar-12.html
<h1 id="deballage-et-configuration-initiale">Déballage et configuration initiale</h1>
<p>Bienvenue sur cet article, dont l'objectif du jour va être de vous expliquer au mieux et simplement, comment installer, mettre en place et utiliser un système d'exploitation Debian sur la plate-forme matérielle Seagate Dockstar FreeAgent.</p>
<h2 id="presentation">Présentation :</h2>
<p>Le Seagate Dockstar FreeAgent est un système vendu par Seagate …</p>
<h1 id="deballage-et-configuration-initiale">Déballage et configuration initiale</h1>
<p>Bienvenue sur cet article, dont l'objectif du jour va être de vous expliquer au mieux et simplement, comment installer, mettre en place et utiliser un système d'exploitation Debian sur la plate-forme matérielle Seagate Dockstar FreeAgent.</p>
<h2 id="presentation">Présentation :</h2>
<p>Le Seagate Dockstar FreeAgent est un système vendu par Seagate à l'origine pour permettre à ses clients d'accéder à leur disques durs (branchés sur le Dockstar) depuis leur interface web, accessible via un abonnement mensuel, plutôt cher. Dès le début, ça n'a pas marché, les prix ont chutés, Seagate à diminué drastiquement les coûts de l'abonnement mensuel et de la machine en elle-même, sans résultats probant sur les ventes. Jusqu'au jour où...</p>
<p>Jusqu'au jour où un petit malin s'est rendu compte que cette sympathique machine disposait d'un accès root ssh débloqué, et qu'à ce titre il était tout à fait possible d'installer un système d'exploitation Debian Squeeze, débloquant ainsi complètement les possibilités de la machine pour en faire un serveur personnel à moindre coût, performant et surtout consommant une quantité ridicule de courant (8Watts à pleine charge).</p>
<p>Dès lors, il est devenu assez difficile de s'en procurer, et les prix ont grimpés, même si Seagate a désespérément tenté différentes mises à jour pour bloquer cet accès ssh et ainsi enrayer le détournement de son matériel.</p>
<p>Le but de cet article est de vous montrer comment utiliser le Dockstar pour justement éviter ces mises à jour, installer un système d'exploitation Debian pleinement fonctionnel, puis certains services intéressants même pour un usage personnel. (la puissance de la machine restant relativement limité)<br/>
Pour plus d’information sur le Dockstar lui-même, voyez [ici)(www.seagate.com/www/fr-fr/products/network_storage/freeagent_dockstar/#tTabContentOverview)</p>
<p>Je tiens à signaler que le blog de Dju m'a été d'une grande aide pour écrire cet article :</p>
<p><a href="blog.crifo.org/post/2010/10/02/Seagate-DockStar-deballage-et-installation-de-debian">Installation et déballage d'un Seagate Dockstar</a></p>
<p>Vous trouverez un détail des sources m'ayant servit pour cet article à la fin de l'article.</p>
<h2 id="demarrage-et-decouverte">Démarrage et découverte</h2>
<p>Tout d'abord, il va vous falloir déballer puis brancher votre Dockstar.<br/>
<strong>ATTENTION!</strong> <em>Pour brancher le cable réseau, faites impérativement attention à ce qu'il ne soit pas relié à Internet ! Auquel cas, le Dockstar téléchargerait automatiquement ses dernières mises à jour, désactivement irrémédiablement l'accès ssh, rendant ainsi votre Dockstar inutile pour toute la suite de cet article. Utilisez donc un switch ou un routeur non relié à Internet, ou branchez directement votre Dockstar à votre ordinateur (celui-ci n'étant bien sûr pas configuré pour servir de passerelle Internet)</em></p>
<p>Une fois ce branchement effectué, nous allons pouvoir attaquer le vif du sujet. La diode à l'avant du Dockstar doit clignoter en orange, vous indiquant qu'il ne parviens pas à télécharger ses mises à jour, ce qui nous convient parfaitement. Pas lieu de s'inquiéter de ce frénétique clignotement orange donc :)</p>
<p>Ici, deux cas :<br/>
- Vous avez branché votre Dockstar sur un routeur utilisant le DHCP, auquel cas le Dockstar et votre ordinateur disposent d'une adresse IP automatiquement attribuée, il vous suffit de trouver laquelle
possède le Dockstar. Vraisemblablement, utiliser l'interface du routeur est une bonne idée, si vous êtes dans ce cas vous êtes sans doute à même de récupérer cette information d'après le modèle de routeur que vous utilisez.<br/>
- Vous avez branché votre Dockstar sur un switch ou sur votre ordinateur, le Dockstar va donc utiliser son adresse IP par défaut, qu'il va vous falloir découvrir.</p>
<p>Deuxièmement, deux nouveaux cas :<br/>
- Vous êtes sous un système Unix (Linux ou Mac OS). Dans ce cas, peu de problème, vous disposez d'un terminal à même de remplir tous les services possibles. Vous devez avoir les applications ifconfig, ssh et nmap d'installées par défaut. Pour plus de rapidité, vous pouvez installer netdiscover à la place de nmap (aptitude install netdiscover sur une Debian like)<br/>
- Vous êtes sous un système Windows. Pour une fois, on ne vous en voudra pas, tout le monde ne peut pas être parfait, au moins vous avez acheté un Dockstar et vous êtes curieux, parfait :)<br/>
- Vous allez devoir télécharger les outils. Récupérez donc nmap et putty. Nmap va vous permettre de trouver l'adresse du Dockstar, putty de vous y connecter en ssh.</p>
<p>Nous sommes prêts pour la suite. </p>
<p>Le Dockstar prend par défaut une adresse IP du type 169.254.xxx.xxx. Pour la trouver, il va donc falloir que vous configuriez votre interface réseau en conséquence, puis que vous scanniez les différents matériels existant sur votre réseau. </p>
<p><strong>Linux et Mac OS :</strong> </p>
<p>Rien de bien compliqué. Ouvrez un terminal, logguez vous en administrateur (ou utilisez sudo), puis reconfigurez votre interface réseau : </p>
<div class="highlight"><pre><span></span><code><span class="err">ifconfig eth0 169.254.1.0/16</span>
</code></pre></div>
<p>Scannez le réseau pour trouver l'adresse du Dockstar : </p>
<div class="highlight"><pre><span></span><code><span class="err">netdiscover -r 169.254.0.0/16 -P</span>
</code></pre></div>
<p>Ou avec nmap : </p>
<div class="highlight"><pre><span></span><code><span class="err">nmap 169.254.0.0/16</span>
</code></pre></div>
<p>Notez que nmap est beaucoup plus long que netdiscover. Vu qu'il va falloir scanner 254*254 adresses, mieux vaut utiliser un outil le plus rapide possible ;-) </p>
<p>Avec netdiscover, vous obtenez quelque chose dans ce goût là : </p>
<div class="highlight"><pre><span></span><code><span class="n">Currently</span> <span class="n">scanning</span><span class="p">:</span> <span class="mi">169</span><span class="p">.</span><span class="mi">254</span><span class="p">.</span><span class="mi">87</span><span class="p">.</span><span class="mi">0</span><span class="o">/</span><span class="mi">16</span> <span class="o">|</span> <span class="n">Our</span> <span class="n">Mac</span> <span class="k">is</span><span class="p">:</span> <span class="mi">00</span><span class="p">:</span><span class="mi">1</span><span class="n">e</span><span class="p">:</span><span class="mi">8</span><span class="k">c</span><span class="p">:</span><span class="n">xx</span><span class="p">:</span><span class="n">xx</span><span class="p">:</span><span class="n">xx</span> <span class="o">-</span> <span class="mi">0</span>
<span class="mi">1</span> <span class="n">Captured</span> <span class="n">ARP</span> <span class="n">Req</span><span class="o">/</span><span class="n">Rep</span> <span class="n">packets</span><span class="p">,</span> <span class="k">from</span> <span class="mi">1</span> <span class="n">hosts</span><span class="p">.</span> <span class="n">Total</span> <span class="k">size</span><span class="p">:</span> <span class="mi">60</span>
<span class="n">_____________________________________________________________________________</span>
<span class="n">IP</span> <span class="k">At</span> <span class="n">MAC</span> <span class="n">Address</span> <span class="k">Count</span> <span class="n">Len</span> <span class="n">MAC</span> <span class="n">Vendor</span>
<span class="c1">-----------------------------------------------------------------------------</span>
<span class="mi">169</span><span class="p">.</span><span class="mi">254</span><span class="p">.</span><span class="mi">214</span><span class="p">.</span><span class="mi">19</span> <span class="mi">00</span><span class="p">:</span><span class="mi">10</span><span class="p">:</span><span class="mi">75</span><span class="p">:</span><span class="n">xx</span><span class="p">:</span><span class="n">xx</span><span class="p">:</span><span class="n">xx</span> <span class="mi">01</span> <span class="mi">060</span> <span class="n">Maxtor</span> <span class="n">Corporation</span>
</code></pre></div>
<p>L'adresse de votre Dockstar est donc le 169.254.214.19 (adaptez ici avec ce que vous obtenez comme résultat bien sûr) </p>
<p>Si vous utilisez ou utiliserez pour la connexion à Internet un serveur DHCP, vous pouvez noter l'adresse MAC du Dockstar pour le configurer en IP fixe dans votre serveur DHCP. Ainsi, il sera toujours facilement accessible plus tard. </p>
<p><strong>Windows :</strong> </p>
<p>Sous Windows, une fois téléchargé nmap, il vous faudra le dézipper, puis vous rendre dans le dossier avec un terminal DOS. Utilisez cd dans votre terminal pour atteindre le dossier de nmap. </p>
<p>Il va également falloir reconfigurer votre interface réseau avec l'adresse 169.254.1.0 et le netmask 255.255.0.0. </p>
<p>Ensuite, retournez sur votre terminal, et entrez </p>
<div class="highlight"><pre><span></span><code><span class="err">nmap -sP 169.254.1.0/16</span>
</code></pre></div>
<p>Il vous faut ensuite attendre que nmap scanne le réseau et découvre l'adresse du Dockstar. Cela peut être un peu long (ok, très long), donc dès que vous voyez apparaître une ligne du type host 169.254.214.19 is UP, vous pouvez faire ctrl+C pour arrêter le scan : vous avez trouvé votre Dockstar. Notez bien son adresse IP. </p>
<h2 id="connexion">Connexion :</h2>
<p>Voila, vous avez l'adresse IP du Dockstar, vous êtes donc prêts à vous connecter dessus et à mettre les mains dans le cambouis. </p>
<p>Pour cela, connectez vous en ssh : </p>
<p><strong>Sous Mac OS/Linux ;</strong> </p>
<div class="highlight"><pre><span></span><code><span class="n">ssh</span> <span class="n">root</span><span class="mf">@169.254.214.16</span>
</code></pre></div>
<p>puis mot de passe <code>stxadmin</code></p>
<p><strong>Sous Windows</strong>, lancez putty, entrez l'adresse Ip du Dockstar, puis logguez vous en root avec le mot de passe stxadmin.</p>
<p>Globalement, accès ssh :<br/>
- Identifiant : root<br/>
- Mot de passe : stxadmin </p>
<p>Notez que le Dockstar a également un accès telnet de débloqué, mais nous préférerons utiliser ssh, plus sécurisé (Même si vous êtes en connexion directe avec le Dockstar pour l'instant, ce n'est pas une raison pour négliger cet aspect ;) Et ça donne de bonnes habitudes) </p>
<p>Vous voilà donc connecté sur la bête ! </p>
<h2 id="connecte">Connecté !</h2>
<p>Une fois connecté, la toute première chose à faire est de monter la partition du système en lecture/écriture, car elle est par défaut uniquement autorisée à la lecture. Pour se faire : </p>
<div class="highlight"><pre><span></span><code><span class="err">mount / -rw -o remount</span>
</code></pre></div>
<p>Deuxième chose importante, empêcher le système de se mettre à jour une fois qu'il se sera connecté à Internet, histoire d'éviter les désagrément du type désactivation de l'accès ssh/telnet. Pour cela, on va indiquer au Dockstar que les adresses sur lesquelles il se connecte pour se mettre à jour sont en fait lui-même (localhost). Ainsi, il va tourner en boucle en demandant à lui-même ses mises à jour, n'obtenant jamais de réponse. On est ainsi sûr qu'il ne se mettra pas à jour : </p>
<div class="highlight"><pre><span></span><code><span class="err"> echo "127.0.0.1 service.pogoplug.com" > /etc/hosts</span>
<span class="err"> echo "127.0.0.1 pm1.pogoplug.com" >> /etc/hosts</span>
<span class="err"> echo "127.0.0.1 pm2.pogoplug.com" >> /etc/hosts</span>
<span class="err"> echo "127.0.0.1 service.cloudengines.com" >> /etc/hosts</span>
<span class="err"> echo "127.0.0.1 upgrade.pogoplug.com" >> /etc/hosts</span>
</code></pre></div>
<p>Ceci est en fait une précaution nécessaire. Pour optimiser cette solution, nous allons carrément empêcher le service popoplug de se lancer au démarrage, ça fera de la ressource supplémentaire, et on en entendra plus parler :) </p>
<p>Editez le fichier /etc/init.d/rcS avec un bon vieux : </p>
<div class="highlight"><pre><span></span><code><span class="err">vi etc/init.d/rcS</span>
</code></pre></div>
<p>(Si vous ne maitrisez pas vi, un petit aperçu des commandes principales pourrait vous être utile : <a href="fr.wikipedia.org/wiki/Vi#D.C3.A9buter_avec_vi">Débuter avec vi</a>)</p>
<p>Dans ce fichier, cherchez la ligne « /etc/init.d/hbmgr.sh start » et mettez là en commentaire : </p>
<div class="highlight"><pre><span></span><code><span class="err">/etc/init.d/hbmgr.sh start</span>
</code></pre></div>
<p>devient : </p>
<div class="highlight"><pre><span></span><code><span class="err"> #/etc/init.d/hbmgr.sh start</span>
</code></pre></div>
<p>Le # sert de commentaire dans ce fichier. </p>
<p>Voila le préambule à la connexion effectué. Maintenant, vous pouvez connecter votre Dockstar en toute sécurité sur Internet, il ne pourra plus se mettre à jour, ni vous ennuyer. </p>
<p>Cependant, avant d'aller plus loin, poussons la curiosité et découvrons un peu ce qu'il a dans le ventre. </p>
<p>La deuxième partie est disponible <a href="https://blog.victor-hery.com/2012/08/installation-dockstar-22.html">ici</a></p>Premier article...2012-08-12T10:20:00+02:002012-08-12T19:30:00+02:00Victortag:blog.victor-hery.com,2012-08-12:/2012/08/premier-article.html<p>... car il en faut bien un, s'pas ?</p>
<p>Bonjour, à tous et bienvenue.</p>
<p>Finalement, je me décide à créer un blog, après quelques autres tentatives plus ou moins fructueuses pour écrire et partager des tutoriels sur des choses qui m'intéressent.</p>
<p>J'espère que ce blog ne mourra pas dans l'oeuf (ça reste …</p><p>... car il en faut bien un, s'pas ?</p>
<p>Bonjour, à tous et bienvenue.</p>
<p>Finalement, je me décide à créer un blog, après quelques autres tentatives plus ou moins fructueuses pour écrire et partager des tutoriels sur des choses qui m'intéressent.</p>
<p>J'espère que ce blog ne mourra pas dans l'oeuf (ça reste une option à ne pas ignorer smiley). En tout cas, je tâcherai de poster des articles et des tutos sur les sujets globaux de systèmes et réseaux.</p>
<p>(Effectivement ça rime)</p>
<p>Si je me sens en forme d'ailleurs, je rédigerai mes postes en alexandrins (parce que c'est marrant).</p>
<p>Plus sérieusement, je tâcherai de faire en sorte de ne pas m'ennuyer ici, et du coup que mes visiteurs en fassent de même !</p>
<p>Bonne journée, et bonne lecture.</p>