C’est les vacances (du moins pour moi), et même si je me concentre sur ma recherche d’appartement, je n’oublie pas le blog qui me manquait effectivement un peu, et pour lequel j’arrive à trouver de l’inspiration. Enfin presque, aujourd’hui, c’est petit pense-bête pêle-mêle (beaucoup de circonflexes là-dedans) d’astuces diverses dans différents domaines, évidemment presque toujours de la ligne de commande.

Un générateur de mot de passe alphanumérique

Les astuces vont souvent prendre la forme d’un alias, et voici donc le premier, un petit générateur de mot de passe aléatoire, par exemple pour la connexion à une base de données :

alias passgen="strings /dev/urandom | grep -o '[[:alnum:]]' | head -n 12 | tr -d '

'; echo" 1 alias passgen = "strings /dev/urandom | grep -o '[[:alnum:]]' | head -n 12 | tr -d '

'; echo"

On l’appelle ensuite sans paramètre, et le résultat est immédiat :

[seboss666@Seboss666LTP ~]$ passgen jytiXt3jkMJjC 1 2 [ seboss666 @ Seboss666LTP ~ ] $ passgen jytiXt3jkMJjC

Vous pouvez changer la taille dans la partie head -n 12 (donc ici douze caractères).

Un dig moins bavare

dig est un outil très pratique quand vous devez manipuler assez souvent des noms de domaines. Mais il est très verbeux par défaut, et l’on a pas forcément besoin au quotidien de toutes les infos. Voici donc comment le rendre plus discret :

alias dig="dig +noall +answer" 1 alias dig = "dig +noall +answer"

Si vous avez malgré tout besoin de la réponse complète, il suffit de rajouter +all à la fin (exemple avant/après) :

[seboss666@Seboss666LTP ~]$ dig blog.seboss666.info A blog.seboss666.info. 82335 IN A 91.121.61.180 [seboss666@Seboss666LTP ~]$ dig blog.seboss666.info A +all ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53262 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;blog.seboss666.info. IN A ;; ANSWER SECTION: blog.seboss666.info. 82294 IN A 91.121.61.180 ;; Query time: 0 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: sam aoû 20 19:52:35 CEST 2016 ;; MSG SIZE rcvd: 64 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [ seboss666 @ Seboss666LTP ~ ] $ dig blog .seboss666 .info A blog .seboss666 .info . 82335 IN A 91.121.61.180 [ seboss666 @ Seboss666LTP ~ ] $ dig blog .seboss666 .info A + all ; ; Got answer : ; ; -> > HEADER << - opcode : QUERY , status : NOERROR , id : 53262 ; ; flags : qr rd ra ad ; QUERY : 1 , ANSWER : 1 , AUTHORITY : 0 , ADDITIONAL : 1 ; ; OPT PSEUDOSECTION : ; EDNS : version : 0 , flags : ; udp : 4096 ; ; QUESTION SECTION : ; blog .seboss666 .info . IN A ; ; ANSWER SECTION : blog .seboss666 .info . 82294 IN A 91.121.61.180 ; ; Query time : 0 msec ; ; SERVER : 127.0.0.1 #53(127.0.0.1) ; ; WHEN : sam ao û 20 19 : 52 : 35 CEST 2016 ; ; MSG SIZE rcvd : 64

Vous comprenez pourquoi je lui « coupe la chique » 🙂

Son propre dossier de scripts

C’est une astuce que j’ai pu présenter dans d’autres articles, mais je la remets ici au cas où. Plutôt que de coller ses scripts persos dans /bin ou /usr/local/bin, vous pouvez vous créer un dossier ~/scripts et le faire prendre en compte par Bash à votre connexion. Pour ça, ajoutez à votre fichier .bashrc :

export PATH=$PATH:/home/seboss666/scripts 1 export PATH = $PATH : / home / seboss666 / scripts

Remplacez par votre dossier à vous hein 🙂

Vérifier que tous les ServerName/Alias ont bien une adresse IP

Petite astuce pour Apache, si vous voulez vérifier que tous les domaines configurés pointent bien dessus (par exemple pour faire le ménage), vous pouvez utiliser la routine suivante, en vous plaçant dans votre dossier sites-enabled (si vous êtes sous Debian, cherchez ailleurs sinon) :

for i in $(grep -Eri "Server(N|A)" * |grep -Ev "(admin|tpl|\#)" |cut -d\: -f2 |awk '{for (i=2; i<NF; i++) printf $i " "; print $NF}'); do echo "$i : $(dig $i A +short)"; done 1 for i in $ ( grep - Eri "Server(N|A)" * | grep - Ev "(admin|tpl|\#)" | cut - d \ : - f2 | awk '{for (i=2; i<NF; i++) printf $i " "; print $NF}' ) ; do echo "$i : $(dig $i A +short)" ; done

Vous devriez obtenir une ligne par domaine présent et leur adresse IP dans la foulée si elle existe. Cela permet notamment de faire le ménage, par exemple si vous avez une quarantaine d’Alias dans le même vhost comme j’ai déjà pu le rencontrer. Et vous devriez pouvoir l’adapter assez rapidement pour Nginx.

Empêcher la désactivation du proxy Apache pour une minute

Un comportement chiant d’Apache 2.4, dans un contexte de proxy (que ce soit au travers de ProxyPass ou de SetHandler, pour la prise en charge de PHP-FPM par exemple), si la connexion au backend est perdue, Apache la désactive pour 60 secondes, et ce même si vous réparez très vite, ce qui vous oblige à également redémarrer Apache. Pénible, mais « contournable » avec la directive retry=0 (exemple) :

ProxyPass / http://127.0.0.1:9000/ retry=0 ProxyPassReverse / http://127.0.0.1:9000/ ########### <Proxy *> ProxySet retry=0 </Proxy> <FilesMatch \.php$> SetHandler "proxy:fcgi://127.0.0.1:9000" </FilesMatch> 1 2 3 4 5 6 7 8 9 10 ProxyPass / http : / / 127.0.0.1 : 9000 / retry = 0 ProxyPassReverse / http : / / 127.0.0.1 : 9000 / ########### < Proxy * > ProxySet retry = 0 < /Proxy > < FilesMatch \.php$ > SetHandler "proxy:fcgi://127.0.0.1:9000" < /FilesMatch >

Lister tous les utilisateurs MySQL et leurs droits

Petit script à se mettre dans un coin, adapter le chemin du fichier de configuration (–defaults-file) qui contient le pass root :

#!/bin/bash source /etc/profile /usr/bin/mysql --defaults-file=/root/my-client.cnf --silent --skip-column-names --execute "select concat('\'',User,'\'@\'',Host,'\'') as User from mysql.user" | sort | \ while read u do echo "-- $u"; /usr/bin/mysql --defaults-file=/root/my-client.cnf --silent --skip-column-names --execute "show grants for $u" | sed 's/$/;/' done 1 2 3 4 5 6 7 #!/bin/bash source / etc / profile / usr / bin / mysql -- defaults - file = / root / my - client .cnf -- silent -- skip - column - names -- execute "select concat('\'',User,'\'@\'',Host,'\'') as User from mysql.user" | sort | \ while read u do echo "-- $u" ; / usr / bin / mysql -- defaults - file = / root / my - client .cnf -- silent -- skip - column - names -- execute "show grants for $u" | sed 's/$/;/' done

Copier/renommer plus rapidement un fichier

La syntaxe habituelle pour copier/déplacer un fichier, c’est <commande> <origine> <destination>, exemple :

cp toto.txt toto2.txt 1 cp toto .txt toto2 .txt

qui crée un fichier toto2.txt identique à toto.txt. Pour aller plus vite, vous pouvez utiliser la syntaxe suivante :

cp toto{,2}.txt 1 cp toto { , 2 } .txt

Et c’est pareil pour mv.

Il y en aura peut-être d’autres, il m’arrive d’en utiliser d’autres mais je ne les ai pas toujours en tête, et ne je prend pas forcément toujours le temps de les noter.

J’ai bien aimé faire le premier billet, alors je vous ai encore noté plusieurs astuces qui sont beaucoup trop courtes et où le contexte de découverte ne serait pas nécessairement intéressant pour en faire des billets à part entière. Et en écrivant ce qui est le deuxième épisode d’une nouvelle série, je pourrais presque en faire une catégorie tiens (Séries ?).

Liste d’arguments trop longue

Vous n’avez jamais eu ce message d’erreur ? Alors regardez cet exemple :

