Filed under: Serveurs
Bon. C’est la rentrée demain, et je n’ai absolument pas envie de dormir. Alors plutôt que de faire quelque-chose d’utile, je vais venir raconter mes douces pensées sur le monde des serveurs web.
L’autre jour, je discutais avec des copains de la mise en prod d’un site Django avec Gunicorn+Nginx. La question qui a été posée, c’est « pourquoi Nginx et pas Lighttpd ? », et la seule réponse que j’ai pu trouver c’est « Bah, le seul intérêt de Lighttpd c’est de ne pas être Apache, et Nginx lui a volé la vedette ».
Ce qui souligne un élément que vous avez sans doute déjà remarqué : on s’acharne à faire la peau à Apache. Pourquoi diable ? Il paraît qu’Apache est lourd et possède plein de fonctionnalités inutiles qui le rende ultra-lent. Ah. Bon voyons voir ce que donne un “ab -n 1000 -c 100 http://monurl/jquery.js” entre 2 serveurs hébergés chez OVH (100Mbps, donc) :
- Apache: 131 requêtes/s, 0.8s/requête
- Nginx: 132 requêtes/s, 0.8s/requête
OH MON DIEU, Nginx traite 1 requête de plus par seconde ! Mais dites donc, c’est fulgurant ! Vous n’allez quand même pas me dire que les gains de performances se jouent sur des microsecondes complètement masquées par la latence du réseau ? Non, impossible !
Les lecteurs assidu se rendront compte à ce point que je suis en train de les arnaquer. En effet, je parlais de mise en prod de Django, et je leur ai servi du benchmark sur du fichier statique. Je dois avouer avoir largement la flemme de faire le benchmark sur du Django. Et pour cause : pour une page à la con, sur mon serveur j’ai besoin d’environ 150ms pour générer la page. Ajoutez à cela que, sauf grosse erreur de ma part, Django est mono-thread, vous imaginez bien que le demi poil de cul d’avance de Nginx ne va pas réussir à faire grand chose.
J’entends quelqu’un au fond me crier « Et la RAM ? », mais lui il va retourner dans son coin parce que certes en gros Nginx prends 2x moins de RAM qu’Apache sur mon installation, mais on parle de ~5Mo VS ~10Mo de RAM, contre les 256Mo que demande WordPress pour fonctionner, je pense qu’on est large.
Donc, si comme moi vous n’êtes pas Facebook, à priori que ce soit Apache ou Nginx, au niveau des performances vous n’allez pas voir la différence. Alors comment choisir l’un ou l’autre ? D’après moi, il y a plusieurs éléments à prendre en compte, le premier étant la constatation suivante : on pourrait prendre le code d’Apache, l’encadrer, et le vénérer jusqu’à la fin des temps tellement c’est bien écrit. Je ne déconne pas, Apache est super bien écrit. Et je vais même aller plus loin : c’est du code C, certes, mais c’est du code C lisible. Ils font très, très fort. Sans oublier la librairie APR dont je vous ai déjà parlé, qui est en grande partie à l’origine de ce miracle.
Une autre raison c’est qu’Apache, c’est du béton armé. En dehors de certaines failles amusantes comme celle qui tourne en ce moment, ce serveur est testé et éprouvé comme peu de logiciels sur cette planète. Inutile de rappeler qu’il y a peu c’était 90% des sites web servi par Apache, et qu’encore aujourd’hui on doit être dans les 60%. Quelqu’un arrive à imaginer ? 60% du web servi par Apache ! En plus de la preuve de viabilité technique (ndlr: les parts de marché de IIS ne prouvent que la viabilité technique des commerciaux de Microsoft), c’est aussi l’assurance que le projet ne sera jamais abandonné, et qu’on peut compter dessus sur le long terme.
J’aimerais aussi pointer du doigt un reproche qu’on fait à Apache : il est trop complet. Attendez une seconde. Trop complet ? Si on met de côté les soit-disant problèmes de performance, ça veut dire que quoi que je veuille faire, Apache pourra le faire. Une fois qu’ils sont performant, les autres serveurs web n’ont qu’un but dans la vie : être aussi puissant qu’Apache. D’ailleurs, les outsiders se prenant trop au jeux pourraient bien finir dans un était « pire » que leur concurrent…
Et pour finir ma petite liste d’arguments, je tiens à faire remarque que tous les administrateurs système Unix connaissent Apache. C’est obligé, sinon c’est qu’ils viennent d’une autre planète. Ce qui veut dire que quand je monte un projet sous Apache, je sais que si j’ai besoin que quelqu’un d’autre travaille dessus, que ce soit à cause de l’agrandissement de l’équipe, la reprise du projet, ou même pour une urgence, il n’y aura pas le moindre souci.
Bon, et en plus je tiens à préciser que je trouve la configuration de Nginx complètement dégueulasse, pour en avoir mis un en prod sur ce serveur même. Sans oublier la doc à moitié en russe… Qui a été traduite depuis, mais avouez que l’anglais comme « langue par défaut » c’est plus pratique quand même.
Finalement, de nos jours pour un projet petit ou moyen, le serveur le plus bas de gamme que vous trouverez pourra probablement accueillir 100 fois plus de visiteurs que ce dont vous avez besoin, alors la question qui se pose est : est-ce que les pouillèmes de performances gagnés par Nginx valent le sacrifice d’un serveur stable, éprouvé et maintenable ?
August 29, 2011
Certains scripts PHP (par exemple Symfony) dépendent lourdement du fait que si on demande la page http://truc/machin.php/bidule/chose, et que http://truc/machin.php est un fichier PHP, alors c’est ce fichier qui est appellé. Le souci, c’est que dans lors de la dernière mise à jour d’Apache dans Sid, ça ne marche plus…
En fait ce comportement est lié à une directive de configuration AcceptPathInfo, qu’il faut placer à On.
February 27, 2010
Si vous êtes un administrateur système, et que vous avez la gentillesse de bien vouloir laisser TeamSpeak passer sur votre firewall pour les pauvres étudiants de la résidence dont vous êtes l’administrateur qui ne pourraient sinon pas passer leur temps à jouer à WoW au lieu de travailler, alors vous avez probablement comme moi remarqué une chose : TeamSpeak n’a pas de port standard. Et c’est la merde ! Mon firewall se transforme peu à peu en gruyère…
Pour repousser la menace, j’ai donc décidé de coder un proxy pour TeamSpeak. Le principe est de l’installer sur une machine qui peut sortir sur tous les ports en UDP. Les clients utilisent un petit logiciel spécial pour ouvrir un canal temporaire le temps de l’utilisation de TS, et le proxy fait du port forwarding.
Pour l’instant
- Le projet est hébergé sur Github, c’est aussi là que vous trouverez les tarballs, installeurs, …
- Il y a un installeur pour le client sous Windows, pour les autres OS vous devez compiler le client à la main (c’est du C++).
- Le serveur est codé en Python, et utilise Twisted. Il n’y pas de paquet Debian ou de truc du genre…
- Pour le support de TeamSpeak 2, je suis à peu près sûr de moi, par contre ce qui est de TeamSpeak 3 c’est encore en version β, histoire de faire un peu moderne.
N’hésitez pas à me contacter si vous n’avez pas la moindre idée de comment ça fonctionne (ça se comprend, c’est moi qui ai codé…) mais que ça vous intéresse quand même
January 21, 2010
Étant administrateur d’un réseau étudiant, j’ai souvent à faire avec des joueurs de WoW mécontent de la qualité de la connexion, voire même de l’impossiblité de se connecter… Quand la connexion est saturée, on peut comprendre que ça foire, mais là je me suis retrouvé face à quelqu’un qui n’arrivait plus du tout à se connecter. Après un peu de bidouille, entre les différents paquets de pollutions par les partages de fichier windows, j’ai fini par trouver le petit minuscule insignifiant paquet qui n’arrivait jamais à destination. En fait, il semblerait que le port de WoW ait changé (car ils utilisent un nouveau protocole si j’ai tout compris). Ce qui est cool, c’est que ça a l’air d’être un “standard”, mais ce qui est pas cool, c’est que le port était pas ouvert…
Bref, tout ça pour dire que le nouveau port de WoW c’est 1116 en TCP.
J’en sais pas grand chose sur ce nouveau protocole, mais si il pouvait devenir un standard pour les jeux ça éviterai de transformer mon firewall en passoire, donc ça serait franchement cool que les éditeurs de jeux se mettent d’accord…
Par contre, je déteste encore plus WoW maintenant…
September 4, 2009
Si vous devez tester le fonctionnement d’un antispam ou d’un antivirus, il existe des chaînes considérées comme tel par les logiciels de protection.
Déjà pour le SPAM, voici le GTUBE (Generic Test for Unsolicited Bulk Email) : doit être placé dans un mail sans aucun espace ou retour à la ligne exactement la chaîne suivante :
XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
Ensuite pour les virus s’applique fichier de test EICAR, à savoir un fichier dont le seul contenu est :
X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
June 2, 2009
Comme c’est la deuxième fois que je dois travailler avec LDAP et que c’est aussi la deuxième fois que je galère pour l’installer, je vais faire ici un petit tuto qui explique comment mettre en place un serveur LDAP valide.
Pour commencer, une petite intro sur LDAP : les serveurs LDAP sont des serveurs d’annuaire, c’est à dire qu’ils ont une base de données contenant divers objets stockés de manière hiérarchique et ayant diverses propriétés : par exemple une société peut stocker les comptes informatiques de ses utilisateurs en les plaçant dans des “dossiers” correspondants aux divisions de la société (par exemple France -> Toulouse -> Département informatique). Chaque compte utilisateur contient le nom d’utilisateur, le nom complet, le mot de passe, l’addresse mail, le numéro de téléphone, etc de chaque utilisateur. On peut faire de même pour stocker les imprimantes, les terminaux ou n’importe quel objet pour lequel il existe une classe (pour chaque type d’objet on créé une classe qui contient la liste des propriétés qu’on peut lui attribuer).
Maintenant passons à la pratique. Les explications sont faites pour ubuntu gutsy gibbon, mais ça devrai marcher à peu près pareil sous debian.
La première étape est d’installer le serveur et les outils d’administrations. Dans un premier lieu, on installe le paquet slapd qui contient le serveur OpenLDAP, ainsi que ldap-utils qui contient un certain nombre d’outils d’administration en ligne de commande et finalement le paquet db4.2-util qui contient les outils permetant de manipuler les fichiers de base de données.
aptitude install slapd ldap-utils db4.2util
Pendant l’installation de slapd, il va vous être demandé de rentrer le mot de passe administrateur. Vous pouvez rentrer n’importe quel mot de passe, nous allons le changer par la suite.
Un autre outil qu’il peut être intéressant d’installer et que nous utiliseront par la suite est phpLDAPadmin, qui est un outil d’administration web de LDAP plutôt puissant (en fait il s’agit du meilleur outil disponible).
Maintenant que slapd est installé, on va le configurer un peu. Tout d’abord, il faut éteindre le serveur :
/etc/init.d/slapd stop
Et on va commencer par calculer le hash du nouveau mot de passe administrateur :
slappasswd -h {SHA}
Il vous est demandé le mot de passe que vous voulez hasher, puis une deuxième fois pour confirmation, et finalement le hash est affiché. Il devrai ressembler à quelquechose comme ça : {SHA}uFjLKCYX+wlW2WAhXI6E0cz5CcY=
Gardez cette valeur bien au chaud dans votre presse papier, on va s’en resservir tout de suite.
Il est temps d’éditer le fichier de configuration, /etc/ldap/slapd.conf
Cherchez ce passage :
# The base of your directory in database #1
suffix "dc=nodomain"
Il s’agit de la configuration de la base de votre serveur. Il s’agit du/des éléments les plus haut dans la hiérarchie. Habituellement on y met son nom de domaine. Par exemple pour hyperthese.net on mettra dc=hyperthese,dc=net
Bien qu’il soit conseillé de mettre un vrai domaine, ça n’a pas vraiment d’importance dans le cadre d’un petit serveur comme il sera probablement le cas poru vous, donc sentez vous libre de mettre ce que vous voulez si vous n’avez pas de domaine (attention tout de même à respecter la syntaxe…)
Une fois que ceci est changé, il faut rechercher dans le fichier de configuration toutes les occurences de dc=nodomain pour les remplacer par la nouvelle base que vous avez défini. Ceci étant fait, on peut changer le mot de passe administrateur. Il faut pour cela s’en prendre à la ligne (attention vu que vous avez remplacé toutes les occurences de dc=nodomain votre ligne sera différente…)
# rootdn "cn=admin,dc=nodomain"
Vous devez la décommanter et lui ajouter une copine de cette manière :
rootdn "cn=admin,dc=nodomain"
rootpw LE_HASH_DE_TOUT_A_L_HEURE
Par exemple dans mon cas ça va donner
rootdn "cn=admin,dc=hyperthese,dc=net"
rootpw {SHA}uFjLKCYX+wlW2WAhXI6E0cz5CcY=
Maintenant que ceci est fait, on va enregistrer le fichier et vider la base de données que l’installateur a créé automatiquement :
rm -rf /var/lib/ldap/*
Et pour finir, on démarre le serveur
/etc/init.d/slapd start
Nous avons normalement un serveur LDAP fonctionnel maintenant. Vous pouvez tester la connexion au serveur avec par exemple la commande
ldapsearch -x -D "cn=admin,dc=hyperthese,dc=net" -W
Il ne reste plus qu’à configurer phpLDAPadmin. Il suffit d’ouvrir le fichier /etc/phpldapadmin/config.php et de chercher la ligne
$ldapservers->SetValue($i,'server','base',array('dc=nodomain'));
Pour ensuite la remplacer, celon la configuration que vous avez rentré précédament, par
$ldapservers->SetValue($i,'server','base',array('dc=hyperthese,dc=net'));
Et vous pourrez normalement accéder à l’administration de votre serveur ldap à l’addresse http://localhost/phpldapadmin/.
Et voila, il ne reste plus qu’à remplir tout ça !
November 1, 2007
Je me suis retrouvé dans la nécessité de configurer un serveur Apache 2.2 (sous debian) pour qu’il puisse puiser sa liste d’utilisateurs dans un serveur LDAP, que j’utilise aussi pour authentifier mes utilisateurs FTP, SSH, Jabber, etc, et donc j’utilise des objectClass faites pour PAM (ce qui est le cas de la plupart des serveurs LDAP je pense…).
Donc me voici dans une section <Directory>, je configure maintenant Apache pour authentifier les utilisateurs à l’aide de LDAP.
## On donne l'url du serveur LDAP. Syntaxe : ldap://serveur:port/base_dn?attribu_a_verrifier?profondeur_de_recherche?filtre_de_recherche
AuthLDAPURL ldap://localhost/dc=thegreatspirit,dc=net?uid?sub?(objectClass=*)
## On spécifie à Apache que l'attribu qui contient le nom d'utilisateur est "memberUid"
AuthLDAPGroupAttribute memberUid
## Et on spécifie aussi que c'est le uid qui est stocké, au lieu que ce soit le DN complet
AuthLDAPGroupAttributeIsDN off
## Maintenant on lance une fenêtre d'authentification
AuthType basic
## Nom de la fenêtre d'authentification
AuthName "Restrited LDAP-protected area"
## On indique à Apache de regarder dans LDAP pour la liste des utilisateurs
AuthBasicProvider ldap
#On veut un utilisateur qui provient du groupe dont le DN est cn=svnUser,ou=SVN,ou=ACL,ou=Groups,dc=thegreatspirit,dc=net
Require ldap-group cn=svnUser,ou=SVN,ou=ACL,ou=Groups,dc=thegreatspirit,dc=net
## On aurai aussi pu tenter :
## Une liste d'utilisateurs
# Require ldap-user user1 user2 etc
## Une liste de DNs
# Require ldap-dn DN1 DN2 etc
## N'importe quel DN avec certains attribus
# Require ldap-attribute attribut="valueur" attribut="valeur" etc
## Ou si le DN passe à travers ce filtre
# Require ldap-filter (filtre ldap)
Si on avait voulu que n’importe quel utilisateur qui a réussi à faire un bind correct puisse se connecter, il faut d’abord que mod_authz_user soit chargé, et que l’option AuthzLDAPAuthoritative soit à off. Ainsi on peut remplacer le require de la configuration précédente par
AuthzLDAPAuthoritative off
Require valid-user
Bien sûr, les noms d’utilisateurs, DN etc peuvent être entré comme n’importe quel chaine en argument dans un fichier de apache : c’est à dire qu’on peut les mettre comme sans rien, ou si on a besoin de délimiter la chaîne on peut la mettre entre guillemets.
Et ausis, Apache n’a pas besoin de pouvoir voir les mots de passes sur LDAP, puisque quand un nom d’utilisateur sera rentré il tentera un bind avec.
January 14, 2007