Dimanche dernier, le serveur qui héberge ce site a été rendu indisponible. De dimanche 16h jusqu'à lundi 11h. La raison de son indisponibilité est que le port réseau a été automatiquement coupé suite à un trafic non désiré.
Dans un premier temps, je me suis demandé quel avait été ce trafic non désiré. En recherchant des informations chez online.net (auprès de qui je loue ce serveur), j'ai trouvé leur critères :
Je passe en revue tous ces points:
Je reste par contre dans le doute concernant le dernier point vu que, même si j'ai plutôt bien configuré mon pare-feu, je ne suis techniquement pas à l'abris d'un déni de service. J'ai donc dû prendre mon mal en patience en attendant de pouvoir enquêter.
Lundi matin, vers 11h, le service de monitoring d'online.net m'envoie un SMS automatique pour me dire que mon serveur répond au ping. Je m'empresse de me connecter pour vérifier rapidement s'il n'y a pas un processus indésirable de lancé, pour charger les règles de mon pare feu et pour faire un check up rapide de choses à sécuriser en attendant de pouvoir enquêter plus tard dans la journée
Étant de sortie ce soir là, j'ai profité de mon trajet en RER pour lancer un tcpdump sur le serveur. J'ai tout de suite compris où était le problème, je recevais entre 600 et 1000 paquets par seconde alors que je n'avais laissé ouverts que peu de services qui ne génèrent pas ce trafic en temps normal. Tcpdump m'a montré qu'il s'agissait de quelques hôtes (2-3 à ce moment là) lançant des séries de requêtes à tour de rôle par lot de plusieurs centaines sur le port 27960 en UDP.
Pour ceux qui font tourner des serveurs de jeux de type FPS, vous aurez certainement reconnu là le port par défaut utilisé par le moteur de Quake 3. J'ai justement sur cette machine un serveur Urban Terror (mod de Quake 3) qui utilise ce port. Je ne l'ai pas relancé depuis le reboot du matin et j'avais même bloqué ce port. Ne pouvant rien faire de plus, je laisse les choses telles quelles en attendant de pouvoir m'en occuper plus sérieusement.
Le lendemain, j'ai finalement le temps de m'en occuper. Pensant être victime d'une attaque de DoS, je commence à faire des recherches dans ce sens. Et je tombe d'abord sur l'article Application-Level Reflection Attacks. Dans un premier temps je me soucie peu du titre et je vais directement à l'endroit où il est question de Quake 3. J'en arrive à lire les points 4 et 5 qui me donnent l'intérêt technique de ces requêtes. Je n'ai par contre pas saisi toute la portée de l'attaque directement et je n'ai même pas remarqué le terme "DRDoS".
Je continue mes recherches en allant cette fois directement sur les forums officiels d'Urban Terror et je tombe directement sur un sujet intitulé "DRDoS". Ne connaissant pas le terme mais voyant que c'est un type de déni de service, je vais voir ce qu'il s'y dit. Et là, bingo ! C'est en effet bel et bien le problème auquel je suis confronté et qui affecte tous les serveurs de la communauté. Je parcours le sujet et vois qu'un patch officiel est disponible. Au cours de la discussion, l'article sur lequel j'étais d'abord tombé est mentionné. Je décide donc d'y retourner pour le lire en entier.
Cette fois-ci, j'ai compris toute la portée de l'attaque et sa gravité. Pour expliquer rapidement la technique utilisée, les serveur de jeux fournissent aux clients des commandes pour obtenir des informations sur le serveur (joueurs en ligne, carte jouée, etc.). Dans le cas d'un FPS, l'interaction en temps réel prime. Ces serveurs utilisent donc UDP plutôt que TCP pour avoir le meilleur temps de réponse possible. Ils fournissent ces commandes via UDP également donc pas besoin d'initialiser de connexion pour faire la requête. Le paquet contenant la requête fait environ 60 octets. Le paquet contenant la réponse fait environ en moyenne 500 octets. Donc en envoyant massivement des requêtes, on reçoit 10 fois plus de données que l'on en envoie. Sachant qu'il existe plusieurs milliers de serveurs de jeux, il est possible de répartir des requêtes sur tous ces serveurs pour avoir encore plus de réponses. Voilà pour la partie technique pure. Maintenant, ce mécanisme exploité d'une certaine manière permet d'attaquer des cibles au choix avec une attaque DRDoS (Distributed Reflection Denial of Service). Au début, je pensais être la victime de cette attaque, mais en fait, aux yeux de la machine ciblée, je suis un des attaquants dans ce déni de service.
Le ou les attaquants réels vont d'abord récupérer la liste des serveurs existants auprès du master server (mécanisme dans lequel les serveurs se notifient auprès des masters pour pouvoir être listés par les clients). Ensuite chaque attaquant va envoyer constamment à tous les serveurs de la liste la requête vue précédemment en ayant pris soin de modifier le paquet à émettre en remplaçant leur adresse dans le champ adresse source du paquet par celle de la machine ciblée pour l'attaque. Chaque serveur reçoit une requête, et renvoie la réponse à l'adresse source renseignée dans le paquet, celle de la victime. En supposant qu'il y ai 100 attaquants envoyant 1paquet/s à 1000 serveurs simultanément, chaque attaquant envoie 1000 paquets de 60 octets par seconde donc un débit de 59ko/s (tout a fait réalisable avec une connexion ADSL classique) et la cible recevra 100 000 paquets de 500 octets par seconde donc un débit de 48Mo/s. S'il s'agit d'un particulier, sur une connexion ADSL classique, celle-ci se fait directement saturer. S'il s'agit d'un serveur avec une connexion 100Mbps, elle sera également saturée. En ce qui concerne un connexion 1Gbps ou 10Gbps, il faudra soit augmenter le nombre de paquets par seconde envoyés par les attaquants, soit augmenter le nombre d'attaquants. Dans tous les cas, la quantité de données générée est impressionnante.
Cette attaque a plusieurs choses d'horrible. Tout d'abord, les paquets ne contiennent pas l'adresse de l'attaquant réel. Pour savoir d'où vient l'attaque, il faudrait remonter toute la chaine de routage du paquet en se basant sur les adresses matériel mais le serveur utilisé pour la réflection ne peut pas connaître directement l'origine réelle du paquet. Ensuite, chaque serveur doit gérer ce trafic parasite. Il entraîne en général du lag pour les joueurs et dans certains cas (le mien apparemment) enclenche le blocage du port réseau par sécurité. Enfin, du point de vue de la victime, ce sont les serveurs de jeu qui ont réalisé le déni de service. Ce sont donc eux les coupables.
Au final, j'ai mis à jour mon serveur Urban Terror avec le patch officiel. Il limite le nombre de requêtes par IP sur un temps donné. J'ai lancé iftop avant le patch et après le patch pour voir son effet et le résultat est sans appel. 4 à 8Mo/s de trafic généré sur la voie montante pour un trafic de 400-600ko/s sur la voie descendante avant le patch. Après le patch, même trafic sur la voie descendante mais 10 à 20ko/s sur la voie montante. Les choses sont maintenant rentrées dans l'ordre pour mon serveur même si je continue de recevoir 600 à 800 paquets par seconde à cause de cette attaque. Je n'ai plus qu'à attendre que tous les serveurs soient patchés pour que cette attaque ne soit plus réalisable avec des serveurs Urban Terror. Mais bon, avant UrT, les serveurs CoD 2 étaient exploités, et beaucoup d'autres sont encore exploitables vu le nombre de jeux basés sur le moteur de Quake 3.
Concernant le procédé de l'attaque, je suis déjà très partagé sur les attaques de type DoS et DDoS. D'un côté selon la cible de l'attaque je peux parfois avoir envie d'approuver un tel acte mais dans tous les cas je suis totalement contre le fait de chercher à mettre hors service un serveur, quel que soit le moyen utilisé et qu'elle qu'en soit la raison. Pour ce qui est des attaques de type DRDoS, je les trouve tout simplement inacceptables, surtout en voyant quelles sont les cibles de telles attaques. J'ai regardé un peu les IP ciblées, j'y ai vu un particulier aux Pays-Bas, un site amateur sur les voitures, un petit site professionnel aux États-Unis, etc. Clairement, tout ce que je vois ici ce sont des attaques soit automatiques et aléatoires soit simplement pour le plaisir de l'attaquant.
Une belle avancée en cette fin d'année, la sortie en version stable de 99ko ! C'est la branche 1.1.x qui nous l'apporte et qui est suffisamment "sûre" pour l'utiliser au jour le jour sans avoir besoin de bidouiller pour que ça fonctionne.
Elle arrive avec quelques optimisations dans le code et pour les utilisateurs, l'apparation d'un fil d’Ariane. Peu de choses visibles donc, mais c'est surtout pour sa stabilité que cette version est sortie.
Elle est fraichement disponible, nul part ailleurs qu'ici : 99ko 1.1.1
De mon côté, je me suis empressé de mettre à jour mon plugin blog pour qu'il utilise le fil d'Ariane, ainsi que quelques nouveautés dans le code de 99ko. Pour ce qui est du changelog :
Peu de choses ici aussi, c'est surtout pour la compatibilité.
Je pense maintenant m'occuper de la version 0.5 qui devrait voir arriver les tags (j'espère) ainsi que la consultation des billets par catégories et par tags. Je pensais aussi éventuellement à l'ajout d'un mode preview pour les billets en cours de rédaction (j'en ressent cruellement le besoin justement pour les billets que j'écris ici >_<).
Dernière petite nouveauté aussi, je viens de mettre en place un dépôt mercurial pour le plugin blog. L'interface web permet de consultés les différentes révisions mais le plus intéressant c'est que vous pourrez suivre le développement du plugin si vous le souhaitez directement depuis le dépôt.
Si vous êtes sous un système unix, il vous faudra faire :
hg clone http://hg.maxgun.fr/99ko/plugins/blog/
dans le répertoire plugin de 99ko pour récupérer le plugin.
Ensuite pour récupérer la dernière version du plugin, il vous suffira de faire (cette fois dans le répertoire blog) :
hg pull && hg update
Pour l'instant la dernière révision disponible est celle de la 0.4.1 donc rien de très intéressant mais à l'avenir vous pourrez avoir accès aux versions en cours de développement.
Pour finir, les liens pour télécharger les dernières versions présentées ici :
Enjoy ! :)
Je viens de sortir une nouvelle version du plugin blog pour 99ko !
Pour ce qu'elle apporte de nouveau, voici le changelog :
Le plugin fait donc un bond en ce qui concerne la praticité d'utilisation du blog pour le blogueur.
Notez que ce blog à eu droit à ces améliorations au fur et à mesure au fil du développement pour me permettre de faire des essais sur un site vitrine en plus des essais en local.
Concernant ce dernier point d'ailleurs, à partir de cette version et pour les suivantes, je vais mettre en place un dépôt mercurial (et/ou git) pour permettre à qui veut de profiter des derniers bugfixes et nouvelles fonctionnalités sans attendre les nouvelles versions. Bien sûr ce sera un dépôt de dev donc totalement instable et sans garantie sur la préservation des données (à la base je compte pas tout casser, mais on sait jamais, un bug pourrait ravager pas mal de choses)
Pour finir, les liens pour le télécharger cette version du plugin directement et pour aller en parler sur le forum de 99ko :
Enjoy ! :)
Je viens de publier un nouveau plugin pour 99ko. Il permet d'ajouter des liens au menu et d'organiser l'ordre des liens. Je voulais développer un truc fait à la va vite en gérant juste l'ajout de lien pour mes propres besoin à la base et puis au final, tant qu'à faire, j'ai décidé d'aller plus loin et d'ajouter la gestion de l'ordre des liens.
Ce plugin nécessite d'avoir une priorité élevée. Dans l'absolu, il doit être chargé après tous les autres plugins qui ajoutent des liens au menu. Si ce n'est pas le cas, le résultat du menu devient imprévisible. Techniquement c'est parce que le plugin réinitialise le tableau qui contient les éléments du menu. Si un autre plugin ajoute un élément au menu après que le plugin menu soit intervenu, on aura soit un lien en double, soit un lien remplacé par le dernier ajouté.
Je compte à terme ajouter des fonctionnalités de sous menu mais ça viendra un peu plus tard.
Pour finir, les liens pour le télécharger directement et pour aller en parler sur le forum de 99ko :
Bien sûr, je l'ai directement installé sur mon 99ko vu que c'était le but à la base. Vous pouvez donc voir deux nouveaux liens là-haut.
Enjoy ! :)
J'avais déjà mis en place il y a quelques temps un site se basant sur une version modifiée (par mes soins) de 99ko, ce petit CMS léger sans base de données.
Depuis, le projet 99ko est passé par un état de pause avant de redevenir d'actualité. C'est une version plus légère encore et de retour sur la voie du noDB à laquelle nous avons droit.
Le point le plus important de cette version je trouve, c'est sa modularité. Dès le départ, un système de plugins a été mis en place et au final, même la fonctionnalité basique des pages statiques est disponible via un plugin. Ça permet d'avoir du contenu généré par la communauté et de vraiment utiliser le CMS comme bon nous semble. C'est d'ailleurs pour ça que je me suis lancé dans la réalisation d'un plugin blog grâce auquel je publie ce message d'ailleurs.
En bref, ce site sera un peu ma vitrine sur ma participation au projet 99ko. D'abord en utilisant ce blog mais aussi avec le thème personnel que vous pouvez voir.