$ mv -v documents.old/* documents/ -bash: /bin/mv: Liste d'arguments trop longue $ ls -l |wc -l 58741 1 2 3 4 5 6 $ mv - v documents .old / * documents / - bash : / bin / mv : Liste d ' arguments trop longue $ ls - l | wc - l 58741

Mais c’est pas une raison pour les faire un par un, ça prendrait trop de temps. Passons plutot par find :

$ find documents.old/ -type f -exec mv {} documents/ \; 1 $ find documents .old / - type f - exec mv { } documents / \ ;

Dans l’absolu, ça sera toujours super long, donc vous pouvez faire autre chose en attendant.

Filtrer la sortie d’un tail -f

Vous détestez les logs verbeux autant que moi (coucou Java) ? Si vous cherchez un message en particulier lors du démarrage d’une application, vous pouvez faire un grep sur la sortie d’un tail -f plutot que de rester hypnotisé devant un écran dégueulant des milliers de lignes de logs. Sisi, c’est faisable :

tail -f catalina.out |grep "Server startup" 1 tail - f catalina .out | grep "Server startup"

Pour l’anecdote, si vous faites un grep sur vim (quoi, ça peut arriver à tout le monde ?), vous pouvez tout de même quitter vim de manière habituelle même si vous ne voyez rien.

Vérifier tous les certificats de vos sites

Si vous cumulez les certificats provenant de différents fournisseurs, il peut être intéressant, si vous les rangez au bon endroit (typiquement, avec la configuration des virtualhosts), d’en vérifier les informations pour ne pas se faire surprendre par un certificat expiré.

mysite=""; num=0; for cert in $(find . -type f -name "*.crt"); do echo -ne "[${num}] Certificate file: ${cert}

-------------------

"; openssl x509 -noout -subject -in ${cert} | sed -n '/^subject/s/^.*CN=//p' | cut -d\/ -f1; openssl x509 -noout -dates -in ${cert}; echo -ne "

"; num=$((${num}+1)); done | egrep -B2 -A3 "${mysite}$" 1 mysite = "" ; num = 0 ; for cert in $ ( find . - type f - name "*.crt" ) ; do echo - ne "[${num}] Certificate file: ${cert}

-------------------

" ; openssl x509 - noout - subject - in $ { cert } | sed - n '/^subject/s/^.*CN=//p' | cut - d \ / - f1 ; openssl x509 - noout - dates - in $ { cert } ; echo - ne "

" ; num = $ ( ( $ { num } + 1 ) ) ; done | egrep - B2 - A3 "${mysite}$"

Peut éventuellement servir dans un rapport mensuel envoyé par mail sur l’état d’une machine.

Purger le cache ARP

Très rare, mais il peut arriver, dans certains réseaux un peu conséquents et posant quelques problèmes de stabilité (un routeur en fin de vie qui fait un peu de la merde par exemple), qu’il faille vider le cache ARP pour retrouver une connexion stable. Ça peut se faire avec une seule boucle :

for i in $(arp -a | awk '{print $2}' | sed "s/(//g;s/)//g"); do arp -d $i; done 1 for i in $ ( arp - a | awk '{print $2}' | sed "s/(//g;s/)//g" ) ; do arp - d $i ; done

Répertoire partagé VirtualBox

Dire que je me suis cassé les dents pendant des mois à faire du sudo cp <fichier> /media/sf_VM/ pour transférer des fichiers entre machine virtuelle et hôte Windows. En fait, il suffit simplement de s’ajouter au bon groupe :

sudo usermod -a -G vboxsf seboss666 1 sudo usermod - a - G vboxsf seboss666

Et de déconnecter/reconnecter la session (ou comme moi, mode bourrin redémarre). Et hop, on peut directement copier/déplacer des fichier dedans.

Purger uniquement certains éléments de la file de mail en attente

Quand vous avez soit subi une attaque sur un site, soit un test mal branlé d’envoi de mail de la part d’un développeur (les deux étant du vécu), il se peut qu’il faille faire le ménage sans perdre de message légitime. Exit dont l’arme atomique postsuper -d ALL, il faut un peu plus de travail, exemple sur une installation qui repose sur Postfix :

mailq |tail -n +2 |awk 'BEGIN {RS=""} /email.com/ {print $1}' |tr -d '*!' |postsuper -d - 1 mailq | tail - n + 2 | awk 'BEGIN {RS=""} /email.com/ {print $1}' | tr - d '*!' | postsuper - d -

Et hop, tous les mails en @email.com à la baille. Les autres peuvent repartir une fois les vannes rouvertes et/ou votre serveur déblacklisté.

Ne pas vérifier la signature SSH d’un serveur

Cas que j’ai régulièrement quand j’essaie de me servir d’Ansible au boulot, pour une raison que j’ignore et sans que les serveurs soient compromis, il me redemande systématiquement de valider la signature de certains serveurs. Pour contourner ça, j’ai placé ces deux petites lignes à la fin de mon fichier ~/.ssh/config :

Host * StrictHostKeyChecking no 1 2 Host * StrictHostKeyChecking no

Et voilà, avec un peu plus de 150 hôtes sur lequel pousser la mise à jour d’un script (avec un nombre en constante augmentation), plus de problème à devoir rester devant pour taper « yes » à tout bout de champ. A utiliser avec précaution toutefois, parce que si jamais vous l’utilisez sur un réseau non maitrisé, c’est la porte ouverte au Man-in-the-middle.

Faire le ménage dans le fichier hosts d’Ansible

Pour reparler d’Ansible, je l’utilise entre autres pour déployer/mettre à jour un script maison sur un gros groupe de machines. Pour mettre à jour le fichiers hosts afin de purger les machines qui ont disparues, et en m’assurant qu’elles sont effectivement à la retraite, je me base sur le fichier .retry qu’il crée pour indiquer les machines sur lesquelles il n’est pas arrivé au bout du playbook. Et c’est sed qui vient à la rescousse :

s.verdet@SebLBNvm:~/ansible/$ for i in $(cat playbook.retry); do sed -i "/$i/d" ./hosts; done 1 s .verdet @ SebLBNvm : ~ / ansible / $ for i in $ ( cat playbook .retry ) ; do sed - i "/$i/d" . / hosts ; done

Si vous n’êtes pas à l’aise, je vous conseille de faire une sauvegarde du fichier hosts auparavant.

Comme d’habitude, tout ce que je présente n’est pas forcément le plus optimisé qui soit, si vous avez des remarques à faire, des suggestions, commentaires toussa, vous commencez connaitre la musique non ? 🙂

J’ai fini par les apprécier, ces billets astuces en vrac. Alors en attendant qu’il y en ai un quatrième et qu’ils aient leur propre série dans le menu idoine, voici déjà le troisième épisode. Au programme, du serveur Web, du Bash, et d’autres joyeusetés.

Whitelister le dossier .well-known derrière un mot de passe htaccess

Sous Apache, si vous voulez créer/renouveler un certificat Let’s Encrypt, vous avez deux solutions, créer un Alias avec un dossier à part qui n’est pas protégé par mot de passe, soit autoriser les requêtes sur le dossier .well-known dans le DocumentRoot déjà protégé. Sur Apache 2.4, il suffit d’ajouter une ligne à côté des autres Require :

Require expr %{REQUEST_URI} =~ m#^/.well-known/acme-challenge/# 1 Require expr %{REQUEST_URI} = ~ m #^/.well-known/acme-challenge/#

Supprimer les règles en doublon dans un fichier de réécriture

Dernièrement, le gros site d’un client a complètement été refondu. Qui dit refonte dit modifications des URLs, et pour ne pas trop perdre en référencement, on procède alors à des réécritures. Un peu pus de 400 réécritures dans le cas présent, mais transmises sous forme de tableau Excel, qu’il faut alors transformer en autant de règles Nginx. Le travail a été douloureux, notamment en raison de doublons qui faisaient que certaines règles n’étaient pas prises en compte. Pour supprimer ces doublons, j’ai utilisé une petite combinaison en Bash :

cat nginx-www.site-inter.net.rewrites |sort |uniq > nginx-www.site-inter.net.final.rewrites 1 cat nginx - www .site - inter .net .rewrites | sort | uniq > nginx - www .site - inter .net .final .rewrites

Il n’y a plus qu’à inclure ce fichier final. 27 doublons de supprimés, autant de règles qui ne font plus chier.

Regex de cochon

On m’a demandé de faire une redirection d’une URI en particulier vers une autre, pour plusieurs domaines. Plutôt que de créer autant de règles en fonction des domaines (avec et sans www), j’ai groupé le tout avec une seule expression régulière, que je partage donc ici pour inspiration :

RewriteEngine On RewriteCond %{HTTP_HOST} ^(www\.)?site.(fr|de|it|be)$ RewriteCond %{REQUEST_URI} ^/raccourci RewriteRule ^(.*)$ http://{HTTP_HOST}/reel [L,R] 1 2 3 4 RewriteEngine On RewriteCond %{HTTP_HOST} ^ ( www \ . ) ? site . ( fr | de | it | be ) $ RewriteCond %{REQUEST_URI} ^ / raccourci RewriteRule ^ ( . * ) $ http : / / { HTTP_HOST } / reel [L,R]

Inverser deux paramètres en bash

Qui n’a jamais pesté, depuis l’arrivée de systemd, d’avoir inversé le nom d’un service et l’opération voulue ?

Remember :

service httpd start systemctl start httpd 1 2 3 service httpd start systemctl start httpd

Et bien plutôt que de tout réécrire ou de jouer avec les flèches et supprimer, vous pouvez, à l’aide d’un Esc , puis t , inverser les deux derniers éléments de la commande. Un vrai bonheur :

Ça fait le café.

Un alias pour relancer une commande avec sudo

Avec l’utilisation quasi-généralisée de sudo dans les distributions, malgré tout, en l’occurrence si vous parcourez souvent mes articles, il se peut qu’on oublie de saisir une commande avec. Plutôt que de revenir en arrière et d’aller ajouter sudo au début, vous pouvez saisir sudo !! qui va lancer sudo avec la dernière commande complète saisie. Collez ça dans un alias, et admirez le travail :

[seboss666@seboss666-pc ~ ]$ pacman -S ansible erreur : vous ne pouvez pas effectuer cette opération à moins d’être root. [seboss666@seboss666-pc ~ ]$ fuck sudo pacman -S ansible [sudo] password for seboss666: résolution des dépendances... recherche des conflits entre paquets... Paquets (6) python2-crypto-2.6.1-3 python2-jinja-2.8-2 python2-markupsafe-0.23-3 python2-paramiko-2.0.2-1 python2-yaml-3.12-1 ansible-2.2.0.0-1 Taille totale du téléchargement : 4,15 MiB Taille totale installée : 38,36 MiB :: Procéder à l’installation ? [O/n] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 [ seboss666 @ seboss666 - pc ~ ] $ pacman - S ansible erreur : vous ne pouvez pas effectuer cette op é ration à moins d ’ê tre root . [ seboss666 @ seboss666 - pc ~ ] $ fuck sudo pacman - S ansible [ sudo ] password for seboss666 : r é solution des d é pendances . . . recherche des conflits entre paquets . . . Paquets ( 6 ) python2 - crypto - 2.6.1 - 3 python2 - jinja - 2.8 - 2 python2 - markupsafe - 0.23 - 3 python2 - paramiko - 2.0.2 - 1 python2 - yaml - 3.12 - 1 ansible - 2.2.0.0 - 1 Taille totale du t é l é chargement : 4 , 15 MiB Taille totale install é e : 38 , 36 MiB :: Proc é der à l ’ installation ? [ O / n ]

Désactiver globalement la géolocalisation dans Firefox

Une fois n’est pas coutume, une astuce pour Firefox qui n’a pas le droit à son propre article (ce qui était arrivé pour les liens Magnet). En effet, par défaut, Firefox vous pose la question chaque fois qu’un site internet demande à utiliser votre position. Mais il n’y a aucune option dans l’interface pour désactiver globalement l’option, ce qui est assez pénible, surtout si vous enchaînez les sites qui ne s’en servent qu’à des fins publicitaires (surtout si comme moi, vous utilisez un bloqueur de pub). C’est donc une fois de plus dans about:config qu’on va modifier l’option :

geo.enabled false 1 geo . enabled false

Désactiver la gestion de l’alimentation au niveau de systemd

En attendant de pouvoir m’équiper pleinement de ce que je veux faire, j’ai ressorti mon vieux laptop pour m’en faire un serveur (sisi c’est possible, j’en avais déjà parlé, souvenez-vous). Mon problème, même en installation Debian minimale il se mettait en veille en rabattant l’écran, ce qui m’est totalement inutile. systemd permet de ne plus s’embêter avec ça :

systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target 1 systemctl mask sleep .target suspend .target hibernate .target hybrid - sleep .target

Cela va remplacer les pointages des liens actuels par /dev/null. Un reboot plus tard, c’est réglé.

Convertir sa clé privée ECDSA pour Filezilla sous Windows

Filezilla supporte l’utilisation de clé SSH au format PPK (celui de PuTTY), et ce même pour les clés ECDSA. Malheureusement, la version « stable » actuelle (0.67) de PuTTYgen ne permet pas d’importer de telles clés. Qu’à cela ne tienne, il suffit de se rabattre sur la version de développement pour faire le boulot. Si vous n’avez pas besoin de PuTTY, mais juste de convertir la clé, vous pouvez juste rapatrier l’utilitaire, il fonctionne en standalone sans problème.

Les doubles crochets pour vos tests dans un script bash

Ils sont super pratiques et permettent non seulement d’utiliser une autre syntaxe pour faire des conditions multiples, mais également écarter des problèmes de types de variables :

[[ $# -ne 1 ]] #(pour tester le nombre de paramètres, sans se soucier si c'est bien un entier et pas une chaine de caractères) 1 [ [ $ # -ne 1 ]] #(pour tester le nombre de paramètres, sans se soucier si c'est bien un entier et pas une chaine de caractères)

Un no-life sur StackOverflow a détaillé les avantages non seulement des crochets, mais aussi des accolades, des parenthèses…

Calculer le poids d’un groupe de fichiers identifiés par find

J’avais besoin de calculer l’espace gagné par un éventuel nettoyage de fichiers de logs Apache de plus d’un an (puisque pour l’instant en France, c’est la limite légale). Compliqué, mais pas impossible, et à combiner différentes recherches je suis arrivé à cette commande :

find . -type f -mtime +365 -print0 | du --files0-from=- -hc | tail -n1 1 find . - type f - mtime + 365 - print0 | du -- files0 - from = - - hc | tail - n1

La suite au prochain épisode comme on dit 🙂

Eh oui, déjà le quatrième épisode de ces astuces en vrac (ah non, en vrac, ce sont les liens), de celles qui n’ont pas nécessairement besoin d’un article dédié. On en trouve des petites conneries à faire dans plein de domaines, c’est ça que j’aime bien dans l’informatique.

Empêcher Nginx de rajouter le port quand on redirige une URI vers une autre URI

Quand votre serveur Nginx est derrière un autre proxy comme Varnish ou HAproxy, il est nécessaire de le faire écouter sur un autre port que le 80/443 s’il se trouve sur la même machine. Hors, si vos règles de redirections ne contiennent que des URIs (et pas des URLs, qui indiquent explicitement ou implicitement le port), il va par défaut rajouter le port sur lequel lui écoute, ce qui va évidemment poser des problèmes. Il suffit donc de rajouter la ligne suivante dans votre fichier de configuration :

port_in_redirect off; 1 port_in_redirect off ;

Afficher/surveiller les stats memcache

Pour vérifier le taux d’utilisation de votre instance Memcache, vous pouvez envoyer des commandes par telnet ou en l’occurrence netcat au port d’écoute. En combinant avec l’utilitaire watch, on peut afficher les statistiques rafraîchies en temps réel :

watch "echo stats | nc 127.0.0.1 11211" 1 watch "echo stats | nc 127.0.0.1 11211"

Modifier à la volée un paramètre php (CLI)

Parfois, pour vérifier qu’un paramètre pose problème dans votre fichier de configuration de PHP, vous pouvez tester, en ligne de commande, en modifiant à la volée le paramètre (pour éviter d’impacter le reste du fonctionnement de vos sites si vous avez un fichier commun à tout le monde) :

php -d memory_limit=512M 1 php - d memory_limit = 512M

Désactiver les demandes de notifications dans Firefox

J’ai expliqué comment désactiver les demandes de géolocalisation, si les notifications vous répugnent aussi, vous pouvez les désactiver globalement, dans about:config :

dom.webnotifications.enabled 1 dom . webnotifications . enabled

Vous le passez à false, et voilà. A part qu’après avoir testé, ça fait déconner la version Web de Twitter, alors vous êtes prévenu.

Créer une archive tar.gz au travers d’SSH avec une barre de progression

Cela évite de créer l’archive sur la machine distante avant de la copier (pratique quand on manque de place), et avec une barre de progression, c’est badass :

seboss666@seboss666-pc:~/archive$ sshpi "tar czf - /home/seboss666/web/pastes" |pv -s 1G > pastes_$(date %s).tar.gz 1 seboss666 @ seboss666 - pc : ~ / archive $ sshpi "tar czf - /home/seboss666/web/pastes" | pv - s 1G > pastes_ $ ( date % s ) .tar .gz

Le -s 1G , c’est la taille du dossier, sinon pv n’affiche pas le pourcentage ni le temps restant estimé, seulement la taille transférée, car il ne peut pas la calculer dans le cas présent. Attention, ici avec la compression ça peut s’arrêter avant les 100%, pas de panique. Au pire vous testez l’archive reçue si vous avez peur.

Vérifier la liste des plugins activés dans WordPress

J’ai eu à traiter une erreur fatale sur un WordPress dont le thème dépendait d’un plugin qui s’est avéré être désactivé. Pour vérifier la liste quand on a pas accès au backoffice mais qu’on a accès à la BDD, une seule requête suffit (pas la peine d’en rajouter) :

SELECT * FROM wp_options WHERE option_name = 'active_plugins'; 1 SELECT * FROM wp_options WHERE option_name = 'active_plugins' ;

Et si vous avez un a:0:{} comme valeur, vous avez un gros problème.

Faire un diff de fichier au travers d’SSH

J’ai eu un doute sur la liste de fichiers à livrer fournie par un client entre sa plateforme de recette et son site de production. Pour comparer le fichier qui m’intriguait, j’ai procédé de cette façon :

diff /var/www/index.php <(ssh 192.168.1.25 'cat /var/www/index.php') 1 diff / var / www / index .php < ( ssh 192.168.1.25 'cat /var/www/index.php' )

Dans mon cas, la seule différence était des lignes vides, étrange mais pas grave, ouf.

Importer un dump MySQL/MariaDB au travers d’SSH en une seule commande

Lors de la migration des données d’un client vers la nouvelle machine, vous avez rsync pour les fichiers, mais pas pour les bases. Dans ce cas, vous pouvez passer par mysqldump au travers d’SSH, et injecter directement, le tout en une seule ligne :

ssh -C 192.168.1.20 mysqldump --defaults-file=/etc/my-client.cnf -Q -B --opt wordpressdb | mysql wordpressdb 1 ssh - C 192.168.1.20 mysqldump -- defaults - file = / etc / my - client .cnf - Q - B -- opt wordpressdb | mysql wordpressdb

Valider la syntaxe YAML d’un playbook Ansible avant de l’exécuter

Le YAML c’est sympa, Ansible c’est le pied, mais quand vous avez du mal à faire fonctionner les deux ensemble, vous pouvez tomber sur un laconique « ERROR! Syntax Error while loading YAML. » Sans plus de détails. Depuis peu, j’utilise yamllint qui permet de faire du check de configuration et d’indiquer clairement les erreurs de syntaxe (la plus courante étant l’indentation je pense). Exemple :

[seboss666@seboss666-pc ~/dev/yamllint ]$ yamllint rhel.yaml rhel.yaml 1:1 warning missing document start "---" (document-start) 2:11 warning truthy value is not quoted (truthy) 1 2 3 4 [ seboss666 @ seboss666 - pc ~ / dev / yamllint ] $ yamllint rhel .yaml rhel .yaml 1 : 1 warning missing document start "---" ( document - start ) 2 : 11 warning truthy value is not quoted ( truthy )

C’est pas mieux comme ça ?

Lancer des commandes bash depuis l’invite de commandes MySQL

Ça arrive parfois : on veut vérifier un truc côté OS alors qu’on est dans une session MySQL (genre le chemin d’un fichier à sourcer). On a alors le choix : sortir de la session, ça peut vite s’avérer chiant, ouvrir une deuxième console en parallèle. Et puis il y a la dernière solution, plus intéressante, de lancer directement des commandes depuis le shell MySQL :

mysql> \! ls -l total 4 drwxr-xr-x 2 root root 4096 Jan 26 15:41 2017 mysql> 1 2 3 4 mysql > \ ! ls - l total 4 drwxr - xr - x 2 root root 4096 Jan 26 15 : 41 2017 mysql >

On peut même relancer une instance de bash, dès qu’on en sort on revient automatiquement dans MySQL. C’est pas cool ça ?

Allez, c’est tout pour aujourd’hui, si j’en trouve d’autres des petites astuces vous aurez droit à un nouveau numéro. Nul doute que ça arrivera 🙂

Encore une flopée de bricoles diverses à réutiliser au besoin. Manifestement ça plaît ces articles, et la source est pratiquement intarissable (il y a beaucoup de Vim aujourd’hui). Pourquoi s’en priver dès lors ?

Un ramdisk pour MySQL

Histoire de soulager un peu le disque d’un client qui fait de la merde avec sa base de données (requêtes SELECT DISTINCT qui créent systématiquement des tables temporaires sur disque), j’ai déplacé le dossier temporaire de MySQL en RAM, avec une ligne dans fstab :

tmpfs /home/mysql/tmp/ tmpfs defaults 0 0 1 tmpfs / home / mysql / tmp / tmpfs defaults 0 0

Attention, il faut couper MySQL, monter le dossier, et relancer.

Cloner une base PostgreSQL

Plutôt que faire un dump, créer la base et réimporter le dump, sous Postgres on peut dire d’utiliser une base comme modèle :

CREATE DATABASE db_copie TEMPLATE db_source; 1 CREATE DATABASE db_copie TEMPLATE db_source;

Et paf, 10 minutes de gagnées sur un client.

Installer la libdvdcss sur Ubuntu

J’ai découvert lors du dernier PSL auquel j’ai participé (je suis un rythme d’un mois sur deux…) que la libdvdcss, composant indispensable à la lecture des DVD du commerce (protection anticopie gnagnagna), n’était plus installé ni installable facilement sous Ubuntu. Voici donc les manips à faire :

Sur Ubuntu 12.04 à 15.04 : Terminal, se rendre dans le dossier /usr/share/doc/libdvdread4 , et exécuter le script install-css.sh

, et exécuter le script Sur Ubuntu 15.04 et suivants : installer le paquet libdvd-pkg , et lancer dpkg-reconfigure libdvd-pkg en suivant les instructions à l’écran.

Un bon retour en arrière pour l’utilisation par les débutants, une fois de plus.

Ouvrir directement un fichier de conf depuis un autre fichier dans vim

(Merci Kooshal) Quand on édite un fichier de configuration avec vim et qu’on tombe sur un include vers un autre fichier de configuration on peut directement ouvrir celui-ci, par exemple :

Phpconf=/etc/php/php.ini 1 Phpconf = / etc / php / php . ini

On déplace le curseur sur le fichier /etc/php/php.ini, ensuite on appuie sur g puis f , et paf, ça fait des Chocapic. Pour retourner au fichier original, Ctrl+o .

Ajouter la liste des paramètres externes dans un script bash perso

Quand vous utilisez des alias, c’est cool, il interprète directement les paramètres supplémentaires occasionnels que vous voulez lui passer (exemple avec mes alias SSH quand je veux ouvrir un tunnel en plus pour faire du SOCKS : sshvox -D 9999 , sshvox étant un alias assez dégueulasse au demeurant). Quand on utilise un script pour faire la même chose (genre celui que j’utilise pour lancer un playbook Ansible), on peut se retourner vers $@ :

ansible-playbook -i hosts playbook.yml --sudo $@ 1 ansible - playbook - i hosts playbook .yml -- sudo $ @

Évidemment, c’est du rapide/crade, en théorie il faudrait vérifier un peu les arguments. Dans un vieux script pour un serveur Call of Duty, j’ai utilisé $*, qui semble fonctionner aussi, la différence semble tenir dans le fait que $@ échappe certains caractères spéciaux, à vous de voir donc.

Vim : se rendre directement à une ligne

Plusieurs méthodes rapides plutôt que de compter : soit vim <fichier> +<n° ligne> , soit dans l’éditeur taper le numéro de ligne puis G (majuscule). Sinon, pour s’éviter de compter, on a aussi l’option ‘set nu’ pour afficher les numéros de ligne 😉

Afficher la collation par défaut d’une base

Parce que ça n’apparaît pas dans un show create database <base> :

SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'db_name'; 1 2 SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'db_name' ;

Obtenir un shell de manière détournée avec Vim

Sur le serveur d’un client, le compte qu’on nous a attribué a le droit d’utiliser sudo, mais pas de faire un sudo su pour s’éviter justement de passer son temps à taper le sésame. Petit détournement de vim, qu’on ouvre avec sudo (sans fichier), on tape ensuite :shell , et hop, un bash avec les droits root 😛

Lancer une commande watch au travers d’SSH

Je souhaitais surveiller le remplissage d’un dossier mais avec une seule commande. Le problème, c’est qu’au départ je tombais sur une erreur « Error opening terminal: unknown. » particulièrement pas explicite. La solution réside dans un simple -t :

ssh -t 192.168.1.200 "watch ls -lah ~/Download" 1 ssh - t 192.168.1.200 "watch ls -lah ~/Download"

Afficher la n-ième ligne d’un fichier

Quand vous avez un boulet qui vous dit :

[s.verdet@SebLBNvm ~ ]$ named-checkzone -d domain.tld ./domain.tld loading "domain.tld" from "./domain.tld" class "IN" dns_master_load: ./domain.tld:15: subdomain.domain.tld: CNAME and other data zone domain.tld/IN: loading from master file ./domain.tld failed: CNAME and other data zone domain.tld/IN: not loaded due to errors. 1 2 3 4 5 [ s .verdet @ SebLBNvm ~ ] $ named - checkzone - d domain .tld . / domain .tld loading "domain.tld" from "./domain.tld" class "IN" dns_master_load : . / domain .tld : 15 : subdomain .domain .tld : CNAME and other data zone domain .tld / IN : loading from master file . / domain .tld failed : CNAME and other data zone domain .tld / IN : not loaded due to errors .

sed vous permet d’éviter l’enchaînement de head |tail -n1 , et c’est plus rapide à taper en plus :

[s.verdet@SebLBNvm ~ ]$ sed -n "15 p" ./domain.tld subdomain CNAME c.storage.googleapis.com. 1 2 [ s . verdet @ SebLBNvm ~ ] $ sed - n "15 p" . / domain . tld subdomain CNAME c . storage . googleapis . com .

Afficher quelques infos rapides sur des domaines

J’ai pris une liste d’alias de Virtualhosts à vérifier, avant de les migrer sur une autre machine. Petite routine pour voir l’état, à savoir l’adresse IP, le code de retour HTTP, l’URL si c’est redirigé :

for i in $(cat domain-list.txt); do echo "$i ($(dig $i A +short)) : "$(curl -s -o /dev/null -w "%{http_code} %{redirect_url}" $i); done 1 for i in $ ( cat domain - list .txt ) ; do echo "$i ($(dig $i A +short)) : " $ ( curl - s - o / dev / null - w "%{http_code} %{redirect_url}" $i ) ; done

Supprimer le début d’une arborescence d’une archive tar

Si vous avez ce genre d’arborescence dans une archive tar :

$ tar tvf /home/user/archive.tar.gz |head -n1 drwxr-xr-x 499/499 0 2016-12-08 18:29 var/lib/docker/lbp/publish/repository/ 1 2 3 $ tar tvf / home / user / archive .tar .gz | head - n1 drwxr - xr - x 499 / 499 0 2016 - 12 - 08 18 : 29 var / lib / docker / lbp / publish / repository /

Mais que vous voulez juste récupérer le dossier repository, il y a une option bien pratique de tar :

$ tar xfz /home/user/archive.tar.gz --strip-components=5 1 $ tar xfz / home / user / archive .tar .gz -- strip - components = 5

Et hop, la partie var/lib/docker/lbp/publish/ est supprimé à l’extraction.

Extraire directement une archive à travers SSH

Dans le même esprit de la bidouille juste au dessus, j’avais pas assez de place donc l’archive a été extraite directement depuis un autre serveur :

$ cat archive.tar.gz | ssh server2 "tar xzf - -C /path/to/dir" 1 $ cat archive .tar .gz | ssh server2 "tar xzf - -C /path/to/dir"

Accélérer les git status

En changeant de serveur et de version de git, j’ai une différence de x7 sur un git status dans le temps de traitement. Problème résolu en ajoutant le paramètre suivant au dépot :

$ git config core.preloadindex true 1 $ git config core .preloadindex true

Avant, 35s, après, 0.8s. Tranquille.

C’est reparti pour un nouvel épisode de bricoles rapides, de oneliners, de ligne de commandes, de petites configurations, bref, du divers, rien que du divers (mais beaucoup de sysadmin, sinon ça serait pas marrant).

Ajuster le volume audio de la lecture de média dans Firefox

Après avoir souffert des différences de volume et surtout d’un volume max très dérangeant, j’ai trouvé la petite ligne qui va bien dans about:config :

media.default_volume;0.2 1 media . default_volume ;0.2

Tester configuration Apache en ligne

Particulièrement pratique pour les regex, et donc les règles de réécriture, ce site vous permet, en donnant votre bout de configuration et l’URL à tester, de vérifier si « ça matche ».

Whitelist .well-known dans un fichier .htaccess de Drupal pour Let’s Encrypt

En effet, par défaut ce couillon veut vous interdire tout ce qui commence par un « . » . Hors c’est justement par un « . » que commence le dossier dans lequel certbot colle le challenge qui vous permettra de générer un certificat X509 de Let’s Encrypt. IL faut donc faire la modification suivante dans le fichier .htaccess :

#RewriteRule "(^|/)\." - [F] RewriteRule "(^|/)\.(?!well-known/)" - [F] 1 2 #RewriteRule "(^|/)\." - [F] RewriteRule "(^|/)\.(?!well-known/)" - [F]

Merci Djerfy pour le coup de main 😉

grep en PowerShell

Oui j’ai eu à chercher un contenu dans un fichier, et si sous Linux on a le puissant grep, sous PowerShell c’est moins sexy, mais ça marche aussi :

Get-Content .\doc.txt | Select-String -Pattern (Get-Content .\regex.txt) 1 Get-Content . \ doc . txt | Select-String -Pattern ( Get-Content . \ regex . txt )

Sauvegarder un contenu de top dans un fichier de log

Pour un petit script de diagnostic, je voulais enregistrer, en plus du processlist de mysql, le contenu de top. Mais c’est pas si facile que ça, notamment si on veut conserver le formatage :

echo -ne "$(top -n 1 -b -o %CPU)

" >>$logfile 1 echo - ne "$(top -n 1 -b -o %CPU)

" >> $logfile

yum : installer depuis une liste texte

Pour le déploiement d’une machine client, on me transmet une liste de paquets sous CentOS à installer pour qu’il puisse procéder à l’installation de son application (un ERP en l’occurrence). Plutôt que de tout taper, on peut coller la liste dans un fichier et la passer à yum :

xargs yum -y install < package_list 1 xargs yum - y install < package_list

Vérifier la taille d’une table MySQL

Lors d’un incident récemment j’ai eu le droit, sur un slave MySQL, à l’erreur suivante :

Last_SQL_Error: Error 'The table 'cache_form' is full' on query 1 Last_SQL_Error: Error 'The table ' cache_form ' is full' on query

Avant de faire du flush ou de pester contre un manque potentiel d’espace disque ou d’inodes (qui ont de grandes chances de ne pas être en cause), vous pouvez utiliser la requête suivante pour calculer la taille de la table :

SELECT table_name AS `Table`, round(((data_length + index_length) / 1024 / 1024), 2) `Size in MB` FROM information_schema.TABLES WHERE table_schema = "database" AND table_name = "cache_form"; +------------+------------+ | Table | Size in MB | +------------+------------+ | cache_form | 1063.39 | +------------+------------+ 1 2 3 4 5 6 7 8 9 10 11 12 SELECT table_name AS ` Table `, round (((data_length + index_length) / 1024 / 1024), 2) `Size in MB` FROM information_schema. TABLES WHERE table_schema = "database" AND table_name = "cache_form" ; +------------+------------+ | Table | Size in MB | +------------+------------+ | cache_form | 1063.39 | +------------+------------+

En effet Houston, on a un problème. Dans le cas présent, c’était un Drupal qui a rempli sa table de cache, le gigot étant la taille limite autorisée par innoDB sur l’installation en cours (taille du fichier sur disque). Et ça a joliment pété une réplication qui après clean de la table et relance, a mis une bonne heure pour rattraper son retard.

Aider les gens à ne plus taper sl au lieu de ls

il existe un petit paquet à installer chez les débutants pour qu’ils apprennent à taper ls au lieu de sl (ce qui peut arriver si on va trop vite). Le résultat est drôle à voir, je vous laisse tester :

#Debian/Ubuntu sudo apt install sl #RedHat/CentOS sudo yum install sl --enablerepo=epel #Arch/Manjaro sudo pacman -S sl 1 2 3 4 5 6 7 8 #Debian/Ubuntu sudo apt install sl #RedHat/CentOS sudo yum install sl -- enablerepo = epel #Arch/Manjaro sudo pacman - S sl

Y’a même quelques options (fouillez la page de manuel).

J’aime mon métier. On est jamais une semaine sans faire quelque chose de nouveau, de bricoler certaines commandes, de gagner du temps dans l’absolu, de devoir contourner une limitation bizarre. Bref, vous l’avez compris, y’a toujours des choses à apprendre, et il serait idiot de ne pas partager tout ça.

Nettoyer les fichiers temporaires de Rsync

Après un rsync foireux (sans utiliser –append-verify), beaucoup de fichiers partiels sont restés sur le serveur de destination. Ce sont de simples fichiers cachés, pour les nettoyer, c’est pas compliqué :

find /dir/to/search/ -type f -iname ".*" -ls 1 find / dir / to / search / - type f - iname ".*" - ls

Attention toutefois si des fichiers cachés légitimes se trouvent dans ces dossiers (.htaccess par exemple).

Synchroniser uniquement les permissions d’une arborescence depuis un backup

J’ai eu l’occasion de devoir uniquement réparer les permissions d’une arborescence après un chmod 755 malencontreux sur tous les dossiers d’un client (cassant des dépots Git, des traitements automatisés…). Contrairement à ce qu’on pense, ce n’est pas rsync qui va faire le taf à partir du backup :

$ cd /mnt/backup/www $ find . ! -type l -exec chmod -v --reference='{}' /www/'{}' \; $ find . ! -type l -exec chown -v --reference='{}' /www/'{}' \; 1 2 3 $ cd / mnt / backup / www $ find . ! - type l - exec chmod - v -- reference = '{}' / www / '{}' \ ; $ find . ! - type l - exec chown - v -- reference = '{}' / www / '{}' \ ;

Bien évidemment j’ai compris ça après avoir fait mon rsync…

Python/virtualenv : faire en sorte qu’un venv puisse exploiter les modules « globaux »

Un problème que j’ai découvert avec virtualenv, c’est que si on installe un module via le gestionnaire de paquets, donc accessible via tout le système, ce n’est pas le cas pour vos environnements virtuels Python, du moins par défaut. Pour corriger ce petit souci, il faut mettre à jour son environnement avec la commande suivante :

virtualenv --system-site-packages <nom_du_venv> 1 virtualenv -- system - site - packages < nom_du_venv >

Évidemment l’alternative est d’installer le module au sein du virtualenv 😀

Utilisateur en lecture seule pour mysqlump

Un collègue a pensé que le SELECT était suffisant pour un utilisateur en lecture seule destiné à faire des dumps. Il n’était pas si loin :

mysql> GRANT SELECT, LOCK TABLES ON 'user'@'host'; 1 mysql > GRANT SELECT , LOCK TABLES ON 'user' @ 'host' ;

diff au travers d’SSH

Quand vous devez comparer le contenu de deux fichiers, diff est un des outils les plus pratiques pour identifier les points à corriger. Il y a par contre quelques subtilités quand les deux fichiers en question ne se trouvent pas sur le même serveur :

Avec une clé SSH sans passphrase : diff foo <(ssh myServer 'cat foo') Si besoin d'un mot de passe : vimdiff /path/to/file scp://remotehost//path/to/file ssh [login]@[host] "cat [remote file]" | diff - "[local file]" 1 2 3 4 5 6 7 8 Avec une cl é SSH sans passphrase : diff foo < ( ssh myServer 'cat foo' ) Si besoin d ' un mot de passe : vimdiff / path / to / file scp : / / remotehost / / path / to / file ssh [ login ] @ [ host ] "cat [remote file]" | diff - "[local file]"

Vérifier la date d’un certificat SSL/TLS avec OpenSSL

Soit vous utilisez votre navigateur, mais c’est lent (chargement complet du site, plusieurs clics pour afficher le contenu du certificat), un peu plus rapide avec une extension comme Calomel SSL Validation, sinon, inévitablement OpenSSL revient sur le tapis :

[seboss666@SebLBNvm ~ ]$ echo | openssl s_client -servername blog.seboss666.info -connect blog.seboss666.info:443 2>/dev/null | openssl x509 -noout -dates notBefore=Jul 7 00:00:00 2017 GMT notAfter=Sep 5 23:59:59 2019 GMT 1 2 3 [ seboss666 @ SebLBNvm ~ ] $ echo | openssl s_client - servername blog .seboss666 .info - connect blog .seboss666 .info : 443 2 > / dev / null | openssl x509 - noout - dates notBefore = Jul 7 00 : 00 : 00 2017 GMT notAfter = Sep 5 23 : 59 : 59 2019 GMT

Relancer automatiquement la connexion MySQL pour votre API en Python

Je suis en train de réécrire l’API pour collect que j’avais commencé à l’époque, toujours en Python, mais avec Flask au lieu de Bottle, et en conservant la base MySQL plutôt que MongoDB. Mais une chose à laquelle je ne m’attendais pas, c’était que la connexion pourtant persistante que mon application crée lors du lancement finit par être coupée (par MySQL probablement). Et par défaut, il ne la rétablit pas, pour ça, il suffit d’ajouter une petite ligne au début de votre code :

base = mdb.connect('127.0.0.1', 'user', 'pass', 'base') base.ping(True) 1 2 base = mdb .connect ( '127.0.0.1' , 'user' , 'pass' , 'base' ) base .ping ( True )

Drupal : lister les modules installés avec Drush

Le site d’un client m’envoyait les logs Drupal dans /var/log/messages (très, très dégueulasse on est d’accord), en lui demandant de changer ce paramètre l’agence nous dit qu’il n’y a rien à faire côté Drupal. Pas de bol, après un grep dégueu j’ai identifié le module coupable . Mais il y a plus propre avec drush :

[www-data@client-p-web01:~/www/current/src]$ drush @sites pm-list --yes --type=module --status=enabled |grep syslog Core Syslog (syslog) 7.56 1 2 [ www - data @ client - p - web01 : ~ / www / current / src ] $ drush @ sites pm - list -- yes -- type = module -- status = enabled | grep syslog Core Syslog ( syslog ) 7.56

Forcer le type d’un fichier particulier avec Nginx

Quand on peut pas installer le module more_headers, et qu’nginx force application/octet-stream, un simple add_header ne suffit pas, il faut jouer un peu plus :

location /download/ { types { } default_type text/plain; } 1 2 3 4 location / download / { types { } default_type text / plain ; }

Whitelister le dossier .well-known pour Let’s Encrypt sur Nginx

Nginx toujours. Un client a empêché que ses certificats Let’s Encrypt soient renouvelés en ajoutant des règles de sécurité. Combiné avec une redirection forcée vers HTTPS, c’est une catastrophe. Pour empêcher Nginx de me renvoyer lors du challenge ACME, j’ai dû adapter un peu la configuration :

server { listen 80; server_name domain.tld; root /var/www/; location ~ ^/(?!\.well-known) { return 301 https://$server_name$request_uri; } } 1 2 3 4 5 6 7 8 server { listen 80 ; server_name domain . tld ; root / var / www / ; location ~ ^ / ( ? ! \ . well - known ) { return 301 https : / / $ server_name $ request_uri ; } }

Je vous laisse vous torturer l’esprit pour comprendre la regex 😛 Le résultat est là : pas de redirection HTTPS lors du challenge ACME, et le renouvellement a pu se faire.

Comme d’habitude, si vous avez vous aussi des bricoles rapidos comme ça à partager, les commentaires complètent très bien 🙂 (ou au pire envoyez par mail, j’inclue dans un prochain billet en vous citant)

Contrairement à ce que beaucoup de monde a pu constater, il n’a pas été question de ralentir au niveau du boulot. J’ai donc de nouveau un petit batch de bricoles à garder dans un coin si besoin 🙂

Bloquer ICMP timestamp

Lors d’un rapport Qualys VM, j’ai découvert qu’il y avait un aspect d’ICMP qu’il était préférable de bloquer, car devenu inutile : l’ICMP timestamp. Sous Linux, avec iptables on a la possibilité de le faire :

iptables -A input -p icmp --icmp-type timestamp-request -j DROP iptables -A output -p icmp --icmp-type timestamp-reply -j DROP 1 2 iptables - A input - p icmp -- icmp - type timestamp - request - j DROP iptables - A output - p icmp -- icmp - type timestamp - reply - j DROP

J’ai moyennement compris les implications (potentiellement sur de la crypto, mais c’est un peu ancien), je vous laisse chercher.

Erreur au redémarrage de MySQL après une modification de innodb_log_file_size

Si vous faites une telle modification et que ça vous pète à la gueule :

InnoDB: Error: log file ./ib_logfile0 is of different size 0 5242880 bytes InnoDB: than specified in the .cnf file 0 268435456 bytes! 100118 20:52:52 [ERROR] Plugin 'InnoDB' init function returned error. 100118 20:52:52 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed. 100118 20:52:52 [ERROR] Unknown/unsupported table type: InnoDB 100118 20:52:52 [ERROR] Aborting 1 2 3 4 5 6 InnoDB : Error : log file . / ib_logfile0 is of different size 0 5242880 bytes InnoDB : than specified in the .cnf file 0 268435456 bytes ! 100118 20 : 52 : 52 [ ERROR ] Plugin 'InnoDB' init function returned error . 100118 20 : 52 : 52 [ ERROR ] Plugin 'InnoDB' registration as a STORAGE ENGINE failed . 100118 20 : 52 : 52 [ ERROR ] Unknown / unsupported table type : InnoDB 100118 20 : 52 : 52 [ ERROR ] Aborting

Il faut supprimer les fichiers ib_logfile0 et ib_logfile1 qui se trouvent par défaut dans /var/lib/mysql. Ça ira beaucoup mieux, et il recréera automatiquement les fichiers à la nouvelle taille.

Un assistant pour les feignants qui ne font pas leur règle DMARC à la main

Comme moi quoi, voilà si vous avez besoin de mettre en place une telle règle et que votre client ne sait pas comment faire (et vous pas trop), je suis tombé sur ce petit assistant en ligne, qui vous permettra de faire ça simplement.

Calculatrice en ligne de commande

Besoin de faire un calcul rapide, genre un pourcentage, et pas d’interface graphique ni de smartphone sous la main ? Pas grave, tout est prévu sur nos bons vieux OS :

server1:~$ echo 'scale=2;425/500' |bc .85 1 2 server1 : ~ $ echo 'scale=2;425/500' | bc . 85

Pour avoir un aperçu des possibilités de bc, c’est par là (en anglais).

Variable d’environnement sous Nginx

Avec Apache via mod_env, SetEnv permet de définir une variable (souvent utilisé avec certains frameworks comme symfony). Sous Nginx, pour PHP ça se fait via une directive fastcgi_param :

fastcgi_param APP_ENV preprod; 1 fastcgi_param APP_ENV preprod ;

On a ensuite accès à cette variable via la variable $_SERVER['APP_ENV'] .

Importer un dump mysql avec clés étrangères (cas d’un prestashop)

Je ne débattrai pas aujourd’hui de la saleté que représente Prestashop, mais c’est lui qui m’a amené à m’approcher des clés étrangères dans MySQL (je connaissais le terme, moins leur usage). Si jamais vous faites un dump qui contient des directives drop table if exists , ça gueulera à l’import. La solution, désactiver temporairement la vérification des clés étrangères :

SET FOREIGN_KEY_CHECKS=0; SOURCE /pathToFile/backup.sql; SET FOREIGN_KEY_CHECKS=1; 1 2 3 SET FOREIGN_KEY_CHECKS = 0; SOURCE /pathToFile / backup . sql ; SET FOREIGN_KEY_CHECKS = 1;

Rediriger un domaine spécifique vers HTTPS sur haproxy

Haproxy est particulièrement souple à l’usage, j’ai occasionnellement l’opportunité de m’en rendre compte. Dernièrement, sur une IP qui doit porter plusieurs sites, je devais effectuer une redirection HTTPS uniquement pour un domaine en particulier. Voici la configuration et les directives que j’ai utilisé :

frontend VIP-CLIENT-1 bind 1.2.3.4:80 bind 1.2.3.4:443 ssl crt /etc/haproxy/ssl/bundle-client.pem mode http http-request add-header X-Forwarded-Proto https if { ssl_fc } redirect scheme https code 301 if { hdr(Host) -i domain.tld } !{ ssl_fc } default_backend BACKEND-CLIENT-1 1 2 3 4 5 6 7 frontend VIP - CLIENT - 1 bind 1.2.3.4 : 80 bind 1.2.3.4 : 443 ssl crt / etc / haproxy / ssl / bundle - client . pem mode http http - request add - header X - Forwarded - Proto https if { ssl_fc } redirect scheme https code 301 if { hdr ( Host ) - i domain . tld } ! { ssl_fc } default_backend BACKEND - CLIENT - 1

Pourquoi le faire au niveau d’Haproxy ? Toujours gérer ce genre de redirection au plus haut de la chaîne de connexion.

Extraire le log git pour un dossier particulier

Un client qui gérait tous ses sites au sein d’un même dépôt git (c’est très con, on est d’accord), cherche malgré tout à conserver un historique des modifications effectuées à une arborescence précise. S’il est impossible de réimporter tout l’historique (ou alors j’ai pas encore trouvé), en manipulant les options de git log on peut arriver à peu près à un gros journal :

server1:/home/www/site1$ git log --oneline --decorate --full-diff --full-history --no-abbrev-commit -p ./ > /home/git_log_site1.log 1 server1 : / home / www / site1 $ git log -- oneline -- decorate -- full - diff -- full - history -- no - abbrev - commit - p . / > / home / git_log_site1 .log

Dans mon cas, ça a donné un gros bousin de 500M.

Vérifier la propagation DNS à travers le monde

Sans prendre en considération les problèmes divers de cache qui se posent régulièrement, il est tout de même possible de vérifier si une modification de zone a bien été prise en compte pour une grande partie du monde, grâce à ce service bien pratique.

Récupérer les infos techniques d’une IP au format JSON

Encore un autre service en ligne bien pratique, gratuit dans une certaine mesure (le service n’est pas libre), permet d’identifier rapidement via curl l’origine d’une IP trouvée dans des logs web par exemple :

root@vox:~# curl ipinfo.io/91.121.61.180 { "ip": "91.121.61.180", "hostname": "vox.clantoc.org", "city": "", "region": "", "country": "FR", "loc": "48.8582,2.3387", "org": "AS16276 OVH SAS" } 1 2 3 4 5 6 7 8 9 10 root @ vox : ~ # curl ipinfo.io/91.121.61.180 { "ip" : "91.121.61.180" , "hostname" : "vox.clantoc.org" , "city" : "" , "region" : "" , "country" : "FR" , "loc" : "48.8582,2.3387" , "org" : "AS16276 OVH SAS" }

Vous découvrirez des choses étonnantes parfois (serveurs compromis, clients infectés, robots d’indexation étranges…).

Certaines des astuces que je partage dans cette série sont anciennes, juste je n’avais pas pensé à les poser là avant, ou bien je viens seulement de les découvrir et de commencer à les utiliser. Dans tous les cas, j’adore ce métier vivant où l’on apprend des choses tous les jours 🙂

Désactiver l’ouverture d’un onglet avec une URL par le bouton du milieu dans Firefox

Une opération qui n’existe que sous Linux, et que Mozilla considérait plus logique, le bouton du milieu étant traditionnellement associé à l’opération « coller »; Mozilla allait plus loin en ouvrant un nouvel onglet et en chargeant l’URL présente dans le presse-papier. Si ce comportement va être désactivé pour les nouveaux à partir de Firefox 57 (ce n’est pas le seul changement), il est possible d’ores-et-déjà de s’en occuper manuellement via about:config :

middlemouse.contentLoadURL;false (défaut:true) 1 middlemouse . contentLoadURL ; false ( d é faut : true )

Mais pourquoi je découvre ça aussi tard ?

Fusionner une liste de vidéos avec ffmpeg sans réencoder

Trois morceaux, dans le même format, que j’avais besoin de recoller, si possible sans réencoder. ffmpeg sait heureusement le faire, pour ça il faut créer une liste de fichiers au préalable :

$ cat mylist.txt file '/path/to/file1' file '/path/to/file2' file '/path/to/file3' $ ffmpeg -f concat -i mylist.txt -c copy output 1 2 3 4 5 6 $ cat mylist .txt file '/path/to/file1' file '/path/to/file2' file '/path/to/file3' $ ffmpeg - f concat - i mylist .txt - c copy output

Tada !

Désactiver l’envoi de statistiques de votre base influxdb chez influxdata.com

Le pétrole du 21° siècle, que tout le monde collecte par tous les moyens possibles, souvent sans vous prévenir ni vous demander la permission. J’ai pu découvrir en réinstallant influxdb qu’il envoyait des statistiques à la maison mère sans m’avoir consulté auparavant, à part un commentaire dans le fichier de configuration :

sept. 10 12:03:11 raspberrypi influxd[377]: [I] 2017-09-10T10:03:11Z Storing statistics in database '_internal' retention policy 'monitor', at interval 10s service=monitor sept. 10 12:03:11 raspberrypi influxd[377]: [I] 2017-09-10T10:03:11Z Sending usage statistics to usage.influxdata.com sept. 10 12:03:16 raspberrypi influxd[377]: [httpd] ::1 - telegraf [10/Sep/2017:12:03:16 +0200] "POST /write?consistency=any&db=telegraf&rp=default HTTP/1.1" 204 0 "-" "-" 43b0934c-960f-11e7-8001-000000000000 756847 1 2 3 sept . 10 12 : 03 : 11 raspberrypi influxd [ 377 ] : [ I ] 2017 - 09 - 10T10 : 03 : 11Z Storing statistics in database '_internal' retention policy 'monitor' , at interval 10s service = monitor sept . 10 12 : 03 : 11 raspberrypi influxd [ 377 ] : [ I ] 2017 - 09 - 10T10 : 03 : 11Z Sending usage statistics to usage . influxdata . com sept . 10 12 : 03 : 16 raspberrypi influxd [ 377 ] : [ httpd ] :: 1 - telegraf [ 10 / Sep / 2017 : 12 : 03 : 16 + 0200 ] "POST /write?consistency=any&db=telegraf&rp=default HTTP/1.1" 204 0 "-" "-" 43b0934c - 960f - 11e7 - 8001 - 000000000000 756847

Bien qu’en théorie les informations collectées ne sont pas sensibles en soi, Il est fort heureusement possible de désactiver ce comportement douteux avec une ligne dans le fichier de configuration :

reporting-disabled = true 1 reporting - disabled = true

Pensez évidemment à redémarrer le service.

Remplacer les espaces par des underscores dans les noms de fichiers

En lien avec la fusion des vidéos présentée jsute au dessus, j’ai rencontré un problème avec des espaces dans les noms de fichier. Comme c’est de toute façon le mal (ça et les accents), on peut remplacer ces espaces par des underscores :

find . -type f -name "* *.webm" -exec bash -c 'mv "$0" "${0// /_}"' {} \; 1 find . - type f - name "* *.webm" - exec bash - c 'mv "$0" "${0// /_}"' { } \ ;

J’adore ce format de remplacement à la volée.

Historique illimité dans Bash

Je suis en effet souvent frustré de pas me souvenir dans le détail d’une commande mais de pouvoir la retrouver dans l’historique. Seulement par défaut la longueur de l’historique est assez courte, et il y a la possibilité de le rendre illimité/permanent en paramétrant ces deux variable d’environnement de la sorte :

HISTSIZE= HISTFILESIZE= 1 2 HISTSIZE = HISTFILESIZE =

Convertir un jeu de png en jpg en renommant l’extension au passage

J’ai procédé à une série de captures d’écran pour une analyse poussée des données de Piwik (que j’ai pas sorti parce que j’ai un vieux bug à l’écriture de l’article, mais passons). Ces captures sont au format png, et je peux économiser en passant au format jpg. On peut faire ça avec un one-liner :

for i in $(ls piwik*.png); do convert $i -flatten -background white -quality 80 ${i//.png/.jpg}; done 1 for i in $ ( ls piwik * .png ) ; do convert $i - flatten - background white - quality 80 $ { i / / .png / .jpg } ; done

On retrouve le modèle de substitution à la volée de tout à l’heure pour les espaces 🙂

Apache : transférer l’authentification HTTP à PHP

Une agence m’a tanné parce que l’authentification Basic ne fonctionnait pas sur l’API de leur WordPress utilisée par leur application mobile. Je ne vais pas m’étendre sur la pertinence du Basic en contexte application mobile, mais il faut savoir que si c’est PHP qui génère le 401, Apache va se réserver l’entête. Pour tout de même le passer, à PHP, une seule ligne suffit, pas la peine d’en rajouter :

SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 1 SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION = $1

Évidemment, personne ne le savait, et ils partaient du principe que si leur environnement de dev fonctionnait comme ça, c’était valable pour la terre entière. Et on me demande pourquoi j’ai du mal avec les devs…

LFTP pour faire du transfert SFTP récursif

Objectif : envoyer un dossier de 14Go sur un serveur distant dont la fonction SFTP est remplie par CoreFTP, et OpenSSH ne supporte pas bien. Je suis passé par lftp :

lftp sftp://login:password@1.2.3.4 -e mirror -R intranet/ ; bye 1 lftp sftp : / / login : password @ 1.2.3.4 - e mirror - R intranet / ; bye

Le mode miroir fonctionne comme un rsync 🙂

Compter le détail des threads d’un processus

Pendant qu’on essayait de comprendre pourquoi une instance Logstash loadait sa race sur VM Azure, un intervenant m’a sorti une commande bien pratique pour vérifier ce qui était lancé par le process :

$ ps -T -p 31298 | cut -f 12 -d ' ' | sort | uniq -c 1 19 java 2 LogStash::Runne 8 [main]<azureblo 27 [main]<azurewad 6845 [main]<wadeph 1 [main]>worker0 1 [main]>worker1 1 [main]>worker2 1 [main]>worker3 7 pipeline.main 1 2 3 4 5 6 7 8 9 10 11 12 $ ps - T - p 31298 | cut - f 12 - d ' ' | sort | uniq - c 1 19 java 2 LogStash :: Runne 8 [ main ] < azureblo 27 [ main ] < azurewad 6845 [ main ] < wadeph 1 [ main ] > worker0 1 [ main ] > worker1 1 [ main ] > worker2 1 [ main ] > worker3 7 pipeline .main

Oui, plus de 6000 threads pour un des plugins. On comprend mieux le load…

Stocker la liste des fichiers d’un dossier sur une seule ligne

Pour exploiter une liste de fichiers dans une commande lftp mput , j’avais besoin de garder tous les fichiers sur la même ligne. ls -x n’ayant pas aidé sur un grosse liste, j’ai du passer autrement, et j’ai trouvé ceci :

filelist=$(ls | xargs) 1 filelist = $ ( ls | xargs )

Aussi simple que ça.

A bientôt pour de nouvelles aventures 🙂

Il serait criminel de terminer l’année sans vous filer une dernière tournée d’astuces à coller sous le sapin numérique que vous avez certainement quelque part 🙂 Comme toujours, à garder dans un coin de votre mémoire ou de votre wiki personnel (ou un simple marque-pages Firefox, ça fonctionne aussi mais c’est moins facile à chercher).

Convertir une vidéo en série d’images

Un petit défi trouvé je ne sais plus où : retrouver une image précise, dans une vidéo où celles-ci défilent très vite. Plutôt que de m’emmerder à lire au ralenti, à repasser 50 fois en espérant voir quelque chose, il « suffit » de convertir et de générer un fichier image par image de vidéo. Pour ça, il faut extraire le nombre de fps de la vidéo en question, et réutiliser ce paramètre pour qu’ffmpeg fasse le boulot :

ffmpeg -i DMdLcMPW4AUQV9t.mp4 -vf fps=27.5 out%d.png 1 ffmpeg - i DMdLcMPW4AUQV9t .mp4 - vf fps = 27.5 out % d .png

On a ensuite autant de fichiers images qu’il y a d’images dans la vidéo, et celle qu’on recherche va forcément apparaître.

L’optimisation d’image rapide pour les pressés

Pour économiser quelques précieux mégaoctets quand on travaille sur un site qui manipule beaucoup d’images, sauf à vouloir faire le traitement au moment de l’upload, on peut le faire après coup :

find . -iname "*.png" -exec optipng -o5 -strip all {} \; find . -iname "*.jpg" -exec jpegoptim -m90 --strip-all {} \; 1 2 3 find . - iname "*.png" - exec optipng - o5 - strip all { } \ ; find . - iname "*.jpg" - exec jpegoptim - m90 -- strip - all { } \ ;

Les deux logiciels sont à installer et sont disponibles dans la plupart des distributions. Petit test rapide sur le dossier wordpress d’un client, passé de 416 à 322Mo. Après, il faut regarder la qualité finale des fichiers pour les jpg qui seront recompressés…

Yaourt : utiliser la puissance du multicœurs pour la compression

J’ai déjà parlé d’AUR et de la puissance de ce système de gestions de paquets (et de ses risques aussi). En voulant réinstaller MARP, j’ai découvert, au delà de la taille aberrante liée à Electron, que la compression du paquet construit se limitait à un seul cœur, et que c’était en particulier la compression qui était en cause. Pour utiliser tous les cœurs disponibles, c’est dans le fichier /etc/yaourtrc qu’il faut se rendre :

COMPRESSXZ=(xz -c -z - --threads=0) #Si gzip, installer pigz puis COMPRESSGZ=(pigz -c -f -n) 1 2 3 COMPRESSXZ = ( xz - c - z - -- threads = 0 ) # Si gzip , installer pigz puis COMPRESSGZ = ( pigz - c - f - n )

A la prochaine installation/mise à jour de paquet, ça devrait être bien plus rapide. Sauf quand votre connexion est merdique…

Asciiart

Je cherche à créer un message sympa pour la connexion SSH à mes serveurs, mais et pour ça, rien de tel qu’un peu d’ascii art. Pour afficher du texte décoré, il y a figlet qui permet de faire quelques trucs sympa.

[seboss666@seboss666-ltp ~ ]$ figlet -f smslant Seboss666 ____ __ ____ ____ ____ / __/__ / / ___ ___ ___ / __// __// __/ _\ \/ -_) _ \/ _ \(_-<(_-</ _ \/ _ \/ _ \ /___/\__/_.__/\___/___/___/\___/\___/\___/ 1 2 3 4 5 [ seboss666 @ seboss666 - ltp ~ ] $ figlet - f smslant Seboss666 ____ __ ____ ____ ____ / __ / __ / / ___ ___ ___ / __ / / __ / / __ / _ \ \ / - _ ) _ \ / _ \ ( _ - < ( _ - < / _ \ / _ \ / _ \ / ___ / \ __ / _ .__ / \ ___ / ___ / ___ / \ ___ / \ ___ / \ ___ /

Vous pouvez vous intéresser à la commande figlist pour avoir une idée des « polices » possibles et faire vos propres tests 🙂

PS : figlet est à installer auparavant évidemment.

REGEX : filtrer only alphanum,_ and –

Celle-là, je la dois en grande partie à Djerfy. Sur le coup, on a pas trouvé mieux, mais ça fonctionne. Je cherchais à filtrer dans un script bash le nom de l’utilisateur saisi pour m’assurer qu’il respecte le format que je voulais, à savoir alphanumérique, underscore et tiret. On a abouti à cette routine :

ISVALID=$(echo ${NEWUSER} | sed "s/[a-zA-Z0-9-]//g;s/_//g") if [ "x" != "x${ISVALID}" ]; then echo -ne "error" fi 1 2 3 4 ISVALID = $ ( echo $ { NEWUSER } | sed "s/[a-zA-Z0-9-]//g;s/_//g" ) if [ "x" != "x${ISVALID}" ] ; then echo - ne "error" fi

Si une brutasse a une meilleure méthode, en sachant que sur la partie sed si on essaie de le faire en une seule fois ça merde, je veux bien un petit partage en commentaire 🙂

Docker : changer la plage d’IP du bridge par défaut

J’ai rencontré un souci après l’installation de Docker sur ma VM Linux au boulot, je n’accédais plus au dépot SVN privé sur lequel nous publions notamment nos clés SSH à déployer sur les milliers de serveurs Linux que nous avons sous notre responsabilité. Il s’avère que c’est l’adresse par défaut du bridge docker0 et surtout la route associée qui n’était pas la bonne. Pour corriger ça, j’ai créé le fichier /etc/docker/daemon.json avec le contenu suivant :

{ "fixed-cidr": "192.168.5.0/24" } 1 2 3 { "fixed-cidr" : "192.168.5.0/24" }

On redémarre ensuite le démon Docker, le bridge a changé d’adresse et de route, joie dans la demeure, les serveurs auront ma nouvelle clé dans la journée 🙂

Remplir un fichier known_hosts pour son service Gogs

Si vous avez lu mon article sur la mise sous Docker de mon service gogs, il ne vous aura pas échappé que le hook du miroir GitHub a un peu été contrarié par le fait que la première fois l’utilisateur git n’a pas enregistré l’identité des serveurs SSH distants. Si j’ai copié un fichier existant, il est également possible, depuis l’hôte Docker, d’utiliser ssh-keyscan :

ssh-keyscan -t rsa github.com >> /home/docker/gogs/git/.ssh/known_hosts 1 ssh - keyscan - t rsa github .com >> / home / docker / gogs / git / .ssh / known_hosts

À répéter deux/trois fois pour choper les trois serveurs. Et c’est valable pour tous les services sur lesquels votre forge doit se connecter.

Gagner quelques secondes en modifiant légèrement votre Dockerfile

Ça révolutionnera pas votre utilisation de Docker, mais en limitant le nombre de commandes RUN, vous limitez la génération d’images intermédiaires et donc gagnez un peu de temps, toujours appréciable si vous enchaînez les « compilations ». Voici ce que je faisais au départ :

RUN apk update RUN add docker RUN pip install --no-cache-dir ovh 1 2 3 RUN apk update RUN add docker RUN pip install -- no - cache - dir ovh

On peut tout regrouper en une seule « étape » :

RUN apk add -U --no-cache docker &&\ pip install --no-cache-dir ovh 1 2 RUN apk add - U -- no - cache docker && \ pip install -- no - cache - dir ovh

Ça ne change absolument rien à la taille potentiellement délirante de votre image évidemment. Pour ça, je vais essayer d’utiliser j’ai utilisé le module Docker, mais la documentation est affreuse (comme trop souvent).

La météo dans son terminal

Très rapide, en couleur en plus, Et si vous avez besoin d’un peu de précision (genre ça vous répond le mauvais Pays), vous pouvez ajouter un ~ devant le nom de la ville pour qu’il tente une localisation :

[seboss666@seboss666-ltp ~ ]$ curl wttr.in/Melun Weather report: Melun, France Overcast .--. 0-4 °C .-( ). ↘ 17 km/h (___.__)__) 10 km 0.0 mm ┌─────────────┐ ┌──────────────────────────────┬───────────────────────┤ Sat 16 Dec ├───────────────────────┬──────────────────────────────┐ │ Morning │ Noon └──────┬──────┘ Evening │ Night │ ├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤ │ \ / Partly cloudy │ Cloudy │ _`/"".-. Light rain sho…│ _`/"".-. Patchy rain po…│ │ _ /"".-. -1-3 °C │ .--. 1-5 °C │ ,\_( ). 1-4 °C │ ,\_( ). 1-4 °C │ │ \_( ). → 12-20 km/h │ .-( ). → 15-22 km/h │ /(___(__) ↗ 13-21 km/h │ /(___(__) ↗ 11-19 km/h │ │ /(___(__) 19 km │ (___.__)__) 18 km │ ‘ ‘ ‘ ‘ 14 km │ ‘ ‘ ‘ ‘ 18 km │ │ 0.0 mm | 0% │ 0.0 mm | 0% │ ‘ ‘ ‘ ‘ 0.3 mm | 58% │ ‘ ‘ ‘ ‘ 0.1 mm | 19% │ └──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘ ┌─────────────┐ ┌──────────────────────────────┬───────────────────────┤ Sun 17 Dec ├───────────────────────┬──────────────────────────────┐ │ Morning │ Noon └──────┬──────┘ Evening │ Night │ ├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤ │ .-. Light drizzle │ .-. Light drizzle │ .-. Light drizzle │ .-. Light rain │ │ ( ). 0-4 °C │ ( ). 2-5 °C │ ( ). 4-6 °C │ ( ). 2 °C │ │ (___(__) ↗ 17-26 km/h │ (___(__) ↗ 19-28 km/h │ (___(__) ↑ 23-36 km/h │ (___(__) ↑ 23-35 km/h │ │ ‘ ‘ ‘ ‘ 20 km │ ‘ ‘ ‘ ‘ 20 km │ ‘ ‘ ‘ ‘ 19 km │ ‘ ‘ ‘ ‘ 20 km │ │ ‘ ‘ ‘ ‘ 0.6 mm | 69% │ ‘ ‘ ‘ ‘ 1.2 mm | 59% │ ‘ ‘ ‘ ‘ 1.4 mm | 75% │ ‘ ‘ ‘ ‘ 1.7 mm | 88% │ └──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘ ┌─────────────┐ ┌──────────────────────────────┬───────────────────────┤ Mon 18 Dec ├───────────────────────┬──────────────────────────────┐ │ Morning │ Noon └──────┬──────┘ Evening │ Night │ ├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤ │ .-. Light rain │ .-. Light drizzle │ \ / Partly cloudy │ \ / Partly cloudy │ │ ( ). 3-6 °C │ ( ). 2-6 °C │ _ /"".-. 1-5 °C │ _ /"".-. 0-3 °C │ │ (___(__) ↘ 19-27 km/h │ (___(__) ↓ 24-32 km/h │ \_( ). ↘ 14-23 km/h │ \_( ). ↘ 13-21 km/h │ │ ‘ ‘ ‘ ‘ 20 km │ ‘ ‘ ‘ ‘ 20 km │ /(___(__) 17 km │ /(___(__) 17 km │ │ ‘ ‘ ‘ ‘ 0.7 mm | 79% │ ‘ ‘ ‘ ‘ 0.2 mm | 69% │ 0.0 mm | 0% │ 0.0 mm | 0% │ └──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 [ seboss666 @ seboss666 - ltp ~ ] $ curl wttr .in / Melun Weather report : Melun , France Overcast . -- . 0 - 4 ° C . - ( ) . ↘ 17 km / h ( ___ .__ ) __ ) 10 km 0.0 mm ┌─────────────┐ ┌──────────────────────────────┬───────────────────────┤ Sat 16 Dec ├───────────────────────┬──────────────────────────────┐ │ Morning │ Noon └──────┬──────┘ Evening │ Night │ ├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤ │ \ / Partly cloudy │ Cloudy │ _ ` / "" . - . Light rain sho …│ _ ` / "" . - . Patchy rain po …│ │ _ / "" . - . - 1 - 3 ° C │ . -- . 1 - 5 ° C │ , \ _ ( ) . 1 - 4 ° C │ , \ _ ( ) . 1 - 4 ° C │ │ \ _ ( ) . → 12 - 20 km / h │ . - ( ) . → 15 - 22 km / h │ / ( ___ ( __ ) ↗ 13 - 21 km / h │ / ( ___ ( __ ) ↗ 11 - 19 km / h │ │ / ( ___ ( __ ) 19 km │ ( ___ .__ ) __ ) 18 km │ ‘ ‘ ‘ ‘ 14 km │ ‘ ‘ ‘ ‘ 18 km │ │ 0.0 mm | 0 % │ 0.0 mm | 0 % │ ‘ ‘ ‘ ‘ 0.3 mm | 58 % │ ‘ ‘ ‘ ‘ 0.1 mm | 19 % │ └──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘ ┌─────────────┐ ┌──────────────────────────────┬───────────────────────┤ Sun 17 Dec ├───────────────────────┬──────────────────────────────┐ │ Morning │ Noon └──────┬──────┘ Evening │ Night │ ├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤ │ . - . Light drizzle │ . - . Light drizzle │ . - . Light drizzle │ . - . Light rain │ │ ( ) . 0 - 4 ° C │ ( ) . 2 - 5 ° C │ ( ) . 4 - 6 ° C │ ( ) . 2 ° C │ │ ( ___ ( __ ) ↗ 17 - 26 km / h │ ( ___ ( __ ) ↗ 19 - 28 km / h │ ( ___ ( __ ) ↑ 23 - 36 km / h │ ( ___ ( __ ) ↑ 23 - 35 km / h │ │ ‘ ‘ ‘ ‘ 20 km │ ‘ ‘ ‘ ‘ 20 km │ ‘ ‘ ‘ ‘ 19 km │ ‘ ‘ ‘ ‘ 20 km │ │ ‘ ‘ ‘ ‘ 0.6 mm | 69 % │ ‘ ‘ ‘ ‘ 1.2 mm | 59 % │ ‘ ‘ ‘ ‘ 1.4 mm | 75 % │ ‘ ‘ ‘ ‘ 1.7 mm | 88 % │ └──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘ ┌─────────────┐ ┌──────────────────────────────┬───────────────────────┤ Mon 18 Dec ├───────────────────────┬──────────────────────────────┐ │ Morning │ Noon └──────┬──────┘ Evening │ Night │ ├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤ │ . - . Light rain │ . - . Light drizzle │ \ / Partly cloudy │ \ / Partly cloudy │ │ ( ) . 3 - 6 ° C │ ( ) . 2 - 6 ° C │ _ / "" . - . 1 - 5 ° C │ _ / "" . - . 0 - 3 ° C │ │ ( ___ ( __ ) ↘ 19 - 27 km / h │ ( ___ ( __ ) ↓ 24 - 32 km / h │ \ _ ( ) . ↘ 14 - 23 km / h │ \ _ ( ) . ↘ 13 - 21 km / h │ │ ‘ ‘ ‘ ‘ 20 km │ ‘ ‘ ‘ ‘ 20 km │ / ( ___ ( __ ) 17 km │ / ( ___ ( __ ) 17 km │ │ ‘ ‘ ‘ ‘ 0.7 mm | 79 % │ ‘ ‘ ‘ ‘ 0.2 mm | 69 % │ 0.0 mm | 0 % │ 0.0 mm | 0 % │ └──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘

Cartographie dans un terminal

Oui, encore un autre service qu’on s’attendait pas à trouver, et pourtant, c’est un truc de dingue :

telnet mapscii.me 1 telnet mapscii .me

Ensuite, on utilise a/z pour zoomer/dézoomer, et les flèches pour se déplacer. Bluffant.

Tribute to Star Wars

Fin d’année oblige, on termine avec quelques petites bricoles en bash qui demandent un écran d’une certaine taille en hauteur, et dans le premier cas l’installation d’ack et de lolcat (dispos dans vos dépôts préférés au moins dans Debian depuis Wheezy). On a donc la première commande :

clear ; while : ; do ack --bar | lolcat --force ; sleep 0.05 ; printf "\e[0;0H" ; done 1 clear ; while : ; do ack -- bar | lolcat -- force ; sleep 0.05 ; printf "\e[0;0H" ; done

Les développeurs doivent s’ennuyer parfois pour cacher ça dans leur code 🙂

Et le bouquet final, la plus délire de ce que j’ai pu voir je pense (après le générique via les reverse IP), raison pour laquelle je vous la donne en dernier, l’épisode 4 en ascii art à portée de telnet :

telnet towel.blinkenlights.nl 1 telnet towel .blinkenlights .nl

C’est un boulot de malade !

On se donne rendez-vous l’année prochaine 😉

J’ai stocké tout ça un peu trop longtemps et il est temps que je partage une nouvelle fournée de bricoles qui vous sauve une journée de boulot, ou un weekend un peu trop accaparé par des soucis ou des maintenances d’infras persos, quand ce n’est pas un dépannage lors d’un PSL 🙂

Coreutils 8.24 et suivants : dd qui cause !

J’ai découvert ça en toute fin d’année, après la finalisation du dernier épisode (et Pierre m’en a reparlé début février quand je suis retourné à la Cité des Sciences). Avec un coreutils récent (Debian Stretch, Ubuntu 16.04, Manjaro/Arch), dd a maintenant un mode verbeux pour dire où il en est, et ça c’est cool :

[seboss666@seboss666-ltp ~/Téléchargements ]$ dd if=manjaro-cinnamon-17.0.6-stable-x86_64.iso of=mcin.iso status=progress 1770226176 bytes (1,8 GB, 1,6 GiB) copied, 14 s, 126 MB/s 1 2 [ seboss666 @ seboss666 - ltp ~ / T é l é chargements ] $ dd if = manjaro - cinnamon - 17.0.6 - stable - x86_64 .iso of = mcin .iso status = progress 1770226176 bytes ( 1 , 8 GB , 1 , 6 GiB ) copied , 14 s , 126 MB / s

Pratique quand on sait que les copies sur clé USB peuvent parfois prendre de longues minutes, surtout avec une clé USB poussive.

Rot13 « quick and dirty » en bash

Lors d’un petit délire sur un challenge de sécurité informatique, l’auteur a trouvé le moyen de s’amuser en ajoutant une petite étape à base de rot13. Quand on est pressé, qu’on a pas forcément le temps de chercher un outil tout fait, y’a moyen de le faire en bash (attention, tr est fourni avec coreutils, merci Exagone313) :

echo 'messagealacon' | tr '[A-Za-z]' '[N-ZA-Mn-za-m]' 1 echo 'messagealacon' | tr '[A-Za-z]' '[N-ZA-Mn-za-m]'

Connexion SFTP avec un client OpenSSH récent et proftpd/mod_sftp

Récemment, le prestataire d’un client rencontrait des difficultés pour se connecter en SFTP à la plateforme de ce dernier. Après vérification, et un énième juron quand aux satanés fanatiques des ordinateurs fruités, il s’avère que le souci venait de proftpd qu’on utilise pour proposer justement la connectivité chiffrée. La solution tient à la modification des Digests :

SFTPDigests hmac-md5 hmac-sha1 hmac-sha2-256 hmac-sha2-512 hmac-ripemd160 hmac-sha1-96 1 SFTPDigests hmac - md5 hmac - sha1 hmac - sha2 - 256 hmac - sha2 - 512 hmac - ripemd160 hmac - sha1 - 96

Exporter les utilisateurs d’un vieux MySQL pour l’importer dans MySQL 5.7

Situation : on me demande de migrer d’un MySQL 5.5 vers MySQL 5.7. Oracle ne supporte que les upgrades de point à point, donc il me faudrait passer par MySQL 5.6. Pas ouf, et comme les bases de ce serveur de dev ne sont pas compliquées, je veux passer par des dumps bases et users à importer ensuite. Problème, Sur les dernières révisions de MySQL 5.7, la création d’utilisateur avec la syntaxe GRANT ... TO <user> IDENTIFIED BY ... ne fonctionne plus. Petite routine maison pour contourner ce problème :

MYSQL_CONN="-uroot -ppassword" mysql ${MYSQL_CONN} --skip-column-names -A -e "SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',host,''';') AS query FROM mysql.user WHERE user NOT IN ('root','pma','phpmyadmin','debian-sys-maint')" | mysql ${MYSQL_CONN} --skip-column-names -A | sed 's/$/;/g' > MySQLUserGrants.sql sed -i.bak 's/GRANT USAGE ON \*\.\* TO/CREATE USER/g' MySQLUserGrants.sql 1 2 3 MYSQL_CONN = "-uroot -ppassword" mysql $ { MYSQL_CONN } -- skip - column - names - A - e "SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',host,''';') AS query FROM mysql.user WHERE user NOT IN ('root','pma','phpmyadmin','debian-sys-maint')" | mysql $ { MYSQL_CONN } -- skip - column - names - A | sed 's/$/;/g' > MySQLUserGrants .sql sed - i .bak 's/GRANT USAGE ON \*\.\* TO/CREATE USER/g' MySQLUserGrants .sql

Et paf, ça fait des Chocapic.

Tunnel SSH en ligne de commande pour connexion MySQL distante

Pour chiffrer une connexion MySQL (qui est en clair par défaut, il faut le souligner), vous avez deux solutions principalement : mettre en place du TLS au niveau de MySQL, mais c’est pas évident, ou, pour du one shot, un tunnel SSH. Sous linux, rapidement :

ssh -L 3306:127.0.0.1:3306 user@server_with_mysql 1 ssh - L 3306 : 127.0.0.1 : 3306 user @ server_with_mysql

Il suffit ensuite de se connecter avec le client mysql en tapant sur son port local :

mysql -h 127.0.0.1 -S 3306 -uuser -p 1 mysql - h 127.0.0.1 - S 3306 - uuser - p

HTTPS, SNI, et Curl sont dans un bateau…

En procédant à des tests sur la bonne installation d’un certificat X509 sur un vhost dont le domaine ne pointe pas encore sur le serveur en question, plutôt que de bricoler du fichier hosts, j’ai préféré utiliser curl, mais il était récalcitrant avec les paramètres « habituels » :

root@vox:~# curl -Iv -H "Host: blog.seboss666.info" https://127.0.0.1 * Rebuilt URL to: https://127.0.0.1/ * Hostname was NOT found in DNS cache * Trying 127.0.0.1... * Connected to 127.0.0.1 (127.0.0.1) port 443 (#0) (...) curl: (51) SSL: certificate subject name 'xxxx.mariz.ovh' does not match target host name '127.0.0.1' 1 2 3 4 5 6 7 root @ vox : ~ # curl -Iv -H "Host: blog.seboss666.info" https://127.0.0.1 * Rebuilt URL to : https : / / 127.0.0.1 / * Hostname was NOT found in DNS cache * Trying 127.0.0.1... * Connected to 127.0.0.1 ( 127.0.0.1 ) port 443 ( #0) ( . . . ) curl : ( 51 ) SSL : certificate subject name 'xxxx.mariz.ovh' does not match target host name '127.0.0.1'

Pas grand chose à voir avec mon vhost. En fait, c’est parce que de cette manière, Curl n’envoie pas d’entête SNI pour indiquer le nom qui doit être validé par le certificat, et dans un contexte avec plusieurs vhosts, cet entête permet de chercher à sélectionner le bon certificat en fonction de l’hôte. Curl sait le faire :

root@vox:~# curl -Iv --resolve blog.seboss666.info:443:127.0.0.1 https://blog.seboss666.info * Added blog.seboss666.info:443:127.0.0.1 to DNS cache * Rebuilt URL to: https://blog.seboss666.info/ * Hostname was found in DNS cache * Trying 127.0.0.1... * Connected to blog.seboss666.info (127.0.0.1) port 443 (#0) (...) HTTP/1.1 200 OK 1 2 3 4 5 6 7 8 root @ vox : ~ # curl -Iv --resolve blog.seboss666.info:443:127.0.0.1 https://blog.seboss666.info * Added blog .seboss666 .info : 443 : 127.0.0.1 to DNS cache * Rebuilt URL to : https : / / blog .seboss666 .info / * Hostname was found in DNS cache * Trying 127.0.0.1... * Connected to blog .seboss666 .info ( 127.0.0.1 ) port 443 ( #0) ( . . . ) HTTP / 1.1 200 OK

Il ne lui manque que la fonction café en fait à curl…

Une meilleure détection de l’état de santé d’un backend dans haproxy

Contexte : par défaut, les checks basiques d’haproxy ne servent qu’à détecter s’il y a toujours un port en écoute au niveau des serveurs de la ferme. Si vous avez deux serveurs et que l’un des deux est à moitié pété (ça écoute toujours mais l’application ne répond plus), vous avez une réponse sur deux qui n’est pas bonne. Pour optimiser ça, on peut faire un peu mieux au niveau de la configuration :

backend mon-backend option httpchk GET /check HTTP/1.1rnHost: www.mondomaine.com <span class="">http-check expect status 200</span> default-server inter 3s fall 3 rise 2 server srv1 10.0.0.1: 80 check server srv2 10.0.0.2: 80 check 1 2 3 4 5 6 backend mon - backend option httpchk GET / check HTTP / 1.1rnHost : www . mondomaine . com < span class = "" > http - check expect status 200 < / span > default - server inter 3s fall 3 rise 2 server srv1 10.0.0.1 : 80 check server srv2 10.0.0.2 : 80 check

Au passage on voit aussi comment modifier les intervalles de vérification pour réellement limiter la visibilité du problème et des dégâts que ça pourrait provoquer.



Curl et Docker : tester un service Swarm en local

J’ai eu le tour sur mon propre cluster ainsi que sur les plateformes de tests fournies lors de ma formation par Treeptik. Une fois mon service déployé, j’essaie de le tester avec curl depuis le nœud où il est déployé, mais ça répond pas. En fait, les deux environnements en question sont paramétrés avec une ipv6, mais le service au sein de docker n’écoute qu’en v4, et ça aussi, curl est capable de s’en accommoder :

curl -4 http://127.0.0.1:8080/ 1 curl - 4 http : / / 127.0.0.1 : 8080 /

Si vous devez tester/forcer en ipv6, utilisez -6 , mais dans mon cas ça ne fonctionnait pas.

Terminator en plein écran dès le lancement

C’est un problème récurrent/chiant que j’ai souvent, le gestionnaire de fenêtres n’enregistre pas les positions des fenêtres quand je les ferme, si bien que je dois les repositionner à chaque lancement (il n’ya guère que Thunderbird qui « tient le coup »). Pour ma machine virtuelle Linux du boulot (et maintenant sur ma grosse bertha à la maison), je lance principalement Terminator, et j’aime bien du coup qu’il prenne toute la place. Après quelques errements liés notamment au fait que je ne connais apparemment pas assez l’anglais, j’ai trouvé la solution en modifiant la commande dans le raccourci :

terminator --maximise 1 terminator -- maximise

Oui, je m’attendais à devoir utiliser --maximize , et apparemment les deux orthographes sont correctes…

Et bien que j’attende généralement une dizaine d’astuces avant de publier, ça fait trop longtemps donc tant pis s’il n’y en a que 9. On essaiera de revenir dans les clous au prochain épisode 🙂

Allez, c’est reparti pour une nouvelle collections de petites bricoles qui facilitent la vie de toux ceux qui bricolent 🙂

Compresser à la volée une image disque

Le problème quand on fait une image d’une partition ou d’un disque, c’est qu’il va tout prendre, les un comme les zéro (pour rappel, tout est binaire à la base). Et si y’a beaucoup de zéro, c’est de l’espace gaspillé; si un disque fait 32Go mais seulement 10 sont utilisés, l’image fera tout de même 32Go. Heureusement on a des outils de compression pour ça, et même certains qu’on peut appeler à la volée à l’aide d’un pipe:

dd if=/dev/sda2 | gzip > /media/disk/sda2-backup-10august09.gz 1 dd if = / dev / sda2 | gzip > / media / disk / sda2 - backup - 10august09.gz

Si le temps d’exécution n’est pas un problème pour vous, vous pouvez également utiliser xz qui sera plus performant mais beaucoup plus lent (on pourrait faire un petit comparatif un jour tiens 🙂 )

Rediriger la sortie d’une commande effectuée avec sudo

Le problème de sudo, c’est qu’il n’applique l’élévation de privilège qu’à la commande en cours et pas à d’éventuelles redirections, ce qui peut s’avérer gênant quand on veut écrire dans un dossier sur lequel on a pas les droits. Dans l’astuce précédente, si on veut avoir le droit d’écrire dans /media/disk (parce que oui parfois ça marche pas bien), on peut englober la commande et sa redirection sur une nouvelle instance de bash :

sudo bash -c "dd if=/dev/sda2 | gzip > /media/disk/sda2-backup-10august09.gz" 1 sudo bash - c "dd if=/dev/sda2 | gzip > /media/disk/sda2-backup-10august09.gz"

Attention cependant, cette nouvelle « session » ne charge peut-être pas tout l’environnement, dans ce cas, préférez des chemins absolus pour les commandes tapées si elles sont dans des chemins non standards.

Let’s Encrypt, Apache, et directive <Limit>

Un client filtre ses accès préprod par IP avec une directive <Limit> contenant une série d’allow et de deny dans le fichier .htaccess à la racine du site. Pour permettre aux serveurs de Let’s Encrypt de contacter le dossier .well-known afin de valider le challenge, j’ai utilisé mod_setenvif :

SetEnvif Request_URI "/.well-known*" lewhitelist <LIMIT> #Whitelist Let's Encrypt Allow from env=lewhitelist 1 2 3 4 SetEnvif Request_URI "/.well-known*" lewhitelist < LIMIT > #Whitelist Let's Encrypt Allow from env = lewhitelist

Pourquoi pas ajouter les IP Let’s Encrypt ? Parce qu’elles ne sont pas fixes (dixit la FAQ) :

What IP addresses does Let’s Encrypt use to validate my web server? We don’t publish a list of IP addresses we use to validate, because they may change at any time. In the future we may validate from multiple IP addresses at once.

Améliorer les performances wifi sous Linux

A la cité des Sciences, mais je pense que ça peut me servir ailleurs, j’ai eu quelques difficultés avec ma carte wifi qui semblait mal conserver un lien avec le point d’accès. Mon dépanneur de Chromebook (avec qui on l’a cassé, j’en ai parlé récemment dans son démontage) m’a filé une astuce, en lien avec la gestion de l’énergie. Il faut passer par l’utilitaire iw (à installer donc) :

$ iw dev wlan0 set power_save off 1 $ iw dev wlan0 set power_save off

Bon par contre, si vous êtes charrette en batterie ça sera peut-être pas recommandé 🙂

Ajouter un fichier swap pour grossir l’espace existant

En attendant de pouvoir empêcher une application de faire de la merde, et d’améliorer un peu la gestion de la mémoire du noyau, un collègue a ajouté un fichier de swap d’un 1Go en plus de la partition existante. Voici la procédure suivie, en mode administrateur :

dd if=/dev/zero of=/swapfile bs=1024 count=1048576 chmod 600 /swapfile mkswap /swapfile swapon /swapfile 1 2 3 4 dd if = / dev / zero of = / swapfile bs = 1024 count = 1048576 chmod 600 / swapfile mkswap / swapfile swapon / swapfile

Vous devriez voir le résultat en direct sur la taille du swap globale. Et si on veut que ça soit persistant, on peut ajouter la ligne suivante au fichier /etc/fstab :

/swapfile none swap sw 0 0 1 / swapfile none swap sw 0 0

Evidemment, ne pas utiliser le swap c’est mieux, mais quand vous avez pas le contrôle de l’application, hein…

Tester un cipher suite en particulier avec openssl

Un client nous demande de modifier le paramètre Diffie-Hellman qui plombe ses notes sur les différents tests SSL/TLS. Je fais la modification mais par défaut en testant openssl va prendre un cipher à base de courbes elliptiques, plus récent et mieux noté, donc je vois pas le résultat :

$ openssl s_client -connect site.client.net:443 -servername site.client.net Peer signing digest: SHA512 Server Temp Key: ECDH, P-256, 256 bits --- SSL handshake has read 4541 bytes and written 471 bytes --- New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 Server public key is 2048 bit 1 2 3 4 5 6 7 8 $ openssl s_client - connect site .client .net : 443 - servername site .client .net Peer signing digest : SHA512 Server Temp Key : ECDH , P - 256 , 256 bits -- - SSL handshake has read 4541 bytes and written 471 bytes -- - New , TLSv1 / SSLv3 , Cipher is ECDHE - RSA - AES128 - GCM - SHA256 Server public key is 2048 bit

Fort heureusement, openssl est plein de ressources et on peut choisir la « qualité » de connexion 🙂

$ openssl s_client -cipher "DHE-RSA-AES256-GCM-SHA384" -connect site.client.net:443 -servername site.client.net Peer signing digest: SHA512 Server Temp Key: DH, 2048 bits --- SSL handshake has read 4983 bytes and written 457 bytes --- New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-GCM-SHA384 Server public key is 2048 bit 1 2 3 4 5 6 7 8 $ openssl s_client - cipher "DHE-RSA-AES256-GCM-SHA384" - connect site .client .net : 443 - servername site .client .net Peer signing digest : SHA512 Server Temp Key : DH , 2048 bits -- - SSL handshake has read 4983 bytes and written 457 bytes -- - New , TLSv1 / SSLv3 , Cipher is DHE - RSA - AES256 - GCM - SHA384 Server public key is 2048 bit

Docker, exporter une image

Dans le cadre d’un cluster DC/OS, un problème avec la registry du client empêchait un container de se redéployer sur un autre nœud qui ne disposait pas de l’image. Fort heureusement, on a un petit contournement pour ça, si on a accès à un nœud ou l’image est déjà là :

#Sur la machine où l'image est présente : $ docker save registry/myimage:lastest | gzip -c > myimage.tgz #Sur la machine qui doit porter le container $ gunzip -c myimage.tgz | docker load 1 2 3 4 5 6 7 #Sur la machine où l'image est présente : $ docker save registry / myimage : lastest | gzip - c > myimage .tgz #Sur la machine qui doit porter le container $ gunzip - c myimage .tgz | docker load

Supprimer le début d’un fichier à partir d’une ligne

J’ai eu à extraire d’un fichier de serveur mail la pièce jointe au format PDF. Dans ce format, la pièce jointe en question est encodée en base64 à la fin du mail. La solution, chercher une ligne de référence à partir de laquelle je conserve tout, et supprime le début. Et on fait ça avec sed :

$ sed -i.bak '1,/application\/pdf/d' fichier_mail 1 $ sed - i .bak '1,/application\/pdf/d' fichier_mail

Un petit vim pour nettoyer quelques lignes superflues, et on peut décoder :

$ base64 -d fichier_mail > cv.pdf $ file cv.pdf $ cv.pdf: PDF document, version 1.5 1 2 3 $ base64 - d fichier_mail > cv .pdf $ file cv .pdf $ cv .pdf : PDF document , version 1.5

Forcer la coloration syntaxique dans vim

Lors de modifications lourdes apportées à un fichier de configuration Apache pour un client (multiples virtualhosts avec le même tronc de directives), j’ai déporté les règles communes dans un fichier à part et je l’inclus dans les différents vhosts. Pour m’assurer que la bonne coloration syntaxique est appliquée quand je charge ce fichier amputé des directives de bases qui permettent la détection automatique, j’ai ajouté une petite ligne au début du fichier :

# vim: filetype=apache 1 # vim : filetype = apache

Attention aux espaces 🙂 Pour savoir tout ce qu’il est possible de faire, vous pouvez vous manger la doc.

Tiret au début d’un nom de fichier

Il y a des gens comme ça sur terre qu’il faudrait brûler, parmi eux ceux qui me collent un tiret au début du nom d’un fichier. Pourquoi ? Ben le tiret en question est couramment utilisé pour désigner des options de commandes, et ça débouche sur ce genre de message d’erreur à la con sur une palanquée de commandes :

[seboss666@seboss666-ltp ~ ]$ mv -fichier-pourri.txt fichier-pourri.txt mv : option invalide -- 'c' Saisissez « mv --help » pour plus d'informations. 1 2 3 [ seboss666 @ seboss666 - ltp ~ ] $ mv - fichier - pourri .txt fichier - pourri .txt mv : option invalide -- 'c' Saisissez « mv -- help » pour plus d ' informations .

Guillemets simples, doubles, rien n’y fait. Pour contourner, il faut que j’utilise une autre astuce, le chemin :

[seboss666@seboss666-ltp ~ ]$ mv ./-fichier-pourri.txt fichier-pourri.txt [seboss666@seboss666-ltp ~ ]$ l fichier-pourri.txt -rw-r--r-- 1 seboss666 seboss666 0 21.04.2018 09:55 fichier-pourri.txt 1 2 3 [ seboss666 @ seboss666 - ltp ~ ] $ mv . / - fichier - pourri .txt fichier - pourri .txt [ seboss666 @ seboss666 - ltp ~ ] $ l fichier - pourri .txt - rw - r -- r -- 1 seboss666 seboss666 0 21.04.2018 09 : 55 fichier - pourri .txt

Deux caractères, une frustration évacuée 🙂

C’est tout pour aujourd’hui, mais je me rend compte d’une chose : j’ai du relire tous les billets précédents pour vérifier que je n’avais pas déjà partagé certaines des astuces présentées ici, et il y a un précédent de doublon. Avec le nombre d’articles qui augmente dans la série, je vais devoir m’organiser pour éviter de perdre du temps et peut-être le votre à l’avenir 🙂

On en apprend tous les jours sur nos systèmes préférés, d’autant plus quand on manipule souvent des installations différentes (c’est pratique le boulot pour ça). Et il est temps de vous livrer une nouvelle tournée 🙂

Xtrabackup et erreur « Too many open files »

« Petite » sauvegarde à faire d’une instance Mysql de 350Go. J’utilise xtrabackup de Percona, outil magnifique mais qui s’est heurté à l’erreur suivante quand lancé avec un utilisateur particulier :

180503 17:44:40 >> log scanned up to (29626811378630) 180503 17:44:41 >> log scanned up to (29626811379886) InnoDB: Operating system error number 24 in a file operation. InnoDB: Error number 24 means 'Too many open files' 1 2 3 4 180503 17 : 44 : 40 >> log scanned up to ( 29626811378630 ) 180503 17 : 44 : 41 >> log scanned up to ( 29626811379886 ) InnoDB : Operating system error number 24 in a file operation . InnoDB : Error number 24 means 'Too many open files'

J’ai du ajouter un petit fichier dans le dossier /etc/security/limits.d/ avec le contenu suivant :

mysql-1 hard nofile 32768 mysql-1 soft nofile 32768 1 2 mysql - 1 hard nofile 32768 mysql - 1 soft nofile 32768

Vous pouvez adapter à vos besoins, pour ma part ça a suffi.

Extlinux, VPS SSD OVH et mauvais noyau au boot

Je suis utilisateur d’un VPS SSD OVH installé initialement en Debian 8 pour le site web de mon équipe « gaming ». Lors du passage de Jessie à Stretch, monsieur continue d’utiliser le noyau 3.16 de Debian Jessie, ce qui n’est pas des plus propres. En fait, l’installation repose sur extlinux au lieu de GRUB (j’ai pas de troll à sortir là-dessus, désolé), et je modifiais le fichier /boot/extlinux/extlinux.conf sans succès. En fait, le fichier à modifier est /extlinux.conf :

default linux timeout 1 label linux kernel boot/vmlinuz append initrd=boot/initrd.img root=/dev/vda1 console=tty0 console=ttyS0,115200 ro quiet 1 2 3 4 5 default linux timeout 1 label linux kernel boot / vmlinuz append initrd = boot / initrd . img root = / dev / vda1 console = tty0 console = ttyS0 , 115200 ro quiet

L’astuce « propre » a été finalement trouvée sur le forum OVH, avec création de liens symboliques pour à priori pouvoir supporter les mises à jour proprement sans impacter la suite des mises à jour.

Afficher les processus qui consomment du Swap

Un serveur tabasse régulièrement son swap sans qu’on aie pour l’instant la cause profonde sachant qu’il a largement de quoi rester en RAM pour bosser. Pour afficher quels processus consomment du swap, on peut utiliser le petit one-liner suivant :

for file in /proc/*/status ; do awk '/VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done | sort -k 2 -n -r | less 1 for file in / proc / * / status ; do awk '/VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file ; done | sort - k 2 - n - r | less

