OpenSSL : voir les détails d’un certificat

Il est possible de voir toutes les données d’un certificat SSL à partir de son fichier .crt ou .pem. La commande à utiliser est : openssl x509 -noout -text -in /chemin/vers/le/certificat. Par exemple :

 

# openssl x509 -noout -text -in /etc/letsencrypt/live/palc.fr/fullchain.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            04:b2:f9:cb:ca:20:c1:05:b9:08:fa:31:80:d8:31:2c:fd:b6
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, O = Let's Encrypt, CN = R3
        Validity
            Not Before: Aug 30 08:10:06 2021 GMT
            Not After : Nov 28 08:10:05 2021 GMT
        Subject: CN = palc.fr
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:b8:88:80:7f:d8:a9:30:71:e7:4e:4f:0d:a3:1b:
                    c9:51:f7:6e:b8:01:49:14:f1:c6:5d:07:fe:da:50:
                    6a:95:5a:fc:d6:97:e1:3b:5e:af:ab:8a:7b:11:8a:
                    a8:33:aa:34:71:0f:9a:0e:32:35:c8:96:29:86:08:
                    52:eb:24:a7:b8:8d:35:9f:e6:af:f7:29:3c:83:d9:
                    e3:89:9e:50:de:a9:fe:43:bd:d8:db:fd:70:f9:52:
                    ae:fd:a7:ae:55:88:6f:a4:da:48:05:7b:4a:ee:41:
                    2b:23:08:38:f3:e8:0f:aa:c7:93:9f:41:a1:1d:dd:
                    45:46:f9:81:da:33:6b:3e:95:28:d5:eb:24:78:35:
                    b9:7c:85:ea:c6:0d:12:d5:a3:8a:50:f6:42:ce:45:
                    1d:f3:41:fd:f4:ce:1c:28:10:45:c1:ad:39:0f:6e:
                    05:7b:8d:b8:f9:98:45:21:7a:b9:df:40:55:26:7a:
                    6f:e1:f6:d5:2a:44:42:92:55:b4:25:f3:97:36:3f:
                    8b:fb:9e:ec:21:2b:b0:36:5b:67:10:b6:75:d3:3b:
                    2b:cc:ed:ec:72:5c:c3:07:1f:b1:ad:f2:67:9e:f1:
                    37:10:16:c4:02:de:57:9f:a4:a6:54:a5:b4:61:5c:
                    63:bc:07:6a:87:00:97:81:d6:b0:2f:2c:1e:cc:e4:
                    11:a1
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier: 
                41:A3:12:A9:41:CF:C4:C4:0B:57:67:C0:1B:97:E4:49:1F:A0:02:B8
            X509v3 Authority Key Identifier: 
                keyid:14:2E:B3:17:B7:58:56:CB:AE:50:09:40:E6:1F:AF:9D:8B:14:C2:C6

            Authority Information Access: 
                OCSP - URI:http://r3.o.lencr.org
                CA Issuers - URI:http://r3.i.lencr.org/

            X509v3 Subject Alternative Name: 
                DNS:palc.fr, DNS:www.palc.fr
            X509v3 Certificate Policies: 
                Policy: 2.23.140.1.2.1
                Policy: 1.3.6.1.4.1.44947.1.1.1
                  CPS: http://cps.letsencrypt.org

            CT Precertificate SCTs: 
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : 5C:DC:43:92:FE:E6:AB:45:44:B1:5E:9A:D4:56:E6:10:
                                37:FB:D5:FA:47:DC:A1:73:94:B2:5E:E6:F6:C7:0E:CA
                    Timestamp : Aug 30 09:10:07.070 2021 GMT
                    Extensions: none
                    Signature : ecdsa-with-SHA256
                                30:45:02:20:71:5B:63:71:90:A2:5F:BE:20:32:CB:54:
                                6B:92:DE:CE:4F:EE:24:AE:8D:95:AE:8E:69:61:5E:19:
                                94:6C:2A:84:02:21:00:8F:B2:5A:AB:36:EA:38:40:CD:
                                13:C2:71:D9:5A:B7:81:86:7C:13:57:8D:4A:B6:2E:6F:
                                65:98:9A:81:AF:AF:78
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : F6:5C:94:2F:D1:77:30:22:14:54:18:08:30:94:56:8E:
                                E3:4D:13:19:33:BF:DF:0C:2F:20:0B:CC:4E:F1:64:E3
                    Timestamp : Aug 30 09:10:07.079 2021 GMT
                    Extensions: none
                    Signature : ecdsa-with-SHA256
                                30:45:02:21:00:F5:6D:43:4C:49:68:F7:E1:E3:D0:E2:
                                D1:1C:B2:A8:55:DA:7F:22:CA:35:17:C5:AE:3C:50:12:
                                1B:A5:D5:AE:D6:02:20:50:EC:B7:A4:37:62:3C:7A:FB:
                                96:4D:1B:17:AB:F8:9D:A1:3C:DE:37:6E:71:45:58:AE:
                                3C:7E:C7:5A:D0:B3:FB
    Signature Algorithm: sha256WithRSAEncryption
         89:34:fa:07:9c:ea:3e:05:70:dd:9f:11:b9:5a:36:3c:49:70:
         47:86:41:bb:97:73:82:52:be:20:1e:93:53:d9:2d:e0:29:2a:
         c7:83:5f:47:54:d8:57:72:f5:05:87:2f:f1:22:6c:bd:20:9f:
         1f:5a:90:73:81:a7:3e:06:63:5f:f1:01:fa:01:2c:4a:13:61:
         91:1e:c4:2d:d5:e1:17:28:8c:23:17:8c:42:b9:32:4d:dd:83:
         1f:ce:a3:51:72:bf:9c:1a:6f:66:1e:75:59:34:c1:e0:b2:83:
         c4:2e:1a:ad:d1:71:4d:43:79:9d:0b:af:1e:7b:7c:e4:d5:08:
         b6:bf:ba:b8:fa:90:49:86:e6:ef:eb:9f:c5:a2:3a:39:2c:49:
         03:81:30:36:e7:ed:d0:2c:1c:94:a7:97:0b:cc:a9:58:d8:0d:
         a6:20:c6:5e:67:7b:b7:5f:13:1a:5b:b1:13:8b:d0:e2:69:79:
         1e:e9:f6:2c:90:30:3c:a9:b8:e2:a5:a7:51:0b:a0:e0:f8:10:
         11:ec:e4:0e:c4:3c:2a:3e:65:39:c7:2e:78:f8:56:52:92:db:
         47:5b:81:9b:d3:f0:7a:be:bf:98:e9:a9:d2:92:d6:46:7d:2f:
         a6:fc:25:eb:9f:5c:94:7a:fb:d0:fc:9a:49:8a:d0:4c:35:bb:
         76:c2:4b:67

