Tag - lighttpd

Entries feed - Comments feed

Last entries

Mon 27 Jul 2009

Secure setup of DokuWiki with Lighttpd web server on Debian Lenny

Logo DokuWiki DokuWiki is a very nice wiki programmed in PHP that does not use any database. It is very simple to setup and use. As I am using the lighttpd web server instead of Apache, making a secure installation requires a configuration a bit different from the usual one.

Here is the configuration I am using. Contrary to our installation in Niadomo, I'm using the original source tarball and not the Debian package. It is heavily inspired by installation documentation and security documentation of DokuWiki. I strongly recommend to read this security documentation before doing any installation.

DokuWiki installation

We firstly download and configure DokuWiki so the installed wiki is available as example.com/mydoku, assuming example.com is the name of your web site. I am assuming /var/www is the root directory of your lighttpd server.

 $ cd /tmp
 $ wget http://www.splitbrain.org/_media/projects/dokuwiki/dokuwiki-2009-02-14b.tgz
 $ tar zxf dokuwiki-2009-02-14b.tgz
 
 $ sudo mv /tmp/dokuwiki-2009-02-14 /var/www/mydoku
 $ sudo chown -R www-data:www-data /var/www/mydoku

We then access the configuration script http://example.com/mydoku/install.php to configure it. I won't detail this part as it is up to you to choose a configuration that suites your needs. Refer to DokuWiki install.php instructions for further details.

Making DokuWiki secure

Firstly, we remove the installation script no longer necessary.

 $ sudo rm /var/www/mydoku/install.php

Secondly, we move data/ and bin/ dokuwiki's directories in a separated directory, /usr/local/installed/mydoku. You can choose any directory that suites your setting but it should be outside of the root directory of your web server, in my case /var/www.

 $ sudo mkdir -p /usr/local/installed/mydoku
 
 $ sudo mv /var/www/mydoku/bin /usr/local/installed/mydoku/
 $ sudo mv /var/www/mydoku/data /usr/local/installed/mydoku/
 
 $ sudo mv /var/www/mydoku/README /usr/local/installed/mydoku/
 $ sudo mv /var/www/mydoku/VERSION /usr/local/installed/mydoku/
 $ sudo mv /var/www/mydoku/COPYING /usr/local/installed/mydoku/

Then we configure conf/local.php so that the installed dokuwiki knows how to look for its data and binaries. We use for this the $conf['savedir'] functionnality[1]. We also configure allowdebug to 0, to avoid giving information to attackers in case of error.

 $ sudo vi /var/www/mydoku/conf/local.php

We add the following two lines:

 $conf['savedir'] = '/usr/local/installed/mydoku/data';
 $conf['allowdebug']  = 0;

We then configure lighttpd to avoid deny accesses to inc/ and conf/ directories. We use the very specific Debian way, creating a dedicated lighttpd configuration file and activating it.

$ cat > /etc/lighttpd/conf-available/11-dokuwiki.conf

Add following content:

  $HTTP["url"] =~ "^/mydoku/inc" {
    url.access-deny = ("")
  }
  else $HTTP["url"] =~ "^/mydoku/conf" {
    url.access-deny = ("")
  }

I am simply using regular expressions to deny access to the two directories.

We then enable this configuration and restart dokuwiki.

 $ sudo lighty-enable-mod dokuwiki
 $ sudo invoke-rc.d lighttpd restart

You can now check that the accesses to http://example.com/mydoku/conf/local.php or http://example.com/mydoku/inc/io.php are now denied.

Have fun with your new wiki!

Notes

[1] Some people would call that a hack. ;-)

Thu 09 Apr 2009

  • David Mentré
  • Web

Un générateur de mots de passe aléatoires en ligne

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.

Mon 23 Feb 2009

  • David Mentré
  • Web
  • 5

Serveurs web haute performance

