structure & meta

This commit is contained in:
Yax 2019-08-17 18:40:27 +02:00
parent da6d838193
commit b25ce65735
284 changed files with 461 additions and 1000 deletions

View file

@ -0,0 +1,179 @@
<!-- title: Mes notes sur RabbitMQ -->
<!-- category: Développement -->
[RabbitMQ](https://www.rabbitmq.com) est un bus de messages Open Source qui
implémente le protocole Advanced Message Queuing (AMQP). Sa fonction est de
faire communiquer entre eux des programmes différents, potentiellement écrits
dans différents langages.<!-- more --> Le serveur RabbitMQ est lui-même écrit dans le
langage de programmation Erlang, ce qui est plutôt atypique. Aucune
connaissance de Erlang n'est nécessaire pour l'utiliser. C'est un produit
édité par Pivotal, un spin-off de VMWare et EMC, connu de tous les
développeurs JAVA pour son fabuleux framework
[Spring](https://en.wikipedia.org/wiki/Spring_Framework).
RabbitMQ demande une complexité de configuration proportionnelle aux exigences
demandées : queues de messages persistantes, dead letters, haute
disponibilité, optimisation des performances... Pour les configurations
compliquées et le support technique avancé dans des mises en oeuvre
d'entreprises, il y a des experts (j'ai une adresse pour ceux intéressés).
Pour une utilisation basique, dans un cadre de développement pépère à la
maison, RabbitMQ est très accessible, bien documenté et permet d'avoir
rapidement un bus de message pour faire communiquer ses applications.
Je m'en sers actuellement pour faire discuter mon petit éco-système hébergé. Dans ce cadre j'ai pris quelques notes sur sa mise en place, de l'installation à la configuration de base.
### Installation
Choix de l'OS : CentOS 7
Page d'aide de référence pour l'installation : https://www.rabbitmq.com/install-rpm.html
Pivotal fournit une installation d'une version allégée de Erlang avec les dépendances nécessaires à RabbitMQ : https://github.com/rabbitmq/erlang-rpm
Et bien sûr, il fournissent aussi un RPM de RabbitMQ (actuellement en version 3.7.2-1) : https://dl.bintray.com/rabbitmq/all/rabbitmq-server/3.7.2/rabbitmq-server-3.7.2-1.el7.noarch.rpm
Gestion du service à la sauce CentOS :
# démarrer le service
/sbin/service rabbitmq-server start
# stopper le service
/sbin/service rabbitmq-server stop
# démarrage automatique du service
chkconfig rabbitmq-server on
Après avoir mis le service en démarrage automatique, on n'utilisa plus que l'outil *rabbitmqctl* :
# démarrer le serveur rabbitmq
rabbitmqctl start_app
# stopper le serveur rabbitmq
rabbitmqctl stop_app
### Droits et permissions
Par défaut, un utilisateur *guest* (mot de passe idem) est créé et il est
attaché à l'interface réseau locale (localhost). Pour se connecter depuis une
autre machine, en distant, il faut créer un nouvel utilisateur.
rabbitmqctl add_user admin <mot de passe dur>
rabbitmqctl set_user_tags admin administrator
rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
### Interface Web d'administration
Une belle interface permet de gérer la configuration et de visualiser des
indicateurs de fonctionnement. C'est un plugin qu'on active en ligne de
commande avec *rabbitmq- plugins*
rabbitmq-plugins enable rabbitmq_management
L'interface Web répond à l'adresse *http://server-name:15672/cli/*
L'utilisateur *guest* n'a accès à l'interface que par localhost. Le nouveau compte admin est nécessaire pour se connecter en distant.
Si l'interface Web est derrière un proxy NginX et qu'elle répond à une sous-URL du domaine, la config pour pour une sous-url */rabbitwebmin* est la suivante :
location /rabbitwebmin/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
rewrite ^/rabbitwebmin/(.*)$ /$1 break;
proxy_pass http://192.168.2.1:15672;
}
Optionnellement, on peut installer [le CLI de rabbitmqadmin](https://www.rabbitmq.com
/management-cli.html) en téléchargeant le programme (Python) depuis
https://raw.githubusercontent.com/rabbitmq/rabbitmq-
management/v3.7.2/bin/rabbitmqadmin et en le plaçant dans */usr/local/bin*.
### Mise en oeuvre
On crée un utilisateur technique pour nos applications dans un virtual host spécifique.
rabbitmqctl add_vhost devhub
rabbitmqctl add_user techuser tech
rabbitmqctl set_permissions -p devhub techuser ".*" ".*" ".*"
A ce niveau, on peut essayer de faire communiquer deux applications à travers Rabbit avec un classique producteur-consommateur écrit en Python, utilisant [la librairie Pika](https://pika.readthedocs.io), dérivé du tutorial de RabbitMQ.
Code du producteur :
``` python
#!/usr/bin/env python
import pika
import sys
credentials = pika.PlainCredentials('techuser', 'tech')
connection = pika.BlockingConnection(pika.ConnectionParameters(host='192.168.2.1',credentials=credentials, virtual_host="devhub"))
channel = connection.channel()
channel.exchange_declare(exchange='hub.topic',
exchange_type='topic')
routing_key = sys.argv[1] if len(sys.argv) > 2 else 'anonymous.info'
message = ' '.join(sys.argv[2:]) or 'Hello World!'
channel.basic_publish(exchange='hub.topic',
routing_key=routing_key,
body=message)
print(" [x] Sent %r:%r" % (routing_key, message))
connection.close()
```
Code du consommateur :
``` python
#!/usr/bin/env python
import pika
import sys
credentials = pika.PlainCredentials('techuser', 'tech')
connection = pika.BlockingConnection(pika.ConnectionParameters(host='192.168.2.1',credentials=credentials, virtual_host="devhub"))
channel = connection.channel()
channel.exchange_declare(exchange='hub.topic',
exchange_type='topic')
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue
print("Queue => " + queue_name)
# on s'abonne aux topics :
binding_keys = ['mail.message', 'mail.command.*']
for binding_key in binding_keys:
channel.queue_bind(exchange='hub.topic',
queue=queue_name,
routing_key=binding_key)
print(' [*] Waiting for logs. To exit press CTRL+C')
def callback(channel, method, properties, body):
print("=> %r:%r" % (method.routing_key, body))
channel.basic_consume(callback,
queue=queue_name,
no_ack=True)
channel.start_consuming()
```
Quelques tests :
# le consommateur lancé dans un shell s'abonne aux topics mail.message et mail.command.*
$ python3 consumer.py
le consommateur doit recevoir le message suivant :
# le producteur produit dans le topic 'mail.message'
$ python3 producer.py "mail.message"
le consommateur doit recevoir le message suivant :
# le producteur produit dans le topic 'mail.command.test'
$ python3 producer.py "mail.command.test"
le consommateur ne doit pas recevoir le message suivant :
# le producteur produit dans le topic 'mail.rate'
$ python3 producer.py "mail.rate"

View file

@ -0,0 +1,122 @@
<!-- title: Choix du système pour s'auto-héberger -->
<!-- category: Hébergement -->
<!-- tag: planet -->
Suite à un échange intéressant sur le choix dune distribution dans Diaspora,
j'ai eu envie de developper le sujet dans un article.<!-- more --> je restreins au choix
d'un système d'exploitation pour de l'auto-hébergement (à la maison ou chez un
hébergeur avec une offre de serveur physique dédié) car je ne me sens plus
assez qualifié pour parler de choix d'entreprise, m'étant recentré sur le
développement ; bon je glisserai quand même quelques avis et les adminsys en
activité commenteront.
En une quinzaine dannées, le choix dun système a traversé trois phases
successives : de **"le meilleur système c'est Gloup"** (remplacez Gloup par
votre système d'exploitation préféré), à **"le meilleur système c'est TOUS"**,
nous sommes arrivés à **"le meilleur système c'est AUCUN"**.
### Phase 1 : le monolithe
<img src="/images/2018/monolithe.jpg" style="float:left; margin: 0px 20px;"/>Le serveur est monolithique donc le choix du système d'exploitation est crucial.
En entreprise, il dépend de la politique interne, des goûts et compétences des
administrateurs système. Généralement on limite la fragmentation des systèmes
déployés. On choisira par exemple RedHat pour les serveurs critiques et CentOS
pour les autres afin d'avoir une homogénéité. Des besoins particuliers (comme
le pare-feu) pourront amener à installer des systèmes spécifiques (comme
PFSense).
Dans le cas de l'auto-hébergement, c'est open bar et nul besoin de se
justifier. On choisit Gloup parce que c'est cool et qu'on veut appendre à le
maîtriser, ou bien parce qu'on pense que c'est le meilleur choix technique (ou
philosophique).
Ce qu'il faut savoir c'est que ce système fournit de base une logithèque plus
ou moins étendue par son gestionnaire de paquets. S'il manque des choses, on
peut ajouter d'autres sources, comme des dépôts tiers de contributeurs. En
dernier ressort, on peut compiler à partir des sources, ce qui peut être un
vrai travail de portage si le programme en question n'est pas prévu pour ce
système. On est très dépendant des versions proposées par le système
d'exploitation et si on a besoin de faire coexister plusieurs versions d'un
même programme, ça commence à se compliquer grandement. Quand on montera en
version le système d'exploitation, tous ces ajouts *non standard* (paquets non
officiels, programmes compilés à partir des sources) compliqueront la mise à
jour du système d'exploitation.
### Phase 2 : pas de limite
Et puis est apparue la virtualisation ! le choix du système d'exploitation
n'est plus une limitation, on mixe à son gré et le système hôte (appelé
hyperviseur) a le rôle principal d'exécuter avec célérité les machines
virtuelles. On a encore une petite adhérence à l'architecture matérielle : si
on tourne sur une architecture x86, on doit installer des systèmes supportant
cette architecture. La virtualisation a un coût même si elle s'appuie sur des
instructions dédiées du processeur pour être très performante.
Sur du matériel modeste, ce qui est souvent le cas en auto-hébergement, on
privilégiera les technologies de conteneurs (LXC pour Linux, Jails pour
FreeBSD) pour isoler ses services et faire cohabiter des versions spécifiques
ou différentes. Les conteneurs sont plus limités que les machines virtuelles
car ils partagent le kernel du système hôte. Sur un serveur Linux, des
containers LXC pourront exécuter différentes distributions GNU/linux, mais
seulement du Linux. Cela permet déjà de faire plein de trucs cool, chaque
conteneur a son IP, on choisit le système le plus adapté à ce qui sera
installé dessus (Debian CentOS, Alpine, ...).
Si on a confiance dans ce qui s'exécute sur ses conteneurs (ce qui devrait
être le cas en auto-hébergement perso), l'approche de la sécurité du serveur
est simple : un gros pare-feu au niveau du serveur physique pour n'ouvrir que
les ports publiques sur Internet et les conteneurs peuvent communiquer entre
eux par des adresses privées.
### Phase 3 : centré sur l'application
Puis Docker a lancé sa technologie de conteneur d'application, basé
techniquement sur les conteneurs Linux LXC mais avec l'enjeu de faire oublier
le système sous-jacent :
- un conteneur Docker = une application (le processus en PID 1)
- un portail d'applications permet de télécharger des images prêtes à l'emploi
- les dépendances entre conteneurs sont déclarées explicitement
Le tout s'accompagne d'un ensemble de bonnes pratiques : pas de données dans
les conteneurs d'applications, une configuration passée au conteneur lors de
son initialisation. Bref je vais pas détailler, plein de bons articles sur le
sujet ont déjà été publiés. Mais c'est une technologie qui vaut la peine de
jouer d'être essayée. Elle ne révolutionne pas la technique sous-jacente qui
existait déjà mais les usages et la façon de repenser un déploiement de
services, réparti entre plusieurs conteneurs faciles à mettre à jour, une
abstraction totale par rapport au système hôte.
Ne nous voilons pas la face, Docker c'est la fin de la distribution serveur.
Est-ce que Debian est mieux que CentOS sur un serveur ? On s'en cogne car peu
importe la logithèque la distribution et les versions fournies de chaque
librairie. En installant Docker dessus, on en fait un chef d'orchestre dont le
rôle se limite à exécuter des dizaines ou des centaines de conteneurs. Et le
catalogue d'applications est énorme, comme les versions proposées. Et si on ne
trouve pas vie ou qu'on a besoin d'empaqueter ses propres applications en
conteneurs Docker, on apprend à fabriquer ses propres conteneurs en quelques
heures d'auto-formation.
Bon j'ai l'air emballé sur Docker et c'est le cas, d'un point de vue
professionnel. Ce n'est pas mon rêve pour mon auto-hébergement, les conteneurs
ont tous la même taille, ça manque de diversité et de fun pour moi.
<img src="/images/2018/havefun.jpg" style="float:left; margin: 0px 20px;"/>La
plupart des entreprises sont entre la phase 2 et la phase 3 : elle ont
virtualisé tout ce qui est possible et elles migrent des services sous
Docker.
Mais que choisir, au final, pour de l'auto-hébergement ? Et bien, je dirais :
**"faîtes vous d'abord plaisir"**. BSD, Linux, il y a de quoi faire. Quitter
le monolithique et passer à l'étape 2 ou 3 ouvre d'autres perspectives dans la
gestion de son serveur. Fan du pare- feu PF ? ajoutez une machine virtuelle
avec PFSense pour gérer la sécurité de votre serveur. Si professionnellement
vous risquez d'être concernés par Docker, formez-vous parce que c'est
intéressant et que ça peut être utile (mais ne baclez pas l'aspect sécurité
des containers). Moi j'ai une passion pour les conteneurs *maison* qui me
permettent de moduler à ma guise : des petits conteneurs avec l'esprit Docker
pour les micro- services (avec Alpine Linux), des gros conteneurs pour les
applications plus conséquentes (comme Nextcloud). Longue vie à l'auto-
hébergement, profitons-en tant que l'Internet n'est pas à péage :-)