Ca peutpermets de vérifier facilement les DNS concerner, ou la date d’expiration, par exemple.

Utiliser tar

Un petit pense-bête personnel, pour gérer des archives.

.tar

Création de l’archive : tar -cvf archive.tar ficher1 fichier2 fichier3
Extraction de l’archive : tar xvf archive.tar

.tar.gz

Création de l’archive : tar zcvf archive.tar.gz ficher1 fichier2 fichier3
Extraction de l’archive : tar zxvf archive.tar.gz

.tar.bz2

Création de l’archive : tar jcvf archive.tar.bz2 ficher1 fichier2 fichier3
Extraction de l’archive : tar -jxvf archive.tar.bz2

.tar.xz

Création de l’archive : tar -Jcvf archive.tar.xz ficher1 fichier2 fichier3
Extraction de l’archive : tar -Jxvf archive.tar.xz

YUM : dbenv->failchk: DB_RUNRECOVERY: Fatal

Il m’est arrivé plusieurs fois de rencontrer l’erreur suivante lors d’un yum update :

rpmdb: Thread/process 12780/140667967072000 failed: Thread died in Berkeley DB library
erreur: erreur db3(-30974) de dbenv->failchk: DB_RUNRECOVERY: Fatal error, run database recovery
erreur: ne peut ouvrir l'index Packages en utilisant db3 - (-30974)
erreur: impossible d'ouvrir la base de données Package dans /var/lib/rpm
CRITICAL:yum.main:

