Magento : ajouter un administrateur avec MySQL

Je me suis retrouvé récemment à devoir me connecter à la console d’admin d’un Magento 1, dont je ne connaissait aucun identifiant. J’avais tout juste accès à MySQL. Sur internet, la plupart des articles proposent de passer par bin/magento, qui n’était pas utilisable dans mon cas. Mais j’ai finalement trouvé la solution chez Webnoo :

LOCK TABLES `admin_role` WRITE , `admin_user` WRITE;

SET @SALT = "ls";
SET @PASS = CONCAT(MD5(CONCAT( @SALT , "adminpassword") ), CONCAT(":", @SALT ));
SELECT @EXTRA := MAX(extra) FROM admin_user WHERE extra IS NOT NULL;

INSERT INTO `admin_user` (firstname,lastname,email,username,password,created,lognum,reload_acl_flag,is_active,extra,rp_token_created_at) VALUES ('AdminFirstname','AdminLastname','admin@email.com','adminusername',@PASS,NOW(),0,0,1,@EXTRA,NOW());
INSERT INTO `admin_role` (parent_id,tree_level,sort_order,role_type,user_id,role_name) VALUES (1,2,0,'U',(SELECT user_id FROM admin_user WHERE username = 'adminusername'),'AdminFirstname');

UNLOCK TABLES;

 

De l’aléatoire prévisible

J’ai voulu créer un nouveau bucket sur AWS. Comme souvent, je mets un nom aléatoire. Mais aujourd’hui j’ai eu une surprise :

Comment un bucket avec un tel nom peut déjà exister ?

La réponse est simple. Pour générer le nom aléatoire, je fais un md5sum sur la sortie de pwgen :

pwgen | md5sum
d605a2ab78b9c7ccae50828133ffa30c  -

Sauf qu’aujourd’hui, j’ai fait :

pwger | md5sum 
bash: pwger: command not found

Notez le pwger à la place du pwgen.

Le command not found est envoyé sur STDERR, donc n’est pas pris en compte par md5sum. Du coup le md5sum est fait sur rien. D’ailleurs on peut arriver au même résultat avec :

echo -n '' | md5sum
d41d8cd98f00b204e9800998ecf8427e  -

Note : le -n sert à éviter le retour chariot.

Si le bucket existait déjà, c’est juste parce-que je ne suis pas être le seul boulet à faire des fautes de frappe.

Comment ne pas anonymiser des données

Il y a quelques jours je suis tombé par hasard sur cet article du Parisien : Essonne : des centaines d’amendes pour non-respect du confinement établies sans contrôles ?

Le contenu de l’article ne m’intéresse pas plus que ça ici. Mais au tiers de l’article on peut voire cette image :

Il s’agit d’une personne anonyme nous montrant une contravention pour « Déplacement hors du domicile interdit », ainsi que sont attestation de déplacement sur son téléphone.

Son nom et son adresse ont été masqués sur la contravention. Par contre le QR Code de l’attestation est bien visible. Et une fois décodé et mis en forme, il donne beaucoup d’informations :

Créé le : 16/04/2020 à 19h35
Nom : Assam
Prénom : Mohamed
Naissance : 31/08/1995 à Ivry sur Seine
Adresse : 1 rue du 19 mars 1962 91860 Epinay-sous-Sénart
Sortie : 16/04/2020 à 19h35
Motifs : courses

Ces données sont suffisantes pour obtenir un acte de naissance (nom, prénom, date et lieu de naissance). C’est même faisable en ligne pour la ville d’Ivry-sur-Seine. Ensuite vous pouvez demander une carte d’identité ou un passeport à ce nom, ce qui est très probablement faisable en ligne suivant la ville dans laquelle vous habitez.

Note : dans cet article j’ai recopié les informations sans les censurer. Elles sont déjà sur le site du Parisien, qui a nettement plus d’audience que le mien. J’ai également écrit au Parisien pour les prévenir, mais ils ne m’ont pas répondu.

