Archives pour la catégorie Tips

Chan­ger ses mots de passe rapi­de­ment avec Salt

Préam­bule

Salt est un logi­ciel de gestion de confi­gu­ra­tion comme Puppet ou Ansible.

Je l’uti­lise chez Frama­soft et sur mon infra person­nelle parce que je l’aime bien :

  • rapide ;
  • très bien docu­menté ;
  • syntaxe claire, acces­sible mais néan­moins flexible et puis­sante.

Je change mes mots de passe régu­liè­re­ment (une fois par an envi­ron). C’est toujours galère à faire quand on gère une tripo­tée de serveurs (entre les serveurs physiques et les VMs, on en est à 80 serveurs chez Frama­soft).

Avant, je faisais ça à la main : je lançais mssh sur 4, 6 ou 8 serveurs à la fois, et je modi­fiais mon mot de passe à la main. Mais ça, c’était avant.

Salt à la rescousse

Pour chan­ger le mot de passe de l’uti­li­sa­teur bar sur le serveur foo avec salt, on fait :

salt foo shadow.set_password bar "$6$saltSALT$HASHEDPASSWORD"

$6$saltSALT$HASHEDPASSWORD corres­pond à votre mot de passe salé et hashé. Vous retrou­vez un brol du genre dans votre /etc/shadow (Oh ! Vous avez remarqué ? C’est le nom du module salt qui permet de modi­fier votre mot de passe ! C’est bien fait quand même 😁)

Pour créer un sel (le saltSALT, rien à voir avec le logi­ciel), j’uti­lise mkpasswd.pl, fourni par le paquet Debian libstring-mkpasswd-perl :

mkpasswd.pl -l 8 -s 0

Pour créer l’en­semble $6$saltSALT$HASHEDPASSWORD, vous pouvez utili­ser python :

python -c "import crypt; print crypt.crypt('PASSWORD', '\$6\$saltSALT')"

Bon, on sait comment faire, mais on ne va pas s’amu­ser à taper 80 fois ces commandes !

Salt permet de véri­fier que les minions (les agents Salt) répondent bien avec cette commande :

salt foo test.ping

Ce qui donne :

foo:
    True

On va chan­ger le format de sortie :

salt foo --out text test.ping

Ce qui nous donne :

foo: True

Bien ! On peut pinguer d’un coup tous les minions avec :

salt \* --out text test.ping

On a donc la liste des minions, la commande pour chan­ger le mot de passe… on va mixer tout ça :

salt \* --out text test.ping | \
 sed -e "s@\([^:]*\):.*@echo salt \1 shadow.set_password bar \\\\\"\$(python -c \"import crypt; print crypt.crypt('PASSWORD', '\\\\\$6\\\\$\$(mkpasswd.pl -l 8 -s 0)')\")\\\\\"@"

1ère regex : on dégage les : True, et la deuxième, on enrobe le nom du minion pour que ça nous donne un truc comme :

echo salt foo shadow.set_password bar \"$(python -c "import crypt; print crypt.crypt('PASSWORD', '\$6\$$(mkpasswd.pl -l 8 -s 0)')")\"

Quand on exécute ça, ça donne un truc genre :

salt foo shadow.set_password bar "$6$8qJhzAi6$.O8bOisJaM9fH05aXx7xnKXOVFoI9CRzjORFWDqoPR/TBOiYVZUEJKtUKirNMyaZJvJMYPVUMhnNry9QPJgHK/"

Bien évidem­ment, on va mettre ça dans un fichier qu’on va éditer pour modi­fier le mot de passe (bah oui, on va quand même pas mettre le même mot de passe sur tous les serveurs).

salt \* --out text test.ping | \
 sed -e "s@\([^:]*\):.*@echo salt \1 shadow.set_password bar \\\\\"\$(python -c \"import crypt; print crypt.crypt('PASSWORD', '\\\\\$6\\\\$\$(mkpasswd.pl -l 8 -s 0)')\")\\\\\"@" > /tmp/chpasswd.txt