Error: rpmdb open failed

Pour corriger ce problème, il faut reconstruire manuellement l’index de yum :

mv /var/lib/rpm/__db* /tmp/
rpm --rebuilddb
yum clean all

Apache : « AH01797: client denied by server configuration » sur le dossier icons

Un client m’a remonté que sur son site le favicon était en erreur 404, de façon incompréhensible.

Si j’essaye d’accéder au favicon avec mon navigateur, j’ai bien une erreur 404. Et dans les logs je vois :

[Fri Feb 26 11:38:36.170743 2021] [access_compat:error] [pid 11523:tid 139967505688320] [client XXX.XXX.XXX.XXX:0] AH01797: client denied by server configuration: [...]/current/favicon.ico

Pourtant le fichier favicon.ico est bien présent au bon emplacement et avec les bons droits.

 

J’ai dû pas mal chercher pour trouver la source du problème. C’est ce site qui m’a aidé.

En fait, le module alias contiens par défaut la configuration suivante :

        # We include the /icons/ alias for FancyIndexed directory listings.  If
        # you do not use FancyIndexing, you may comment this out.

        Alias /icons/ "/usr/share/apache2/icons/"

        <Directory "/usr/share/apache2/icons">
                Options FollowSymlinks
                AllowOverride None
                Require all granted
        </Directory>

Sur tous les vhosts du serveur, le dossier /icons/ est réécrit vers /usr/share/apache2/icons/, donc toutes les icônes ajoutées par le client ne sont pas accessibles.

La solution évoquée sur le site est de renommer le dossier /icons/ sur le site. Ça ne me conviens pas, parce-qu’il faut que le client modifie son site. La seule solution est de commenter ces lignes.

Drupal et PostgreSQL : Error at offset 0 of … bytes drupal/includes/cache.inc

Il y a quelques jours j’ai dû copier un site Drupal de prod vers un autre serveur, pour en faire une préprod. Malgré une configuration qui semblait entièrement ISO, j’avais une plâtrée de messages d’erreur, du type :

Notice: unserialize(): Error at offset 0 of 1009 bytes in [...]drupal/includes/cache.inc on line 449
Notice: unserialize(): Error at offset 0 of 50487 bytes in [...]drupal/includes/cache.inc on line 449
Warning: Invalid argument supplied for foreach() in [...]drupal/includes/module.inc on line 213
Warning: array_keys() expects parameter 1 to be array, null given in [...]drupal/includes/module.inc on line 89
Notice: unserialize(): Error at offset 0 of 50487 bytes in [...]drupal/includes/cache.inc on line 449
Warning: Invalid argument supplied for foreach() in [...]drupal/includes/module.inc on line 213
Warning: array_keys() expects parameter 1 to be array, null given in [...]drupal/includes/module.inc on line 89
Notice: unserialize(): Error at offset 0 of 1009 bytes in [...]drupal/includes/cache.inc on line 449
Notice: unserialize(): Error at offset 0 of 13 bytes in [...]drupal/includes/cache.inc on line 449
Notice: unserialize(): Error at offset 0 of 50487 bytes in [...]drupal/includes/cache.inc on line 449
Warning: Invalid argument supplied for foreach() in [...]drupal/includes/module.inc on line 213
Warning: array_keys() expects parameter 1 to be array, null given in [...]drupal/includes/module.inc on line 89
Notice: unserialize(): Error at offset 0 of 50487 bytes in [...]drupal/includes/cache.inc on line 449
Warning: Invalid argument supplied for foreach() in [...]drupal/includes/module.inc on line 213
Warning: array_keys() expects parameter 1 to be array, null given in [...]drupal/includes/module.inc on line 89
Notice: unserialize(): Error at offset 0 of 50487 bytes in [...]drupal/includes/cache.inc on line 449
Warning: Invalid argument supplied for foreach() in [...]drupal/includes/module.inc on line 213
Warning: array_keys() expects parameter 1 to be array, null given in [...]drupal/includes/module.inc on line 89
Fatal error: Call to undefined function system_run_automated_cron() in [...]drupal/includes/common.inc on line 2784
Il m’a fallu du temps pour trouver comment corriger ce problème. (d’ailleurs c’est même pas moi qui ai trouvé)
D’après internet, ces messages indiquent un problème dans la sérialisation des données.
Drupal a une drôle de façon de stocker ses données. Par exemple, si sur le serveur de base de données de prod je fais un :