Vérifier un tweet

Aujourd’hui je suis tombé sur cet échange de tweets :

D’après @PerdereauxP, beaucoup de riches le sont devenu grâce à leur travail. Ce n’est pas compliqué à vérifier, même si c’est un peu chiant. J’ai donc pris les 25 personnes les plus riches de France d’après le classement de challenges.fr. Voilà ce que ça donne :

Classement Nom Fortune (M€) Héritier
1 Bernard Arnault et sa famille 88286 Oui
2 Alain Wertheimer et Gérard Wertheimer ainsi que leur famille 50000 Oui
3 Françoise Bettencourt-Meyers et sa famille 45800 Oui
4 Famille Hermès 43000 Oui
5 Gérard Mulliez et sa famille 32000 Oui
6 François Pinault et sa famille 29000 Non
7 Laurent, Olivier, Marie-Hélène & Thierry Dassault 23000 Oui
8 Pierre Castel et sa famille 14000 Non
9 Emmanuel Besnier et sa famille 12000 Oui
10 Patrick Drahi 9000 Non
11 François Perrodo et sa famille 8500 Oui
12 Vincent Bolloré 7300 Oui
13 Pierre Omidyar 7300 Non
14 Pierre Bellon et ses enfants 6500 Oui
14 Danièle Ricard et sa famille 6500 Oui
16 Xavier Niel et sa famille 5900 Non
17 Famille Courtin-Clarins 5800 Oui
18 Rodolphe Saadé et sa famille 5500 Oui
19 Anne Beaufour et Henri Beaufour ainsi que leur famille 5300 Oui
20 Margarita Louis-Dreyfus et sa famille 5200 Oui
20 Alain Mérieux et sa famille 5200 Oui
22 Benjamin de Rothschild et sa famille 5000 Oui
23 Marie-Christine Coisne-Roquette et Familles Coisne et Lambert 4800 Oui
24 Famille Decaux 4400 Non
25 Marc Ladreit de Lacharrière 4300 Oui

Si je fais le total de tout ça j’arrive à :

Fortune total (M€) Pourcentage
Héritier 433586 95%
Pas héritier 23000 5%

@PerdereauxP a une drôle de définition de « s’en donner les moyens » et de « durement travailler ».

MySQL : Copie une base de données d’un serveur à un autre

Une petite commande pense-bête, qui permets de copier une base de données MySQL d’un serveur à un autre. Quand on est sur le serveur de destination :

ssh SERVER_SOURCE 'mysqldump base_de_donnees_source | gzip' | gunzip | mysql base_de_donnees_cible

Les gzip / gunzip sont facultatifs. Ils permettent de compresser les données pendant le transfert pour gagner du temps. Mais si SERVER_SOURCE est particulièrement lent, ça peut être plus rapide de les enlever.

Linux : monter une image disque ISO contenant plusieurs partitions

Dans le cadre de mon travail j’ai dû monter une image ISO contenant plusieurs partitions. Il s’agissait de l’image disque d’une VM s’étant fait pirater, sur laquelle je devais faire des investigations. Si on fait un bête mount, ça ne marche pas :

$ sudo mount image.iso /mnt/
mount: /mnt: mauvais type de système de fichiers, option erronée, superbloc erroné sur /dev/loop0, page de code ou programme auxiliaire manquant, ou autre erreur.

Il faut procéder autrement. D’abord j’utilise fdisk pour récupérer les informations de base sur l’image ISO.

$ sudo fdisk image.iso

J’utilise la commande p pour avoir les informations :

