5943 links
  • GuiGui's Show

  • Home
  • Login
  • RSS Feed
  • Tag cloud
  • Picture wall
  • Daily
Links per page: 20 50 100
◄Older
page 80 / 298
Newer►
  • ALAIN SOUCHON : Allo Maman bobo - YouTube

    J'suis mal en campagne, et mal en ville, peut-être un p'tit peu trop fragile. Allô maman bobo.
    […]
    Moi je voulais les sorties de port à la voile, la nuit barrer les étoiles. Moi les chevaux le révolver et le chapeau clown, la belle Peggy du saloon.
    J'suis mal en homme dur, et mal en p'tit cœur, peut-être un p'tit peu trop rêveur. Allô maman bobo.

    Énorme +1. Qui suis-je ? Trop attentionné et pas assez. Trop sensible et pas assez. Trop concerné / impliqué et pas assez. Trop pragmatique et trop rêveur. Comment se trouver ? Comment gérer ses contradictions ? Comment trouver sa place ? Vastes questions pour tant de tristesse. :'(

    Wed Dec 16 21:56:30 2020 - permalink -
    - https://www.youtube.com/watch?v=J9pld-Z-L9s
  • « Il faut que tout change pour que rien change »

    Un collègue répète souvent la phrase « il faut que tout change pour que rien change » à propos de la politique politicienne, des décisions circulaires (qui tournent en rond) de nos chefs, ou des comportements individuels tout en sourçant le film Le Guépard.

    Forcément, j'ai jeté un œil, et le dialogue est encore plus savoureux :

    ‒ Un Falconeri doit être avec nous, pour le Roi !
    ‒ Pour le Roi d'accord, mais lequel ? Mais quel roi ? Est-ce que tu peux me le dire ? Pour celui qui veut faire l'unité de l'Italie [ Ferninand ], oui. Mais le petit François [ François II ], Dieu le bénisse, non, mon oncle, non.
    ‒ Alors, tu t'imagines que le roi Piémontais qu'on appelle l'honnête homme vaut vraiment mieux que l'autre ? Le patois de Turin à la place du Napolitain, c'est tout.
    ‒ Tu préférerais peut-être la République de Don Peppino Mazzini ?
    ‒ Bah
    ‒ Crois-moi mon petit oncle : si nous ne nous mêlons pas de cette affaire, ils vont nous fabriquer la République en deux temps trois mouvements. Si nous voulons que tout reste pareil, il faut que nous changions tout. J'espère que tu me comprends ?

    Wed Dec 16 21:27:28 2020 - permalink -
    - http://shaarli.guiguishow.info/?2hzC8g
  • [ Joindre / fusionner plusieurs fichiers PDF en un seul fichier ] pdftk [Wiki ubuntu-fr]

    Pour joindre / fusionner plusieurs fichiers PDF en un seul fichier, j'utilise pdftk (paquet logiciel du même nom dans Debian) : pdftk 1.pdf 2.pdf 3.pdf cat output 123.pdf.

    Chez moi, pdfjoin / pdfjam fonctionnent jamais : au-delà du premier PDF, les PDF suivants sont orientés selon le format paysage alors qu'ils sont conçus au format portrait, comme le premier document…

    Sun Dec 13 19:45:26 2020 - permalink -
    - https://doc.ubuntu-fr.org/pdftk
  • Le général Pierre de Villiers : «Les Français réclament de l’autorité» - Le Parisien

    Tout devient tellement chaotique que les gens ressentent ce besoin, réclament de l'autorité.

    Ha bah oui, bien sûr, c'est une évidence.
    Ce qui est bien avec ce genre de propos, c'est que ça marche avec tout. Exemple : les Français réclament une sodomie par semaine. Les Françaises réclament un fist-fuck par mois.


    L’ancien chef d’Etat major des armées, qui avait démissionné avec fracas au début du quinquennat d’Emmanuel Macron, est inquiet.

    Rappel des faits : il a été poussé à la démission par Macron, son chef, après s'être opposé à lui, devant une commission de l'Assemblée et en des termes fleuris, au sujet du montant du budget 2017 de la Défonce. Macron lui répondra d'ailleurs « Je suis votre chef » devant tout le gratin de la Défonce (source). En plus d'être discrédité devant ses troufions, il n'avait pas d'autre choix que de démissionner, Macron l'aurait viré de toute façon (source).

    En gros, Pierre de Villiers a été viré pour insubordination, parce qu'il a refusé l'autorité dont il prétend aujourd'hui que c'est ce que les Français réclament.

    Soit il n'est pas français, soit il se moque du monde, soit il est incohérent (syndrome faites ce que je dis, pas ce que je fais). La première hypothèse est fausse. Dans les deux autres cas, une seule réponse s'impose : « casse-toi d'là, pov' con », les Français n'ont pas besoin d'un nouveau De Gaulle (on rappellera que ce mec, DG, a aussi bien bien bien foiré : tranquillement planqué à Londres, coup d'État, Constitution à son image qui nous pose problème aujourd'hui ‒ exécutif fort, institutions faibles et inefficace, personnification-starification du président, etc. ‒, le SAC, la non-gestion de la guerre d'Algérie et plus largement de la colonisation française, mai 68, etc.).

    Sat Dec 12 21:54:09 2020 - permalink -
    - https://www.leparisien.fr/politique/le-general-pierre-de-villiers-les-francais-reclament-de-l-autorite-05-12-2020-8412630.php
  • Lecteur partagé winwin + Ubuntu 20.04 = impossible de monter le partage Windows : Le logiciel a provoqué l'abandon de la connexion

    Résumé : impossible de se connecter à un lecteur réseau winwin / CIFS depuis une machine Ubuntu 20.04 ? Ajouter client min protocol=NT1 dans la section [global] du fichier /etc/samba/smb.conf. Attention : cela pose des problèmes de sécurité !

    Depuis le gestionnaire de fichiers d'une machine Ubuntu 20.04, impossible de se connecter à un serveur CIFS. L'erreur suivante s'affiche avant même de demander l'identifiant + domaine + mot de passe :

    Oups ! Quelque chose s'est mal passé.
    Message d'erreur non géré : impossible de monter le partage Windows : Le logiciel a provoqué l'abandon de la connexion.

    Si l'on essaye de s'y connecter avec le logiciel smbclient, on obtient l'erreur suivante avant toute demande d'identifiant :

    smbclient //serveur.monorganisation.exemple/nom_lecteur -u <identifiant>
    protocol negotiation failed: NT_STATUS_CONNECTION_DISCONNECTED

    En revanche, cela fonctionne toujours avec mount -t cifs //serveur.monorganisation.exemple/nom_lecteur /point/de/montage -o username=<identifiant>,vers=1.0.

    Il ne faut pas aller chercher bien loin : mount d'une part et smbclient et gvfs d'autre part ne doivent pas utiliser le même sous-système, et l'antique version 1 du protocle SMB doit être désactivée dans l'un d'eux. C'est en effet le cas depuis la version 4.11 de Samba… Qui est justement celle distribuée dans Ubuntu 20.04. On notera que le problème se présentera aux Debianeux avec Bullseye. ;)

    Un contournement est indiqué dans le journal des changements de Samba : il faut ajouter client min protocol=NT1 dans la section [global] du fichier /etc/samba/smb.conf. Pas besoin de redémarrer quoi que ce soit : la modification est immédiatement effective.

    SMBv1 est dépréciée + elle pose des problèmes de sécurité, donc il faut la réactiver avec précaution. Dans notre cas, c'est en attendant la fin de la migration vers notre nouveau NAS.

    Wed Dec 9 21:40:27 2020 - permalink -
    - http://shaarli.guiguishow.info/?t_5Brw
  • Les nouveaux automates La Poste ou la notation au détriment de la critique constructive

    Depuis quelques mois, l'interface des automates de La Poste (qui permettent de peser / affranchir le courrier et acheter divers produits) a changé. Désormais, à la fin, l'usager est invité à noter le service à l'aide de pictogrammes-smyleys colorés que j'ai toujours trouvé infantilisants.

    Noter, encore et toujours, comme si c'était un but en soi. Noter, évaluer, dormir. Frénétiquement. Il faut que le jugement fuse et puisse être exprimé sans contrainte. Point de démarches compliquées, il faut que la sanction tombe rapidement.

    Oui, la collecte de retours utilisateurs est intéressante. Néanmoins, cette façon de faire, à l'aide de pictogrammes simplistes, restreint fortement l'utilité desdits retours : La Poste ne saura pas ce qui fonde le mécontentement de l'usager. Qu'est-ce qui n'a pas plu ? L'interface de l'automate ? Une fonctionnalité manquante ? Le fait de devoir utiliser un automate ? Le prix d'un produit ? L'usager a-t-il allumé son cerveau en utilisant l'automate ? A-t-il pris du recul sur son coup de sang ? Bien sûr que non. Rien ne pourra être retiré des retours. Mais, c'est cool, le prolo aura pu s'exprimer, c'est tout ce qui compte, on l'aura soulagé, ouf. Le système ne sera pas amélioré, mais le prolo aura l'impression d'être écouté.

    Ce genre de démarche amoindrit la pensée et les processus de contestation. Cela stérilise la critique et l'auto-critique. Simplement car c'est moins engageant de noter avec des smyleys que d'envoyer un courrier de réclamation (tu notes, tu passes à autre chose). On oublie comment contester (comment construire un argumentaire et l'articuler, logique d'une argumentation, forme, etc.) au profit du simpliste « moi content / pas content ». C'est comme cela que l'on éteint des citoyens.

    Il sufffit de patienter une petite dizaines de secondes pour que la demande de notation disparaisse. Je vais continuer à faire ça. Ne surtout pas jouer à ce jeu malsain.

    Tue Dec 8 23:49:24 2020 - permalink -
    - http://shaarli.guiguishow.info/?AQOkZA
  • Pourquoi la girafe a-t-elle un long cou ?

    La girafe a un long cou car elle prend du recul. Elle a de grandes pattes car elle est orientée résultats, elle veut trouver une solution.

    2020, """"formation"""" obligatoire « Bien vivre le télétravail ».

    Rigole pas, c'est avec ton pognon qu'on finance ce genre de bullshit. Les charlatans ne perdent pas de temps, et les gaspilleurs qui les financent non plus.

    Tu vas me dire « tu prends une phrase dans une formation de plusieurs heures ».

    Même pas. Y'avait aussi :

    • la communication non-violente renommée OSBD (observation, sentiment, besoin, demande) étudiée sous l'aspect hausse de la productivité (on ne pratique pas la CNV afin d'atteindre une plus grande humanité, mais pour engendrer plus de fric en exploitant mieux les sous-fifres ‒ je fais le même reproche au team building ‒).

    • les exercices de reformulation permettant de faire passer la pilule (demande de comptes, d'avancement, inquisition dans l'organisation), auprès des sous-fifres ;

    • l'infantilisation : "il faut éviter le « tu » accusatoire. On ne dit pas « tu devais faire ceci pour telle date », mais « ceci devait être fait pour telle date »", le « on » / « nous » au lieu du « tu » ;

    • un "il faut se donner de la force !" avec les mouvements bullshit des bras ;

    • les analogies foireuses et les schémas tout claqués que tous les formateurs se partagent entre eux et recyclent.

    Je suis bien content d'avoir échappé à c'te connerie même si, au fond, je suis l'idiot : mieux vaut être payé à (faire semblant d')écouter c'te blague qu'à travailler, ça demande moins d'efforts.

    Allez, je vais être gentil : j'imagine que cette """"formation"""" est déjà plus acceptable (en termes de gaspillage de pognon) que les """"formations"""" sophrologie et autres gabegie en matière de formation professionnelle.

    Ça me rappelle l'habilitation électrique ou une formation sur les méthodes agiles : bullshit over bullshit for more bullshitness.

    Tant qu'il y aura des gens pour trouver ces """"formations"""" « pas si mal »…

    Tue Dec 8 23:10:58 2020 - permalink -
    - http://shaarli.guiguishow.info/?EvjiyQ
  • Les conditions propres aux concours externes | Portail de la Fonction publique

    Les concours externes sont réservés aux candidats possédant un niveau de diplôme déterminé. Les concours internes sont réservés aux agents déjà en poste dans une administration après une durée minimale de service. Les troisièmes concours sont ouverts aux personnes justifiant d’une activité professionnelle (dans le secteur privé, associatif) ou d’un mandat local pendant une durée déterminée. (source)

    Les conditions propres aux concours externes […] Aucune condition de diplôme n'est exigée pour les pères et mères qui élèvent ou ont élevé au moins trois enfants, ainsi que pour les sportifs de haut niveau, figurant sur une liste fixée chaque année par le ministre chargé de la jeunesse et des sports.

    Ça fait plusieurs fois que j'entends dire cela. C'est donc vrai.

    Quand j'y réfléchis, cette dispense peut avoir du sens : élever plusieurs gamins (les textes ne disent pas qu'il faut les avoir conçus, juste en avoir la charge), ça nécessite de gérer des ressources rares (affection, temps, argent, etc.), de gérer des conflits (X enfants veulent jouer avec le même jouet en même temps, par exemple), de bien gérer son temps (amener les gamins à l'école, puis à telle activité, chez le docteur, vaccins, chez les potes, etc.), gérer les priorités (genre si t'as bouclé ta journée en faisant tout ce que tu devais sauf nourrir les gamins, ben t'as perdu), gérer la frustration (aujourd'hui, je voulais prendre du temps pour moi, pas pour aller récupérer le gamin malade à l'école), etc. Tout ça ressemble très fortement à ce que l'on attend d'un employé, surtout s'il est ingénieur / cadre. Donc, si t'es capable de faire tout ça, oui, je peux admettre une équivalence à un diplôme.

    Dans nos sociétés où s'occuper des gosses est un travail délégué aux femmes, on peut trouver fort de café que les hommes puissent, eux aussi, obtenir la dérogation.

    Ce qui me dérange plus, c'est que l'on pose une définition (concours externes = réservés aux diplômés) et qu'on la contredit juste après (ha non en fait le concours réservé aux diplômés n'est pas réservé aux diplômés). Bullshit habituel, certes, mais ça reste un non-sens gonflant.

    Sat Dec 5 10:31:07 2020 - permalink -
    - https://www.fonction-publique.gouv.fr/score/concours/conditions-propres-aux-concours-externes
  • 🐶💘 Filtre d'amour #20816 - DTC Dans Ton Chat - BashFR - Humour perles citations

    Saka: Tain mais les meufs sur Tinder
    Saka: C'est quoi votre délire avec le filtre chien ?
    Saka: Vous comptez attirer qui ? Les zoophiles ?

    Énorme +1.

    Fri Dec 4 21:38:09 2020 - permalink -
    - https://danstonchat.com/20816.html
  • Statut LRAR = « Votre envoi a été remis en lot au destinataire. Nous attendons la confirmation de sa réception. »

    J'envoie une LRAR à un grand groupe commercial français. Je la suis sur le site web de La Poste.

    Ma LRAR est à l'étape « Votre envoi a été remis en lot au destinataire. Nous attendons la confirmation de sa réception. ». C'est la première fois que je vois ce statut. Si ça parle à quelqu'un du milieu, je suis preneur de sa signification exacte (en coulisse, pas le bullshit de façade).

    Je suis dubitatif : La Poste remet un lot de LRAR au groupe commercial et ce dernier doit confirmer qu'il a bien reçu le lot entier ? Il n'y a pas de suivi individualisé ? Ce n'est pas le facteur, en tant que tierce partie neutre, qui valide qu'il a bien remis le pli au destinataire ? N'est-ce pas pour cela que je paye ce service ?

    Fri Dec 4 19:16:16 2020 - permalink -
    - http://shaarli.guiguishow.info/?lv7a9A
  • ImageMagick security policy 'PDF' blocking conversion - Stack Overflow

    J'essaye d'intégrer une image au format png dans un document PDF avec ImageMagick : convert image.png document.pdf.

    Cette fois-ci, ça ne fonctionne pas : convert-im6.q16: attempt to perform an operation not allowed by the security policy 'PDF' @ error/constitute.c/IsCoderAuthorized/408.

    Réponse sur StackOverflow : suite à une vulnérabilité dans Ghostscript, et en attendant le correctif, l'une des mesures de mitigation consistait à désactiver le traitement de scripts PostScript lorsqu'on utilise ImageMagick en ajoutant des lignes dans /etc/ImageMagick-6/policy.xml. Si l'on a un Ghostscript à jour (gs --version >= 9.24), on pourrait désactiver la restriction visant PDF en commentant la ligne « <policy domain="coder" rights="none" pattern="PDF" /> » dans la configuration d'ImageMagick. La solution fonctionne, mais les risques ne sont pas précisés et l'histoire (c'est lié à la vulnérabilité X) ne colle pas avec la réalité de ce qui s'est passé dans Debian.



    Allons plus loin et découvrons quelques outils et horreurs de l'écosystème Debian.

    Plusieurs points me font tiquer : la vulnérabilité date de 2018, Debian stable embarque une version corrigée de Ghostscript depuis septembre 2018[*] a minima, et je pouvais encore convertir vers PDF il y a quelques mois. Conclusion : la configuration d'ImageMagick a été changée récemment. Quand ? Pourquoi puisque Ghostscript été corrigé à date ?

    ls -lh /etc/ImageMagick-6/policy.xml affiche le 25 juin 2020 comme date de dernière modification. Si tu l'as modifié avant de penser à faire un ls, tu peux vérifier l'horodatage dans le paquet binaire. (Quand le temps aura passé, il faudra récupérer la version dont je parle, 6.9.10.23+dfsg-2.1+deb10u1, depuis les archives des paquets Debian). Pour savoir que le fichier /etc/ImageMagick-6/policy.xml provient du paquet logiciel imagemagick-6-common : apt-file search /etc/ImageMagick-6/policy.xml ou dpkg -S /etc/ImageMagick-6/policy.xml.

    Ça ne prouve pas que la modification est apparue dans la version 6.9.10.23+dfsg-2.1+deb10u1 ? Il suffit de récupérer la version précédente, 6.9.10.23+dfsg-2.1, du paquet logiciel dans les archives de paquet de Debian. Le paquet date de mai 2019 et le fichier policy.xml ne contient pas les changements.

    J'aurais voulu utiliser git pour retrouver l'info, mais : 1) le dépôt Debian d'ImageMagick n'a pas de branche ni tag pour la version 6.9.10.23+dfsg-2.1+deb10u1 (c'est probablement normal : il s'agit d'une version publiée par l'équipe sécurité de Debian, pas par les mainteneurs Debian d'ImageMagick), ni pour la version 6.9.10.23+dfsg-2.1 ni pour la version 6.9.10.23+dfsg-2 et les tags de version 6.9.10-23 et 6.9.10.23-dfsg-1 ne contiennent pas les modifications de policy.xml. La version upstream ne contient pas non plus la modification. On trouve l'adresse du dépôt git Debian depuis la page du Package Tracker dédiée à ImageMagick. On trouve le dépôt officiel / upstream avec un moteur de recherche (ou dans les commits du dépôt Debian si l'on a l'œil et de la chance).

    Cette date de modification de policy.xml, 25 juin 2020, apparaît dans le journal des changements du paquet (/usr/share/doc/imagemagick-6-common/changelog.Debian.gz ou lien « Debian Changelog » dans la page dédiée au paquet) : tout plein de vulnérabilités ont été corrigées ce jour-là. Les bulletins de sécurité Debian associés sont le DSA-4712-1 et le DSA-4715-1 [**]. L'identifiant CVE de la vulnérabilité mentionnée sur StackOverflow n'est pas mentionné dans la liste (et pour cause, elle a été corrigée + elle concerne un autre logiciel, Ghotscript).

    On remarque que les vulnérabilités corrigées ce jour-là (25 juin 2020) ont été enregistrés en 2019 dans le CVE… Ça fait long la correction de la vulnérabilité. :O Il est donc plus probable que le changement dans le fichier policy.xml d'ImageMagick soit une mesure préventive afin de tenter de mitiger, à l'avance, les vulnérabilités liées à des logiciels tiers dont Ghostscript. Dans Debian stable, il y a actuellement 36 vulnérabilités non-corrigées dans ImageMagick.

    Sur un serveur web avec du contenu dynamique exposé sur Internet, je pense qu'il ne faut pas désactiver les restrictions définies dans policy.xml.

    En revanche, sur mon ordinateur de bureau, je peux désactiver la restriction PDF sereinement en la commentant avec <!-- --> (c'est comme ça qu'on commente en XML…) : 1) je ne télécharge pas n'importe quoi depuis n'importe où, que ce soit sur le web ou par email ou Jabber ou… ; 2) dans mon gestionnaire de fichiers, je désactive l'indexation et la prévisualisation des fichiers, qui sont toutes deux susceptibles de faire exécuter du PostScript dangereux dans mon dos.

    Bref, ce n'est pas simple faire court sans dire nawak / faire des raccourcis et ce n'est pas simple non plus d'approcher la vérité dans un écosystème aussi vaste que Debian…



    [*] Comment sais-je que Ghostscript n'est plus vulnérable depuis septembre 2018 ? Je cherche le numéro de CVE, donné sur StackOverflow, dans le Security Tracker de Debian (champ de recherche tout en bas). Je trouve le numéro du bulletin de sécurité Debian : DSA-4294-1. Je consulte les archives de la liste de diffusion debian-security-announce (si t'es l'admin d'un parc de machines Debian, je te conseille de t'y abonner) ou je cherche dans le dépôt git du security tracker de Debian (fonctionnalité « blame » pour identifier le commit qui a ajouté telle ligne dans tel fichier). Dans les deux cas, je trouve que la vulnérabilité CVE-2018-16509 dans Ghostscript a été corrigée le 16 septembre 2018.

    [**] Même raisonnement qu'au point précédent pour trouver ces bulletins de sécurité Debian.

    Sun Nov 29 20:59:54 2020 - permalink -
    - https://stackoverflow.com/questions/52998331/imagemagick-security-policy-pdf-blocking-conversion
  • Ceci expire le 19 novembre 1981 à 08 h 52

    Résumé : un entête HTTP Expires: Thu, 19 Nov 1981 08:52:00 GMT est déposé lors d'un appel à la fonction session_start() de PHP. Il s'agit d'une date symbolique (date de naissance ?) codée en dur dans le limitateur de cache de PHP. À quoi il sert, ce limitateur ? À éviter que des informations privées soient stockées dans un cache mutualisé entre plusieurs utilisateurs et fuitent (une date passée empêche la mise en cache). Quelques révisions de quelques-uns des entêtes HTTP relatifs à la mise en cache (« Cache-Control », « Expires », « Vary », « Pragma ») s'impose.



    Quand je testais h2c (HTTP/2 sans chiffrement) puis quand j'essayais de comprendre l'origine des cookies déposés par Shaarli, j'ai remarqué cet étrange entête HTTP lorsque je navigue sur mon shaarli : Expires: Thu, 19 Nov 1981 08:52:00 GMT.

    Au début, j'ai pensé à un défaut dans ma configuration de la mise en cache / compression / expiration dans Apache httpd. (J'ai écrit cette configuration il y a 8-10 ans en suivant les recommandations du Hollandais Volant, vache !). Néanmoins, cet en-tête n'apparaît pas sur mon blog qui partage pourtant la même configuration. Sans compter que ma configuration calcule la date d'expiration en additionnant la durée de validité souhaitée à la date actuelle, donc elle ne peut pas être dans le passé. Mauvaise piste.

    J'ai pensé que c'est le logiciel Shaarli qui dépose lui-même cet entête. grep -Ri montrera que ce n'est pas le cas. Peut-être qu'Apache httpd positionne cet entête quand les entêtes « Cache-Control » et/ou « Pragma », eux aussi liés à la mise en cache, sont déposés (comme c'est le cas avec Shaarli) ? Aucune idée.

    Je me pose, je cherche sur le web et je trouve une réponse : l'un des contributeurs à PHP a laissé sa date de naissance (ou celle d'une personne proche, on ne sait pas) dans le code. En effet, n'importe quelle date suffisamment loin dans le passé aura pour effet que les navigateurs web et les intermédiaires (comme les serveurs proxy / mandataires) ne mettront pas la page web en cache. Partant de là, autant mettre une date symbolique.

    Ce n'est pas tout à fait exact, car plusieurs entêtes influent sur la mise en cache : « Pragma », « Expires », et « Cache-Control ». « Pragma » s'adresse aux clients HTTP/1.0. Le comportement qu'il actionne dépend des implémentations (source). « Expires » s'adresse aux clients web et aux intermédiaires HTTP/1.0 et 1.1. « Cache-Control » apparaît réellement avec HTTP 1.1 (source, source) et il s'adresse aux clients web et aux intermédiaires. Il a la priorité sur « Expires ». Dans le cas présent, PHP dépose aussi un entête « Cache-Control » d'où mon « ce n'est pas tout à fait exact ».

    Du coup, lors d'un appel à la fonction session_start() de PHP, le limitateur de cache se met en place. En l'absence d'appel à la fonction session_cache_limiter(), il adopte le comportement défini par le paramètre de configuration (php.ini) « session.cache_limiter » (source), soit, par défaut « nocache » (source), c'est-à-dire que le navigateur web et les proxies ne doivent pas mettre en cache la page web (source). Or, on a vu, dans le code source de PHP, qu'en mode « private » et « nocache », le limitateur de cache positionne l'entête « Expires: Thu, 19 Nov 1981 08:52:00 GMT ». Tout s'explique.

    Pourquoi désactiver le cache lors de l'ouverture d'une session sur un site web ? Pour limiter le risque qu'une information privée (relative à un utilisateur) se retrouve dans un cache mutualisé entre plusieurs clients web que ce soit au niveau d'un navigateur web ou d'un intermédiaire (proxy) et qu'elle fuite donc vers d'autres utilisateurs. Dans la réalité, l'entête « Vary » permet de mettre en cache des versions différentes d'une même page si des entêtes diffèrent (source). Donc, il est possible de mettre en cache en fonction d'un cookie et ainsi éviter les fuites, mais c'est jouer avec le feu : un intermédiaire peut désobéir, avoir un bug dans son code de normalisation des requêtes (qui vise à augmenter le taux de pages mises en cache en détectant les variations d'entêtes qui ont, en réalité, la même signification / effet, donc qui conduiront à la génération de la même page), etc.

    On notera que d'autres logiciels déposent un entête « Expires » contenant une date symbolique. WordPress dépose un entête « Expires: Wed, 11 Jan 1984 05:00:00 GMT » quand on accède à son administration.

    Mon Nov 23 21:23:34 2020 - permalink -
    - http://shaarli.guiguishow.info/?KFjitA
  • Adminsys : cas d'étude d'un diagnostic

    Je vais revenir sur un problème informatique. Sa résolution technique est insignifiante, mais je veux illustrer le déroulé d'un diagnostic, l'arbre de décisions, les différentes possibilités techniques, les différentes contraintes, les erreurs de réflexion, etc. En parlant autour de moi, je me suis rendu compte que quelques-unes des notions et des commandes / variables que je vais présenter ci-dessous sont méconnues (apt-file, apt-mark, dpkg-divert, ldconfig, LD_LIBRARY_PATH, PPID, snoopy, etc.).

    Pour notre supervision, nous utilisons Xymon. Alors, oui, il est rustique, mais, pour avoir manipulé pas mal des standards du marché (Zabbix, Icinga, Centreon, Shinken, etc.), je peux affirmer qu'au moins il est KISS, flexible, et qu'il fonctionne. Je parle bien de la partie supervision, les graphes (via RRDtool) sont une plaie à configurer. L'écriture d'un test de supervision est facile : il suffit d'apeler un binaire en lui donnant un état + message, en gros. Il s'appelle de n'importe où, par n'importe qui, point d'authentification ni autres. Juste, ça fonctionne.

    Le test interne nommé « memory » affiche une ligne « physical » (consommation totale de RAM ‒ processus + cache + tampons ‒), une ligne « actual » (consommation de la RAM par les processus, hors cache et tampons), et une ligne « swap ». Sur certains de nos serveurs, la ligne « actual » n'apparaît pas. On en avait viteuf déduit que ça se produit sur nos machines Debian >= 9.

    Quel logiciel Xymon utilise-t-il pour connaître la consommation RAM ? Avec grep -Ri memory, je cherche dans la configuration de Xymon (/etc/xymon) et dans les scripts et binaires (/usr/lib/xymon) aussi bien sur le serveur que sur un client. Je trouve rien. Cela doit se faire au sein d'un binaire, illisible par grep.

    Essayons de deviner le logiciel utilisé en sous-main par Xymon. Pour afficher la consommation RAM, je connais vmstat (dont je sais qu'il est utilisé par Xymon, je l'ai déjà vu plein de fois dans une sortie ps faux avec Xymon comme parent) et free. J'utilise whereis pour localiser ces deux binaires et chmod -x pour les rendre inutilisables. J'attends la fréquence d'actualisation du test (5 minutes) et, par déduction, j'en arrive à la conclusion que Xymon utilise free car la sortie du test est vide quand je bloque l'exécution de free.

    J'aurais pu utiliser snoopy logger afin de tracer les commandes lancées par Xymon, mais je ne suis pas sûr qu'il fonctionne avec un compte système sans shell (car c'est ce qu'utilise Xymon), il faut l'installer, et je me suis dit que c'était "too much" pour mon besoin.

    À ce stade, remplacer /usr/bin/free par un script shell qui aurait juste exécuté un ps aux | grep $PPID > /tmp/debugXymon aurait été utile : j'aurais appris quel composant précis de Xymon exécute la commande système free ($PPID : identifiant numérique du processus parent ;) ). Mais, sur le coup, je n'y ai pas pensé.

    Qu'est-ce qui a changé dans free entre Debian 8 et Debian 9 ? Le format de la sortie :

    • L'intersection de la ligne « Mem » et de la colonne « used » comptabilise uniquement la mémoire consommée par les processus (hors cache et tampons)… Ce que Xymon nomme « actual » ;

    • La ligne « -/+ buffers/cache » a été retirée. Dans le manuel, je trouve aucune option pour la faire revenir. Or, Xymon utilisait cette ligne pour son item « actual ». La ligne « -/+ buffers/cache » est remplacée par les colonnes « buff/cache » et « available ». La méthode pour calculer la mémoire disponible hors cache et tampons a changé afin d'être plus exacte, je vais y revenir.

    On a donc la raison qui explique notre constat : Xymon n'a pas été mis à jour pour tenir compte de ce changement dans l'affichage de free (enfin, je croyais, mais je me trompe, voir ci-dessous). Il ne trouve plus la ligne « -/+ buffers/cache » donc il n'affiche plus sa ligne « actual ». Et ce qu'il nomme « physical », qui était toute la RAM consommée (processus + cache + tampons), prend le nouveau sens de la commande free, à savoir la mémoire utilisée par les processus hors cache et tampons.

    Est-ce un problème ? Puisqu'« actual » est, de fait, devenue la ligne « physical », tout va bien, on a l'info qu'on a toujours eu.

    Sauf que je pense que la quantité de RAM utilisée par le cache et les tampons est une info intéressante. Pas forcément sur tout type de serveur. Mais moins on a de lectures depuis les supports de stockage, mieux on se porte. Elle m'a permis d'ajuster la quantité de RAM de notre serveur LDAP. De même, le cache est important sur un serveur de bases de données. Je pense que c'est aussi important sur des serveurs d'applications web (PHP, uwsgi/django, Tomcat, etc.

    Pour me contredire, on peut citer les propos de tonton Torvalds : "toute RAM libre est du gâchis". Linux va toujours exploiter la RAM au maximum, y compris pour mettre en cache des trucs qui serviront qu'une fois genre une mise à jour aptitude. Donc, la quantité de cache va augmenter constamment. De ce fait, mesurer cette quantité est inintéressant. Ceci dit, ce n'est pas parce qu'on voit un chiffre augmenter dans sa supervision qu'on augmente automatiquement la quantité de RAM. En revanche, avoir l'historique de la consommation de RAM par le cache+tampons est intéressant (si au boot de la machine LDAP, le cache monte direct à 500 Mo, c'est qu'il est plutôt utile ; si un reboot libère 3 Go de cache sans y revenir avant 6 mois, c'est qu'il contenait nawak, donc il ne faut pas redimensionner la RAM).

    Avant de me demander si j'agis, je trouve sain de me demander si le problème est temporaire ou définitif.

    J'installe un agent / client Xymon sur une machine Debian 10 (oui, en supervision, un logiciel est installé sur les ordinateurs à surveiller, et un serveur de supervision centralise les remontées d'informations et présente les informations aux administrateurs). Je l'ajoute dans notre supervision. *Le problème demeure. En même temps, entre Stretch et Buster, on passe de la version 4.3.28-2 de Xymon à la 4.3.28-5… Version très mineure voire interne à Debian, donc il ne fallait pas en attendre grand-chose.

    Peut-être que l'analyse des données se fait côté serveur Xymon (je ne le sais pas encore, mais c'est bien le cas) ? Nous ne prévoyons pas de le mettre à jour puisque nous allons migrer vers une autre solution de supervision. Quand ? Aucune idée, aucun projet à l'horizon. Cela justifie qu'on corrige temporairement ce problème.

    Je pourrais coder un nouveau test qui surveille la quantité de RAM. J'ai pas trouvé comment désactiver le test « memory » intégré à Xymon. Je pense que cumuler deux tests qui font la même chose est confusant. De plus, il faudrait re-coder toutes les subtilités du test : les seuils d'alerte, le passage de paramètres depuis la configuration du serveur (chose qu'on ne fait pas dans nos autres scripts, d'où il faudra du temps pour chercher comment faire) ‒ car, sur certains de nos serveurs, on change les seuils, entre autres ‒, etc. Tout ça sera spécifique à Xymon… Dont nous voulons nous débarrasser à moyen-terme. Trop d'investissement pour pas grand-chose, à mon avis. Je laisse tomber cette piste.

    Une piste vient à l'esprit : remplacer /usr/bin/free par un script. S'il est exécuté par Xymon, il lancera l'ancien binaire free ou un script maison qui collectera les données et les affichera dans le même format que le faisait l'ancienne version de free. S'il est lancé par quoi ou qui que ce soit d'autre, il lancera le vrai binaire free que l'on déplacera en /usr/bin/free.new (par exemple). Afin de ne pas lever d'alerte ni d'écraser notre /usr/bin/free modifié sans pour autant se priver des mises à jour de free, ce qui serait le cas si l'on empêchait sa mise à jour avec apt-mark hold procps (je sais que free est empaqueté dans ce paquet grâce à apt-file search -x '/usr/bin/free$'), on utiliserait dpkg-divert.

    Je scp le binaire free depuis un Debian 8 sur un Debian 9. Il refuse de s'exécuter car il manque la bibliothèque de fonctions libprocps.so.3. En effet, c'est la version 6 de cette bibliothèque qui est empaquetée dans Debian Stretch / 9. Créons un lien symbolique afin de le duper : sudo ln -s /lib/x86_64-linux-gnu/libprocps.so.6 /lib/x86_64-linux-gnu/libprocps.so.3. Cela fonctionne mais la ligne « -/+ buffers/cache » présente des nombres négatifs. Si je copie la version 3 depuis Debian 8, cela fonctionne. La bibliothèque a changé…

    Je pourrais déployer la vieille version de free et de libprocps sur nos Debian >= 9. Le risque que la vieille bibliothèque soit utilisée par d'autres binaires que notre vieux free est proche de 0. Si je voulais m'en assurer, je pourrais la stocker dans une arborescence ignorée par ldconfig (configuration du chargement à chaud des bibliothèques de fonctions) et utiliser LD_LIBRARY_PATH pour forcer son utilisation quand free est exécuté par Xymon. Sauf qu'à ce stade-là, je ne sais pas quel composant de Xymon exécute free, donc il est inenvisageable de surcharger son appel à free.

    De toute façon, free dépend d'autres bibliothèques de fonctions (libc, libdl) qui peuvent changer de version et/ou de comportement. Plus le temps (et les versions de Debian) passe, plus la probabilité que ça casse augmente. Utiliser une vieille version de free est donc plutôt un mauvais choix.

    D'autant que, de l'autre côté de la balance, écrire un script qui va chercher les mêmes informations que free ne semble pas être difficile puisque le manuel de free expose qu'il récupère les informations dans le fichier /proc/meminfo.

    Au début, je pars dans l'idée d'exécuter la version actuelle de free, d'y ajouter une ligne « -/+ buffers/cache » et de remplacer l'intersection de la ligne « Mem » et de la colonne « used ». J'ai considéré que je change 3 valeurs (Mem+used + 2 valeurs sur la ligne « -/+ buffers/cache ») alors que free en affiche 11 en tout. Les deux tiers des valeurs sont valides, donc pourquoi s'embêter à les récupérer nous-même ?

    En pratique, je récupère les infos manquantes depuis /proc/meminfo et je les stocke dans des variables, je stocke les deux premières lignes de la sortie de free avec head -n 2 dans une variable, la dernière ligne avec tail -n 1 dans une deuxième variable, je corrige Mem+used avec un awk -v memUsed="$memUsed" 'FNR==2 { $3=memUsed }; { print };' (-v permet de créer une variable interne à awk et de lui attribuer la valeur d'une variable shell et FNR est le numéro de la ligne, donc on remplace le troisième élément de la deuxième ligne par le contenu de la variable shell maison nommée memUsed), j'affiche tous les variables, et hop, ça fonctionne.

    Ça fonctionne, mais c'est un mauvais raisonnement : afin de corriger un problème lié à un changement dans la sortie d'un programme, je crée un script qui dépend lui-même de la sortie d'un programme qui peut changer (il a même déjà changé, c'est l'origine du problème). Genius!

    Je ré-écris tout. Je récupère toutes les valeurs depuis /proc/meminfo et je les affiche. Le code est même plus simple : juste un cat, des grep, des additions / soustractions et des echo. Comment sais-je quelles valeurs dans /proc/meminfo dois-je utiliser ? Je lis le code source de la commande free. Enfin… L'ancienne version, évidemment. Je cherche où est défini la fonction meminfo() qui semble collecter les données… Dans sysinfo.c. Ainsi, mémoire totale = kb_main_total dans le code = « MemTotal » dans /proc/meminfo, mémoire utilisée = « MemTotal » - « MemFree », mémoire réellement utilisée = mémoire utilisée - (« Buffers » + « Cached ») , etc.

    Au final, ça donne ça :

    #!/bin/bash
    
    # On récupère les valeurs depuis procfs
    meminfo=$(cat /proc/meminfo)
    
    memTotal=$(grep '^MemTotal:' <<< "$meminfo" | awk '{ print $2 }')
    memFree=$(grep '^MemFree:' <<< "$meminfo" | awk '{ print $2 }')
    shared=$(grep '^Shmem:' <<< "$meminfo" | awk '{ print $2 }')
    buffers=$(grep '^Buffers:' <<< "$meminfo" | awk '{ print $2 }')
    cached=$(grep '^Cached:' <<< "$meminfo" | awk '{ print $2 }')
    
    swapTotal=$(grep '^SwapTotal' <<< "$meminfo" | awk '{ print $2 }')
    swapFree=$(grep '^SwapFree' <<< "$meminfo" | awk '{ print $2 }')
    
    # On calcule ce qui nous manque
    memUsed=$(( $memTotal - $memFree ))
    swapUsed=$(( $swapTotal - $swapFree ))
    
    # voir https://gitlab.com/procps-ng/procps/-/blob/099bf9a26a074a7f58442aa0c907980459afdc02/free.c
    buffers_plus_cached=$(( $buffers + $cached ))
    
    # +/- used = kb_main_used - buffers_plus_cached
    #          = memUsed      - buffers_plus_cached
    buffersUsed=$(( $memUsed - $buffers_plus_cached ))
    
    # # +/- free =  kb_main_free + buffers_plus_cached
    #            =  memFree      +  buffers_plus_cached
    buffersFree=$(( $memFree + $buffers_plus_cached ))
    
    # Affichage
    echo -e '\ttotal\t\tused\t\tfree\t\tshared\t\tbuffers\t\tcached'
    echo -e "Mem:\t$memTotal\t\t$memUsed\t\t$memFree\t\t$shared\t\t$buffers\t\t$cached"
    echo -e "-/+ buffers/cache:\t$buffersUsed\t\t$buffersFree"
    echo -e "Swap:\t$swapTotal\t\t$swapUsed\t\t$swapFree"
    
    exit 0

    Alors, oui, les chiffres remontés à notre supervision seront moins fiables que la colonne « available » d'un free moderne puisque le calcul de la mémoire utilisée pour le cache a changé (source : https://gitlab.com/procps-ng/procps/-/blob/13f20a48119894638a98b9a17a714704c69492d4/proc/sysinfo.c#L685 versus https://gitlab.com/procps-ng/procps/-/blob/master/proc/sysinfo.c#L781), mais on est à quelques dizaines de mégaoctets d'écart… Nous ne sommes pas la NASA : cette imprécision est largement tolérable.

    Il me reste plus qu'à écrire le script qui prendra la place de /usr/bin/free et qui dirigera vers le bon binaire en fonction de qui l'exécute. Comment savoir qui exécute un script ? Il existe la variable shell USER, ce qui rend envisageable une condition if [ "$USER" == 'xymon' ]. La variable PPID permet de connaître l'identifiant du processus parent, ce qui rend envisageable un if ps aux | grep $PPID | grep -q xymon. Plein d'autres moyens existent.

    Dans mon cas, USER n'est pas provisionnée. Car Xymon est exécuté par un compte utilisateur système qui a /bin/false pour shell ? Je pourrais utiliser id -u, mais je pars sur $PPID, comme ça, sans raison. Mais… Attends… Je peux donc savoir quel composant de Xymon exécute free : il suffit de remplacer /usr/bin/free par un script ps aux | grep $PPID > /tmp/debugXymon. J'attends la fréquence d'actualisation du test « memory ». le fichier apparaît dans /tmp et je découvre que le processus Xymon qui exécute free est /usr/lib/xymon/client/bin/xymonclient-linux.sh.

    Comment a-t-il échappé à mes grep du début ? Parce qu'à ce stade-là, le test se nomme « free », pas « memory ». Je n'ai pas lancé une nouvelle campagne de grep quand j'ai compris que c'était bien la commande free qui était utilisée en sous-main, donc j'ai rien vu, forcément. Cela permet d'affirmer que le test définitif, « memory », est produit côté serveur Xymon à partir des données remontées par xymonclient-linux.sh sous le nom de « free ». Comme pour l'espace disque. Comme pour les processus. Comme pour… De même, si j'avais percuté qu'une version de Xymon est sortit en 2019 et si j'avais lu le journal des changements j'aurais compris que le problème qui m'interroge a été corrigé dans la version 4.3.20 du serveur Xymon (notons que le fichier « README » de la version la plus récente ne contient pas tout l'historique, il faut donc remonter de version en version pour prendre connaissance de tous les changements…). Ce constat ne change pas la conclusion : le problème se situe côté serveur… que nous ne mettrons pas à jour.

    Du coup, nul besoin de remplacer /usr/bin/free : il suffit de lancer notre script depuis xymonclient-linux.sh. Cela fonctionne. \o/

    Avec Puppet, je déploie, sur nos Debian >=9 uniquement, mon script qui émule l'ancienne version de free et une nouvelle version de xymonclient-linux.sh qui exécute mon script au lieu de free afin de remonter l'utilisation de la RAM.

    Fin.

    Sun Nov 22 21:24:22 2020 - permalink -
    - http://shaarli.guiguishow.info/?GU_XIg
  • La grande flexibilité du mod_userdir d'Apache httpd

    Le module userdir du serveur web Apache httpd permet à chaque utilisateur d'un serveur d'héberger un site web dans son dossier personnel ($HOME). Celui-ci sera accessible à l'URL https://www.monorganisation.example/~<IDENTIFIANT_UTILISATEUR>.

    Du moins, ça c'est la théorie. J'ignorais la grande flexibilité de mod_userdir :

    • Par défaut, le site web d'un utilisateur doit se trouver dans un dossier « public_html » situé dans le $HOME (home directory, dossier personnel) de cet utilisateur. Mais, en fait, ce dossier peut se trouver n'importe où, tant que le chemin pour y accéder contient / dépend de l'identifiant de l'utilisateur. Même le nom du dossier n'est pas imposé ;

    • Il est possible de préciser plusieurs chemins vers le dossier contenant le site web d'un utilisateur. Apache httpd cherchera le dossier contenant le web d'un utilisateur dans telle arborescence, et s'il ne trouve pas le dossier, il le cherchera dans telle autre arborescence, puis dans telle autre, etc.


    Cas d'étude

    Nous avons un serveur Debian GNU/Linux sur lequel tous nos utilisateurs peuvent se connecter en SSH et déposer des pages web (entre autres choses).

    Deux espaces de stockage sont à leur disposition : leur dossier personnel ($HOME) et leurs données. Les deux sont montés en NFS. Les données sont aussi accessibles en CIFS depuis n'importe quelle machine et n'importe quel système d'exploitation. Le dossier personnel est accessible seulement depuis ce serveur.

    Certains utilisateurs veulent modifier leur site web depuis winwin (entre l'encodage des caractères, le codage différent d'un retour à la ligne, et autres fourberies, ce n'est pas une bonne idée, mais je ne suis pas là pour empêcher nos utilisateurs de se faire mal). On va donc stocker les sites web dans l'espace de stockage « données ».

    Comment faire ? Simple. Voici le contenu du fichier /etc/apache2/mods-enabled/userdir.conf :

    <IfModule mod_userdir.c>
    
        UserDir disabled root
    
        UserDir /nfs/nas-datas/datas/*/public_html
    
        <Directory /nfs/nas-datas/datas/*/public_html>
            AllowOverride All
            Options Indexes
            Require all granted
        </Directory>
    
    </IfModule>

    Commentaires :

    • Par sécurité, on désactive ce module pour l'utilisateur root ;

    • Pour servir une URL de la forme https://www.monorganisation.example/~<IDENTIFIANT>, Apache httpd cherchera les fichiers dans le dossier /nfs/nas-datas/datas/<IDENTIFIANT>/public_html ;

    • On autorise Apache httpd à accéder au dossier public_html des utilisateurs. Selon la documentation, ici, le caractère substituable « * » n'est pas remplacé par l'identifiant demandé dans l'URL, mais signifie « n'importe quels caractères qui apparaît 0, 1 ou une infinité de fois ».



    Difficulté supplémentaire : en fait, sur notre NAS, pour des raisons de performances, le dossier d'un utilisateur est en fait un sous-dossier d'un dossier qui peut prendre le nom d'un hash ou celui du groupe auquel appartient l'utilisateur (son service, par exemple) ou l'année d'arrivée de l'utilisateur, etc. Pour cet exemple, on considérera que c'est le groupe de l'utilisateur et que celui-ci équivaut à son service.

    Comment faire ? Facile. Le module userdir peut chercher le site web dans plusieurs dossiers en s'arrêtant à la première occurrence trouvée. Quant à elle, la directive « Directory » autorise plusieurs caractères substituables.

    Le contenu du fichier /etc/apache2/mods-enabled/userdir.conf devient :

    <IfModule mod_userdir.c>
        UserDir disabled root
    
        UserDir /nfs/nas-datas/datas/info/*/public_html /nfs/nas-datas/datas/compta/*/public_html /nfs/nas-datas/datas/direction/*/public_html
    
        <Directory /nfs/nas-datas/datas/*/*/public_html>
            AllowOverride All
            Options Indexes
            Require all granted
        </Directory>
    
    </IfModule>



    Allez, une dernière chose : si le site web n'est pas trouvé dans l'espace de stockage « données », on souhaite le chercher dans le dossier personnel.

    Ce n'est pas un problème : on peut bien évidemment cumuler les différentes syntaxes de la directive « UserDir » : UserDir /nfs/nas-datas/datas/info/*/public_html public_html. Dans cet exemple, Apache httpd ira chercher dans le dossier /nfs/nas-datas/datas/info/<IDENTIFIANT>/public_html et, si ce dossier n'existe pas, il ira chercher dans le dossier public_html du home directory (qui n'est pas toujours /home/<IDENTIFIANT>, pour rappel).

    Évidemment, pour que cela fonctionne, il faut ajouter une directive « Directory » supplémentaire autorisant l'accès au dossier « public_html » situé dans le $HOME. Exemple :

    <Directory /nfs/nas-homedir/homedirs/*/*/public_html>
        AllowOverride All
        Options Indexes
        Require all granted
    </Directory>
    Mon Nov 16 20:41:55 2020 - permalink -
    - http://shaarli.guiguishow.info/?LvGB_A
  • Barre de progression d'un upload web calculée côté serveur

    Je me suis toujours demandé comment fonctionne les barres de progression d'un téléchargement / téléversement que l'on trouve sur les sites web : comment le code du site web peut-il être au courant de l'avancement d'une telle action puisqu'il est exécuté une fois l'upload terminé ?

    Au temps du module PHP pour Apache httpd, je me disais que, vu qu'il s'agit d'un module, il est incrusté au cœur d'Apache httpd donc il doit certainement disposer d'infos supplémentaires. Mais quid des installations dans lesquelles le serveur web est uniquement un reverse proxy vers un serveur d'applications (FastCGI, PHP-FPM, Python uwsgi) ?

    La première réponse qui vient à l'esprit est : on surveille la progression de l'upload entièrement côté client avec Ajax.

    J'ignorais qu'il est également possible de surveiller l'upload côté serveur. Enfin, pas totalement, puisqu'il faudra toujours de l'Ajax pour actualiser la barre de progression. Mais le reste est fait côté serveur.


    Fonctionnement d'une barre de progression côté serveur

    A priori, tout le monde s'est mis d'accord sans pour autant produire une norme (en tout cas, le RFC 1867, souvent cité, normalise l'envoi de fichiers avec un formulaire web, mais pas la mesure de la progression d'un upload) :

    • Le script côté client génère un identifiant unique pour chaque upload ;

    • Le navigateur web lance l'upload ;

    • Le serveur fait les calculs de la progression de l'upload ;

    • En parallèle de l'upload, le client interroge le serveur grâce à Ajax (requêtes asynchrones) en utilisant une URL convenue à l'avance choisie par l'application et en rappelant l'identifiant unique de l'upload. Exemple : XHR GET https://www.monorganisation.example/progressbarupload/upload_progress?X-Progress-ID=42122089-d6dd-4570-9ded-09e75f8a50d2 ;

    • Le serveur répond du JSON. Exemple : « { "state" : "uploading", "received" : 49478497, "size" : 65730134 } ».

    • Le client actualise la barre de progression, puis refait une requête au serveur web afin de connaître l'avancement de l'upload, donc retour au 4e point ci-dessus ;



    Quand j'écris « le serveur fait » ceci ou cela, de quel composant précis est-ce que je parle ?

    • Cela peut être PHP, nativement ou couplé au module APC. Dans ces deux cas, le suivi de la progression fonctionne uniquement avec le module PHP pour Apache httpd, pas en FastCGI ni avec PHP-FPM ;

    • Cela peut être le serveur web. Il existe un module pour nginx, un module pour Apache httpd, un module pour Lighttpd, etc. Dans Debian GNU/Linux, celui pour nginx est activé par défaut, celui pour Apache httpd est disponible dans le paquet libapache2-mod-upload-progress. Celui pour nginx est plutôt bien documenté (peut mieux faire sur les valeurs par défaut des paramètres, par exemple) alors que celui pour Apache httpd ne l'est quasiment pas (ça ne permet pas de comprendre que l'URL à laquelle récupérer les rapports de progression est configurable, par exemple).


    Configurer nginx

    • Dans le bloc http du fichier ngnix.conf, il faut ajouter : upload_progress uploadp 1m;. On réserve un espace mémoire d'un mégaoctet nommé « uploadp » pour le suivi des uploads ;

    • Dans le serveur virtuel, dans le bloc location qui envoie les requêtes vers un serveur d'applications, il faut ajouter track_uploads uploadp 30s. On surveille tous les uploads en les enregistrant dans l'espace mémoire « uploadp » défini ci-dessus. On conserve la trace d'un upload jusqu'à 30 secondes après sa complétion ;

    • Dans le serveur virtuel, on ajoute un nouveau bloc location capturant l'URL à laquelle l'application est programmée pour venir chercher les informations concernant un upload à coup de XMLHTTPRequest. nginx répondra aux requêtes GET qu'il recevra à cette URL avec les informations concernant un upload dont l'identifiant est passé en argument si celui-ci a été surveillé dans l'espace mémoire « uploadp » :

      location ^~ /progressbarupload/upload_progress {
          upload_progress_json_output
          report_uploads uploadp;
      }


    • On recharge la configuration : sudo systemctl reload nginx.

    Notons que le module nginx prend en charge JSONP, JSON with Padding, qui encapsule les données dans un appel de fonction afin de contourner les restrictions inter-domaines : la récupération d'un fichier depuis un autre domaine avec XMLHTTPRequest est interdite par défaut par les navigateurs web sauf si l'on positionne des en-têtes CORS sur le site web sur lequel les données doivent être récupérées, alors que la récupération d'un script JavaScript sans utiliser XMLHTTPRequest est autorisée par défaut. Pour activer un retour au format JSONP, il faut remplacer upload_progress_json_output par upload_progress_jsonp_output.


    Configurer Apache httpd :

    • On installe le module (il sera activé et httpd sera redémarré) : sudo apt-get install libapache2-mod-upload-progress ;

    • Dans le serveur virtuel, dans le bloc location qui envoie les requêtes vers un serveur d'applications, il faut ajouter TrackUploads On ;

    • Dans le serveur virtuel, on ajoute un nouveau bloc location capturant à l'URL à laquelle l'application est programmée pour venir chercher les informations concernant un upload à coup de XMLHTTPRequest. nginx répondra aux requêtes GET qu'il recevra à cette URL avec les informations concernant un upload dont l'indentifiant est passé en argument :

      <Location ~ '^/progressbarupload/upload_progress'>
          ReportUploads On
      </Location>


    • On recharge la configuration : sudo systemctl restart apache2.

    Le module Apache httpd prend aussi en charge JSONP. Pour l'activer, il suffit d'ajouter le paramètre callback=<nom_désiré_pour_la_callback> à la requête HTTP GET qui viendra consulter le rapport d'avancement de l'upload produit par le serveur, il y a rien à activer dans la configuration du serveur web.

    Sun Nov 15 19:14:33 2020 - permalink -
    - http://shaarli.guiguishow.info/?TtmNbA
  • OpenLDAP : faire des recherches <= / >= sur des attributs de type entier

    Réponse : ajouter « ORDERING integerOrderingMatch » à la définition de l'attribut.

    Sur les attributs numériques (integer) de notre annuaire LDAP (OpenLDAP), nous aimerions faire des recherches de la forme « valeur supérieure ou égale à ». Exemples : trouver les prénoms+nom des personnels dont employeeNumber est >= XXXXXXXX ; trouver tous les uid des personnels dont pwdLastChange est <= 20191231 (cela fonctionne car la date est au format ISO 8601 dont le Hollandais Volant présente les avantages) ; trouver tous les uid des personnels dont gidNumber >= XXXXXXXX.

    Notons que la norme LDAP ne permet pas des recherches avec les opérateurs strictement inférieur (<) et strictement supérieur (>). Uniquement <= et >=.

    Notre recherche sur le gidNumber fonctionne. Elle échoue sur les autres attributs : aucun résultat est retourné alors que des objets correspondent à notre recherche.

    J'ai déjà présenté les règles de comparaison qui peuvent être affectées à un attribut LDAP afin de pouvoir comparer deux objets LDAP entre eux et le fait que, par défaut, aucune régle de comparaison est associée à un attribut. Je pressens qu'il en va de même pour une recherche ordonnée portant sur des attributs numériques.

    Je parcours à nouveau le RFC 4517. Bingo, il existe bien des règles de comparaison ordonnée.

    Ainsi, pour être en mesure d'effectuer une recherche <= ou >= sur un attribut LDAP de type entier, il faut ajouter « ORDERING integerOrderingMatch » à sa définition en mettant à jour le schéma qui la contient.

    Sun Nov 15 17:00:28 2020 - permalink -
    - http://shaarli.guiguishow.info/?x7DXvQ
  • Rappels de sécurité concernant sudo

    Ces derniers temps, j'ai utilisé sudo pour faire du contrôle d'accès, donc j'ai dû réviser les bases :

    • sudo ne prend pas en charge les regex dans sa configuration, uniquement les glob patterns, un sous-ensemble de caractères substituables. Il n'est donc pas possible d'indiquer la répétition d'un ou de plusieurs caractères avec « + », « * » ou « {} », par exemple ;

    • Le caractère substituable « * » autorise toujours plus d'actions que ce que l'on pense initialement en écrivant la règle sudo. Parfois à cause des programmes à qui l'on donne des droits avec sudo (exemple avec less, mais on peut faire la même avec vim qui permet d'exécuter des commandes ;)), très souvent à cause de la configuration de sudo.

    Exemples :

    • toto ALL=(titi) NOPASSWD: /usr/bin/id : l'utilisateur toto peut se faire passer pour l'utilisateur titi afin d'exécuter la commande id sans avoir à saisir un mot de passe. Tous les paramètres du programme id sont utilisables (« - g », par exemple). Plus largement, tous les arguments sont possibles : autoriser less ou cat donne la possibilité de consulter tooous les fichiers du système en se faisant passer pour titi. C'est pourquoi il ne faudrait jamais avoir une entrée dans la configuration de sudo de la forme toto ALL=(root) NOPASSWD: /usr/bin/id * si le but est d'autoriser tous les arguments d'une commande (lire les points suivants pour connaître les dangers de l'entrée sudo énoncée à l'instant) ;

    • toto ALL=(titi) NOPASSWD: /usr/bin/id -[gu] (pas « -(g|u) » puisque sudo ne prend pas en charge les regex) : toto peut lancer id -u et id -g sans mot de passe en se faisant passer pour titi ;

    • toto ALL=(root) NOPASSWD: /usr/bin/ssh root@cluster[0-9] id : toto peut se faire passer pour root afin de se connecter, en SSH, aux machines nommées clusterX où X doit être entre 0 et 9 inclus. Pour autoriser les dizaines (« clusterXX ») : « cluster[0-9][0-9] ». Surtout pas « cluster[0-9]* » : il ne s'agit pas d'une regex, donc « * » n'agit pas sur le groupe précédent afin de le répéter 0 ou n fois : il autorise clusterX (où X = entre 0 et 9, ça ne change pas) suivi de n'importe quoi (des chiffres, des lettres, des espaces, etc.). Toto peut donc exécuter : sudo ssh root@cluster10 'rm -rf / ; id' ;

    • toto ALL=(root) NOPASSWD: /usr/bin/ssh root@web[0-9]*.monorganisation.example id : toto pourra exécuter sudo ssh root@web1 rm -rf /#.monorganisation.example id. # = commentaire, tout ce qui suit ne sera pas exécuté. Il faudra juste définir le nom web1 dans /etc/hosts (sauf s'il y a une instruction search ou domain dans /etc/resolv.conf).

    Il y a un cas que je ne sais pas résoudre sur le plan de la lisibilité :

    • On veut se connecter à un serveur pour exécuter un script maison. Jusque-là, c'est facile : toto ALL=(root) NOPASSWD: /usr/bin/ssh root@srv.monorganisation.example /usr/local/bin/script.sh ;

    • S'il y a des arguments facultatifs et/ou dont la valeur change ? Facile : toto ALL=(root) NOPASSWD: /usr/bin/ssh root@srv.monorganisation.example /usr/local/bin/script.sh -a start, /usr/bin/ssh root@srv.monorganisation.example /usr/local/bin/script.sh -a stop. Mais plus il y a d'arguments et de valeurs, plus la configurarion de sudo devient lourde, longue et illisible ;

    • Et si, parmi les arguments du script, il y a une chaîne de 4 caractères variables ? toto ALL=(root) NOPASSWD: /usr/bin/ssh root@srv.monorganisation.example /usr/local/bin/script.sh -a start -b [a-z][a-z][a-z][a-z], /usr/bin/ssh root@srv.monorganisation.example /usr/local/bin/script.sh -a stop ;

    • Et si, parmi les arguments du script, il y a une longue chaîne de caractères (comme un hash) ? Il faut les préciser caractère par caractère ;

    • Au final, la configuration de sudo devient illisible.
    Sat Nov 14 13:05:03 2020 - permalink -
    - http://shaarli.guiguishow.info/?e6SBSw
  • adduser / passwd demandent de saisir le mot de passe actuel ?! Merci, pam_script

    Sur ma machine perso GNU/Linux Buster, j'ajoute un utilisateur :

    $ sudo adduser toto
    [sudo] Mot de passe de guigui : 
    Ajout de l'utilisateur « toto » ...
    Ajout du nouveau groupe « toto » (1002) ...
    Ajout du nouvel utilisateur « toto » (1002) avec le groupe « toto » ...
    Création du répertoire personnel « /home/toto »...
    Copie des fichiers depuis « /etc/skel »...
    Current password: 
    New password: 
    New password (again): 
    Mot de passe inchangé
    passwd: Erreur de manipulation du jeton d'authentification
    passwd: password unchanged

    Le comportement est identique après un su - root.

    Depuis quand passwd demande l'ancien mot de passe quand on crée un compte ?! Depuis quand cette demande se fait-elle en anglais ?

    Je crée un compte sans mot de passe (entrée, entrée, entrée, entrée, etc.) puis je tente de changer le mdp :

    # passwd toto 
    Current password: 
    New password: 
    New password (again): 
    Aucun mot de passe fourni
    passwd: Erreur de manipulation du jeton d'authentification
    passwd: password unchanged

    … … …

    J'ai trouvé l'origine du problème avec de la chance : j'ai installé le module pam_script. Celui-ci modifie le fichier /etc/pam.d/common-password de la manière suivante :

    - password        [success=1 default=ignore]      pam_unix.so obscure sha512
    + password        sufficient                      pam_script.so
    + password        [success=1 default=ignore]      pam_unix.so obscure use_authtok try_first_pass sha512

    C'est donc pam_script qui affiche « Current password » / « New password » / « New password (again) ». A priori, ce n'est pas un script lancé par pam_script mais bien pam_script lui-même qui affiche cela, car, en mettant mon /etc dans un dépôt git, je n'ai pas trouvé un quelconque script et l'installation de libpam-script ne modifie / n'ajoute pas d'autres fichiers dans /etc.

    Du coup, si l'on répond uniquement avec entrée, on devrait passer au module suivant, pam_unix.so, non ? Oui.

    Donc retrouver le comportement habituel ? Non. Car pam_unix est exécuté avec l'argument « use_authtok » qui lui ordonne de définir le nouveau mot de passe à la valeur fournie par un module précédent… Or, nous ne l'avons pas saisi. Le module pam_unix affiche donc « Aucun mot de passe fourni ». Puis le module pam_deny afffiche les deux dernières lignes.

    Saisir un nouveau mot de passe sans saisir le mot de passe actuel change rien : la comparaison entre le mot de passe enregistré en base et celui saisi échouera, donc pam_unix échouera.

    Solution ? Soit désinstaller libpam-script (je l'avais installé pour tester des choses). Soit commenter la ligne pam_script et virer les arguments « use_authtok try_first_pass » de pam_unix.

    Fri Nov 13 19:51:51 2020 - permalink -
    - http://shaarli.guiguishow.info/?E9iTJw
  • How to Send a Message to Logged Users in Linux Terminal

    Envoyer un message sur tous les tty/pts d'une machine GNU/Linux : wall <message>. Utile pour annoncer une maintenance imprévue et urgente ou pour rappeler une maintenance planifiée.

    Ça faisait bien bien bien longtemps que je n'avais pas eu l'opportunité de faire ça. \o/

    Thu Nov 12 21:56:00 2020 - permalink -
    - https://www.tecmint.com/send-a-message-to-logged-users-in-linux-terminal/
  • systemd - What are the systemctl options to "List all failed units" - Unix & Linux Stack Exchange

    Quand systemctl status affiche qu'une ou plusieurs units sont en état « failed », systemctl list-units --state=failed permet d'identifier laquelle / lesquelles. Je l'oublie toujours…

    Thu Nov 12 17:48:46 2020 - permalink -
    - https://unix.stackexchange.com/questions/341060/what-are-the-systemctl-options-to-list-all-failed-units
Links per page: 20 50 100
◄Older
page 80 / 298
Newer►
Mentions légales identiques à celles de mon blog | CC BY-SA 3.0

Shaarli - The personal, minimalist, super-fast, database free, bookmarking service by the Shaarli community