View file

@ -0,0 +1,55 @@
<!-- title: Surveiller l'état du serveur -->
<!-- category: Hébergement -->
<!-- tag: planet -->
J'ai un peu compliqué l'installation de mon serveur en répartissant les
services dans des conteneurs. J'ai un serveur HTTP NginX en frontal qui
distribue les requêtes vers les bon conteneurs<!-- more --> en fonction du nom DNS (un
reverse proxy). Je me retrouve donc avec une dizaine de conteneurs, partageant
un même plan d'adressage IP, et presque autant de serveurs HTTP. J'ai eu
besoin d'un outil qui me donne une vision globale de l'état du serveur et soit
capable de m'alerter en cas d'incident.
J'aurais pu m'orienter vers des solutions de supervision (Nagios et autres),
surtout vu mon background sur le sujet, mais le besoin est simple et les
ressources de mon serveur sont limitées. Je n'ai pas jugé utile de dégainer
la grosse artillerie. J'avais noté l'existence de
[Cachet](https://cachethq.io), utilisé, notamment, [par
Framasoft](https://status.framasoft.org), qui fournit une page de statut et
gère les notifications (e-mail ou abonnement RSS). Cachet, pour les intimes,
se cantonne donc à la visualisation et la notification. On crée des
composants, on les regroupe à sa guise, et une API Rest permet d'alimenter en
événements : changer l'état d'un composant (opérationnel, hors service,
partiellement défaillant), déclarer une maintenance planifiée. Il y a aussi
des indicateurs mais je n'ai pas encore exploré cette possibilité.
Comme pleurniché dans Diaspora, le plus dur c'est de l'installer, surtout
quand je rate la ligne importante du manuel qui précise que PHP 5 est requis
(la version 7 n'est pas encore supportée). Je me retrouve avec des erreurs
bizarres sans lien évident avec la version (du moins quand on n'est pas
PHPiste confirmé). Après une relecture du guide d'installation, plutôt bien
fait, et correction de mon déploiement, l'installation se déroule sans
problème avec Composer qui télécharge et installe les dépendances. Cachet est
prévu pour un grand nombre d'utilisateurs donc une base MySQL ou PostgreSQL
est recommandée. Pour peu d'utilisateurs il peut fonctionner avec SQLite, mon
choix de prédilection, quand c'est possible, pour ne pas multiplier les
serveurs de base de données, ni partager un serveur de base de données entre
mes conteneurs.
Une fois installé et la configuration HTTP mise en place, on accède à
l'interface d'administration pour créer ses objets. J'ai créé un groupe
**Système** avec tous mes conteneurs et un groupe **Service** avec mes
services critiques.
![Cachet Admin](/images/2018/cachet-admin.png)
Pour animer les statuts des composants c'est donc indépendant de Cachet. L'API
REST de Cachet est bien pensée et bien documentée. Elle permet de créer /
modifier des objets ou de les animer. Je me suis limité à cette dernière
possibilité pour l'instant en développant un programme qui récupère l'état des
conteneurs, des services et envoie les changements d'etat à Cachet. Ce
programme est exécuté toutes les 5 minutes. C'est sans prétention et ça répond
à mon besoin ; le code source est [ici](https://github.com/kianby/cachetmonitor).
Ma page de statut est accessible ici : https://status.madyanne.fr

View file

@ -0,0 +1,58 @@
<!-- title: Travailler sous Windows -->
<!-- category: Humeur -->
Depuis presque une année, je suis revenu à un poste de travail professionnel
sur Ms Windows 7, pour me conformer à la politique de l'entreprise qui
m'emploie. La réadaptation a été un peu douloureuse (doux euphémisme...) après
6 années de bonheur<!-- more --> avec des distributions comme Fedora et Debian.
Le premier point qui m'a vraiment gêné c'est l'installation de logiciels :
- trop de sources pour installer un programme : le site officiel, des sites alternatifs, c'est une jungle dont les prédateurs sont le spyware et le malware.
- aucune gestion centrale des mises à jour : certains programmes installent une cochonnerie lancée au démarrage pour détecter la présence de mise à jour, d'autres le font à chaque lancement et quant à ceux qui restent, il faut deviner qu'ils ne sont pas dans leur dernière version
Dans Windows 10, une boutique d'applications a été rajoutée, néanmoins, je
doute qu'elle soit assez complète dans mon cadre d'utilisation et pour
l'instant je suis sous Windows 7. Sur les conseils éclairés de mon ami
moustachu, j'ai essayé et rapidement adopté
[Chocolatey](https://chocolatey.org), un gestionnaire de programmes très
complet, géré en ligne de commande. C'est ma source d'installation prioritaire
car je peux mettre à jour tous mes programmes en une commande. Si ce n'est pas
disponible dans Chocolatey, je me rabats sur les méthodes traditionnelles.
Le second point qui pique c'est l'absence d'un terminal digne de ce nom. La
taille des fenêtres CMD n'est toujours pas redimensionnable dynamiquement et il
n'y a pas d'onglets. Plusieurs alternatives existent, j'ai opté pour
[Cmder](http://cmder.net) basé sur [ConEmu](https://conemu.github.io), un peu
plus connu, qui comble ces lacunes. J'ai aussi besoin d'un shell Unix pour
certaines tâches et me connecter en SSH sur des serveurs. Après beaucoup de
recherches infructueuses, j'ai opté pour [MSYS2](https://www.msys2.org), un
terminal moderne (colorisé, gestion des onglets) qui sous le capot repose sur
[Cygwin](https://www.cygwin.com) auquel on a greffé le gestionnaire de paquets
en ligne de commande de ArchLinux, à savoir Pacman. Qui a eu l'occasion d'utiliser
l'installeur graphique de Cygwin pour ajouter ou mettre à jour des paquets
comprendra vite l'avantage d'avoir un Pacman en mode console... ce n'est pas du
tout une fantaisie de geek.
A ce stade, j'étais paré pour bosser sereinement.
J'ai installé [Clover](http://en.ejie.me) pour rajouter des onglets à
l'explorateur de fichier standard de Ms Windows, je ne voulais pas le remplacer
par une alternative mais juste ajouter ce qui lui manque. Très récemment
j'ai installé [Keypirinha](http://keypirinha.com)
pour ~~ne plus avoir à fouiller le menu Démarrer~~ lancer les applications
rapidement. Pour le reste, mes outils n'ont pas vraiment changé : je navigue
sur la toile avec [Firefox](https://www.mozilla.org/fr/firefox), mon bloc-notes
déstructuré est [Zim](http://zim-wiki.org), je me connecte aux bases de données
avec [DBeaver](https://dbeaver.jkiss.org), je reste fidèle à
[Eclipse](https://eclipse.org) pour le développement Java et pour le reste
(JavaScript, HTML, CSS, Python, Markdown) j'ai goûté à [Visual Studio
Code](https://code.visualstudio.com), fortement inspiré du meilleur de Sublime
Text, avec une richesse et une qualité de plugins supérieure (un avis qui n'engage que
moi). Bravo à Microsoft pour cet outil, quand c'est réussi, il faut le dire.
Malgré ce changement de système de système d'exploitation, je continue à
privilégier les logiciels libres et Open Source, pas seulement par conviction
mais aussi parce que c'est du gagnant-gagnant. Et je rassure mon auditoire : je
n'ai pas sombré du côté obscur et privateur, mes serveurs restent sous Unix
ainsi que ma machine perso.

View file

@ -0,0 +1,44 @@
<!-- title: Les mots de passe -->
<!-- category: Sécurité -->
<!-- tag: planet -->
J'ai été sensible assez tôt à l'importance de la sécurité des mots de passe. Aujourd'hui, plus qu'hier, on ouvre quantité de comptes sur des sites de commerce, de banque ou d'assurance, de santé.<!-- more --> J'avais choisi le logiciel [KeePassX](https://www.keepassx.org), un coffre fort numérique protégé par un mot de passe unique, et suivi les bonnes pratiques : associer un mot de passe costaud et différent pour chaque site. Tout avait bien démarré avec de la bonne volonté, mais l'informatique des nuages et la mobilité ont progressivement compliqué les choses.
Au début, c'était simple car on avait une machine familiale dans la maison. Puis au fil des ans, j'ai acquis un portable, puis une tablette et un smartphone, et le casse-tête de la synchronisation entre les périphériques s'est posé. J'ai commencé simple (la machine familiale est la machine maître pour le fichier et des copies sont installées sur les autres périphériques) puis ça a fini par une synchronisation de la base KeePassX à travers Nextcloud, ce qui permet à n'importe quel périphérique de rajouter un mot de passe si besoin.
Enfin il s'est rajouté le problème de l'accès à ses mots de passe depuis des machines tierces (en milieu professionnel notamment). On peut ouvrir les mots de passe sur le téléphone et recopier le mot de passe dans le navigateur de la machine mais c'est pénible. Quand on est développeur, on a forcément une identité numérique (un compte GitHub, un compte StackOverflow, etc...) et on n'est pas ~~forcément~~ schizophrène donc on ne va pas en ouvrir un différent à chaque changement de poste. Du coup, j'ai ajouté la synchronisation de Mozilla Firefox dans la boucle, protégé par un *master password* pour partager certains identifiants liés à mon activité professionnelle en me rassurant que la référence c'est ma base KeePassX.
Le bilan, au bout de 12 ans, c'est que c'est un sacré bazar :
- j'utilise une version antédiluvienne de KeePassX pour être compatible avec celle supportée par mon téléphone : la sécurité globale est nivelée par celle du maillon le plus faible
- j'ai des mots de passe dans KeePassX, des doublons dans Firefox et probablement des mots de passe oubliés uniquement mémorisés dans Firefox.
- la sécurité du stockage des mots de passe dans Firefox [n'est pas terrible](https://www.bleepingcomputer.com/news/security/firefox-master-password-system-has-been-poorly-secured-for-the-past-9-years) mais c'est tellement commode le remplissage automatique des formulaires quand on est sur un site.
- la base KeePassX est physiquement sur mon téléphone : même si c'est chiffré sérieusement, combien de temps faudrait-il à quelqu'un de motivé et équipé pour la craquer en cas de vol ?
Cela fait beaucoup de points négatifs, il était temps de repenser tout cela et de se mettre au goût du jour. J'ai regardé un peu ce qui se fait avec quelques idées en tête :
- copier-coller des mots de passe entre une application et un site Web c'est dépassé (et compliqué sur un appareil mobile),
- stocker une base de mots de passe sur un périphérique mobile c'est risqué,
- le risque de piratage des sites Web est plus grand qu'auparavant, la solution doit être simple pour créer un mot de passe différent par site.
J'ai finalement choisi [BitWarden](https://bitwarden.com) qui remplit mes critères. Le coffre-fort est hébergé sur leurs serveurs, dans le cloud Azure Microsoft pour être exact. On peut décider de l'héberger soi-même mais je doute faire mieux que des professionnels pour en sécuriser l'accès. On déverrouille l'accès au coffre-fort avec un mot de passe maître, le seul à retenir finalement ; idéalement c'est une phrase plutôt qu'un simple mot de passe car toute la sécurité repose sur lui. Et si on l'oublie, ce n'est pas la peine de le demander aux administrateurs de BitWarden car ils ne l'ont pas, il n'est pas stocké chez eux. L'avantage de BitWarden par rapport à d'autres solutions du même genre c'est aussi qu'il propose des applications pour toutes les plateformes : des extensions de navigateurs, des applications bureau et mobiles. Autre bon point, ils ont des fonctions d'import pour la plupart des solutions concurrentes.
Alors comment décider de faire confiance à BitWarden ? Ce qui compte pour moi c'est :
- la publication en Open Source du cryptage pour être audité en toute transparence,
- la possibilité de sortir ses données avec un export en CSV,
- le sérieux de l'hébergement de la solution.
La confiance, c'est compliqué. Quelles que soient les garanties, il y a un moment où, en son âme et conscience, il faut se lancer ou rebrousser chemin. J'ai franchi le pas et décidé de leur confier mes mots de passe.
Premier écueil pour sortir les mots de passe de Firefox : l'extension [Password Exporter](https://addons.mozilla.org/en-US/firefox/addon/password-exporter) ne supporte pas Firefox 57, j'installe la version Firefox 52 ESR. D'ailleurs on annonce la version Firefox 62 ESR pour le mois d'août, ça me conforte dans l'idée que c'est le moment de s'en occuper. L'extension exporte les mots de passe dans un fichier CSV et BitWarden permet de les importer. Pour KeePass, on a un import mais comme j'ai une version KeePassx 0.4 j'ai du passer par la migration vers une version récente de KeePass avant de pouvoir importer ma base de mots de passe dans BitWarden. A ce stade, j'ai un coffre-fort avec plein de doublons entre les données de FireFox et KeePass ; bien fait pour moi, le gros ménage commence.
Je désactive la mémorisation des identifiants de Firefox et je vide les identifiants enregistrés puis j'installe l'extension BitWarden pour Firefox. On ouvre le coffre-fort en entrant son méga mot de passe.
![Ouverture coffre-fort](/images/2018/bitwarden-ouverture.png)
On peut paramétrer la fermeture du coffre-fort. A la maison, on laissera le coffre-fort ouvert jusqu'à la fermeture du navigateur ; au travail on optera pour une fermeture automatique sur inactivité, au bout de 15 minutes. Le principal intérêt d'avoir un gestionnaire de mots de passe couplé au navigateur c'est le remplissage des formulaires pour ne plus faire de copier-coller de mots de passe. L'icône de BitWarden change quand un mot de passe est disponible pour un site et il suffit de le sélectionner pour remplir le formulaire.
![Remplissage de formulaire](/images/2018/bitwarden-remplissage.png)
J'ai terminé ma bascule vers BitWarden depuis une semaine ; je me sers de l'extension Firefox et de [l'accès Web](https://vault.bitwarden.com), je n'ai installé aucune application native sur mes périphériques. Par sécurité, j'ai prévu une sauvegarde régulière et manuelle vers un support physique, c'est à dire un export des mots de passe vers une clef USB qui reste dans un coffre (non numérique celui-ci)... au cas où BitWarden disparaitrait ou bien si je deviens amnésique ;-)

View file

@ -0,0 +1,38 @@
<!-- title: Hébergement et taille de containers -->
<!-- categories: Hébergement Containers -->
<!-- tag: planet -->
Dans le prolongement de mon article ["Choix du système pour s'auto-héberger"](https://blogduyax.madyanne.fr/2018/quel-systeme-serveur), je peux faire un bilan des 6 mois écoulés avec mon hébergement à base de containers LXC avec la distribution [Proxmox](https://fr.wikipedia.org/wiki/Proxmox_VE).<!-- more -->
# Commençons par les avantages
Le passage d'une installation monolithique à une installation containerisée avec des services répartis dans une dizaine de containers donne la flexibilité de choisir le meilleur outil pour chaque tâche :
- les micro-services Python se contentent de containers Alpine ultra-légers (64 Mo de RAM).
- le service Nextcloud a migré d'un container Alpine à un container ArchLinux. Je n'aurais jamais pensé utiliser Arch sur un serveur mais c'est une bonne solution pour garantir une version stable et toujours à jours en terme de sécurité de Nextcloud.
- [le middleware RabbitMQ](https://blogduyax.madyanne.fr/2018/mes-notes-sur-rabbitmq) est installé sur sa distribution de prédilection **CentOS** dans un container dédié.
La modularité facilite l'administration du serveur : on a besoin d'un nouveau service, on rajoute un container et on limite les risques de *casser quelque chose* sur l'installation existante.
L'interface Web d'administration de Proxmox est de qualité. Au delà de la gestion des machines virtuelles KVM et des containers LXC, elle donne une vision des ressources CPU /Mémoire consommées par container et au niveau physique.
![Tableau de bord Proxmox](/images/2018/proxmox-dashboard.png)
# Ce qui n'est pas parfait
J'ai un service Nextloud, aisé à gérer dans un seul container avec l'application, les données et la base de donnée. Pour sauvegarder, c'est moins drôle, cela revient à sauvegarder le container de bientôt 100 Go avec Proxmox et la balancer sur l'espace FTP de 100 Go offert par Online. Autre option, sauvegarder les données du calendrier et les contacts [avec des scripts *maison*](https://blogduyax.madyanne.fr/2015/deploiement-et-sauvegarde/) et mettre en place une sauvegarde classique vers un disque externe des fichiers synchronisés sur mon ordinateur portable. C'est vers cette solution que je m'oriente.
La nuée de services développés par bibi autour du blog (SRMail, Stacosys) serait parfaite pour Docker. Aujourd'hui c'est installé dans des containers LXC, avec des partages de répertoires entre le hôte et les containers pour externaliser la configuration et les données. Docker permettrait de standardiser cet assemblage et d'en profiter à la maison pour facilement remonter un environnement de test.
C'est vraiment le point négatif : j'ai des relations troubles entre la machine hôte et les containers. J'ai installé un serveur NginX sur Proxmox qui fait du proxy vers les NginX des différents containers en fonction du service demandé. J'ai partagé des répertoires entre le hôte et les containers pour externaliser les parties sensibles (la configuration et les données) et faciliter leur sauvegarde puis la machine hôte. Je gère les certificats Let's Encrypt au niveau du hôte aussi. Bref j'ai une installation *custom* de Proxmox avec des containers mais aussi plein de trucs installés au niveau de l'hyperviseur.
# Conclusion
Ca fonctionne bien mais si j'ai un souci (mise à jour de Proxmox qui casse quelque chose, panne du serveur), je risque de passer des jours à tout remettre en service car j'ai tout installé à la mano. L'idée de tout reprendre à zéro en passant plus de temps pour tout containeriser refait surface. L'idéal pour moi serait de tout exécuter dans des containers et d'avoir une seule arborescence de fichiers à sauvegarder. J'avais tâté un peu Docker et je sais que ça prend pas mal de temps de repenser en containers, de choisir les bonnes images de base... Autre bémol, miser sur une seule entreprise ne m'emballe pas, malgré les efforts de l'[Open Container Initiative](https://blog.docker.com/2017/07/demystifying-open-container-initiative-oci-specifications) pour standardiser partiellement la technologie.
Donc j'étudie les options :
- un provisioning avec Ansible d'un container LXC générique
- l'ajout de Docker à Proxmox pour rajouter Docker au panel KVM / LXC: dockeriser c'est long, donc garder Proxmox permettrait de répondre rapidement à un besoin avec un container LXC, quitte à dockeriser ensuite le service dans un 2ème temps...
Si vous avez des suggestions je suis carrément preneur :-)

View file

@ -0,0 +1,113 @@
<!-- title: Proxmox, NAT et DHCP -->
<!-- categories: Hébergement Containers -->
J'ai eu beaucoup de retours à [mon dernier article](https://blogduyax.madyanne.fr/2018/hebergement-containers/) qui ont alimenté ma réflexion et m'ont permis de clarifier mon objectif avec mon serveur [Proxmox](https://fr.wikipedia.org/wiki/Proxmox_VE).<!-- more --> J'ai décidé de pousser plus loin avec les containers LXC, de ne pas utiliser Docker sur le serveur mais d'améliorer certains aspects de mon installation : containeriser ce que j'ai installé directement sur l'hyperviseur (que ce soit par flemme, pour aller vite ou par manque de connaissances) et automatiser le déploiement de certains containers pour faciliter une éventuelle migration et me permettre d'installer un environnement de test local.
Voici un diagramme à gros grain de l'architecture actuelle :
![Architecture Proxmox](/images/2018/archi-proxmox.jpg)
Au niveau de l'hyperviseur, on a un pare-feu et une interface *Bridge* et j'ai installé un serveur NginX au niveau de l'hyperviseur qui joue le rôle de proxy Web vers les containers. Cela implique de modifier la configuration de NginX à chaque ajout d'un service Web et donc de se connecter en SSH à l'hyperviseur. C'est le premier point que je compte améliorer en migrant ce serveur Web vers un container. Or les containers sont configurés en IP fixe. Pour simplifier les configurations, je veux attribuer les adresses IP par DHCP et d'utiliser des noms DNS plutôt que des adresses.
Au préalable, approfondissons la configuration réseau de mon Proxmox déjà en place... rien de révolutionnaire car la plupart de ces choix ont été documentés par d'autres (et j'ai seulement assemblé pour arriver à mes fins) mais ça permettra de mieux comprendre la partie DHCP qui arrive ensuite. Mon serveur est [une Dedibox hébergée chez Online](https://www.online.net/fr/serveur-dedie) et Proxmox est une distribution officiellement supportée, donc l'installation initiale est réalisée via l'interface Web d'administration du serveur. De base, une interface physique est configurée avec l'adresse IP fixe du serveur et l'adresse IP de la passerelle. Online attribue une adresse IP fixe à chaque dédibox et on peut acheter des adresses IP supplémentaires. C'est idéal pour associer une adresse IP à chaque container, mais on ne va pas faire ça du tout car :
1. c'est coûteux (2 euros HT par IP / mois) pour le l'auto-hébergement,
2. chaque container est directement exposé sur Internet donc il doit être capable d'assurer sa sécurité.
On va plutôt créer un réseau privée (non routable sur Internet), caché derrière l'IP publique du serveur. Les containers peuvent envoyer du trafic sortant sans restriction et le trafic entrant passe par le tamis du pare-feu avant d'être redirigé vers le bon container. C'est similaire à ce qu'on a tous à la maison avec un réseau en 192.168.x.x. derrière une box ADSL (ou fibre pour les chanceux). Pour cela on crée une interface *bridge* nommée vmbr0 qui sert de passerelle aux containers et on ajoute une règle de translation d'adresse (NAT) pour faire passer le trafic sortant de vmbr0 vers l'interface physique enp1s0.
Configuration dans */etc/network/interfaces* :
auto lo
iface lo inet loopback
auto enp1s0
iface enp1s0 inet static
address xx.xx.xx.xx
netmask 255.255.255.0
gateway xx.xx.xx.1
auto vmbr0
iface vmbr0 inet static
address 10.10.10.1
netmask 255.255.255.0
bridge_ports none
bridge_stp off
bridge_fd 0
post-up echo 1 > /proc/sys/net/ipv4/ip_forward
post-up iptables -t nat -A POSTROUTING -s '10.10.10.0/24' -o enp1s0 -j MASQUERADE
post-down iptables -t nat -D POSTROUTING -s '10.10.10.0/24' -o enp1s0 -j MASQUERADE
Sans surprise, le pare-feu de Proxmox est basé sur [iptables](https://fr.wikipedia.org/wiki/Iptables) et l'interface Web facilite vraiment sa configuration en présentant trois niveaux de pare-feu : un niveau datacenter (qui peut contenir plusieurs Proxmox si on gère un cluster), un niveau noeud et un niveau container. On peut activer le pare-feu à chaque niveau.
Ma configuration de base est la suivante :
- au niveau datacenter
- input policy = DROP : tout le trafic entrant non autorisé explicitement est rejeté
- output policy = ACCEPT : tout le trafic sortant est autorisé
- autoriser le PING entrant des serveurs ONLINE (62.210.16.0/24) pour qu'ils puissent m'avertir si mon serveur n'est plus joignable
- au niveau noeud (mon proxmox principal)
- autoriser TCP/8006 entrant : l'accès distant à l'interface Web de Proxmox
- autoriser SSH
- autoriser HTTP et HTTPS
Pour finaliser l'aspect sécurisé, on peut installer fail2ban pour scruter les logs des services critiques et bannir les fâcheux.
A ce niveau là, on a un Promox opérationnel : les containers en IP fixe dans le réseau 10.10.10.0/24 peuvent communiquer avec l'extérieur. On va modifier le système pour fournir du DHCP. La première action consiste à remplacer [le serveur DNS Bind](https://fr.wikipedia.org/wiki/BIND) fourni avec Proxmox par [Dnsmasq](https://fr.wikipedia.org/wiki/Dnsmasq) qui combine les fonctions DNS et DHCP.
systemctl disable bind9
apt-get install dnsmasq
Et on crée un fichier de configuration dans */etc/dnsmasq.d/containers* :
domain-needed
bogus-priv
no-poll
no-hosts
no-dhcp-interface=enp1s0
interface=vmbr0
expand-hosts
domain=madyanne.lan
dhcp-authoritative
dhcp-leasefile=/tmp/dhcp.leases
dhcp-range=10.10.10.100,10.10.10.200,255.255.255.0,12h
dhcp-option=3,10.10.10.1
dhcp-option=19,1
dhcp-option=6,10.10.10.1
cache-size=256
log-facility=/var/log/dnsmasq.log
#log-queries
Quelques points clés de la configuration :
- une allocation DHCP entre 10.10.10.100 et 10.10.10.200
- on fixe la passerelle de sortie 10.10.10.1
- un domaine *interne* : madyanne.lan
- les baux DHCP sont stockés dans un fichier */tmp/dhcp.leases*
Pour tester, je configure un container en DHCP, démarre le container et... ça ne marche pas :-) Le container n'arrive pas à récupérer une adresse IP. En fait, le pare-feu bloque les requêtes DHCP. Je débloque la solution en autorisant les ports UDP/67 et UDP/68 en entrée de l'interface vmbr0.
La configuration du pare-feu au niveau Proxmox est la suivante :
![Configuration pare-feu](/images/2018/proxmox-firewall-rules.png)
Ainsi configuré, cela fonctionne ! Dnsmasq ajoute automatiquement les noms obtenus par DHCP à son service DNS. Ainsi depuis n'importe quel container je peux adresser un autre container par nom court :
# ping dev
PING dev (10.10.10.100) 56(84) bytes of data.
64 bytes from dev.madyanne.lan (10.10.10.100): icmp_seq=1 ttl=64 time=0.137 ms
64 bytes from dev.madyanne.lan (10.10.10.100): icmp_seq=2 ttl=64 time=0.076 ms
Il reste un problème en suspens : les containers de type Alpine ont le mauvais goût de ne pas propager leur nom au serveur DHCP ; c'est peut-être paramétrable dans leur [service Udhcpc](https://wiki.alpinelinux.org/wiki/Udhcpc), il faut que je regarde...
Ma prochaine évolution consiste à migrer le serveur NginX installé par mes soins au niveau de le Proxmox vers un container dédié avec la gestion des certificats SSL Let's Encrypt.

View file

@ -0,0 +1,48 @@
<!-- title: Spam des commentaires -->
<!-- categories: Blog Containers -->
<!-- tag: planet -->
Pour lutter contre le spam dans les commentaires du blog, j'ai opté pour la simplicité dès le début parce que l'audience est restreinte, que je ne veux pas compliquer la vie des lecteurs avec des systèmes de captchas<!-- more --> (de plus en plus illisibles d'ailleurs) et que [je veux préserver l'accès au blog sans JavaScript](/2017/un-blog-plus-respectueux/) pour les durs, les vrais, les tatoués ;-)
Ma naïve défense est basée sur un [pot de miel](https://fr.wikipedia.org/wiki/Honeypot) : un champ caché dans le formulaire de saisie de commentaire, invisible pour l'humain normalement constitué, qui ne peut donc être rempli que par un bot qui analyse les pages HTML. Ces commentaires sont jetés directement par [mon gestionnaire de commentaires Stacosys](https://github.com/kianby/stacosys). Pendant longtemps, ce fut une défense suffisante ; de rares fois un facheux postait un commentaire pour me vanter un site de vente de pilules : je refusais le commentaire et voilà.
Mais depuis quelques temps, je reçois des rafales de spams : soit les robots sont plus efficaces et analysent aussi la CSS de la page, soit quelqu'un a embauché une armée de zombies pour poster manuellement sur tous les sites à moins de 100 visiteurs / jour. J'ai donc mis en place une 2ème ligne de défense. Quand j'étiquète *spam* le commentaire, Stacosys écrit une ligne de log avec l'adresse IP du spammeur, et [fail2ban](https://github.com/fail2ban/fail2ban) ajoute une règle *iptables* pour le bannir. La méthode n'est pas révolutionnaire, ça a demandé quelques lignes de code dans Stacosys ; ce qui est plus intéressant, c'est sa mise en oeuvre dans une architecture Docker avec un reverse proxy.
![Architecture Docker blog](/images/2018/docker-blog.png)
Nginx joue le rôle de *reverse proxy*, il balance les requêtes du blog vers Hugo et le post du formulaire vers Stacosys. Pour ne pas perdre l'adresse IP réelle du visiteur, on la propage jusqu'à Stacosys dans l'attribut HTTP *X-Forwarded-For*.
On a une configuration NginX de ce genre :
location /newcomment {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://stacosys:8100/newcomment;
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://nginx-blog;
}
Stacosys est un container Docker donc l'application (PID 1) écrit ses logs dans la sortie standard (STDOUT) ; c'est le comportement par défaut. Mais, afin d'ajouter des règles *iptables*, le container **fail2ban** a besoin de lire ces logs. On va donc exporter les logs de stacosys vers le container **logger** en rajoutant une section **logging** dans le fichier *docker-compose* qui décrit le lancement du service **stacosys** :
logging:
driver: syslog
options:
syslog-address: "tcp://127.0.0.1:514"
tag: "stacosys"
et le container **logger**, qui n'est rien d'autre qu'un serveur syslog, écrit ses logs dans un volume Docker :
logger:
image: bobrik/syslog-ng
volumes:
- syslog:/var/log/syslog-ng
ports:
- "514:514"
Le volume de données **syslog** est partagé avec le container **fail2ban** qui peut ainsi lire les logs de stacosys, appliquer ses règles de filtrage et définir dynamiquement des règles *iptables* pour bannir les vilains.

View file

@ -0,0 +1,183 @@
<!-- title: Installation d'un serveur de containers -->
<!-- categories: Hébergement Containers -->
<!-- tag: planet -->
Plus des notes techniques pour ma mémoire défaillante qu'un véritable article, je vais compiler les étapes d'installation d'un serveur de containers.<!-- more --> Quel système d'exploitation ? j'ai envie de dire on s'en cogne mais il est préférable de choisir une distribution poussée par Docker pour se simplifier la vie ; ce sera donc Debian 9 *Stretch* supportée sur Dedibox.
J'installe donc via l'interface d'administration Online. Je choisis le mot de passe *root*, le compte utilisateur et son mot de passe. Online me communique ma configuration réseau :
- Adresse IP : xxx.yyy.zzz.xxx
- Masque réseau : 255.255.255.0
- Passerelle : xxx.yyy.zzz.1
- DNS primaire : 62.210.16.6
- DNS secondaires : 62.210.16.7
# SSH
Je vérifie qu'on peut se connecter au serveur :
ssh yax@xxx.yyy.zzz.xxx
Je me déconnecte et génère une clef avec **ssh-keygen**, en choisissant une clef RSA. On peut fournir une *passphrase* si on pense qu'elle peut tomber entre de mauvaises mains. Je nomme ma clef *fr_mondomaine* ; cela génère une clef publique *fr_mondomaine_rsa.pub* et une clef privée *fr_mondomaine_rsa*.
Je copie la clef publique sur le serveur :
ssh-copy-id -i fr_mondomaine_rsa.pub yax@xxx.yyy.zzz.xxx
On peut simplifier la connexion au serveur en modifiant la configuration du client SSH *~/.ssh/config* de sa machine pour que l'utilisateur et la clef soient choisis sans le spécifier sur la ligne de commande :
Host fr.mondomaine
User yax
Hostname xxx.yyy.zzz.xxx
IdentityFile ~/.ssh/fr_mondomaine_rsa
Je vérifie qu'on se connecte sans saisir de mot de passe :
ssh fr.mondomaine
J'interdis complètement la connexion SSH au compte *root*. Pour cela, je me connecte au serveur, je passe en *root* avec **su** et j'édite le fichier de configuration du service SSH */etc/ssh/sshd_config* pour fixer les paramètres suivants :
PermitRootLogin no
PasswordAuthentication no
Je redémarre le service SSH :
systemctl restart sshd
Et si on s'est raté ou si on perd la clef RSA sur notre PC à la maison ? Et bien on est bon pour redémarrer le serveur en mode secours avec la console Dedibox, monter les partitions et se *chrooter* pour arranger la configuration de SSH. C'est encore faisable facilement car systemd n'a pas encore binarisé tout le système (*troll inside*).
Je ne configure pas **sudo**, je veux pouvoir tout faire avec un utilisateur standard, les connexions à root par **su** doivent rares, principalement pour effectuer les mises à jours du système Debian.
# Docker
Installation de Docker CE sur Debian Stretch avec la procédure officielle qui ajoute des dépôts APT Docker pour récupérer une version de Docker plus récente que celle fournie avec Debian Stretch : https://docs.docker.com/engine/installation/linux/docker-ce/debian/
Installation d'une version récente de **Docker Compose** en suivant aussi la procédure officielle : https://docs.docker.com/compose/install/
Ajout de l'utilisateur yax dans le groupe docker
usermod -aG docker yax
Démarrage automatique de Docker:
systemctl enable docker
# Pare-feu
J'installe **shorewall** pour IPv4, un pare-feu puissant qui ne rajoute pas de service supplémentaire au système puisqu'il traduit ses règles assez complexes en règles *iptables*.
apt-get install shorewall
Par sécurité, le temps de mettre au point les règles, je désactive le démarrage automatique :
systemctl disable shorewall
Si ça foire, je pourrai toujours forcer un redémarrage électrique du serveur :-)
Docker a la particularité de gérer ses propres règles *iptables* pour l'accès aux containers ce qui rend sa cohabitation délicate avec tout pare-feu basé sur *iptables* Depuis quelques versions, Shorewall supporte Docker, ce qui revient à dire qu'il le laisse faire sa sauce et gère les règles *iptables* qui lui sont propres.
Donc j'édite */etc/shorewall/shorewall.conf* et déclare que je vais utiliser Docker :
STARTUP_ENABLED=Yes
DOCKER=Yes
Puis j'édite */etc/shorewall/zones* pour définir mes zones :
#ZONE TYPE OPTIONS
fw firewall
net ipv4
dock ipv4 # 'dock' is just an example
Et les règles de passage d'une zone à l'autre en éditant */etc/shorewall/policy* :
#SOURCE DEST POLICY LEVEL
$FW net ACCEPT
net all DROP info
dock $FW REJECT
dock all ACCEPT
# last rule
all all REJECT info
Enfin, j'associe les zones aux interfaces physiques (attention *enp1s0* est le nom de l'interface Ethernet de mon serveur), en éditant */etc/shorewall/interfaces* :
?FORMAT 2
#ZONE INTERFACE OPTIONS
net enp1s0 dhcp,tcpflags,logmartians,nosmurfs,sourceroute=0
dock docker0 bridge,routeback=0 #Disallow ICC
Là on a un pare-feu opérationnel qui refuse toute connexion entrante ; on ajoute quelques règles pour autoriser le PING ICMP et les connexions SSH avec une limite de 3 connexions par minute (pour calmer les facheux).
Ca se passe dans le fichier */etc/shorewall/rules* :
#ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL RATE USER/ MARK CONNLIMIT TIME HEADERS SWITCH HELPER
# PORT PORT(S) DEST LIMIT GROUP
?SECTION ALL
?SECTION ESTABLISHED
?SECTION RELATED
?SECTION INVALID
?SECTION UNTRACKED
?SECTION NEW
# Drop packets in the INVALID state
Invalid(DROP) net $FW tcp
# Drop Ping from the "bad" net zone.. and prevent your log from being flooded..
Ping(ACCEPT) net $FW
# Permit all ICMP traffic FROM the firewall TO the net zone
ACCEPT $FW net icmp
SSH(ACCEPT) net all - - - - s:1/min:3
# Tester la sécurité
Là ça devient plus amusant ! Je reboote et je démarre manuellement shorewall puis je jette un oeil à la bonne cohabitation des règles **iptables** entre Shorewall et Docker :
iptables -L -n -v
D'abord je teste les accès distants :
- on peut scanner les ports avec NMAP depuis sa machine : on voit le port 22 ouvert
- on vérifie facilement que SSH est limité à 3 connexions par minute
Enfin je teste la sécurité intra-docker en déployant 3 containers Docker avec [l'image tcpping](https://hub.docker.com/r/kianby/tcpping/) :
version: "3"
services:
web1:
image: tcpping
expose:
- 80
networks:
- frontend
web2:
image: tcpping
networks:
- frontend
- backend
web3:
image: tcpping
ports:
- 8000:80
networks:
- backend
networks:
frontend:
backend:
Les containers web1 et web2 sont sur le réseau *frontend*
Les containers web2 et web3 sont sur le réseau *backend*
Je vérifie les points suivants :
- chaque container peut accèder à Internet
- aucun container ne peut accéder au serveur : ni ping, ni SSH
- web1 et web2 se voient en ICMP et en TCP 80
- web2 et web3 se voient en ICMP et en TCP 80
Je refais un scan de port plus poussé avec NMAP et je vois que le port 22 et 8000 (celui de web3) sont accessibles depuis Internet.
Si je liste les règles *iptables*, je remarque que l'isolation des réseaux entre les containers donne lieu à des règles *iptables* supplémentaires.

View file

@ -0,0 +1,37 @@
<!-- title: Gadget Bridge et autres connectés -->
<!-- category: Matériel -->
<!-- tag: planet -->
Je porte un bracelet Xiaomi Mi-Band connecté depuis Noël dernier. Ce n'est pas un cadeau tentateur pour libriste en perdition mais un achat assumé.<!-- more --> L'angoisse de l'approche de la cinquantaine probablement, je voulais moi aussi mesurer la qualité de mon sommeil et mon manque d'activité physique, bref vérifier [si moi aussi je ne serais pas l'homme du 21ème siècle.](https://www.youtube.com/watch?v=AEv9VLQegvY&list=PLTwkIOfLU8_reQI_2mapPF4zv2Co6lSTg&index=8) Je pensais que ça m'amuserait quelques semaines mais c'est devenu une habitude et ça a aidé à une reprise d'activité sportive plus régulière.
Le bracelet est autonome ; il a des capteurs, il enregistre et à l'occasion on synchronise les données vers une application mobile. Dans ce mode, il a une autonomie de 4 à 6 semaines, c'est impressionnant. On peut aussi l'utiliser en mode connecté au téléphone pour envoyer des notifications en temps réel : appels, messages. Ce mode est beaucoup plus consommateur en batterie (du bracelet et du téléphone).
J'ai utilisé l'objet en mode autonome pendant plusieurs mois. Le premier jour, j'ai installé l'application officielle Xiaomi qui s'occupe aussi des mises à jour du firmware. Il faut créer un compte chez Xiaomi (sic!)
et le lendemain matin on apprend qu'on a mieux dormi que 43% des autres ~~membres du troupeau~~ utilisateurs. Et oui, le ticket d'entrée du 21ème siècle coûte le leg de ses données personnelles... que deviennent les données ensuite ? combien d'années avant qu'elles soient revendues à mon groupement mutualiste qui me fera un tarif santé fonction de mon rythme de vie ? Bref, on sait où ça mène !
Donc déconnexion de l'appli officielle et recherche d'une meilleure solution ; je n'ai pas cherché longtemps, je traîne suffisamment sur [la boutique F-Droid](https://f-droid.org) pour avoir remarqué l'application [Gadgetbridge](https://github.com/Freeyourgadget/Gadgetbridge) qui :
- gère la plupart des bracelets / montres Xiaomi et les Pebble,
- conserve les données sur l'appareil et propose même un import / export de la base de données
- propose des fonctionnalités communes à tous les équipements supportés : activité (compteur de pas), qualification du sommeil, réveil,
- des fonctionnalités spécifiques en fonction du type de bracelet ou de montre joliment détaillées [dans cette matrice](https://github.com/Freeyourgadget/Gadgetbridge/blob/master/FEATURES.md)
Je n'ai pas parlé de la fonction réveil. Ca peut sembler anecdotique mais quand on est traumatisé par les sonneries à l'aube, on échange volontiers contre la douce vibration du bracelet.
![gadget bridge](/images/2018/gadgetbridge.png)
Récemment je suis passé dans le mode d'utilisation connecté au téléphone alors que je refusais, au début, ce fil à la patte. Mais avec ces téléphones Android un peu récents, tous identiques, rectangulaires, sans saveur où les constructeur ont le droit de choisir la taille et la qualité de l'appareil photo mais surtout aucune personnalisation matérielle non validée par le dieu Google, on n'a même plus la LED de notification qu'on trouvait sur les premiers modèles et on se retrouve finalement à les allumer régulièrement juste pour vérifier si on n'a pas raté un appel ou un SMS important. J'ai donc commencé à utiliser le mode notification du bracelet en environnement professionnel.
La notification sur le bracelet Mi Band 2 est minimale : on sait que le téléphone (en vibreur dans un coin) sonne ou qu'on a reçu un message. C'est déjà pas mal et ça m'a donné envie de passer au niveau supérieur avec la montre Xiaomi Amazfit Bip qui reçoit les messages SMS, affiche le nom des correspondants des appels et peut même afficher les prévisions météorologiques. Pour le reste on retrouve les fonctionnalités du bracelet Mi Band (someil, activité) et la même technologie d'écran qui fournit une autonomie de plusieurs semaines. C'est ce qui a entériné mon choix d'ailleurs, je fuis les montres qu'il faut recharger chaque soir.
C'est donc mon cadeau d'anniversaire (merci M. de mon coeur), étrenné depuis 2 semaines, toujours de concert avec Gadgetbridge qui est la meilleure solution pour ce matériel car il sait résoudre le problème des accents. En effet, la montre propos un firmware chinois et un firmware anglais pour l'international. Soit on teste des firmware non officiels pour le français, soit on reste en international ce qui est mon choix. Et dans ce cas-ci, les SMS sont épurés de leurs caractères accentués ce qui complique un peu la lecture. Gadgetbridge fournit un paramètre *transcription* qui remplace les accents par leur équivalent ASCII : "é" devient "e", ce qui est bien mieux qu'un abscons symbole ¤
La fonction météo semblait mal engagée mais on trouve l'application *Weather Notification* sur F-DROID qui fournit les prévisions de OpenWeather Map à GadgetBridge et cela fonctionne très bien.
Enfin que serait une montre connectée sans la possibilité de changer de cadran au gré de ses humeurs. Le site [Amazfitwatchfaces](https://amazfitwatchfaces.com/bip/) recense les contributions des graphistes et permet de télécharger des nouveaux cadrans. On peut créer un compte et voter pour les meilleurs artistes pour les encourager, c'est bon enfant.
![watch face](/images/2018/amazfitwatchfaces.png)
Bon voilà je suis revenu sur Android et je suis connecté. A ce propose je remercie le talentueux [Bunnyy](https://forum.xda-developers.com/member.php?u=8946392) pour le portage de [la ROM Resurection Remix](https://forum.xda-developers.com/samsung-a-series/development/rom-resurrection-remix-rr-v6-unofficial-t3765542) sur Samsung A5 2016 : je compte sur toi pour faire fonctionner les appels Bluetooth sous peu.
Est-ce que je suis entré dans le 21ème siècle ? un peu mais tout est loin de me plaire et j'essaie de ne choisir que les meilleurs côtés :-)

View file

@ -0,0 +1,39 @@
<!-- title: Il court, il court, le furet -->
<!-- categories: Humeur Containers -->
Il court, il court, le furet... ça résume à peu près mes semaines en ce moment.<!-- more --> Le thème de celle-ci (oui j'ai des semaines à thème) est la vente d'électro-ménager sur le site du Bon Coin (à ne pas confondre avec le bon sens près de chez vous) pour cause de rénovation. D'ailleurs si quelqu'un veut un frigo pas cher qu'il me contacte ;-)
Mon expérience passée des annonces m'a définitivement vacciné d'afficher mon téléphone ou mon e-mail principal. Heureusement on peut masquer son téléphone le temps de s'assurer que la personne est vraiment interessée. Quant à l'e-mail, un jetable ferait l'affaire. Bon un jetable du style [10 minutes e-mail](https://10minutemail.com) c'est un peu court pour une annonce destinée à être publiée une semaine. Du coup il me reste deux options :
1. créer un alias ou un e-mail chez moi puisque je suis maître de mon ~~destin~~ domaine
2. créer une boite chez un fournisseur
Je cherche un fournisseur respectable qui propose le service de transfert des e-mails pour tout rediriger sur mon e-mail principal. Je pensais que La Poste propose ce service mais il semble que cette époque soit révolue. Après quelques égarements avec des offres floues qui annoncent des options qui s'avèrent finalement payantes (n'est-ce pas Net-C) je finis chez un GAFAM et tant qu'à faire le plus gros de tous : Google... *applaudissements du lectorat en liesse, perte de ceux qui manquent d'humour*
Alors Google c'est *all inclusive* : récupération des autres boites e-mail (miam miam de la donnée), transfert vers une autre boite (pas grave j'ai tout lu au passage), toutes les options avancées sont offertes. Au moins le contrat est clair : tu as un service haut de gamme mais tu paies avec tes données. Pas de souci, ils vont se régaler avec mes conversations dartyesque :-)
Bon utiliser Google d'accord, mais soyons un peu parano en évitant de transférer les e-mails vers ma boite principale ; inutile de donner un lien facile à établir, faisons transpirer un peu leur IA. Je peux récupérer les e-mail à distance mais GMail râle dès qu'on active IMAP ou POP3 qu'il considère, à raison, comme des protocoles moins sécurisés. Je vais donc faire un rebond : GMail transfère tous les e-mails vers ma vénérable boite e-mail Free et je prévois de rapatrier celle-ci vers mon e-mail principal par POP3.
Bon rapatrier une boite e-mail par POP3 et faire un transfert SMTP c'est pas sorcier, il y a plein de documentation sur fetchmail / procmail / les relay MTA. C'est vrai et j'ai passé un couple d'heures à paramétrer tout cela pour finalement jeter l'éponge : manque de temps sur mon planning de furet et moins de goût à peaufiner une config système au poil pendant des heures. Du coup, j'ai mis ma casquette de codeur et réglé le problème par code en une heure de temps avec Python et ses librairies SMTP et POP3 incluses dans un projet nommé [popforward](https://github.com/kianby/popforward) ; *vous apprécierez ma créativité pour le nommage*.
A ce stade, vous pensez : *"c'est bizarre il ne nous a pas encore bassiné avec Docker"*... j'y viens :-)
La mise en prod a pris 15 minutes chrono : écriture d'un docker-compose en utilisant [mon image pour les applications Python](https://hub.docker.com/r/kianby/pythonapp/) et déploiement sur le serveur de containers.
``` docker
popforward:
image: kianby/pythonapp:latest
environment:
APP_NAME: popforward
APP_CONFIG: /app/config.ini
volumes:
- ${SOURCEDIR}/popforward:/app/popforward
- ${DATADIR}/popforward/popforward.config.ini:/app/config.ini
```
Bon... je retourne courir !
![furet](/images/2018/furet.jpg)
*[Photo by Alex Makarov on Unsplash](https://unsplash.com/photos/pIarqh5GU0I?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)*

View file

@ -0,0 +1,57 @@
<!-- title: Retour sur la migration vers Docker -->
<!-- categories: Containers Hébergement -->
<!-- tag: planet -->
Ce ne sera pas un scoop car j'ai distillé l'information à travers mes derniers articles : j'ai transformé mon serveur de virtualisation en serveur de containers Docker<!-- more --> depuis quelques mois. C'est l'occasion de faire un bilan en listant ce qui a bien fonctionné mais aussi ce qui a posé problème, et les avantages et inconvénients d'un serveur de containers. Au préalable, je n'utilise pas Docker dans un contexte professionnel mais pour héberger mes services personnels.
Docker n'est pas une lubie... je suis ses avancées depuis plus de trois ans. Il a eu sa période très instable où le choix de la distribution et surtout du kernel étaient primordiaux, puis celle où la sécurité était discutable. Mais aujourd'hui il est difficile de trouver des arguments pour ne pas au moins l'essayer. Docker est une vague de fond qui a déjà conquis les grandes entreprises et les développeurs. Ces derniers maintiennent de plus en plus souvent une version Docker de leurs logiciels en plus (mais jusqu'à quand ?) des paquets pour telle ou telle distribution. [J'ai déjà abordé le sujet](https://blogduyax.madyanne.fr/2018/quel-systeme-serveur/) : pour moi Docker, c'est la fin de la distribution serveur à court terme comme [flatpak et consorts](https://fr.wikipedia.org/wiki/Flatpak) annoncent la fin de la distribution bureau à moyen terme.
On entend souvent :
Docker n'a rien inventé, les containers existaient déjà !
Oui c'est vrai, on avait déjà chroot, LXC, OpenVz, les jails. D'ailleurs Docker s'est appuyé sur LXC dans ses premières versions. Mais ça, c'est la plomberie du sous-sol. C'est nécessaire et ça doit être performant mais ça ne résume pas Docker et ça n'explique pas son succès qui, pour moi, a 3 raisons principales :
1. l'abstraction (partielle) au système d'exploitation, ce qui donne accès à Docker à un autre public que des ingénieurs système
2. un langage de description *Dockerfile* / *docker-compose.yml* facile d'apprentissage
3. et, surtout, un écosystème communautaire : je parle bien sûr du marché au containers : [le Hub](https://hub.docker.com/)
Si je fais un parallèle rapide avec le langage Java, Maven a beaucoup concouru à son succès en donnant accès à toutes les librairies tierces Open Source. Et bien c'est exactement ce que fait Docker avec le hub : récupérer une image pour l'enrichir et fabriquer la sienne.
On est en plein dans l'essence même de l'Open Source, le partage. Il faut toutefois prendre des précautions :
- priviligier une image officielle d'un logiciel
- ne pas se dispenser de lire son Dockerfile pour voir comment elle est construite et sur quelles couches elle s'appuie
En fait, ce sont les mêmes réflexes qu'avec l'intégration d'une librairie inconnue à son programme. Cela explique aussi l'engouement des développeurs pour Docker et on peut faire plein de parallèles avec le développement. J'ai passé du temps à pratiquer et j'ai pris de la compétence progressivement. Je pense avoir atteint le 2ème dan, selon ma vision de la courbe d'apprentissage de Docker :
- **1er dan** : docker file : écriture, réutilisation, exposition / attachement de ports, utilisation des volumes, publication dans une registry
- **2ème dan** : docker compose : composition de containers, communication intra-container, compréhension du cycle de vie des images et des containers
- **3ème dan** : orchestration, supervision, sécurité avancée : Kubernetes, Docker Swarm, audits de sécurité
Ma prochaine étape est d'effleurer le 3ème dan avec Swarm. Faute de ressources matérielles suffisantes, je ne me formerai probablement pas à Kubernetes dans la sphère personnelle.
Pour progresser, j'ai déployé au plus vite pour me confronter en situation réelle. A l'époque, mon serveur fonctionnait avec des containers LXC dans Proxmox. Il a donc été aisé de migrer des bouts vers Docker sans faire la bascule d'un coup. De plus, j'avais le pare-feu de Proxmox et mes containers s'exécutaient dans une marchine virtuelle KVM ; cela m'a permis de me concentrer sur la création des images et des containers et retarder l'apprentissage de la sécurisation.
Une bonne partie des containers font tourner des projets persos écrits en Python. j'ai donc naturellement créé une image commune pour les applications Python. Par paresse et comme je ne suis pas dans un contexte professionnel, j'ai réutilisé la même image pour plusieurs containers / applications en connectant un volume avec les sources Python dessus. Dans un contexte professionnel, j'aurais créé une image versionnée pour chaque application embarquant les sources. J'ai publié mes [quelques images sur le Hub](https://hub.docker.com/u/kianby/) et les sources sont [sur mon GitHub](https://github.com/kianby/docker)
J'ai basé mon démarrage sur un simple fichier docker-compose qui décrit tous mes containers et une commande *docker-compose up* pour tout démarrer. Quand je me suis senti à l'aise et capable de sécuriser correctement Docker, [j'ai réinstallé le serveur de zéro avec une Debian et Docker](https://blogduyax.madyanne.fr/2018/installation-dun-serveur-de-containers/) pour en faire un serveur de containers bare metal.
Pour la supervision, je suis resté simple en installant [Portainer](https://www.portainer.io/) pour redémarrer les containers, voir les logs... et [Glances](https://nicolargo.github.io/glances/) pour avoir une vision détaillés de l'usage des ressources. Les 2 outils sont s'exécutent eux-même dans des containers.
Voilà j'en suis à 18 containers déployés avec 30% des 4 Go de RAM du serveur utilisé. Les performances sont très proches d'une installation monolithique. Docker demande un peu plus de RAM car même si les images sont légères on duplique des OS légers. En tout cas, on est très au dessus des performances de la virtualisation.
Le plus gros bénéfice de ma migration est un environnement de test identique, le truc que je n'ai jamais pu avoir auparavant. Pour cela, j'ai souscrit un nom de domaine .space à 0,99 centimes (merci les promos) et j'ai décliné la configuration de mon environnement sur ce domaine. Résultat, j'ai un environnement complet qui tourne sur mon PC de développement : très appréciable quand la moitié des containers exécutent du code écrit par soi-même et quand on veut tester des nouveaux containers avant de les mettre en production. Autre avantage, la sauvegarde en un tour de main : une arborescence de données, quelques volumes Docker.
Ce qui a moins bien marché, c'est le 1er démarrage de mes containers Python dépendants les uns des autres et habitués à avoir les services dépendants opérationnels. Dans Compose, on ne définit ~~pas~~ plus d'ordre de démarrage. le cycle de vie des containers est aussi plus volatile : une modification de *docker-compose* recrée juste les containers impactés. On a donc plus souvent des containers détruits / recréés. C'est donc une bonne approche d'avoir du code orienté micro-services, capable de :
- gérer la non disponibilité d'un service en fournissant un service dégradé
- stocker localement les données reçues pour les traiter quand l'ensemble du système redevient opérationnel
J'ai donc revu le code de certains de mes projets pour leur ajouter une base de donnée locale SQLite et gérer le dynamisme de l'environnement. C'est positif et pas forcé par Docker ; son fonctionnement rend juste cette approche pertinente et on obtient du code plus résilient. Je suis très satisfait de cette migration et pas prêt de revenir en arrière.
![Docker](/images/2018/docker.jpg)
**Est-ce que Docker est indétrônable ? Est-ce qu'il y aura une alternative libre ?**
Une partie de Docker est sous licence Open Source et on a des alternatives pour l'exécution de containers (comme rkt de CoreOS). L'arrivée un peu tardive de Swarm et les lacunes de ses premières versions ont permis à Kubernetes de remporter une grosse partie du marché de l'orchestration. Mais Docker a construit une communauté ces cinq dernières années et démocratisé la publication de containers au format Dockerfile, difficile d'imaginer qu'il puisse disparaitre comme ça. En tout cas, je pense que la mode de la containerisation a gagné le marché durablement.