diff --git a/content/add.sh b/content/add.sh
new file mode 100755
index 0000000..5f5441d
--- /dev/null
+++ b/content/add.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+if [[ -z "$@" ]]; then
+ echo "add.sh
"
+ exit 1
+fi
+title="$@"
+filename="$(echo $@ | tr ' ' '_' | tr '[:upper:]' '[:lower:]')"
+if [[ -e $filename.md ]]; then
+ echo "$filename.md already exists"
+ exit 1
+fi
+echo "Title: $title" >> $filename.md
+echo "Date: $(date -Iminutes)" >> $filename.md
+echo "Author: Wxcafé" >> $filename.md
+echo "Category: " >> $filename.md
+echo "Slug: " >> $filename.md
+echo -e '\n'>> $filename.md
+vim +7 $filename.md -s <( echo -n A)
diff --git a/content/envie-partout-temps-nulle-part.md b/content/envie-partout-temps-nulle-part.md
new file mode 100644
index 0000000..13fea24
--- /dev/null
+++ b/content/envie-partout-temps-nulle-part.md
@@ -0,0 +1,30 @@
+Title: Envie partout, temps nulle part
+Date: 2016-06-13T09:11+02:00
+Author: Wxcafé
+Category: Note
+Slug: envie-partout-temps-nulle-part
+
+Ça fait assez longtemps que j'ai pas posté ici, j'en suis bien conscient, et
+j'écris donc ce petit post pour dire que c'est le cas, pourquoi c'est le cas, et
+que ça va pas durer.
+
+J'ai beaucoup de choses qui me prennent pas mal de temps en ce moment,
+notamment:
+
+- un boulot, je suis en stage
+- la rédaction d'un rapport, puisque... je suis en stage
+- la recherche d'une alternance, pour l'an prochain
+- un bon nombre de démarches administratives variées
+- insert autre raison here.
+
+par contre, j'ai /énormément/ de choses dont j'aimerais parler, notamment:
+
+- de la redondance de routeurs, avec CARP, PfSync, dhcpsync et ifstated
+- du backup de confs réseau avec Oxidized
+- des mésaventures avec debian et nvidia
+- du junk hacking sur une liseuse ukrainienne
+- des backups automatisés via puppet
+- encore d'autres trucs, que j'ai oublié la comme ça mais ça va revenir
+
+
+Du coup, vous inquietez pas, j'ai pas oublié ce blog, et je reviens vite.
diff --git a/content/let's_encrypt.md b/content/let's_encrypt.md
new file mode 100644
index 0000000..7c67ee1
--- /dev/null
+++ b/content/let's_encrypt.md
@@ -0,0 +1,165 @@
+Title: Let's Encrypt, enfin
+Date: 2015-12-13T18:48+0100
+Author: Wxcafé
+Category: Tutoriel
+Slug: lets-encrypt-enfin
+
+Vous avez peut être vu que ce blog, entre autres sites que j'administre, n'est
+disponible depuis quelques jours qu'en HTTPS, et avec un certificat valide. Bon,
+si vous êtes là, vous avez déjà entendu parler de Let's Encrypt, mais pour les
+deux trois du fond on va résumer:
+
+LE est une nouvelle autorité de certification (ceux qui valident les certificats
+SSL), basée sur une organisation, et dont le but est de fournir des certificats
+valides, automatiquement et gratuitement. Leur certificat racine est signé par
+IdenTrust, et est donc considéré valide par tous les navigateurs modernes.
+
+Bon, maintenant qu'on est tous au même point, voyons comment ça marche. Depuis
+dix jours LE est ouvert en bêta publique, donc il n'est plus nécessaire de
+préciser les domaines pour lesquels on veut un certificat sur un formulaire,
+comme c'était le cas pendant la période de bêta fermée. Le système qui est
+utilisé repose sur le protocole ACME (Automatic Certificate Management
+Environment), qui automatise complètement la signature des certificats. Du coup,
+les certificats que délivre LE ne sont valides que 90 jours, ce qui serait super
+chiant avec une autorité de certification classique, mais qui la veut simplement
+dire qu'il faut mettre un cron en place.
+
+Bref, comment mettre en place vos certificats? On va faire ça sans trop modifier
+vos sites, et en automatisant au maximum. LE utilise, dans son système par
+défaut, un fichier sur le site web, dont le serveur de certification vérifie
+l'existence lors de la requête (si le fichier est présent avec le bon contenu,
+c'est que le client tourne bien sur ce domaine, et donc que la personne qui
+a demandé le certificat contrôle bien le domaine). Ce fichier est situé dans un
+dossier dans la racine, `.well-known`. Plutôt que de se faire chier a gérer ce
+dossier pour tous nos vhosts nginx, on va simplement créer un alias vers un
+dossier commun sur le système de fichier, que tous les vhosts partagerons, et
+qui permettra aussi de valider tous les domaines pour lesquels on veut un
+certificat à la fois (avec un AltName) (sur un seul serveur, par contre. Enfin
+si vous voulez vraiment vous pouvez faire des mounts cross-serveurs (avec du
+sshfs ou des trucs du genre), mais c'est un peu sale quand même. Et faudra quand
+même distribuer le certificat après, donc bon...).
+
+Donc, on va rajouter ça dans nos blocs `server` :
+
+```shell
+location /.well-known {
+ alias /srv/letsencrypt/.well-known;
+}
+```
+
+(bien sûr il faut créer le dossier, hein.)
+Après, on `git clone https://github.com/letsencrypt/letsencrypt`, dans `/opt/` ou
+dans `/usr/local/`, peu importe, on le clone quelque part, et on cd dans le
+dossier en question. Une fois là, on demande un certificat :
+
+```shell
+sudo ./letsencrypt-auto certonly \
+ -a webroot \
+ --webroot-path /srv/letsencrypt/ \
+ -d \
+ -d \
+ -d \
+ --server https://acme-v01.api.letsencrypt.org/directory
+```
+
+Normalement, maintenant, on a un certificat valide dans
+`/etc/letsencrypt/live//`. Reste à configurer nginx pour qu'il serve
+nos sites en https en utilisant notre nouveau certificat. Perso, j'utilise une
+template qui ressemble à ça :
+
+```shell
+server {
+ listen 80;
+ listen [::]:80;
+ server_name SERVERNAME;
+ return 302 https://$server_name$request_uri;
+}
+
+server {
+ listen 443 ssl;
+ listen [::]:443 ssl;
+ ssl_certificate /etc/letsencrypt/live/DOMAIN/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/DOMAIN/privkey.pem;
+ ssl_dhparam /etc/nginx/dhparams.4096;
+ ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
+ ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";
+ ssl_prefer_server_ciphers on;
+ add_header Strict-Transport-Security "max-age=15552000; includeSubDomains; preload";
+
+ root SERVERROOT;
+
+ index index.html index.htm;
+
+ server_name SERVERNAME;
+
+ server_tokens off;
+ client_max_body_size 5m;
+
+ access_log /var/log/nginx/access.log;
+ error_log /var/log/nginx/error.log;
+
+ location /.well-known {
+ alias /srv/letsencrypt/.well-known;
+ }
+
+ location / {
+ try_files $uri $uri/ =404;
+ }
+}
+```
+
+Alors c'est pas /tout à fait ça/ d'un point de vue parano du TLS (genre je
+devrais désactiver TLS 1.0 et EECDH+aRSA+RC4, notamment) mais ça marche pas trop
+mal et c'est plus compatible comme ça (mon telephone est sous Android 4.4, donc
+je suis content d'avoir encore TLS 1.0 par exemple).
+
+Vous pouvez ajouter votre domaine à la liste préloadée dans Chrome/ium, Firefox,
+IE, Edge, Safari, le Tor Browser Bundle, etc...
+[ici](https://hstspreload.appspot.com/) (oui ça fait clairement site de
+phishing, mais apparemment c'est serieux...)
+
+Enfin, il nous faut un renouvellement automatique, puisque notre certificat ne
+sera valide que 90 jours. On va utiliser un cron tout con, avec un script :
+
+```shell
+00 01 */14 * * /usr/local/bin/cert-renew 2>&1 | mail -s "certificates renewal report"
+```
+
+(oubliez pas que ça doit aller dans le crontab du root)
+Et le script qui va bien :
+
+```shell
+#!/bin/bash
+
+if [[ $UID != 0 ]]; then
+ echo "please run as root"
+ exit 1
+fi
+
+cd /opt/letsencrypt/
+
+git pull 2>&1 >> /dev/null
+
+
+# Renewing the cert
+./letsencrypt-auto certonly \
+ -a webroot --webroot-path /srv/letsencrypt \
+ -d \
+ -d \
+ -d \
+ --server https://acme-v01.api.letsencrypt.org/directory \
+ --renew \
+ 2>&1
+
+systemctl restart nginx
+exit 0
+```
+
+Notez bien le `--renew` qui spécifie qu'on renouvelle le certificat, le `git pull`
+qui met à jour le client, et le `systemctl restart nginx` qui prend en compte le
+nouveau certificat automatiquement
+
+Et puis voilà, normalement avec ça vous devriez pouvoir chopper des certificats
+valides. C'est plutôt cool, en pratique.
+
+Merci Let's Encrypt
diff --git a/content/openvpn-openbsd.md b/content/openvpn-openbsd.md
new file mode 100644
index 0000000..9f4bd4b
--- /dev/null
+++ b/content/openvpn-openbsd.md
@@ -0,0 +1,174 @@
+Title: OpenVPN on OpenBSD
+Date: 2016-11-30T23:59+01:00
+Author: Wxcafé
+Category: Tutorial
+Slug: openvpn-openbsd
+
+So this is a small article, because I wanted to see if I could write more if
+I just wrote small things like that about a single, simple thing I did, without
+too much detail and fluff
+
+Also, I'm writing this in English, while I usually write in French. I'm
+switching language because I believe English is a lot easier to express
+technical concepts in, or at least I'm more fluent in it when it comes to
+expressing technical concepts, and I believe now that my audience (at least, the
+people I know/talk to on twitter/IRC/etc...) speak or read English much more
+than French, and so it makes more sense for me to write in English here.
+Therefore, I'll be writing in English only on this blog from now on.
+
+
+(French version :)
+De plus, j'écris ceci en Anglais, alors que j'écrivais ici habituellement en
+Français. Je change de langue, parce qu'il me semble qu'il est plus facile
+d'exprimer des concepts techniques en Anglais qu'en Français, ou en tout cas
+que cela m'est plus facile personnellement, mais aussi parce que je pense que
+mon audience (ou en tout cas, les gens que je connais/auxquels je parle sur
+twitter/IRC/etc...), parlent ou lisent l'Anglais bien plus que le Français, et
+il est donc plus logique pour moi d'écrire en Anglais ici.
+J'écrirais donc uniquement en Anglais sur ce blog a partir de maintenant.
+
+So, now that that's done, I can go on and write that "small article" I promised
+at the top.
+
+So, the idea is that I had a FreeBSD OpenVPN box that I used to have
+a semi-decent Internet connection while at school (my school blocks all ports
+that are not tcp/80 or tcp/443 or udp/53, basically. And apparently udp/443
+too...). I wanted to try running that VM on OpenBSD, because of three things :
+
+1. I really like OpenBSD, and wanted to have a VM that I could do some
+experiments on without breaking all of my stuff,
+2. I found a way to run OpenBSD on the provider I used for that box,
+[vultr](https://vultr.com), and
+3. why not?
+
+Anyway, so once you've installed the OS, the first thing to do is
+
+ ::bash
+ $ doas pkg_add openvpn
+
+...
+
+well okay the first thing to do is to
+
+ # vi /etc/doas.conf
+
+and put this in it :
+
+ ::bash
+ permit keepenv :wheel as root
+ permit nopass root as root
+
+once this is done, you can now go and install the packages, before creating the
+CA:
+
+ $ doas pkg_add vim openvpn easy-rsa
+ $ cd /usr/local/share/easy-rsa
+ $ doas ./easyrsa init-pki
+ $ doas ./easyrsa gen-dh
+ $ doas ./easyrsa build-ca [nopass]
+ $ doas ./easyrsa build-server-full [CN of the server] [nopass]
+ $ doas ./easyrsa build-client-full [CN of a client] [nopass]
+
+please note that you can use passwords on all of those, but then you'll have to
+type them every time you use one of them. I see no problem with having
+a password on the CA and the client, but the server should be able to restart by
+itself in my opinion.
+
+Anyway, now we can write the config for OpenVPN:
+
+ $ doas mkdir /etc/openvpn/
+ $ doas vim /etc/openvpn/openvpn.conf
+
+We'll run with these settings :
+
+ dev tap
+ tls-server
+ cert /usr/local/share/easy-rsa/pki/issued/[CN of the server].crt
+ key /usr/local/share/easy-rsa/pki/private/[CN of the server].key
+ ca /usr/local/share/easy-rsa/pki/ca.crt
+ dh /usr/local/share/easy-rsa/pki/dh.pem
+ proto udp
+ port 53
+ verb 3
+ status /var/log/openvpn-status.log
+ ifconfig 172.16.0.10 255.255.0.0
+ route-gateway 172.16.0.10
+ persist-key
+ persist-tun
+ keepalive 10 120
+ server 172.16.0.0 255.255.0.0
+ client-to-client
+ tls-cipher TLS-DHE-RSA-WITH-AES-256-CBC-SHA TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA
+ push "route 172.16.0.0 255.255.0.0"
+
+Of course, feel free to edit that to match whatever you need.
+
+Anyway, the next thing we need to do is to configure pf.
+
+What, you thought that was it? Of course we're gonna filter this, it's an
+internet-facing server!
+
+ $ doas vim /etc/pf.conf
+
+So, here is the pf configuration file :
+
+ # $OpenBSD: pf.conf,v 1.54 2014/08/23 05:49:42 deraadt Exp $
+ #
+ # See pf.conf(5) and /etc/examples/pf.conf
+
+ set block-policy drop
+ set skip on lo0
+ block return in on ! lo0 proto tcp to port 6000:6010
+ match in all scrub (no-df random-id max-mss 1440)
+
+ block log all
+
+ match out on egress from (tap0:network) to any nat-to (egress:0)
+ pass out quick
+
+ # ssh
+ pass in on egress proto tcp from any to (egress) port 22
+
+ # mosh
+ pass in on egress proto udp from any to any port 60000:61000
+
+ # snmp
+ pass in on egress proto udp from [IP of my SNMP server] to any port 161
+ pass in on egress proto udp from [IPv6 block of my SNMP server]/48 to any port 161
+
+ # openvpn
+ pass in on egress proto udp from any to (egress) port 53
+ pass in on egress proto udp from any to (egress) port 443 rdr-to (egress:0) port 53
+ pass in on tap0
+
+So, this should be easy enough to read, but just in case : we skip lo, we block
+X, we scrub weird packets, we block and log by default.
+
+Then, we NAT everything that comes out of the VPN and to the 'net. We let what
+comes from the server out too, tho that could be improved...
+
+The next three blocks are easy, and then in the OpenVPN block, we let in port
+udp/53, we redirect port udp/443 to udp/53, and we let everything in from the
+VPN.
+
+We have to reload pf and add a sysctl knob if we want to actually route packets
+coming from the VPN:
+
+ $ doas pfctl -f /etc/pf.conf
+ $ echo 'net.inet.ip.forwarding=1' | doas tee -a /etc/sysctl.conf
+
+And now, we simply enable the OpenVPN service, and we're done:
+
+ $ doas rcctl enable openvpn
+ $ doas rcctl enable pflogd
+ $ doas rcctl start openvpn
+ $ doas rcctl start pflogd
+ $ doas rcctl ls on # to check
+
+That's it! It was actually pretty easy, I guess.
+
+Also, if you don't know what's wrong and want to get a detailed log, run
+`/usr/local/sbin/opvnpn --verb 11 --config /etc/openvpn/openvpn.conf`
+
+
+Seeya!
diff --git a/content/openwrt-usbnet.md b/content/openwrt-usbnet.md
new file mode 100644
index 0000000..34d1518
--- /dev/null
+++ b/content/openwrt-usbnet.md
@@ -0,0 +1,132 @@
+Title: OpenWRT, l'USBNet, et l'histoire des 4Mo
+Date: 2015-10-16 10:27
+Author: Wxcafe
+Category: Hacking
+Slug: openwrt-usbnet
+
+Donc, j'ai récemment obtenu un [TP-Link
+TL-MR12U](http://www.dx.com/p/tp-link-tl-mr12u-portable-5200mah-mobile-battery-3g-router-white-231188),
+qui est vendu comme "routeur 3G portable", mais qui est en réalité une grosse
+batterie avec une antenne wifi, un port USB, et un port Ethernet. Perso, ça me
+va, vu que je comptais de toute façon pas prendre un deuxième abonnement 3G
+juste pour ce truc là (surtout vu la couverture 3G qu'on se tape en France...)
+
+Bref, tout ça pour dire : quand j'ai reçu ce truc, j'ai tout de suite commencé
+par y installer OpenWRT (parce que de 1, je parle pas chinois, et de 2, j'aime
+bien avoir des firmwares corrects sur mes routeurs). Bon, c'est super simple, il
+suffit de chopper ce fichier
+\[binaire\] [la](http://downloads.openwrt.org/chaos_calmer/15.05/ar71xx/generic/openwrt-15.05-ar71xx-generic-tl-mr12u-v1-squashfs-factory.bin),
+et de trouver la page d'update (pas forcément super simple en chinois, mais avec
+un peu de temps, ça se fait. C'est celle avec un bouton upload). Ensuite on
+upload l'image sur le bouzin, et c'est parti. Pas de signatures, pas de
+vérifications, osef total, mais bon pour le coup ça m'arrange.
+
+Une fois ceci fait, je me trouva bien démuni de ne pas pouvoir utiliser le
+partage de connexion USB de mon intelliphone android, car l'image OpenWRT par
+defaut ne comprend pas USBNet, et ne peut donc pas créer de réseau sur de l'USB.
+Qu'à cela ne tienne, me dis-je! Je vais l'installer!
+Je courra donc installer le package grâce à `opkg`. Las! Le système n'avait plus
+de place.
+
+... Atta. Le système avait plus de place? J'ai encore rien mis dessus!
+
+Eh bah ouais. Il se trouve que TP-Link, en 2015, trouve que 4Mo de flash sur un
+routeur, c'est largement suffisant, et que de toute façon personne aura jamais
+besoin de plus.
+
+Serieux, mettre 8Mo c'était tellement plus cher? u_u
+
+Bon, bref, je vais pas m'étendre la dessus. J'ai décidé de saisir mes petits
+bras, et de tenter de pousser bien fort pour convaincre OpenWRT qu'il était tout
+a fait possible de faire rentrer à la fois le système de base avec LuCi, uhttpd,
+un serveur DHCP, etc; et USBNet, dans 4Mo. Ça à pas été vraiment facile, et j'ai
+du virer pas mal de trucs, mais... ça fonctionne!
+
+Bon, alors, comme je suis quelqu'un de sympa, je vais vous filer à la fois le
+fichier de config et l'image finale. Si vous voulez pas utiliser une image qui
+vient d'un mec que vous connaissez pas, vous pouvez toujours la rebuilder vous
+même. Mais avant ça, je vais vite fait expliquer ce qui est dans l'image et ce
+qui n'y est pas
+
+Alors, pour faire rentrer tout ça, vous vous doutez que j'ai du faire quelques
+concessions. J'ai donc viré tout ce qui a trait à *PPP*, *PPPoE*, le client
+*DHCPv6*, tous les *outils de debug*, quelques *fonctionnalités de busybox*, et
+bien sûr *opkg*. Dans ce qui à été ajouté, simplement ce qui est nécessaire au
+fonctionnement de *l'USBNet*.
+
+Une petite modification doit être effectuée pour que le tout fonctionne : le
+fichier `package/feeds/luci/luci/Makefile` doit être modifié pour que la
+dépendance sur `luci-proto-ppp` ne soit plus présente. Ainsi, on passe de
+
+```makefile
+LUCI_DEPENDS:= \
+ +uhttpd +uhttpd-mod-ubus +luci-mod-admin-full +luci-theme-bootstrap \
+ +luci-app-firewall +luci-proto-ppp +libiwinfo-lua +IPV6:luci-proto-ipv6
+```
+
+à
+
+```makefile
+LUCI_DEPENDS:= \
+ +uhttpd +uhttpd-mod-ubus +luci-mod-admin-full +luci-theme-bootstrap \
+ +luci-app-firewall +libiwinfo-lua +IPV6:luci-proto-ipv6
+```
+
+Une fois que c'est fait, ça devrait mieux marcher (et ça sauve un peu
+d'espace...)
+
+Bon. Le fichier de config est
+[là](http://pub.wxcafe.net/static/openwrt/tl-mr12u/config), l'image finale est
+[là](http://pub.wxcafe.net/static/openwrt/tl-mr12u/openwrt-15.05-wx-ar71xx-generic-tl-mr12u-v1-squashfs-factory.bin),
+et j'ai une petite surprise.
+
+Bien sûr, le switch situé sur le côté du TL-MR12U ne fonctionne pas sous
+OpenWRT de base, parce que c'est un truc lié au hardware et que du coup c'est
+assez compliqué à gérer sur une base de matos aussi grande que celle d'OpenWRT.
+Bah j'ai à peu près trouvé comment le faire fonctionner.
+Voilà le code :
+
+```shell
+#!/bin/sh
+if [ $ACTION == "released" ]; then
+ if [ $BUTTON == "BTN_0" ]; then
+ # Position is 3G
+ logger "slider 3G"
+ elif [ $BUTTON == "BTN_1" ]; then
+ # Position is Router
+ logger "slider Router"
+ fi
+elif [ $BUTTON == "BTN_1" ] || [ $BUTTON == "BTN_0" ]; then
+ if grep -qe "sw1.*in hi" /sys/kernel/debug/gpio\
+ && grep -qe "sw2.*in hi" /sys/kernel/debug/gpio; then
+ # Position is AP
+ logger "slider AP"
+ fi
+fi
+```
+
+Et ça va dans `/etc/hotplug.d/button/00-buttons` (créez le chemin, il existera
+pas à la base). Du coup là comme ça ça fait rien, ça loggue juste les events.
+Mais comme vous êtes pas cons vous avez peut être deviné qu'on pouvait très bien
+activer l'USBNet que quand l'interrupteur est en position 3G, le wifi et
+l'ethernet quand il est en position AP, et juste la batterie quand il est en
+position Router. Par exemple.
+
+Tiens, d'ailleurs. Pour activer le partage de connexion, suffit pas d'ajouter le
+support USBNet. Il faut aussi configurer le système pour qu'il demande un lease
+DHCP, toussa. Du coup vous pouvez (peut être, j'ai pas testé) le faire par LuCi,
+mais sinon vous pouvez le faire en CLI :
+
+```shell
+uci del network.wan
+uci set network.wan=interface
+uci set network.wan.ifname=usb0
+uci set network.wan.proto=dhcp
+uci commit network
+ifup wan
+```
+
+Et pouf, ça marche.
+
+Voilà. Amusez vous bien avec votre grosse batterie portable, qui fait maintenant
+point d'accès wifi/partage de connexion 3G/whatever.
diff --git a/content/redondance_de_routeurs,_avec_openbsd_et_freebsd.md b/content/redondance_de_routeurs,_avec_openbsd_et_freebsd.md
new file mode 100644
index 0000000..1f66ea7
--- /dev/null
+++ b/content/redondance_de_routeurs,_avec_openbsd_et_freebsd.md
@@ -0,0 +1,405 @@
+Title: Redondance de routeurs, avec OpenBSD et FreeBSD
+Date: 2016-07-29T17:53+02:00
+Author: Wxcafé
+Category:
+Slug: redondance-routeurs-openbsd-freebsd
+
+Depuis le début de mon DUT (il y a deux ans), j'ai découvert le monde du réseau,
+alors que j'étais plus système auparavant. Au cours de ce processus, j'ai
+pu observer quelques coutumes étranges de ce milieu. Ainsi donc, dans cet étrange
+domaine, il arrive parfois qu'on cherche à avoir un réseau stable pendant une
+période relativement longue. Bien évidemment, ceci se trouve être un problème
+Complexe®, a cause notamment des différents constructeurs de matériel réseau, et
+des différents systèmes d'exploitation des machines qui font passer les chatons
+dans les tuyaux.
+
+Bref, en général on règle ce problème de façon relativement simple : en
+utilisant un système stable, _par exemple_ OpenBSD. Cependant, ça ne suffit pas
+toujours: on peut aussi rencontrer des erreurs hardware. Et puis même OpenBSD
+peut rencontrer des problèmes softwares aussi, de temps en temps. Il paraît.
+J'ai lu un truc la dessus quelque part.
+
+Bref, après cette intro complètement objective, on va parler de redondance de
+routeurs (c'est a dire la mise en place de deux routeurs hardwares en même
+temps, avec un qui prend le relai de l'autre en cas de problème). On va aussi
+faire en sorte qu'ils utilisent deux réseaux externes différents (d'opérateurs
+séparés, par exemple), pour faire bonne mesure.
+Vu que c'est un projet pour mon DUT à la base, et qu'on a fait que du Linux la
+bas, j'ai décidé de le réaliser avec un OpenBSD et un FreeBSD, sur un laptop et
+une Cubieboard 2 (une board ARM qui traînait chez moi), en utilisant des VLANs
+(puisqu'ils n'ont qu'une seule NIC). C'est aussi pour ça qu'il y a un FreeBSD,
+vu que la Cubieboard ne supporte qu'assez mal OpenBSD (en tout cas d'après mon
+expérience)
+
+Tout d'abord, je vais mettre [ici](https://pub.wxcafe.net/static/redondance.pdf)
+le rapport produit pour mon DUT, comme le veut la tradition du TL;DR (tu le sens
+mon LaTeX?). Si vous voulez pas lire cette explication, vous pouvez lire l'autre
+explication qui est en PDF et orientée pour des profs de DUT. Si vous êtes prof
+de DUT j'imagine que ça peut être intéressant.
+
+Bon, donc la première chose a faire c'est de définir quelques trucs. La
+redondance, on l'a dit, c'est le fait d'avoir plusieurs équipements effectuant
+une tâche similaire, pour qu'en cas de panne l'un prenne la place de l'autre
+sans interruption. Quelques acronymes :
+
+- CARP, *Common Address Redundancy
+Protocol*, est un protocole (développé par OpenBSD pour remplacer VRRP) qui
+permet de faire de la redondance entre des équipements IP, en leur permettant
+de partager une adresse IP en switchant rapidement en cas de problème avec l'un
+des équipements.
+
+- PF, *Packet Filter*, est le firewall d'OpenBSD et de FreeBSD.
+Enfin, des versions différentes. Mais l'idée est la. (en pratique, la version de
+FreeBSD est plus ancienne mais supporte le multi-CPU, contrairement a celle
+d'OpenBSD (mais bon, on connait le support multi-CPU d'OpenBSD...)).
+
+- PfSync, *Packet Filter Synchronisation*, est un service qui permet de
+synchroniser la table d'état de deux instances de PF. De cette façon, quand un
+des deux crashe, le second peut reprendre les connexions en cours et évite de
+couper trop de transmissions.
+
+- IfStated est un petit programme qui permet de vérifier l'état d'une interface
+réseau régulièrement et de lancer des commandes en fonction de l'état de celle
+ci.
+
+
+Bon, maintenant que ces définitions sont claires, passons à la réalisation. Le
+système OpenBSD sera le serveur primaire, et le FreeBSD sera la réplique, car
+OpenBSD est capable de routage multipath (répartition du traffic entre deux
+routes de manière égale), ce que FreeBSD ne sait pas faire. Ainsi, si R1 (la
+machine OpenBSD) est primaire, elle est capable de transférer une partie du
+traffic vers R2 (la machine FreeBSD). Si elle s'arrête de fonctionner, R2 n'a
+pas besoin de faire de multipath, puisqu'a ce moment la une seule route valide
+est encore disponible.
+
+La première chose à faire est de configurer le réseau sur nos deux machines.
+Puisqu'elles ont toutes les deux une seule interface réseau, nous utilisons des
+VLANs (en conjonction avec un switch correct, je vous laisse trouver la
+configuration de celui-ci. Il faut connecter les deux machines sur des ports
+Trunk). Le VLAN 300 sera utilisé pour le réseau interne, le 400 pour le réseau
+externe A et le 500 pour le réseau externe B. Ainsi, on aura un réseau qui
+ressemble à ceci :
+
+```
+╭──╮ ╭─────────────╮ ╭──╮
+│ │ │ Switch │ │ │
+│R1│ │ │ │R2│
+│ │ │ │ │ │
+╰──╯ ╰─────────────╯ ╰──╯
+ ╚════════╝ ╚═════════╝
+```
+
+en terme physique, et ceci :
+
+```
+ ╔══════╗ ╔══════╗
+╭──╮ ╭────╮ ╭─────╮ ╭────╮ ╭──╮
+│OP│ │ │ │ │ │ │ │OP│
+│ │ │ R1 │ │ LAN │ │ R2 │ │ │
+│A │ │ │ │ │ │ │ │B │
+╰──╯ ╰────╯ ╰─────╯ ╰────╯ ╰──╯
+ ╚════════╝ ╚════════╝
+```
+
+au niveau réseau.
+On va aussi utiliser le réseau 30.30.30.0/24 sur le réseau interne pour cet
+exemple.
+
+Pour ce faire, on configure les routeurs ainsi :
+
+#### R1 (OpenBSD):
+
+**/etc/hostname.em0:**
+
+```
+up
+```
+
+**/etc/hostname.vlan0:**
+
+```
+inet 30.30.30.1 255.255.255.0 30.30.30.255 vlan 300 vlandev em0
+```
+
+**/etc/hostname.vlan1:**
+
+```
+dhcp vlan 400 vlandev em0
+```
+
+#### R2 (FreeBSD):
+
+**/etc/rc.conf**
+
+```
+[...]
+vlans_dcw0="300 500"
+ifconfig_dwc0_300="inet 30.30.30.2 netmask 255.255.255.0"
+ifconfig_dwc0_500="DHCP"
+```
+
+Une fois ceci fait, nos machines sont configurées sur leurs réseaux externes
+respectifs (via DHCP, adaptez si votre réseau externe utilise une autre
+méthode) et sur le réseau interne. Il faut bien entendu remplacer les noms
+d'interfaces (`em0`, `dcw0`) par le noms des interfaces présentes sur vos
+machines.
+
+Nous allons maintenant configurer la redondance elle même avec CARP. Le réseau
+avec lequel nous allons nous retrouver ressemble à ceci :
+
+```
+ ╭───────╮
+ ╔═════│ VIP │══════╗
+ ║ ╰───────╯ ║
+ ║ ║ ║
+╭──╮ ╭────╮ ╭─────╮ ╭────╮ ╭──╮
+│OP│ │ │ │ │ │ │ │OP│
+│ │ │ R1 │ │ LAN │ │ R2 │ │ │
+│A │ │ │ │ │ │ │ │B │
+╰──╯ ╰────╯ ╰─────╯ ╰────╯ ╰──╯
+ ╚════════╝ ╚════════╝
+```
+
+La configuration de CARP se fait en fait comme pour une interface réseau
+classique :
+
+#### R1:
+
+**/etc/hostname.carp0:**
+
+```
+vhid 125 pass pwd12345 carpdev vlan0 advbase 3 advskew 1 state master
+30.30.30.254 netmask 255.255.255.0
+```
+
+#### R2:
+
+**/etc/rc.conf:**
+
+```
+[...]
+ifconfig_dwc0_300_alias0="vhid 125 advbase 3 advskew 200 \
+ state backup pass pwd12345 alias 30.30.30.254/24"
+```
+
+Une fois que CARP est mis en place, nous configurons PF, pour filtrer les flux
+que nous laissons passer sur notre réseau. Les configurations suivantes,
+différentes pour R1 et R2 (puisque FreeBSD et OpenBSD n'utilisent pas les mêmes
+versions de PF), sont évidemment à modifier en fonction de votre installation:
+elles sont très minimales (ne laissant même pas passer le http...)
+
+#### Pour R1:
+
+**/etc/pf.conf:**
+
+```
+set skip on lo
+
+# définition des variables
+int="30.30.30.0/24"
+ext="0.0.0.0/0"
+int_addr="30.30.30.1"
+int_if="vlan0"
+ext_if="vlan1"
+
+# defaut : bloquage
+block all
+
+# vérification des paquets, anti-spoofing
+antispoof for $int_if
+antispoof for $ext_if
+
+# nous laissons passer l'icmp
+pass proto icmp
+
+# nous mettons en place le NAT de l'interieur vers Internet
+pass in on $int_if from $int to any keep state
+pass out on $ext_if from $int to $ext nat-to $int_if keep state
+
+# carp, pfsync et dhcpsync
+pass out on $int_if proto carp keep state
+pass quick on $int_if proto pfsync keep state
+pass in on $int_if proto udp to any port 8067 keep state
+pass out on $int_if proto udp to any port 8067 keep state
+
+# nous laissons passer les connexions SSH vers le routeur
+pass in on $int_if proto tcp from $int to $int_addr port ssh keep state
+pass out on $int_if proto tcp from $int_addr port ssh to $int keep state
+```
+
+#### Et pour R2:
+
+**/etc/pf.conf:**
+
+```
+set skip on lo
+
+# définition des variables
+int="30.30.30.0/24"
+ext="0.0.0.0/0"
+int_addr="30.30.30.2"
+int_if="dwc0.300"
+ext_if="dwc0.500"
+
+# défaut : bloquage
+block all
+
+# vérification des paquets, anti-spoofing
+antispoof for $int_if
+antispoof for $ext_if
+
+# nous laissons passer l'icmp
+pass proto icmp
+
+# nous mettons en place le NAT de l'interieur vers Internet
+nat on $ext_if from $int to any -> ($ext_if)
+pass in on $int_if from $int to any keep state
+pass out on $ext_if from any to $ext
+
+# carp, pfsync et dhcpsync
+pass out on $int_if inet proto carp keep state
+pass quick on $int_if inet proto pfsync keep state
+pass in on $int_if inet proto udp to port 8067 keep state
+pass out on $int_if inet proto udp to port 8067 keep state
+
+# nous laissons passer les connexions SSH vers le routeur
+pass in on $int_if inet proto tcp from $int to $int_addr \
+port ssh keep state
+pass out on $int_if inet proto tcp from $int to $int_addr \
+port ssh keep state
+```
+
+Une fois que PF est configuré, on passe a pfsync, qui permet de synchroniser
+l'état de deux instances de PF, même de versions différentes (je trouve ce truc
+génial):
+
+#### Pour R1:
+
+**/etc/hostname.pfsync0:**
+
+```
+syncdev vlan0 syncpeer 30.30.30.2
+```
+
+#### Et pour R2:
+
+**/etc/rc.conf:**
+
+```
+pfsync_enable="YES"
+pfsync_syncdev="dwc0.300"
+pfsync_syncpeer="30.30.30.1"
+```
+
+Passons à ifstated. Puisque R1 supporte le multihoming mais pas R2, nous allons
+faire en sorte que R1 aie une route multipath vers R2. De cette façon, R1 (qui
+est la machine principale pour CARP, et reçoit donc toutes les connexions venant
+du réseau interne), transmet la moitié de ces connexions vers R2, qui les gère
+comme nécessaire. Si R1 arrête de fonctionner, R2 récupère l'ensemble des
+connexions (grâce a CARP), qui ne sont pas interrompues (grâce a pfsync). Si R2
+arrête de fonctionner, ifstated rentre en action et retire la route multipath de
+R1 vers R2, ce qui permet d'éviter de transmettre la moitié des connexions à un
+routeur qui ne fonctionne plus (c'est en général une chose a éviter).
+
+Par conséquent, la configuration d'ifstated n'a à être effectuée que sur R1 :
+
+**/etc/ifstated.conf:**
+
+```
+peer = '( "ping -q -c 1 -w 3 30.30.30.2>/dev/null" every 5 )'
+
+state auto {
+ if $peer
+ set-state multihome
+ if ! $peer
+ set-state singlehome
+}
+state multihome {
+ init {
+ run "route add -mpath default 30.30.30.2"
+ }
+ if ! $peer
+ set-state singlehome
+}
+state singlehome {
+ init {
+ run "route delete default 30.30.30.2"
+ }
+ if $peer
+ set-state multihome
+ }
+
+init-state auto
+```
+
+Enfin, dernier point a configurer, la synchronisation DHCP. Elle nous permet de
+faire en sorte que les machines gardent les mêmes adresses IP même si un des
+deux routeurs reste en rade pendant une période prolongée. On configure donc
+`isc-dhcpd` sur les deux routeurs, comme suit:
+
+#### R1:
+
+**/etc/dhcpd.conf:**
+
+```
+authoritative;
+ddns-update-style none;
+
+failover peer "dhcp-failover" {
+ primary;
+ address 30.30.30.1;
+ port 8067;
+ peer address 30.30.30.2;
+ peer port 8067;
+}
+
+subnet 30.30.30.0 netmask 255.255.255.0 {
+ option routers 30.30.30.254;
+ option domain-name-servers 30.30.30.254;
+ pool {
+ failover peer "dhcp-failover";
+ max-lease-time 86400;
+ range 30.30.30.10 30.30.30.250;
+ }
+}
+```
+
+#### Et pour R2:
+
+**/usr/local/etc/dhcpd.conf:**
+
+```
+authoritative;
+ddns-update-style none;
+
+failover peer "dhcp-failover" {
+ secondary;
+ address 30.30.30.2;
+ port 8067;
+ peer address 30.30.30.1;
+ peer port 8067;
+}
+
+subnet 30.30.30.0 netmask 255.255.255.0 {
+ option routers 30.30.30.254;
+ option domain-name-servers 30.30.30.254;
+ pool {
+ failover peer "dhcp-failover";
+ max-lease-time 86400;
+ range 30.30.30.10 30.30.30.250;
+ }
+}
+```
+
+Et voilà! Notre réseau ressemble désormais à ça (j'ai repris le schéma de mon
+rapport, j'ai pas le courage de le refaire en texte encore):
+
+
+
+avec le PC1 qui représente le réseau local.
+
+Si vous avez bien lu la configuration du serveur DHCP, il reste encore à mettre
+en place un serveur DNS écoutant sur l'IP virtuelle, donc a priori synchronisé
+entre les deux routeurs. Comme c'est quelque chose de simple a mettre en place
+et que c'est assez bien documenté ailleurs, je laisse cette tâche comme exercice
+aux lecteurs-ices.