On a souvent besoin de générer des mots de passe aléatoires pour un nouveau compte sur un site web, mettre à disposition des photos ou chiffrer une archive. Habituellement, j'utilise un petit programme libre en C, dev-random-pass-gen.c, mais cela nécessite d'avoir une machine Linux à disposition avec le programme disponible, de se connecter dessus et d'exécuter le programme. Donc, comme tout bon informaticien qui se respecte, je suis flemmard et j'ai voulu me faire un petit service en ligne sur un serveur web qui me fournit ces mots de passe pour n'avoir ensuite qu'à les copier/coller. Maintenant, il me suffit d'aller sur https://bentobako.org/newpassword. :-)

Pour réaliser ce service, j'ai procédé en deux étapes :

  1. faire un petit programme C utilisable sous forme de CGI ;
  2. configurer le serveur web pour rendre accessible le CGI à la bonne URL, en HTTPS.

Générateur de mot de passe en CGI

Le générateur de mot de passe proprement dit est un petit programme C utilisable sous forme de CGI, Common Gateway Interface. Un CGI est un programme appelé par le serveur web qui peut lire certains paramètres envoyés par le serveur (URL, valeurs de formulaires, etc.), travaille un peu puis renvoie un document (une page HTML, une image, une redirection, etc.). Concrètement, il faut renvoyer le type de document (par exemple Content-type: text/html), une ligne vide puis le document lui-même (<HTML><HEAD>...) (voir cette documentation pour plus de détails).

Pour ma part, vu que je ne lis aucun paramètre d'entrée, le programme se contente de renvoyer le mot de passe en texte simple :

 Content-type: text/plain
 
 6fimuNfg8GoCEmhCkpPrX1NyELpXWv1iJrR6XHUJDSq

Je suis parti de mon générateur de mots aléatoires précédent, avec trois modifications :

  • lecture de /dev/urandom, non bloquant s'il n'y a pas assez d'entropie, au lieu de /dev/random, bloquant, pour éviter un Dénis de Service sur le serveur : un attaquant pourrait épuiser toute l'entropie du serveur en faisant des demandes répétées de mots de passe ;
  • chaque lettre du mot de passe est un caractère alpha-numérique (A-Z, majuscule et minuscule, et 0-9). Comme je ne compte pas mémoriser les mots de passe produits, ça me donne plus de possibilités, c.-à-d. plus d'entropie ;
  • le mot de passe final fait 43 caractères, ce qui fait une entropie de 256 bits (log2((26+26+10)^43).

Le code résultant est disponible à l'URL http://www.linux-france.org/~dmentre/code/dev-random-pass-gen-cgi.c.

Son exécution donne :

$ ./dev-random-pass-gen-cgi 
Content-type: text/plain

6fimuNfg8GoCEmhCkpPrX1NyELpXWv1iJrR6XHUJDSq

Configuration du serveur web

Grosso-modo, il faut configurer le serveur web pour :

  • exécuter le CGI quand on accède à l'URL désirée ;
  • utiliser une URL en HTTPS pour éviter que tout le monde puisse lire le mot de passe en cours de route.

Voici la configuration lighttpd utilisée.

J'ai compilé et copié le programme sur mon serveur web, dans /var/www/ :

# gcc -Wall -o /root/dev-random-pass-gen-cgi \
                          /root/dev-random-pass-gen-cgi.c
# mv /root/dev-random-pass-gen-cgi /var/www/newpassword
# chown www-data:www-data /var/www/newpassword

Ensuite, j'ai configuré un fichier /etc/lighttpd/conf-available/11-redirect-to-https.conf qui fait une redirection en HTTPS de tout accès à l'URL http://bentobako.org/newpassword :

$SERVER["socket"] == ":80" {
  $HTTP["host"] =~ "bentobako.org" {
      url.redirect = ( "^/(newpassword.*)" => "https://bentobako.org/$1"
		     )
  }
}

Il faut ensuite un fichier /etc/lighttpd/conf-available/11-newpassword.conf qui permette l'exécution du programme en CGI uniquement pour l'URL /newpassword (voir la doc de mod_cgi pour plus de détails) :

server.modules  += ( "mod_cgi" )

$HTTP["url"] =~ "^/newpassword" {
    cgi.assign = ( "/newpassword" => "" )
}

Il ne reste plus qu'à activer cette configuration :

# lighttpd-enable-mod redirect-to-https
# lighttpd-enable-mod newpassword
# invoke-rc.d lighttpd restart

Et hop, ça marche ! :-)

Rapide analyse de sécurité

Le programme C ne présente aucun risque de sécurité car :

  • il ne prend aucune entrée venant du navigateur client ;
  • il n'utilise aucune ressource permanente sur le serveur (mémoire, disque) ;
  • il utilise /dev/urandom en mode non bloquant ;
  • il fournit un mot de passe avec 256 bits d'entropie qui est considéré comme largement suffisant pour les besoins actuels.

La configuration du serveur web garantit :

  • qu'un programme ne sera exécuté en CGI que s'il est accédé par l'URL /newpassword ;
  • que le mot de passe est protégé en transit par l'utilisation d'HTTPS qui chiffre le transfert ;
  • qu'on a l'assurance de bien parler à son serveur grâce à HTTPS, pour peu qu'on ait enregistré son certificat dans son navigateur ;
  • qu'on ne peut pas faire d'erreur en accédant en clair au CGI grâce à la redirection obligatoire vers HTTPS.

Vous pouvez utiliser librement mon serveur, mais rien ne vous garantit que j'utilise réellement le programme ci-dessus et que je ne stocke pas tous les mots de passe générés. ;-) Mais vous avez maintenant toutes les informations pour le faire chez vous.