UPDATE: Aeris m’a proposé sur Twitter une version que les nerds qualifieraient de plus élégante, puisque awk fait tout le taf sans la boucle for :

awk '/Name/ {printf $2} /VmSwap/ {print " ",$2}' /proc/*/status |sort -k 2 -n -r |less 1 awk '/Name/ {printf $2} /VmSwap/ {print " ",$2}' / proc / * / status | sort - k 2 - n - r | less

Comparer deux arborescences pour détecter des fichiers modifiés

Une routine crade, lente, mais utile pour tenter de détecter des traces d’attaques sur des fichiers :

find original/ -type d -exec md5sum {} \; |sed -e 's/^original/infected/' |md5sum -c |grep -Ev "OK$" 1 find original / - type d - exec md5sum { } \ ; | sed - e 's/^original/infected/' | md5sum - c | grep - Ev "OK$"

Plus que jamais, pitié, mettez à jour non seulement le CMS lui-même, mais aussi les plugins.

Virtualbox, USB3, erreur bizarre lors du l’ajout d’un disque

Sur le PC du boulot, Full USB3, je dois brancher un disque dur externe à la VM Virtualbox, je me prend un joli fail :

En fait, il faut faire attention au type de contrôleur dans la configuration de la VM (nécessite le pack d’extensions à la licence limite) :

Faut mettre full USB3 pour tout le monde, et ça marche beaucoup mieux curieusement 🙂

« Le nom de fichier est trop long ou invalide » sous Windows

Ceci est la source de l’astuce précédente. Un dossier de série à transférer (bouh pirate toussa), certains titres contiennent des « ? », pas surprenant le disque a toujours été manipulé sous Linux. Sous Windows pas de solutions, je suis passé sous Linux, en ligne de commande pour filtrer uniquement ces épisodes-là :

[seboss666@SebLBNvm /media/veracrypt1/Multimédia/Vidéos/Séries/Dragon Ball Z ]$ find . -name "*\?*" ./083 Doit-on sauver Vegeta ?.mkv ./087 Sangoku tiendra-t-il sa promesse ?.mkv ./121 Qui est ce mystérieux guerrier ?.mkv ./131 Qui sont les cyborgs ?.mkv ./166 Pourquoi un tournoi ?.mkv [seboss666@SebLBNvm /media/veracrypt1/Multimédia/Vidéos/Séries/Dragon Ball Z ]$ find . -name "*\?*" -exec cp {} /media/seboss666/Stockage_Externe/Séries/DBZ/ \; 1 2 3 4 5 6 7 8 [ seboss666 @ SebLBNvm / media / veracrypt1 / Multim é dia / Vid é os / S é ries / Dragon Ball Z ] $ find . - name "*\?*" . / 083 Doit - on sauver Vegeta ? .mkv . / 087 Sangoku tiendra - t - il sa promesse ? .mkv . / 121 Qui est ce myst é rieux guerrier ? .mkv . / 131 Qui sont les cyborgs ? .mkv . / 166 Pourquoi un tournoi ? .mkv [ seboss666 @ SebLBNvm / media / veracrypt1 / Multim é dia / Vid é os / S é ries / Dragon Ball Z ] $ find . - name "*\?*" - exec cp { } / media / seboss666 / Stockage_Externe / S é ries / DBZ / \ ;

Tada ! C’est chiant Windows. Ceci dit, Thunar m’a sorti la même erreur une fois arrivé sur mon laptop (probablement le NAS ce coup-ci, à tout le moins le CIFS). J’ai pas cherché à comprendre, j’ai renommé les fichiers avant de les transférer #PayeTaFlemme

Fusion d’images avec ImageMagick

Pour le journal de bord de mes vacances, j’ai pris deux photos d’une carte de visite d’un restaurant que je recommande volontiers si vous vous baladez un jour à Roses. Deux problèmes, les photos sont à la verticale et j’aimerais les fusionner. J’aurais pu perdre du temps dans le GIMP nouvelle génération mais j’ai voulu plutôt bricoler en ligne de commande :

convert carte_visite_resto_1.jpg -rotate 270 carte_visite_resto_1_rotated.jpg convert carte_visite_resto_2.jpg -rotate 270 carte_visite_resto_2_rotated.jpg montage carte_visite_resto_*rotated.jpg -tile x1 -geometry +0+0 carte_visite_resto.jpg convert carte_visite_resto.jpg -resize 1920x1080 -quality 85 carte_visite_resto_resized.jpg 1 2 3 4 convert carte_visite_resto_1 .jpg - rotate 270 carte_visite_resto_1_rotated .jpg convert carte_visite_resto_2 .jpg - rotate 270 carte_visite_resto_2_rotated .jpg montage carte_visite_resto_ * rotated .jpg - tile x1 - geometry + 0 + 0 carte_visite_resto .jpg convert carte_visite_resto .jpg - resize 1920x1080 - quality 85 carte_visite_resto_resized .jpg

C’était beaucoup plus rapide que de faire ça avec le touchpad 🙂

Lancer vlc avec l’utilisateur root

Par défaut pas le droit, mais c’est possible avec un hack dégueu :

sed -i 's/geteuid/getppid/' /usr/bin/vlc 1 sed - i 's/geteuid/getppid/' / usr / bin / vlc

Évidemment je recommande pas la modification de binaires à la volée, surtout que ça sautera à la prochaine mise à jour…

Désactiver les rétroliens sur vos articles WordPress

Grosse méthode de bourrin, pratique si vous n’en avez rien à foutre des rétroliens (surtout qu’il y a un historique de sécurité pas folichon), et que vous avez beaucoup d’articles. Ça se passe dans Mysql :

MariaDB [c0blog]> update wp_posts set ping_status = 'closed'; Query OK, 1015 rows affected (0.06 sec) Rows matched: 3466 Changed: 1015 Warnings: 0 1 2 3 MariaDB [c0blog] > update wp_posts set ping_status = 'closed' ; Query OK, 1015 rows affected (0.06 sec) Rows matched: 3466 Changed : 1015 Warnings : 0

Si vous utilisez des plugins de cache quelconques, vous devrez peut-être avoir à les flusher, je vous recommande d’util