SELECT variables FROM watchdog WHERE wid=10969;

ça me retournes :

a:2:{​​​​​​​s:5:"@type";s:4:"page";s:6:"%title";s:52:"Titre chelou, j'ai pas le droit de mettre le vrai";}

Je ne sais pas pourquoi ils ont fait ça, mais Drupal utilise une base de données PostgreSQL pour ensuite stocker des données formatées en JSON.
Maintenant, si je fais la même requête sur le serveur de base de données de préprod, j’ai :

\x5469747265206368656C6F752C206A27616920706173206C652064726F6974206465206D6574747265206C652076726169

Le résultat est retourné au format hexadécimal. Si on le convertit en texte, on obtient bien la même chaîne que sur le serveur de prod. C’est juste le format de la donnée qui est différente.
En fait le serveur de base de données de prod avait été installé avec PostgreSQL 8, puis a ensuite été mis à jour vers PostgreSQL 9. Le serveur de prérpod, plus récent, a été installé directement en version 9.
Sauf qu’entre les versions 8 et 9 de PostgreSQL, la gestion par défaut des données a changé
Ce qui me pose problème dans ce cas précis, c’est le bytea_output, qui est à escape en prod, mais à hex en préprod. Ca se corrige très simplement avec :

ALTER DATABASE nom_de_la_base SET bytea_output to 'escape';

Wallix : réinitialiser le mot de passe admin

Il faut se connecter au wallix en SSH avec le compte wabadmin sur le port 2242 :

ssh wabadmin@serveur_wallix -p 2242

Ensuite la commande super permets de se connecter au compte wabsuper. De là, la commande sudo -i permets de se connecter en root.

Ensuite, pour réinitialiser le mot de passe admin, il faut entrer les deux commandes suivantes :

WABRestoreDefaultAdmin
echo "update user set pwdChangeTime = now() where cn = 'admin';" | mysql -u root -h localhost wallix --password=admin --default-character-set=utf8

Les identifiants admin seront rétablis à admin / admin. Wallix demandera de les changer à la première connexion.

Apache : AH01071: Got error Primary script unknown

Lors de la création d’un vhost sur Apache, une fois le code du site importé j’ai eu l’erreur suivante dans les logs :
AH01071: Got error 'Primary script unknown\n'
Plusieurs pages du site affichaient également un File not found.

 

J’ai pas mal galéré avant de trouver l’origine du problème, et surtout comment le résoudre.

 

Le code PHP du client était exécuté via FPM, avec la directive suivante :
ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/var/www/palc.fr/$1

Mais à la racine de son site, un fichier .htaccess était rempli de règles de ce style :
RewriteRule ^/gallery/index.php /phototheque.php [NC,L]
RewriteRule ^/gallery/client.php /phototheque-client.php [NC,L]

Le problème c’est que le ProxyPassMatch est exécuté avant les RewriteRule du .htaccess. Du coup, quand on demande une page PHP correspondant à une RewriteRule, Apache va d’abord essayer de l’exécuter avec FPM et retourner une erreur, puisque le fichier PHP n’existe pas.

 

La solution est de demander à Apache de n’utiliser FPM que si le fichier existe. Il faut remplacer
ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/var/www/palc.fr/$1
Par :
<FilesMatch \.php$>
SetHandler "proxy:fcgi://127.0.0.1:9000/"
</FilesMatch>

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
d41d8cd98f00b204e9800998ecf8427e

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.