Préproduction
Une préprod doit être un environnement le plus similaire possible à la production (versions et services déployés), mais en plus petit, histoire de limiter les coûts.
Il ne faut pas oublier les proxys applicatifs, les CDN, les services tiers, tout, absolument tout doit être similaire à la production.
Les préprods sont tellement pratique, que maintenant, on peut en avoir une par branche de développement, pour peu que l'on utilise des conteneurs.
L'anglicisme pour désigner ça est app review .
Les préprods sont utiles et pratiques, mais on ne souhaite pas forcément que n'importe qui puisse y jeter un oeil (pour faire des tweets moqueurs ou casser le suspens), et surtout qu'elles soient indexées par un moteur de recherche.
Robots
Pour les moteurs de recherche, il existe le célèbre robots.txt et le un peu moins célèbre header X-Robots-Tag reconnu au moins par Google et Yahoo. Ces outils ne sont qu'indicatifs, mais bon, un peu d'hygiène ne fait jamais de mal.
Mot de passe
Il est techniquement facile de coller un mot de passe en basic-auth sur n'importe quel serveur web, mais ça va stresser les personnes qui devraient y avoir accès mais qui ne connaissent pas le mot de passe, et à la fin, le mot de passe est connu de la Terre entière.
La bonne approche est de passer par de l'OAuth2, comme le permet l'incontournable OAuth2-Proxy dont on vous a déjà parlé, vu qu'il y a des pull requests à nous dedans .
Ces deux approches sont parfaites (la seconde est même encore plus parfaite) pour un site qui sera public, mais empiler les authentifications est une très mauvaise idée.
Si votre site a des utilisateurs authentifiés, il va falloir trouver autre chose pour protéger la préprod.
VPN
Un VPN ( Wireguard , what else?™) va garantir un accès exclusif à votre application, mais va poser des problèmes avec https .
Ou alors, vous fournissez un certificat racine à vos utilisateurs, et donc la possibilité de forger n'importe quel certificat, et là c'est assez flippant.
Les certificats modernes peuvent s'engager à ne signer qu'une liste de domaines bien spécifiés, mais ce n'est pas encore géré par tout le monde.
Letsencrypt a besoin d'accéder au site en HTTP pour aller chercher une preuve, avec le challenge HTTP, ce qui ne fonctionnera pas derrière un VPN.
Il faut passer à un challenge DNS, et donc avoir une API pour modifier automatiquement votre DNS (ce que propose la plupart des DNS, la liste est large ).
Le soucis va être de déployer le VPN de partout, sur toutes les machines.
Bon courage si vous bossez dans l'IOT, l'Internet Des Machins qui se connectent alors qu'on ne leur avait rien demandé.
Filtrage par IP
Finalement, la protection un peu naïve, est de filtrer par IP, soit vous êtes dans la liste, soit rien du tout, le serveur, ou le firewall, bloque les autres IPs.
Pour les entreprises c'est assez facile de connaitre les IPs.
Pour les connections personnelles (xDSL, Fibre, cable), ça va dépendre du fournisseur. Certains vicelards s'amusent même à déco/reco au milieu de la nuit pour assigner une nouvelle IP, et on ne va même pas évoquer ceux qui attribuent la même IP publique à l'intégralité de leurs abonnés en leur fournissant un gros LAN, merci le CGNAT.
Pour les connections itinérantes ([1-5]G) ça va aussi être le bazar.
Pour les gens dans un café/gare/coworking ça va être la foire.
Filtrage par IP dynamique
Pour avoir une solution de filtrage par IP simple et souple à mettre en place, il est possible d'utiliser un service authentifié (votre cher Gitlab, par exemple), qui va utiliser votre user agent (massivement tweaké pour des raisons de tracking publicitaire) et votre IP, pour les mettre dans la bonne liste pour votre préprod.
N'utilisez pas ce système dans un salon, un coworking space et autre wifi nébuleux.
Lire les logs
Spoiler : la paire IP/User agent se trouve dans les logs du serveur HTTP.
Vous n'avez pas envie de patcher votre application pour qu'elle fournisse la liste des invités, il est tellement plus sage de se brancher depuis l'exterieur, de la manière la moins intrusive possible.
Coup de chance, l'arrivée des micro services, qui tournent "quelque part" sur le cluster a obligé à normaliser les flux de logs.
J'exclu Syslog avec son routage trop petit, ses messages trop courts et son UDP trop YOLO. Mais oui, techniquement, c'est faisable.
Logstash est bien gentil, mais les cycles de debug avec un reboot de 2 minutes, non merci.
Le protocole pour faire transiter ses logs, lumberjack, est décrit et il existe même une lib officielle pour golang . Filebeat a lui aussi sa place dans la galaxie ELK, mais sans l'exotisme de Jruby utilisé par son meilleur ennemi, Logstash. Lumberjack est une solution crédible.
Le lobby des conteneurs, aka CNCF a désigné Fluentd comme solution de gestion de logs.
Le protocole est documenté , docker le cause en natif , et le client officiel, fluentbit s'installe facilement sans dépendance pénible.
Grafana conforte sa position de hub universel, en ajoutant à sa pile un serveur de logs : Loki .
Plein de gens parlent le Loki : Fluentbit, Vector , Docker, via un plugin de chez Grafana et bien sur Promtail le client fournit avec Loki.
Avec les premiers protocoles cités, vous allez devoir créer un serveur ad hoc pour récupérer le flot de logs. Avec Loki, c'est dans l'autre sens : vous allez demander à Loki de vous abonner à un flot de logs.
Loki va apporter une indirection, mais aussi un buffer (1h par défaut) et donc la possibilité de bidouiller vos analyses de logs sans perdre de message, ou même d'aller explorer le passé.
Il faut visualiser Loki comme un data lake suffisamment rangé pour pouvoir router simplement les différents flots de log, en batch, et en temps réel.
Autre arme secrète, Loki propose une nouvelle syntaxe pour parser les logs bien systématique, sans recourir aux expressions régulières (et au terrible Grok ). Ça s'appelle pattern et il faut chercher dans la documentation pour en avoir une description.
Chevillette
Chevillette est un projet en Go, sous licence AGPL-3.0. Il va lire des logs d'un serveur web, filtrer sur des chemins avec des status 200, par exemple le chemin d'un projet Gitlab, il va garder dans sa liste la paire IP/user agent pendant quelques temps.
Pour l'instant, Chevillette sait écouter du fluentd (il se comporte comme un serveur, avec les différentes authentifications implémentées).
L'abonnement à un serveur Loki est en cours.
Si il y a de la demande, la bibliothèque officielle est disponible, avoir un server Lumberjack sera pas trop compliqué à mettre en place.
De l'autre coté, Chevillette implémente le auth_request de Nginx (que Traefik sait aussi utiliser).
Auth_request permet de déléguer le filtrage de requêtes à un service HTTP, en se mettant à coté, et non devant comme le ferait un proxy HTTP. HAproxy, pour sa part, utilise un protocole spécifique, SPOE pour déléguer la qualification des requêtes à un service tiers. La lib golang est disponible , et le sujet est passionnant, il est donc possible que son implémentation arrive rapidement.
Les logs sont un flot d'événements plus ou moins qualifiés, ce n'est pas juste le truc qui explique pourquoi le service est vautré.
Il y a clairement des choses à faire avec, et Loki est manifestement un bon point de départ (avec son ami Grafana) pour explorer et déclencher des actions.