Une remarque de Jean-Marie m'a rappelé que la plupart des sites web actuels sont vraiment lents (un exemple au hasard ? Voyages-sncf.com bien sûr !) alors que nos machines, disques durs et réseaux sont de plus en plus rapides ! La principale cause, comme d'habitude, c'est que l'on utilise de plus en plus de logiciel dynamique et plus ou moins interprété comme du PHP ou du Python. Mais un composant essentiel de la pile web, c'est quand même le serveur web. Et celui que la plupart des gens utilise, Apache (52% de part de marché en janvier 2009), est il faut le dire une vraie bouse. Heureusement, le monde du Libre est formidable : il y a des alternatives ! \o/

La première alternative, c'est lighttpd (prononcer lighty) et c'est celui que j'utilise sur mon serveur web. Subjectivement, c'est vrai qu'il est rapide. Il se lance ou se relance en un clin d'œil et le fichier de configuration a une syntaxe plutôt agréable. Et objectivement, il est rapide d'après des tests faits par Fred sur deux machines identiques. ;-) Malheureusement, sa documentation est plutôt légère : quand je me pose des questions sérieuses sur un module, par exemple l'ordre d'interprétation des règles de ré-écriture d'URL, je ne trouve pas d'information détaillée. Par contre, comme il est utilisé par beaucoup de gros sites pour leurs parties statiques (YouTube, Wikipédia, ...), on peut supposer qu'il est correctement programmé du point de vue sécurité.

L'autre prétendant, c'est nginx. Pour lui, je n'ai pas trop d'expérience. Il fait un peu fouilli puisqu'il fait, en plus de serveur web, mail proxy server. Et j'ai entendu dire qu'il y avait des bugs et que les développeurs étaient plus intéressés à rajouter de nouvelles fonctionnalités qu'à les corriger : un peu embêtant pour un serveur web accessible à la sauvagerie du Wild Wide Web. Mais bon, ce ne sont que des ouïes dire, à vérifier donc.

Le troisième prétendant, petit nouveau dans l'arène, c'est Cherokee, que j'ai découvert grâce aux notes de version de la toute nouvelle Debian Lenny. :-) Cherokee a l'air très sympa (outre son logo ;-) : configuration par une interface web (sécurisée par mot de passe unique et ssh) mais sauvegardée dans un fichier texte, documentation qui a l'air complète, et toutes les fonctionnalités qu'on peut attendre d'un serveur web moderne : équilibrage de charge, ré-écriture d'URL, support de FastCGI et consorts, serveurs virtuels, etc. Et surtout, il est rapide... enfin d'après leurs propres benchmarks. :-) Mais bon, j'envisage à moyen terme de le tester à la place de lighttpd.

Enfin, mon outsider, c'est Ocsigen. Plus qu'un serveur web, c'est un environnement de développement complet, en OCaml, qui est intégré au serveur web. Et depuis la dernière version 3.11 du compilateur OCaml qui permet de charger des modules de code natif dans un programme OCaml, Ocsigen fonctionne en code natif ! Cela veut dire que l'on a un environnement de développement web avec toutes les bonnes propriétés d'OCaml (typage fort à la compilation, y compris sur des requêtes SQL de PostgreSQL, garbage collector performant, beaucoup de bibliothèques, ...) et qui en plus produit du code natif, donc réellement efficace (comme le montre ces tests de Dario Teixeira). Cela me semble la meilleur combinaison pour faire des sites web qui poussent ! Évidemment, il faut programmer en OCaml et surtout se faire à l'environnement d'Ocsigen, ce qui n'est pas aussi simple qu'en PHP par exemple. Mais même en tant que simple serveur web de pages statiques, Ocsigen se compare correctement à lighttpd et Apache, sans toutefois être aussi performant. Et bien sûr, pour les sites dynamiques, il est nettement plus rapide que Ruby (qui certes n'est pas le langage le plus rapide) !

Face à Apache, tous ces serveurs web ont beaucoup d'avantages mais un gros inconvénient : les logiciels web sont tous conçus pour Apache. Donc il faut souvent adapter la configuration du serveur web, notamment dans la gestion des droits d'accès (configuration équivalente aux .htaccess). Rien de bien mortel, mais c'est toujours du travail en plus et on a toujours le risque de faire une erreur.

En tout cas, une chose est sûre, la liberté et la dynamique du Libre nous permet d'avoir des solutions réellement innovantes. Il ne vous reste plus qu'à les utiliser. ;-)