Florent Fortat

Stuff

How Angular 6 Schematics works

Package Manager - Trala

I've been working on a kind of a package manager for my day job lately. It's aimed at handling our own concept of packages inside a modular Angular project. It's called trala, it's published on NPM and the sources are on Github. As of writing this, the tool is very rough and very specific to our needs but I aim to make it a generic tool.

For now, trala can do the following operations:

  • init -- initialize a project by cloning a skeleton git repository (hardcoded for now), create a branch specific to this new project and retrieve default modules that should be coming with the project (the theme we use, also hardcoded)
  • install -- add a package to the project by cloning it's repository, creating a branch from a given or the latest version tag and import all the modules and services it exports into the app module
  • remove -- remove the package from the file system and remove the imports added with the install command
  • update -- update a package to a newer version (basically doing a remove then install)

The part that has taken me most time into creating this tool has been the import of modules and services into the application.

Because Schematics.

Schematics

Angular has a devkit package that includes a tool called Schematics. This tool is used to make operations on the filesystem like generating files, deleting files, editing files following implemented rules. The thing is, schematics is very badly documented. I've spent a good amount of hours to procrastinate understand how schematics works and now I'm going to document it a bit here.

Create a collection

A collection is a bunch of schematics grouped together. You can find angular cli's collection here for exemple of the default collection for the schematics package here. The interesting part here is you can create your own collection in any npm package. To setup a collection, you need to do 2 things:

  • Create a folder where you will put a collection.json manifest and all your schematics in subfolders
  • Add a schematics entry in your package.json that points to your collection.json like this : 
    "schematics": "./dist/schematics/collection.json"

The collection.json format looks like this:

{
  "schematics": {
    "addModule": {
      "aliases": [ "am" ],
      "factory": "./add-module",
      "description": "Add a Tralalere module.",
      "schema": "./add-module/schema.json"
    },
    "removeModule": {
      "aliases": [ "rm" ],
      "factory": "./remove-module",
      "description": "Remove a Tralalere module.",
      "schema": "./remove-module/schema.json"
    }
  }
}

Add Schematics


Adobe Air sur Ubuntu 13.10 64bits

Adobe Air était, selon moi, une bonne chose. Je ne porte pas particulièrement Adobe dans mon cœur mais, pour le coup, au début j'ai trouvé que c'était un bon moyen de faire du développement cross-platform avec la possibilité de le faire en html5. Forcément, le jour où Adobe a arrêté le support pour GNU/Linux, Air a perdu énormément de son intérêt. Bon au début ça allait, les applications étaient encore compatibles mais plus le temps passe moins c'est le cas.

On est même arrivé à un point où il est moins évident d'installer Adobe Air sur des distributions récentes. C'est le cas notamment avec Ubuntu 13.10 64bits (je n'ai pas encore testé avec 14.04, je n'ai pas encore upgrade). C'est encore possible de l'installer mais la documentation n'est pas évidente à trouver donc je vais rassembler ça ici.

Pour commencer, on va télécharger la dernière version compatible d'Adobe Air disponible actuellement sur cette page : https://helpx.adobe.com/air/kb/archived-air-sdk-version.html . Pour prendre directement l'installeur de la version 2.6 d'Adobe Air : http://airdownload.adobe.com/air/lin/download/2.6/AdobeAIRInstaller.bin 

Si on essaye de l'installer maintenant (en rendant le fichier exécutable au préalable), on se mange une erreur à propos de libgtk version 32bits. En fait on a besoin de du pacage ia32-libs qui a été retiré depuis Ubuntu 13.10. On peut cependant l'installer depuis les dépôts 13.04.

Pour ça, on commence par ajouter le dépôt suivant à notre /etc/apt/sources.list (ou un fichier .list dans /etc/apt/sources.list.d/) :

deb http://archive.ubuntu.com/ubuntu/ raring main restricted universe multiverse

Ensuite on fait un update des dépôts :

sudo aptitude update

Et enfin on installe ia32-libs

sudo aptitude install ia32-libs