On édite /tmp/chpasswd.txt pour mettre ses mots de passe bien comme il faut puis :

bash /tmp/chpasswd.txt | bash

Le echo va nous sortir la commande kiva­bien qui sera inter­pré­tée par bash. Le $(mkpasswd.pl -l 8 -s 0)') sera remplacé par un sel diffé­rent à chaque fois et le bout de python trans­for­mera le sel et le mot de passe en hash dans le format kiva­bien pour le fichier /etc/shadow, et la commande salt sera lancée sur chaque minion.

Et voilà 🙂

Crédits : photo par Nikita Andreev

Me soutenir sur Tipeee Me soutenir sur Liberapay

Lut.im : une tragé­die des communs évitée

Savez-vous ce qu’est la tragé­die des communs ? C’est quand une ressource commune est surex­ploi­tée et au final, tout le monde est perdant.

C’est un peu ce qui se passe en ce moment sur l’ins­tance offi­cielle de mon logi­ciel Lutim : https://lut.im.

En effet, depuis déjà quelques jours, ce site est inac­ces­sible en soirée. Trop d’uti­li­sa­teurs qui veulent voir trop d’images en même temps. Lut.im victime de son succès ?

Oui et non : oui car le site commence à être plutôt connu (surtout en Russie, allez savoir pourquoi) ; non car c’est un problème d’abus de la ressource commune qu’est lut.im : en effet, le problème vient de l’uti­li­sa­tion qui est en faite par quelques personnes.

Pour comprendre ce qui se passait, j’ai activé les logs d’ac­cès au service — en prenant soin de ne pas affi­cher les adresses des images deman­dées (voir plus bas) — et j’ai noté quelques adresses de refe­rer suspectes ainsi qu’un nombre incroyable de requêtes deman­dées par des user-agent Kodi et quelques XBMC.

J’ai été voir sur un des refe­rer suspects : un site de strea­ming de chaîne télé… et certains des logos des chaînes étaient héber­gés sur https://lut.im ! Ça m’a mis la puce à l’oreille quant aux user-agent Kodi. Un peu de recherche genre kodi tv channel "https://lut.im" et je tombe sur un truc comme http://www.listaiptv­bra­sil.com.br/paste.php?id=3 (oui, je savais qu’il y avait moyen de voir des chaînes de télé sur Kodi, j’en ai un et j’avais regardé si je pouvais voir des chaînes de télé mais j’avais au final laissé tomber, vu la qualité de ce qu’on peut voir à la télé (pis bon, la pub…)).

J’ai donc bloqué, pour éviter l’in­dis­po­ni­bi­lité fréquente de https://lut.im, les refe­rer de ce genre que j’ai trouvé ainsi que les user-agent Kodi et XBMC :

if ($http_referer ~ (site1|site2) {
    return 429;
}
if ($http_user_agent ~* (Kodi|XBMC)) {
    return 429;
}

Le statut 429 que je renvoie corres­pond à « Too Many Requests ». Disons que c’est le statut que j’ai trouvé le plus proche de la situa­tion. Certes, ce n’est pas le client qui fait trop de requêtes, mais bon.

La soirée d’hier s’est passée sans alerte de la part de la super­vi­sion et chaque fois que j’ai été voir le site, celui-ci était acces­sible ! Mes actions ont donc évité la surex­ploi­ta­tion de la ressource commune 🙂

Et voilà comment j’ai modi­fié le format de mon log d’ac­cès pour ne pas loguer les IPs de mes visi­teurs ni les URLs des images deman­dées :

log_format lutim '$remote_user [$time_local] $status $body_bytes_sent "$http_referer" "$http_user_agent" "$gzip_ratio"';
server {
    …
    access_log /var/log/nginx/lutim.access.log lutim;
    …
}

J’ai après cela remis la confi­gu­ra­tion à access_log off; et supprimé les jour­naux d’ac­cès.

Crédit : Photo de Brad Helmink sur Unsplash

Me soutenir sur Tipeee Me soutenir sur Liberapay