Commande (m pour l'aide) : p
Disque image.iso : 50 GiB, 53687091200 octets, 104857600 secteurs
Unités : secteur de 1 × 512 = 512 octets
Taille de secteur (logique / physique) : 512 octets / 512 octets
taille d'E/S (minimale / optimale) : 512 octets / 512 octets
Type d'étiquette de disque : dos
Identifiant de disque : 0xe483a6f1

Périphérique Amorçage   Début       Fin  Secteurs Taille Id Type
image.iso1               2048   3905535   3903488   1,9G 82 partition d'échange Linux / Solaris
image.iso2   *        3905536 104857599 100952064  48,1G 83 Linux

Ici je vous qu’il y a deux partitions. La première c’est du swap, elle ne m’intéresse pas. La deuxième est la partition système, c’est celle là que je veux monter. J’ai besoin de récupérer trois informations : Taille de secteur, Début et Id. Dans mon cas, c’est respectivement 512, 3905536 et 83.

Id est un code indiquant le type formatage de la partition. Dans mon cas je sais ça correspond ext4, mais si on ne le sait pas, il suffit de faire la commande l pour lister les types existants :

Commande (m pour l'aide) : l

 0  Vide            24  NEC DOS         81  Minix / Linux a bf  Solaris        
 1  FAT12           27  TFS WinRE masqu 82  partition d'éch c1  DRDOS/sec (FAT-
 2  root XENIX      39  Plan 9          83  Linux           c4  DRDOS/sec (FAT-
 3  usr XENIX       3c  récupération Pa 84  OS/2 cachée ou  c6  DRDOS/sec (FAT-
 4  FAT16 <32M      40  Venix 80286     85  Linux étendue   c7  Syrinx         
 5  Étendue         41  PPC PReP Boot   86  NTFS volume set da  Données non-FS 
 6  FAT16           42  SFS             87  NTFS volume set db  CP/M / CTOS / .
 7  HPFS/NTFS/exFAT 4d  QNX4.x          88  Linux plaintext de  Dell Utility   
 8  AIX             4e  2e partie QNX4. 8e  LVM Linux       df  BootIt         
 9  Amorçable AIX   4f  3e partie QNX4. 93  Amoeba          e1  DOS access     
 a  Gestionnaire d' 50  OnTrack DM      94  Amoeba BBT      e3  DOS R/W        
 b  W95 FAT32       51  OnTrack DM6 Aux 9f  BSD/OS          e4  SpeedStor      
 c  W95 FAT32 (LBA) 52  CP/M            a0  IBM Thinkpad hi ea  Alignement Rufu
 e  W95 FAT16 (LBA) 53  OnTrack DM6 Aux a5  FreeBSD         eb  BeOS fs        
 f  Étendue W95 (LB 54  OnTrackDM6      a6  OpenBSD         ee  GPT            
10  OPUS            55  EZ-Drive        a7  NeXTSTEP        ef  EFI (FAT-12/16/
11  FAT12 masquée   56  Golden Bow      a8  UFS Darwin      f0  Linux/PA-RISC b
12  Compaq diagnost 5c  Priam Edisk     a9  NetBSD          f1  SpeedStor      
14  FAT16 masquée < 61  SpeedStor       ab  Amorçage Darwin f4  SpeedStor      
16  FAT16 masquée   63  GNU HURD ou Sys af  HFS / HFS+      f2  DOS secondaire 
17  HPFS/NTFS masqu 64  Novell Netware  b7  BSDI fs         fb  VMware VMFS    
18  AST SmartSleep  65  Novell Netware  b8  partition d'éch fc  VMware VMKCORE 
1b  W95 FAT32 masqu 70  DiskSecure Mult bb  Boot Wizard mas fd  RAID Linux auto
1c  W95 FAT32 masqu 75  PC/IX           bc  Acronis FAT32 L fe  LANstep        
1e  W95 FAT16 masqu 80  Minix ancienne  be  Amorçage Solari ff  BBT

Ensuite on peut quitter fdisk avec q :

Commande (m pour l'aide) : q

Maintenant il ne reste plus qu’à utiliser mount pour monter l’image ISO, mais en spécifiant l’offset de début de la partition qui nous intéresse. Ça se fait en multipliant les valeurs Taille de secteur et Début récupérées plus tôt. Dans notre cas : 3905536 × 512 = 1999634432

sudo mount -t ext4 -o loop,offset=1999634432 image.iso /mnt/

UEFI : impossible de changer l’ordre du boot

Un de mes collègues a rencontré un problème sur son ordinateur Hewlett-Packard. Après une installation fraîche de Debian, il ne pouvait pas modifier l’ordre du boot dans l’UEFI. Résultat, l’ordinateur cherchait systématiquement à démarrer sur la clé USB d’installation, même quand elle n’est pas présente. Il était obligé de modifier l’ordre du boot dans l’UEFI à la main à chaque démarrage.

La solution ne se trouvait pas dans l’UEFI mais dans Debian. Il est possible d’y forcer l’ordre du boot de l’UEFI. D’abord on liste les boots possibles :

$ efibootmgr
BootCurrent: 0000
Timeout: 5 seconds
BootOrder: 0007,0004,0005,0003,0000
Boot0000* Intel Corporation: Realtek PXE B01 D00
Boot0003* SK hynix BC501 HFM256GDJTNG-8310A-NN95N694013905P6U
Boot0004* Pen Drive CE775CCD63720020
Boot0005* Pen Drive CE775CCD63720020
Boot0007* debian

Celui qui nous intéresse ici est Boot0007. Pour l’activer :

efibootmgr --bootorder 0007

C’est ironique de voir qu’on est obligé de passer par le système d’exploitation pour paramétrer l’UEFI, alors que la raison principale de sa création est d’empêcher que le système d’exploitation ne puisse modifier le démarrage de l’ordinateur.

Apache : SSLProtocol ignoré

J’ai rencontré un problème récemment. J’avais beau modifier la variable SSLProtocol dans n’importe quel fichier de /etc/apache2/sites-enabled/, ce n’étais jamais pris en compte.

En fait, en bas de la configuration de chaque vhost, Let’s Encrypt avait rajouté la ligne suivante :

Include /etc/letsencrypt/options-ssl-apache.conf

Il fallait donc modifier le SSLProtocol directement dans ce fichier.

Python : jouons avec coding

En lisant l’article Un header d’encoding plus simple pour Python et ses commentaires, j’ai voulu voir jusqu’où on pouvait aller dans la déclaration coding en Python 3.

Je commence par créer le script suivant :

#!/usr/bin/python3
# coding: Latin-1
print('é')

Comme Python 3 est par défaut en UTF-8, je suis obligé d’utiliser un autre coding pour voir si c’est pris en compte. Je créé donc le script en UTF-8 mais je déclare un coding en Latin-1. De cette manière, si le coding fonctionne ça affichera é, sinon ça affichera é.

J’aurais pu créer un fichier source en Latin-1, mais si le coding ne fonctionne pas ça me retourne une erreur :

SyntaxError: (unicode error) 'utf-8' codec can't decode byte 0xe9 in position 0: unexpected end of data

Je trouve ça beaucoup moins propre.

J’ai aussi choisi de ne pas utiliser le shebang préconisé (#!/usr/bin/env python3). Ça sera utile plus tard.

Je lance donc le script, et le résultat correspond à mes attentes :

$ ./coding.py
é

Le coding est bien pris en compte.

 

Maintenant je vais tester quelques exemples dans les commentaire de l’article. Je commence par celui de Biganon :

#!/usr/bin/python3
# Bonjour, je voudrais utiliser cet encoding: Latin-1 ; et sinon, la famille ça va ?
print('é')
$ ./coding.py
é

Parfait, ça marche.

 

Ensuite je passe à haypo :

#!/usr/bin/python3
# cocoricoding: Latin-1, l’encoding bien français
print('é')
$ ./coding.py
é

Ça marche aussi. On peut donc bien mettre des caractères non-ASCII sur la ligne qui déclare l’encodage.

 

D’après mgautierfr et Sam, la regex permettant de détecter le coding est coding[:=]\s*([-\w.]+). Elle est testée uniquement sur les deux premières lignes du fichier. Voyons ce qu’il est possible de faire avec ça.

 

#!/usr/bin/python3
import os # coding: Latin-1
print('é')
./coding.py
é

Le coding n’est pas pris en compte s’il y a une instruction avant sur la ligne. Dommage, j’aurais bien aimé pouvoir changer l’encodage au milieu d’un script.

 

#!/usr/bin/python3
print('coding: Latin-1')
print('é')
$ ./coding.py
coding:Latin-1
é

Si le coding fait partie de l’instruction, ça ne marche pas non plus.

 

#!/usr/bin/python3
""" coding: Latin-1 """
print('é')
$ ./coding.py
é

Si le coding est entre triple quotes, ça ne fonctionne pas non plus. Si j’ai bien compris la doc (c’est pas garanti), les triples quotes sont considérées comme des instructions par Python. Il est donc normal que ça ne fonctionne pas.

 

#!/usr/bin/python3
# coding: Latin-1 # coding: UTF-8
print('é')
$ ./coding.py
é

S’il y a plusieurs coding, c’est le premier qui est pris en compte.

 

#!/usr/bin/python3 # coding: Latin-1
print('é')
$ ./coding.py
/usr/bin/python3: can't open file '# coding: Latin-1': [Errno 2] No such file or directory

On ne peut pas mettre le coding sur la même ligne que le shebang. Mais ça a l’air d’être une limitation de Bash. Si je garde le même script mais que je le lance directement avec python3 :

$ python3 ./coding.py
é

Là ça marche.

Edit : d’après un article de Xavier Claude, le shebang est géré directement par le noyau, et pas par Bash.

 

Puisque le shebang est géré par Bash et le coding par Python, il est possible de faire des choses sympa. Je commence par créer un lien symbolique /usr/bin/coding:Latin-1 qui pointe vers /usr/bin/python3 :

sudo ln -s /usr/bin/python3 /usr/bin/coding:Latin-1

Ensuite je créé le script suivant :

#!/usr/bin/coding:Latin-1
print('é')
$ ./coding.py
é

Et voilà, en une seule ligne tout le monde est content ! Bash a pu lancer Python via le lien symbolique coding:Latin-1, et Python a trouvé son coding sur la première ligne du script.

Docker : can’t create socket (must run as root?) : Permission denied

Dans le cadre de la dockerisation de proxy Zabbix, je suis tombé sur un problème étrange.

Je fais les commandes suivantes :

docker run -it zabbix/zabbix-proxy-sqlite3:ubuntu-3.4-latest /bin/bash
[...]
root@220fab01aae4:/var/lib/zabbix# fping palc.fr
palc.fr is alive
root@220fab01aae4:/var/lib/zabbix# su - zabbix -s /bin/bash
zabbix@220fab01aae4:~$ fping palc.fr
(null): can't create socket (must run as root?) : Permission denied

Note : l’option -it /bin/bash me permets d’avoir directement un bash pour faire mes tests. Lors d’un lancement de Docker en prod, il faudrait utiliser les options -d -t à la place.

Note 2 : vous pouvez également avoir une erreur du type socket: Operation not permitted.

Dans le container Docker, la commande fping fonctionne en root mais pas avec l’utilisateur Zabbix. Pourtant sur le système host, qui utilise le même OS, ça fonctionne bien.

Pour corriger le problème il faut simplement ajouter l’option --sysctl net.ipv4.ping_group_range="0 65535" à la commande lançant le container docker. Ça permets à n’importe quel utilisateur d’accéder directement au réseau de l’hôte, ce qui est indispensable pour effectuer des requêtes ICMP, comme le ping. Dans le cas contraire, seul l’utilisateur root serait autorisé à le faire.