Maintenant que c'est fait, on peut lancer l'installation d'Adobe Air sans erreur. Ou presque. La fenêtre d'installation donne une erreur au deuxième écran en parlant de l'absence de de Gnome keyring. Normalement le keyring est installé, mais Adobe Air ne va pas chercher la bibliothèque au bon endroit. Il va donc falloir faire un lien symbolique de la bibliothèque vers le bon endroit :

sudo ln -s /usr/lib/x86_64-linux-gnu/libgnome-keyring.so.0 /usr/lib/

Et voilà ! On peut lancer l'installation d'Adobe Air, finalement ! Une fois installé, c'est bon on peut installer des applications Air. Seul bémol, certaines applications ne sont compatibles qu'avec des versions récentes d'Adobe Air et donc ne pourront pas tourner sous Linux. C'est triste mais là il n'y a rien à faire à part demander au développeur de l'application de la rendre compatible.

Comparatif personnel entre Deezer et Spotify

Récemment, je me suis retrouvé à devoir choisir entre Deezer et Spotify comme service musicale. Je me suis contenté de comparer uniquement ces deux service (et pas d'autres) un peu par fainéantise et parce qu'ils proposent tous les deux un catalogue assez conséquent.

Pour remettre les choses dans leur contexte, j'utilise Deezer depuis ses tout débuts en 2007. Et je me suis abonné avec un compte Premium+ en décembre 2009 soit 1 mois après son lancement. En clair, j'ai toujours utilisé Deezer et j'étais plutôt satisfait du service.

Sauf qu'en juin dernier je reçoit une notification me disant que ma CB arrive à expiration dans 1 mois et que je devais en renseigner une nouvelle pour continuer à profiter de mon compte Premium+. Je vérifie la date d'expiration de CB, elle ne correspond pas à ce que dit cette notification. J'ignore donc le message en me disant que je verrai ça plus tard.

En juillet rebelotte, une notification me prévient : si je ne met pas à jour mes informations bancaires, je n'aurait plus accès au service à la fin du mois. Bon, soit, j'ai dû faire une erreur la dernière fois que j'ai entré mon numéro de CB. Je vais donc renseigner mes informations bancaires. J'arrive sur la page du formulaire, qui n'est autre qu'un pseudo pop-up en html. Bon... vérifions la sécurité alors (on notera au passage dans le formulaire un logo portant la mention "Formulaire sécurisé").

Premier point, la page sur laquelle je me trouve n'est pas en https. Donc n'importe quel élément externe appelé depuis la page peuvent accéder à mon numéro de CB. Et quand on voit la quantité d'éléments appelés, c'est d'autant moins rassurant. Bon, eh bien essayons de voir si le site supporte le https. Ah, oui. Enfin... presque. Page chargée en https mais plus de la moitié des scripts sont chargés en http depuis la page. Autant dire qu'on a la même sécurité qu'en http. Bon bah... leur formulaire sécurisé est troué bien comme il faut. Et ce, même si le formulaire est envoyé en https.

Du coup je regarde voir s'il est possible de passer par paypal pour l'abonnement. Oui c'est possible mais pour passer de l'un à l'autre il faut se désabonner puis se réabonner. Je vais d'abord voir ce que propose la concurrence et je reviendrai par là si je ne suis pas satisfait. Notons au passage que Deezer affirme à tort que son formulaire est sécurisé, on peut alors légitimement se poser des questions sur la sécurité de leur infrastructure.

Pour la concurrence, je vais jeter un œil chez Spotify. Comme je l'ai expliqué en préambule, je ne suis allé voir que Spotify un peu par fainéantise et parce qu'il propose un catalogue assez large. Le service est aussi assez répandu donc on peut supposer qu'il tiendra sur le long-terme (à la différence de Jiwa par exemple)

Je vais donc pour m'inscrire sur Spotify. Le site me propose de m'inscrire rapidement à l'aide de mon compte facebook mais je préfère avoir un compte distinct donc je cherche le formulaire d'inscription propre à Spotify et... et... je ne le trouve pas. J'ai cherché un peu partout sur le site, je n'ai trouvé nul part la possibilité de s'inscrire avec un compte propre à Spotify. Pourtant il est possible de se connecter avec ce type de compte mais je suppose qu'ils ont supprimé cette possibilité pour forcer les gens à avoir une utilisation "sociale" du leur compte Spotify (à moins qu'il y ai là une autre raison plus commerciale encore)

Je me retrouve devant ce formulaire que je ne veux pas remplir. Et aucune alternative. Je dois donc choisir entre un site que ne sécurise pas ses formulaires bancaires et un autre qui me force à me connecter avec un compte que je ne veux pas utiliser pour son service.

Petit aparté pour rapporter une information que j'ai trouvée en fouillant sur le site de Spotify, il est dit dans les CGU qu'il faut avoir au minimum 12 ans pour créer un compte sur Spotify. Sur Facebook l'âge minimum pour créer un compte est de 13 ans. Comme Spotify ne permet plus les inscriptions sur son site que via un compte Facebook alors quand t'as 12 ans, bah t'as le droit d'accéder au service, mais en fait non, tu peux pas. Génial hein ?

Revenons à nos moutons, je me retrouve donc devant un choix à faire, et finalement Spotify a gagné. Oui je sais je suis faible mais... j'ai fini par m'inscrire avec mon compte Facebook (ma première action a été de désactiver toutes les publications "sociales" du service). Au final je l'ai surtout fait pour pouvoir quand même comparer les deux services dans les fonctions qu'ils proposent et comparer leur utilisabilité.

Comme Spotify offre le premier mois de service premium (à condition de fournir un moyen de paiement valide) pour le tester et voir ce que ça donne. Du coup j'ai pu réellement comparer les deux services à niveaux égaux avant de faire mon choix. C'est parti pour le comparatif à l'utilisation.

Commençons par le contexte d'utilisation. Je suis principalement un utilisateur de linux, j'ai tendance à éviter flash au maximum (merci Flash Block) et je préfère un lecteur audio sous forme de logiciel. On pourrait se demander pourquoi j'utilise Deezer depuis tout ce temps alors, mais j'utilise en fait Deezer via son application bureau réalisée avec Adobe AIR. Les deux défauts à cela sont que Deezer ne supporte plus cette application et Adobe AIR ne supporte plus Linux. Donc je tourne forcément avec des versions qui ne pourront plus évoluer, ça fonctionne mais ça s'arrête là. Du côté de Spotify, ils n'ont pas d'application web donc j'avais commencé à installé l'application native via wine. Puis j'ai vu qu'ils avaient une version linux en beta, donc j'ai installé celle là, et elle fonctionne plutôt bien. Depuis que je l'ai installé je n'ai pas eu de mise à jour et j'ai l'impression que ça fait quelques temps qu'il n'y en a pas eu mais on peut toujours espérer pour le futur.

Après plusieurs années d'utilisation de Deezer via son application AIR, je lance Spotify. Premier constat et première déception, on ne peut pas enregistrer ses albums préférés pour ensuite les retrouver rapidement. En contre-partie, Spotify offre une gestion plus simple des playlist, surtout pour l'ajout de musique, on peut cliquer/glisser des albums ou juste des titres dans les playlist pour les ajouter, là où sur l'application Deezer il faut enchaîner toute une série de clics. Au niveau des fonctionnalités, je laisse de côté toute la partie "sociale" qui ne m'intéresse pas (je désactive), on a des choses assez proches entre les deux entre le téléchargement des morceaux pour une écoute hors ligne et les "smart radios" qui se basent sur un artiste et enchaîne avec des titres d'artistes similaires.

Je vais terminer avec mon ressenti après 3 mois d'utilisation de Spotify. Ce que je reprochais pas mal à Deezer au final était la difficulté de créer une playlist. Du coup j'avais tendance à lancer des albums individuels, mais du coup au bout d'1h d'écoute, il fallait que je choisisse un nouvel album à écouter. À ce niveau, quand j'ai commencé à utiliser Spotify, j'ai repris les albums que j'écoutais sur Deezer et je les ai placés dans des playlist. Je me suis retrouvé avec des playlists "thématiques" de plusieurs heures. Du coup maintenant je lance la playlist que je veux écouter en random et en repeat, et j'ai de la musique pour la journée. J'utilise aussi parfois la "smart radio" mais elle a malheureusement tendance à se couper après quelques heures, je dois donc relancer une session de radio, c'est dommage. L'application Spotify est aussi mieux intégrée au système que celle de Deezer. Elle présente des interfaces génériques pour le contrôle via des commandes multimédias et visualiser la lecture en cours. Enfin, l'application de Deezer avait tendance à planter ou à être parfois lente. Ça rendait presque désagréable le fait de la lancer pour écouter de la musique. Celle de Spotify est plutôt agréable à utiliser, un très bon point.

Au final vous l'aurez compris, je suis resté sur Spotify. Depuis que j'ai fait le changement, je lance plus souvent de la musique en fond sonore et j'ai la même qualité d'utilisation sur toutes mes machines. Il ne reste que deux points qui me déçoivent : certains artistes que j'écoutais sur Deezer ne sont pas présents sur Spotify et contrairement à Deezer, il n'y a pas d'application Spotify pour Playbook. Donc je ne peux pas écouter exactement tous les artistes que je veux et si je veux une utilisation mobile, je dois sortir ma tablette Android que je n'utilise plus beaucoup alors que j'ai toujours ma Playbook sur moi. Il reste donc ça à améliorer et je serait totalement satisfait.

99ko 1.2.4 et plugins à jour

Un petit billet après plusieurs longs mois de silence. Pendant tout ce temps, 99ko a continué d'évoluer. Il est maintenant en version 1.2.4 avec un retour en statut beta pour la branche 1.2.

Cette branche apporte pas mal de nouveautés par rapport à la 1.1.x, notamment une nouvelle interface d'administration, une meilleure structuration pour les plugins et les thèmes et un peu de tambouille interne. Pour la version 1.2.4, c'est avec elle qu'arrive l'url rewriting pour de plus belles url ainsi que quelques améliorations au niveau de la sécurité. Sur ce point nous retrouvons un hashage plus sûr du mot de passe administrateur ainsi que la restriction d'accès depuis l'extérieur aux fichiers de données des plugins.

Comme d'habitude, elle peut être trouvée ici : 99ko 1.2.4

Avec toutes ces nouveautés et surtout les modifications dans la gestion des plugins, le plugin blog n'était plus compatible. J'ai dû le mettre à jour et donc la version 0.5 est désormais disponible. J'en ai d'ailleurs profité pour procéder à une réécriture en profondeur du plugin pour me faciliter les développements futurs dessus. Pour ce qui est du changelog :

  • Mise à niveau pour 99ko 1.2.4
  • Réécriture quasi-complète du plugin pour faciliter la maintenance et améliorer les performances
  • Réorganisation du stockage des données
  • Outil de migration des données du plugin < 0.5 vers >=0.5

Concrètement pour les utilisateurs peu de changements mais ça a pris quand même pas mal de temps. Le point le plus important étant que les données sont mieux manipulées et j'ai considérablement réduit la quantité de données chargées inutilement à chaque requête. Il y a encore quelques améliorations possibles mais globalement c'est déjà beaucoup mieux.

Le plugin blog n'est pas le seul qui n'était plus compatible avec la nouvelle version de 99ko. J'ai donc aussi mis à jour le plugin menu qui passe en version 0.2.1 qui apporte comme seule nouveauté un peu de cosmétique pour son apparence dans l'interface d'admin de 99ko. C'est donc surtout mise à jour de compatibilité.

Avec tout ça, j'ai enfin mis à jour 99ko pour ce site. Vous êtes donc devant la vitrine de toutes ces nouvelles versions ;)

Pour finir, les liens vers tout ça :

Enjoy ! :)

DRDoS is nasty

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 :

  • DHCP
  • adresse MAC non attribuée au serveur
  • requête ARP
  • trop de requêtes par seconde en émission ou réception

Je passe en revue tous ces points:

  • je n'ai pas installé de serveur DHCP
  • je n'ai pas touché à mon adresse MAC
  • je n'ai rien qui puisse générer des requêtes ARP (à moins qu'un programme non légitime le fasse pour moi)

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.

<< Billets plus anciens