Archives du mot-clé Sécurité

Signer ses commits Git et trans­fé­rer son gpg-agent sur un serveur distant

GPG, c’est bien. C’est encore ce qu’on a trouvé de mieux pour que tout un chacun puisse s’as­su­rer de l’au­then­ti­cité d’un message (non-modi­fi­ca­tion de celui-ci et que son auteur est bien celui annoncé) et chif­frer ses messages.

OK, c’est pas un exemple d’er­go­no­mie, OK, c’est pas ma mère qui va s’en servir sciem­ment tous les jours (sous le manteau, si, puisque les paquets de sa Debian sont signés avec GPG). Mais d’un autre côté, ma mère ne risque pas non plus (et je dirais même encore moins) de se payer un certi­fi­cat X509 pour signer ses mails. Ne parlons pas de mon père, à côté de lui, ma mère fait figure de hax0r.

Bon, d’ac­cord, c’est un bon gros truc de geek. OSEF, c’est cool quand même, c’était pour dire que c’était robuste et que tout le monde peut l’uti­li­ser sans bourse délier.

Que vous le sachiez (dans la colle) ou pas, on peut signer ses commits git avec GPG, histoire d’ajou­ter encore une couche de sécu­rité aux modi­fi­ca­tions qu’on apporte à un logi­ciel. Des forges comme Gitlab permettent d’ajou­ter une clé GPG à son profil permet­tant ainsi de véri­fier les signa­tures des commits d’un projet. Voyez sur ce commit le joli petit bouton « Veri­fied ».

Ceci n’est pas un cours sur GPG, on va donc consi­dé­rer que vous avez déjà une clé GPG.

Signer ses commits Git

Rien de plus simple. Il faut tout d’abord décla­rer à Git quelle clé doit être utili­sée pour signer ses commits (chan­gez l’em­preinte, ça c’est la mienne ) :

git config --global user.signingkey EA868E12D0257E3C

Main­te­nant, soit vous ajou­tez -S quand vous commit­tez :

git commit -S

Soit vous confi­gu­rez Git pour signer tous vos commits :

git config --global commit.gpgsign true

Voilà, c’est bon. Pour véri­fier un commit :

git verify-commit cce09ca

C’est bien beau, mais ça m’ar­rive de déve­lop­per direc­te­ment sur des serveurs, et surtout, je déve­loppe géné­ra­le­ment dans une machine virtuelle sur mon PC. Je ne vais certai­ne­ment pas aller copier ma clé privée sur les-dits serveurs ou dans la machine virtuelle ! C’est là qu’in­ter­vient le trans­fert du gpg-agent sur le serveur distant.

Ceci n’est toujours pas un cours sur GPG, on va donc consi­dé­rer que vous avez déjà un gpg-agent fonc­tion­nel sur votre ordi­na­teur.

Trans­fé­rer son gpg-agent sur un serveur distant

ATTENTION On ne trans­fère son agent gpg que sur une machine dans laquelle on a confiance, et dont on sait que les personnes y ayant accès ne s’amu­se­ront pas à utili­ser votre agent (rien de plus simple si on a un accès root à la machine). Cela vaut aussi pour l’agent ssh !

Premiè­re­ment, on va dire à l’agent de créer un socket supplé­men­taire en mettant dans ~/.gnupg/gpg-agent.conf (rempla­cez <user> par votre login) :

extra-socket /home/<user>/.gnupg/S.gpg-agent.extra

Ce socket a des restric­tions que n’a pas le socket habi­tuel (ne me deman­dez pas lesquelles) mais surtout, le logi­ciel qui vous deman­dera votre mot de passe (pinen­try de son petit nom géné­rique) vous présen­tera la demande de mot de passe diffé­rem­ment d’ha­bi­tude. Moi, il m’a dit en gros « Cette demande provient d’une machine distante », ce qui permet de repé­rer d’où vient la demande (déjà pas de votre machine pour déchif­frer un mail par exemple) et de réflé­chir à si c’est bien vous qui avez fait une action deman­dant la clé GPG.

On redé­marre l’agent pour prendre en compte la nouvelle confi­gu­ra­tion :

gpg-connect-agent /bye

Ensuite, il va falloir modi­fier sa confi­gu­ra­tion SSH. Comme un bon adminSys est fainéant, vous avez bien sûr utilisé concierge pour gérer votre fichier ~/.ssh/config. Il suffit d’ajou­ter dans le bloc de confi­gu­ra­tion du serveur souhaité la ligne (rempla­cez uid par votre uid (id pour le connaître) et <user> par votre login):

RemoteForward /run/user/<uid>/gnupg/S.gpg-agent /home/<user>/.gnupg/S.gpg-agent.extra

Enfin, il faut ajou­ter ceci dans le /etc/ssh/sshd_config du serveur distant (et redé­mar­rer son dæmon ssh après) :

StreamLocalBindUnlink yes

C’est fini ! Vous pouvez main­te­nant utili­ser votre clé GPG sur un serveur distant en vous y connec­tant en SSH, sans copier votre clé sur le serveur

Connec­tez-vous en SSH et testez avec

echo "test" | gpg2 --clearsign

Si, lorsque vous tentez de signer un commit sur votre serveur distant, cela échoue, assu­rez-vous que git utilise bien gpg2 :

git config --global gpg.program gpg2

Merci à Thomas Citha­rel pour avoir mis la signa­ture GPG des commits sur le tapis d’une discus­sion, ce qui m’a poussé à me pencher sur le trans­fert de l’agent GPG.

Crédit image d’en-tête de ce billet : logo de GnuPG, licence GPL, récu­péré sur Wiki­me­dia Commons

Me soutenir sur Tipeee Me soutenir sur Liberapay

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