Catégorie : LINUX

Mise à jour Drupal 8.9.17 vers 10.2.3.

 

 

Bonjour à tous,

Utilisant DRUPAL pour un de mes projets (CRX-RADIO-CLOUD), j’ai été déjà amené à faire des mises à jour. Pour ce faire j’ai toujours utilisé COMPOSER, un outil que j’aime bien, cependant je dois dire que là j’en ai « bavé » à chercher des solutions à différentes erreurs/bugs et versions de librairies, je partage ici mes notes de cette mise à jour « massive ».

A savoir que DRUPAL utilise différentes version de PHP suivant la version ici 8, 9 puis 10, J’ai donc du suivre aussi la mise à jour de PHP (7.4,8.0,8.1). Heureusement j’avais à disposition toutes les versions et modules APACHE donc pas de soucis ici pour le prérequis PHP du serveur utilisé pour faire la mise à jour :

Voici mon « upgrade path » ici : 

8.9.17 à 9.0
9.0 à 9.1.0
9.1.0 à 9.2.21
9.2.1 à 9.2.4
9.2.4 à 9.4.15
9.4.15 à 9.5.0
9.5.0 à 10.2.3
10.2.3 à 10.2.4

=> A savoir que mettre à jour DRUPAL via COMPOSER prend énormément de mémoire, je dois donc ajouter une SWAP sur mon serveur pour absorber la charge mémoire : ( >=4G )

# mkdir -p /var/_swap
# cd /var/_swap
# fallocate -l 4G swapfile
# chmod 600 swapfile
# mkswap swapfile
# swapon swapfile


Tableau des commandes COMPOSER ‘utiles’ ici :

#affiche les infos de versions : 
composer outdated "drupal/*"

#enlève une lib au composer.json (+ --no-update): 
composer remove 'lib/lib:^x.x'                              

#ajout une lib au composer.json  (+ --no-update): 
composer require 'lib/lib:^x.x.x'       

#mise à jour std, après avoir modifier le composer.json en conséquence :

composer require drupal/core-recommended:[VERSION] \
drupal/core-composer-scaffold:[VERSION] \
drupal/core-project-message:[VERSION] \
--update-with-all-dependencies


Mise à jour DRUPAL 8.9.17 à 9.0 :

Pour commencer, je suis donc parti d’un PHP7.3 que j’ai du passé en 7.4 (partie CLI), puis une bascule du module PHP/APACHE.

Après un DUMP complet de la base et un SNAPSHOT des données, je peux démarrer cette mise à jour :

#bascule du PHP/CLI en v7.4, préalablement installé : 

# update-alternatives --display php
# update-alternatives --set php /usr/bin/php7.4


Lancement de la mise à jour :

# composer require 'drupal/core-recommended:^9' 'drupal/core-composer-scaffold:^9' 'drupal/core-project-message:^9' --update-with-dependencies --no-update
# composer require 'drupal/core-dev:^9' --dev --update-with-dependencies --no-update
# composer require "drupal/core:9.0.0 as 8.9.17" --no-update && composer update

A la suite d’une erreur PHP ‘fatal error: require(): failed opening required vendor/composer/../symfony/polyfill-intl-normalizer/bootstrap.php’
=> je renomme le dossier vendor en vendor_, pour forcer sa mise à jour complète en réinstallant toutes les librairies :

# mv vendor vendor_

Je peux alors lancer la mise à jour, l’option ‘no-update‘ permet de préparer le fichier composer.json,
avec l’ajout des versions de libs qui va être utilisé par le gestionnaire de paquets COMPOSER :

# composer require 'drupal/core-recommended:^9' 'drupal/core-composer-scaffold:^9' 'drupal/core-project-message:^9' --update-with-dependencies --no-update

# composer require 'drupal/core-dev:^9' --dev --update-with-dependencies --no-update

# composer require "drupal/core:9.0.0 as 8.9.17" --no-update && composer update

Une fois exécuté, je passe au lancement du script en HTTPS : /update.php  qui permet le passage des mises à jour sur la base de données.
Ce script est très important car il remonte aussi les soucis de d’extensions ou thèmes non compatibles, c’est aussi pour ca que je préfère ne pas utiliser DRUSH qui lui gère cela automatiquement.


Mise à jour DRUPAL de 9.0 à 9.1.0 :

Je viens modifier la version de 9.0 à 9.1.0 dans le composer.json :

Modification du composer json : 

    "require": {
        "composer/installers": "^1.0.24",
        "drupal/core": "9.1.0",
        "drupal/codesnippet": "^1.6",
        "drupal/colorbox": "^1.4",
        "drupal/bootstrap": "^3.15",
        "drupal/bootstrap_library": "^1.11",
        "egulias/email-validator": "^2.0",
        "drupal/core-recommended": "9.1.0",
        "drupal/core-composer-scaffold": "9.1.0",
        "drupal/core-project-message": "9.1.0",

+ rm -f composer.lock

Ensuite je passe le COMPOSER de la version 1 à 2 puis le PHP CLI de la version 7.4 à 8.0 + du module APACHE  :

Passage de COMPOSER en Version 2 : 

# composer self-update --2     ( peux etre rollback via :  composer self-update --rollback     ). 

Patch important pour passer en 9.1 : 

composer config --unset scripts.post-package-install
composer config --unset scripts.post-package-update
composer require drupal/core-vendor-hardening:^9


Use the `composer fund` command to find out more!
Scaffolding files for drupal/core:
  - Copy [web-root]/.htaccess from assets/scaffold/files/htaccess
  - Copy [web-root]/INSTALL.txt from assets/scaffold/files/drupal.INSTALL.txt
  - Copy [web-root]/README.txt from assets/scaffold/files/drupal.README.txt
  - Copy [web-root]/robots.txt from assets/scaffold/files/robots.txt
  - Copy [web-root]/update.php from assets/scaffold/files/update.php

In Filesystem.php line 288:

  Could not delete /dataglusterfs_mount/project.crx.cloud/html/sites/default/default.services.yml:


root@crx-webng03 mods-enabled # a2dismod php7.4
Module php7.4 disabled.
To activate the new configuration, you need to run:
  systemctl restart apache2


root@crx-webng03 mods-enabled # a2enmod php8.0
Considering dependency mpm_prefork for php8.0:
Considering conflict mpm_event for mpm_prefork:
Considering conflict mpm_worker for mpm_prefork:
Module mpm_prefork already enabled
Considering conflict php5 for php8.0:
Module php8.0 already enabled


+ PHP CLI : 
# update-alternatives --display php
# update-alternatives --set php /usr/bin/php[VERSION]


Mise à jour DRUPAL de 9.1.0 à 9.2.21 :

Rien de particulier si ce n’est que j’installe en + drupal/upgrade_status qui va me permettre de récupérer un status de la mise à jour sous forme de rapport :

composer require drupal/upgrade_status

Création d'un report : 
root@crx-webng03 html # composer require drupal/upgrade_status --with-all-dependencies



Modification :  ^9.1  : 

cat composer.json
{
    "name": "drupal/drupal",
    "description": "Drupal is an open source content management platform powering millions of websites and applications.",
    "type": "project",
    "license": "GPL-2.0-or-later",
    "require": {
        "composer/installers": "^1.0.24",
        "drupal/core": "^9.1",
        "drupal/codesnippet": "^1.6",
        "drupal/colorbox": "^1.4",
        "drupal/bootstrap": "^3.15",
        "drupal/bootstrap_library": "^1.11",
        "egulias/email-validator": "^2.0",
        "drupal/core-recommended": "^9.1",
        "drupal/core-composer-scaffold": "^9.1",
        "drupal/core-project-message": "^9.1",
        "drupal/remove_meta_info": "^1.0",
        "drupal/core-vendor-hardening": "^9",
        "drupal/upgrade_status": "^4.1"

composer update

composer require drupal/core-recommended:9.2.21 drupal/core-composer-scaffold:9.2.21 drupal/core-project-message:9.2.21 --update-with-all-dependencies

Je lance ensuite cette commande très pratique qui va m’afficher ce qui reste à mettre à jour :

root@crx-webng03 html # composer outdated "drupal/*"
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Continue as root/super user [yes]? yes
Legend:
! patch or minor release available - update recommended
~ major release available - update possible

Direct dependencies required in composer.json:
drupal/bootstrap              3.24.0 ! 3.26.0 Built to use Bootstrap, a sleek, intuitive, and powerful front-end framework for faster and easier web development.
drupal/bootstrap_library      1.15.0 ~ 2.0.2  Provides Bootstrap Integration.
drupal/colorbox               1.10.0 ~ 2.0.1  A light-weight, customizable lightbox plugin for jQuery.
drupal/core                   9.2.21 ! 9.5.11 Drupal is an open source content management platform powering millions of websites and applications.
drupal/core-composer-scaffold 9.2.21 ~ 10.2.3 A flexible Composer project scaffold builder.
drupal/core-dev               9.1.0  ~ 10.2.3 require-dev dependencies from drupal/drupal; use in addition to drupal/core-recommended to run tests from drupal/core.
drupal/core-project-message   9.2.21 ~ 10.2.3 Adds a message after Composer installation.
drupal/core-recommended       9.2.21 ~ 10.2.3 Locked core dependencies; require this project INSTEAD OF drupal/core.
drupal/core-vendor-hardening  9.5.11 ~ 10.2.3 Hardens the vendor directory for when it's in the docroot.

Transitive dependencies not required in composer.json:
Everything up to date


Mise à jour DRUPAL de 9.2.1 à 9.2.4 :

root@crx-webng03 html # composer require drupal/core-recommended:^9.2.4 drupal/core-composer-scaffold:^9.2.4 --update-with-dependencies
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Continue as root/super user [yes]? yes
./composer.json has been updated
Running composer update drupal/core-recommended drupal/core-composer-scaffold --with-dependencies
Loading composer repositories with package information
Dependency drupal/core is also a root requirement. Package has not been listed as an update argument, so keeping locked at old version. Use --with-all-dependencies (-W) to include root dependencies.
Dependency egulias/email-validator is also a root requirement. Package has not been listed as an update argument, so keeping locked at old version. Use --with-all-dependencies (-W) to include root dependencies.
Updating dependencies
Lock file operations: 0 installs, 1 update, 0 removals
  - Upgrading drupal/core-composer-scaffold (9.2.21 => 9.5.11)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 0 installs, 1 update, 0 removals
  - Upgrading drupal/core-composer-scaffold (9.2.21 => 9.5.11): Extracting archive
Package doctrine/reflection is abandoned, you should avoid using it. Use roave/better-reflection instead.
Package laminas/laminas-zendframework-bridge is abandoned, you should avoid using it. No replacement was suggested.
Package symfony/debug is abandoned, you should avoid using it. Use symfony/error-handler instead.
Package behat/mink-goutte-driver is abandoned, you should avoid using it. Use behat/mink-browserkit-driver instead.
Package fabpot/goutte is abandoned, you should avoid using it. Use symfony/browser-kit instead.
Generating autoload files
> Drupal\Core\Composer\Composer::preAutoloadDump
Hardening vendor directory with .htaccess and web.config files.
> Drupal\Core\Composer\Composer::ensureHtaccess
87 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
Cleaning installed packages.
Found 25 security vulnerability advisories affecting 6 packages.
Run "composer audit" for a full list of advisories.
root@crx-webng03 html #

 

Mise à jour DRUPAL de 9.2.4 à 9.5.0 (en passant par la 9.4.15) :

 ^9.5
 root@crx-webng03 html # 
 composer require drupal/core-recommended:9.5.0 drupal/core-composer-scaffold:9.5.0 drupal/core-project-message:9.5.0 --update-with-all-dependencies

  Problem 1
    - drupal/codesnippet is locked to version 1.9.0 and an update of this package was not requested.
    - drupal/codesnippet 1.9.0 requires drupal/ckeditor * -> found drupal/ckeditor[dev-1.0.x, 1.0.0-rc1, ..., 1.0.x-dev (alias of dev-1.0.x)] but these were not loaded, likely because it conflicts with another require.

FAILED composer require drupal/core-recommended:9.5.0 drupal/core-composer-scaffold:9.5.0 drupal/core-project-message:9.5.0 -W

=> Désinstallation de drupal/codesnippet. 

=> Relance : 

root@crx-webng03 html # composer require drupal/core-recommended:9.5.0 drupal/core-composer-scaffold:9.5.0 drupal/core-project-message:9.5.0 --update-with-all-dependencies

#note : j'ai activé ckeditor5 (pour ne plus utiliser la V4 dans DRUPAL). 

=> Au final je dois rollback en 9.2.4, je décide alors de passer par la 9.4.15 (intermédiaire ici avance la 9.5) :

root@crx-webng03 html # cat composer.json
{
    "name": "drupal/drupal",
    "description": "Drupal is an open source content management platform powering millions of websites and applications.",
    "type": "project",
    "license": "GPL-2.0-or-later",
    "require": {
        "composer/installers": "^1.0.24",
        "drupal/core": "9.4.15",
        "drupal/colorbox": "^1.4",
        "drupal/bootstrap": "^3.15",
        "drupal/bootstrap_library": "^1.11",
        "egulias/email-validator": "^3.2",
        "drupal/core-recommended": "9.4.15",
        "drupal/core-composer-scaffold": "9.4.15",
        "drupal/core-project-message": "9.4.15",
        "drupal/remove_meta_info": "^1.0",
        "drupal/core-vendor-hardening": "^9",
        "drupal/upgrade_status": "^4.1",
        "drupal/highlightjs_input_filter": "^1.1",
   
...
 1280  composer require drupal/core-recommended:9.4.15 drupal/core-composer-scaffold:9.4.15 drupal/core-project-message:9.4.15 --update-with-all-dependencies

root@crx-webng03 html # composer require 'drupal/addtoany:^2.0'


Bootstrap (Thème)	8.x-3.24	8.x-3.30 (Notes de version)
Requires Drupal core: 9.5.0 to 10.2.4

...


Mise à jour DRUPAL 9.4.15 à 9.5.0 : 

root@crx-webng03 html # cat composer.json
{
    "name": "drupal/drupal",
    "description": "Drupal is an open source content management platform powering millions of websites and applications.",
    "type": "project",
    "license": "GPL-2.0-or-later",
    "require": {
        "composer/installers": "^1.0.24",
        "drupal/core": "9.5.0",
        "drupal/colorbox": "^2.0",
        "drupal/bootstrap": "^3.30",
        "drupal/bootstrap_library": "^2.0",
        "egulias/email-validator": "^3.2",
        "drupal/core-recommended": "9.5.0",
        "drupal/core-composer-scaffold": "9.5.0",
        "drupal/core-project-message": "9.5.0",
        "drupal/remove_meta_info": "^1.0",
        "drupal/core-vendor-hardening": "^9",
        "drupal/upgrade_status": "^4.1",
        "drupal/highlightjs_input_filter": "^1.1",
        "drupal/addtoany": "^2.0"
    },

 1317  composer require drupal/core-recommended:9.5.0 drupal/core-composer-scaffold:9.5.0 drupal/core-project-message:9.5.0 --update-with-all-dependencies



=> composer require 'drupal/bootstrap:^3.30'

Scaffolding files for drupal/core:
  - Copy [project-root]/.gitattributes from assets/scaffold/files/gitattributes
  - Copy [web-root]/.htaccess from assets/scaffold/files/htaccess
  - Copy [web-root]/robots.txt from assets/scaffold/files/robots.txt
  - Copy [web-root]/web.config from assets/scaffold/files/web.config
  - Copy [web-root]/sites/example.settings.local.php from assets/scaffold/files/example.settings.local.php


...
87 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
Scaffolding files for drupal/core:

In Filesystem.php line 288:

  Could not delete /dataglusterfs_mount/project.crx.cloud/html/sites/default/default.services.yml:


Mise à jour DRUPAL 9.5.0 à 10.2.3 puis 10.2.4 : 

Surement l’étape la plus difficile ici car le changement de version majeure implique l’obsolescence de pas mal de lib/thèmes côté DRUPAL :

root@crx-glust01 html # cat composer.json
{
    "name": "drupal/drupal",
    "description": "Drupal is an open source content management platform powering millions of websites and applications.",
    "type": "project",
    "license": "GPL-2.0-or-later",
    "require": {
        "composer/installers": "^1.0.24",
        "drupal/core": "10.2.4",
        "drupal/colorbox": "^2.0",
        "drupal/bootstrap": "^3.30",
        "drupal/bootstrap_library": "^2.0",
      "egulias/email-validator": "~4.0.2",
        "drupal/core-recommended": "10.2.4",
        "drupal/core-composer-scaffold": "10.2.4",
        "drupal/core-project-message": "10.2.4",
        "drupal/remove_meta_info": "^1.0",
        "drupal/core-vendor-hardening": "^9",
        "drupal/upgrade_status": "^4.1",
        "drupal/highlightjs_input_filter": "^1.1",
        "drupal/addtoany": "^2.0",
        "symfony/console": "^6.4",
        "guzzlehttp/guzzle": "^7.5",
        "drupal/classy": "*",
        "drupal/bartik": "^1.0",
        "drupal/seven": "^1.0",
        "drupal/bartik-bartik": "^1.0",
        "drupal/rdf": "^2.1",
        "drupal/quickedit": "^1.0",
        "drupal/color": "^1.0",
        "drupal/ckeditor": "*"
    },

...

composer require 'egulias/email-validator:^3.2.1' --update-with-dependencies --no-update
=> egulias/email-validator ~3.2.1

composer require 'symfony/console:^6.4' --update-with-dependencies --no-update
composer require 'egulias/email-validator:^4.0.2' --update-with-dependencies --no-update
 
=> egulias/email-validator[4.0.2]
=> drupal/addtoany 2.0.5
=> symfony/console ^6.4

composer remove 'drupal/core-dev:9.1.0'
composer require 'guzzlehttp/guzzle:^7.8.1' --update-with-dependencies --no-update
=> guzzlehttp/guzzle ~7.8.1

root@crx-webng03 html # composer prohibits drupal/core 10.2.3
root@crx-webng03 html # composer require drupal/core-recommended:10.2.3 drupal/core-composer-scaffold:10.2.3 drupal/core-project-message:10.2.3 --update-with-all-dependencies

composer require symfony/console:6.4 --no-update 

root@crx-webng03 html # composer require drupal/core-recommended:10.2.3 drupal/core-composer-scaffold:10.2.3 drupal/core-project-message:10.2.3 --update-with-all-dependencies
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Continue as root/super user [yes]? yes
./composer.json has been updated
Running composer update drupal/core-recommended drupal/core-composer-scaffold drupal/core-project-message --with-all-dependencies
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Root composer.json requires symfony/console ^6, found symfony/console[v6.0.0-BETA1, ..., 6.4.x-dev] but these were not loaded, likely because it conflicts with another require.
  Problem 2
    - Root composer.json requires drupal/core 10.2.3 -> satisfiable by drupal/core[10.2.3].
    - drupal/core 10.2.3 requires symfony/console ^6.4 -> found symfony/console[v6.4.0-BETA1, ..., 6.4.x-dev] but these were not loaded, likely because it conflicts with another require.
  Problem 3
    - Root composer.json requires drupal/core-recommended 10.2.3 -> satisfiable by drupal/core-recommended[10.2.3].
    - drupal/core-recommended 10.2.3 requires guzzlehttp/guzzle ~7.8.1 -> found guzzlehttp/guzzle[7.8.1, 7.8.x-dev] but these were not loaded, likely because it conflicts with another require.
  Problem 4
    - drupal/core 10.2.3 requires symfony/console ^6.4 -> found symfony/console[v6.4.0-BETA1, ..., 6.4.x-dev] but these were not loaded, likely because it conflicts with another require.
    - drupal/addtoany 2.0.5 requires drupal/core ^9.4 || ^10.0 -> satisfiable by drupal/core[10.2.3].
    - drupal/addtoany is locked to version 2.0.5 and an update of this package was not requested.

root@crx-webng03 html # composer require symfony/console:6.4.4 --no-update
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Continue as root/super user [yes]? yes
./composer.json has been updated

composer prohibits drupal/core 10.2.3

composer require symfony/*:6.4 --no-update

--------

root@crx-webng03 html # composer prohibits drupal/core 10.2.3
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Continue as root/super user [yes]? yes
drupal/drupal           -      requires         drupal/core (9.5.0)
drupal/core-recommended 9.5.0  requires         drupal/core (9.5.0)
drupal/core             10.2.3 requires         symfony/console (^6.4)
drupal/drupal           -      requires         symfony/console (4.4.49)
drupal/core             10.2.3 requires         symfony/dependency-injection (^6.4)
drupal/drupal           -      does not require symfony/dependency-injection (but v4.4.49 is installed)
drupal/core             10.2.3 requires         symfony/event-dispatcher (^6.4)
drupal/drupal           -      does not require symfony/event-dispatcher (but v4.4.44 is installed)
drupal/core             10.2.3 requires         symfony/filesystem (^6.4)
drupal/drupal           -      does not require symfony/filesystem (but v4.4.42 is installed)
drupal/core             10.2.3 requires         symfony/finder (^6.4)
drupal/drupal           -      does not require symfony/finder (but v4.4.44 is installed)
drupal/core             10.2.3 requires         symfony/http-foundation (^6.4)
drupal/drupal           -      does not require symfony/http-foundation (but v4.4.49 is installed)
drupal/core             10.2.3 requires         symfony/http-kernel (^6.4)
drupal/drupal           -      does not require symfony/http-kernel (but v4.4.51 is installed)
drupal/core             10.2.3 requires         symfony/mime (^6.4)
drupal/drupal           -      does not require symfony/mime (but v5.4.13 is installed)
drupal/core             10.2.3 requires         symfony/routing (^6.4)
drupal/drupal           -      does not require symfony/routing (but v4.4.44 is installed)
drupal/core             10.2.3 requires         symfony/serializer (^6.4)
drupal/drupal           -      does not require symfony/serializer (but v4.4.47 is installed)
drupal/core             10.2.3 requires         symfony/validator (^6.4)
drupal/drupal           -      does not require symfony/validator (but v4.4.48 is installed)
drupal/core             10.2.3 requires         symfony/process (^6.4)
drupal/drupal           -      does not require symfony/process (but v4.4.44 is installed)
drupal/core             10.2.3 requires         symfony/yaml (^6.4)
drupal/drupal           -      does not require symfony/yaml (but v4.4.45 is installed)
drupal/core             10.2.3 requires         twig/twig (^3.5.0)
drupal/drupal           -      does not require twig/twig (but v2.15.6 is installed)
drupal/core             10.2.3 requires         doctrine/annotations (^1.14)
drupal/drupal           -      does not require doctrine/annotations (but 1.13.3 is installed)
drupal/core             10.2.3 requires         guzzlehttp/guzzle (^7.5)
drupal/drupal           -      requires         guzzlehttp/guzzle (6.5.8)
drupal/core             10.2.3 requires         guzzlehttp/psr7 (^2.4.5)
drupal/drupal           -      does not require guzzlehttp/psr7 (but 1.9.1 is installed)
drupal/core             10.2.3 requires         asm89/stack-cors (^2.1)
drupal/drupal           -      does not require asm89/stack-cors (but 1.3.0 is installed)
drupal/core             10.2.3 requires         psr/log (^3.0)
drupal/drupal           -      does not require psr/log (but 1.1.4 is installed)
Not finding what you were looking for? Try calling `composer require "drupal/core:10.2.3" --dry-run` to get another view on the problem.
root@crx-webng03 html #


?? asm89/stack-cors
core_version_requirement: ^8 || ^9

Notes :

=> (à moi même)   C’est mal de lancer COMPOSER en root (   ajout d’un shell temporaire sur le www-data c’est mieux )       🙂

=> j’ai du désinstaller des thèmes/modules qui n’étaient plus valables en v10, pour le reste, j’ai du ajouter ce tag (sur les fichiers info.yml) :
‘  core_version_requirement: ^8 || ^9  ‘

=> j’ai aussi du réinstaller certaines >LIB en V10 pour ensuite les désactivées depuis l’interface d’administration :  ( messages remontés via update.php ) :

 1432  composer require drupal/core-recommended:10.2.3 drupal/core-composer-scaffold:10.2.3 drupal/core-project-message:10.2.3 --update-with-all-dependencies --no-update
 1461  composer require drupal/classy
 1463  composer require 'drupal/bartik:^1.0'
 1464  composer require 'drupal/seven:^1.0'
 1470  composer require 'drupal/bartik-bartik:^1.0'
 1472  composer require 'drupal/rdf:^2.1'
 1473  composer require 'drupal/quickedit:^1.0'
 1474  composer require 'drupal/color:^1.0'
 1495  composer require drupal/ckeditor
 1504  composer require drupal/core-recommended:10.2.4 drupal/core-composer-scaffold:10.2.4 drupal/core-project-message:10.2.4 --update-with-all-dependencies

Bon courage à vous pour vos mises à jour DRUPAL !

Voir aussi : https://bastien.barbe.pw/mise-a-jour-drupal-8-5-5-vers-8-5-6/

Update GITLAB-CE

Hello to all,

Hosting a GITLAB-CE solution (DEBIAN12 OS), I had to perform an update 14 to 16.
This is relatively long because you have to update in stages.

Fortunately the official site offers a tool to generate all the versions to use,
to arrive at the target version.

After migrate to DEBIAN12 i lost all gitlab repo, and finnaly i’ve done this update manually
version after version. Here is the process :

I retreive my gitlab version  here 14.2.1 and target to 16.9.1 :

# dpkg -l | grep gitlab 

Then i go to this site, to build my upgrade path :   ( 10 steps !!! )
https://gitlab-com.gitlab.io/support/toolbox/upgrade-path/?current=14.2.1&edition=ce

Basically after updating Debian 11 to 12, we have the GIT package which is ‘orphaned’,
we can see it via this command:

apt-show-versions | grep -i "no available version"

I go to this link to retreive all of packages needed :

https://packages.gitlab.com/app/gitlab/gitlab-ce/search?dist=debian&filter=all&page=1&q=

let’s go :

apt-get install gitlab-ce=14.3.6-ce.0
--------------------------------------	
	=> root@crx-git01 sources # wget https://packages.gitlab.com/gitlab/gitlab-ce/packages/debian/buster/gitlab-ce_14.3.6-ce.0_amd64.deb/download.deb
		
		mv download.deb gitlab-ce_14.3.6-ce.0_amd64.deb
		dpkg -i gitlab-ce_14.3.6-ce.0_amd64.deb

		...
		Keeping all older configuration backups
		Unpacking gitlab-ce (14.3.6-ce.0) over (14.2.1-ce.0) ...
		...
		...
		1709459914_2024_03_03_14.2.1_gitlab_backup.tar
		...

	Upgrade complete! If your GitLab server is misbehaving try running
		sudo gitlab-ctl restart

		root@crx-git01 sources # dpkg -l | grep git
		ii  gitlab-ce                      14.3.6-ce.0                    amd64        GitLab Community Edition (including NGINX, Postgres, Redis)


apt-get install gitlab-ce=14.9.5-ce.0
--------------------------------------
   => https://packages.gitlab.com/gitlab/gitlab-ce/packages/debian/buster/gitlab-ce_14.9.5-ce.0_amd64.deb

	root@crx-git01 sources # wget https://packages.gitlab.com/gitlab/gitlab-ce/packages/debian/buster/gitlab-ce_14.9.5-ce.0_amd64.deb/download.deb
		
	root@crx-git01 sources # wget https://packages.gitlab.com/gitlab/gitlab-ce/packages/debian/buster/gitlab-ce_14.9.5-ce.0_amd64.deb/download.deb
	--2024-03-03 11:08:46--  https://packages.gitlab.com/gitlab/gitlab-ce/packages/debian/buster/gitlab-ce_14.9.5-ce.0_amd64.deb/download.deb
	Resolving packages.gitlab.com (packages.gitlab.com)... 104.18.39.11, 172.64.148.245, 2606:4700:4400::6812:270b, ...
	Connecting to packages.gitlab.com (packages.gitlab.com)|104.18.39.11|:443... connected.
	HTTP request sent, awaiting response... 302 Found
	Location: https://d20rj4el6vkp4c.cloudfront.net/7/8/debian/package_files/127567.deb?t=1709460826_348df00b8ce7a24a8a77d0cd338f45a39ee4bba5 [following]
	--2024-03-03 11:08:46--  https://d20rj4el6vkp4c.cloudfront.net/7/8/debian/package_files/127567.deb?t=1709460826_348df00b8ce7a24a8a77d0cd338f45a39ee4bba5
	Resolving d20rj4el6vkp4c.cloudfront.net (d20rj4el6vkp4c.cloudfront.net)... 52.222.153.188, 52.222.153.182, 52.222.153.31, ...
	Connecting to d20rj4el6vkp4c.cloudfront.net (d20rj4el6vkp4c.cloudfront.net)|52.222.153.188|:443... connected.
	HTTP request sent, awaiting response... 200 OK
	Length: 1034232620 (986M) [application/x-debian-package]
	Saving to: 'download.deb'

	download.deb                                      100%[==========================================================================================================>] 986.32M  10.5MB/s    in 90s

	2024-03-03 11:10:17 (10.9 MB/s) - 'download.deb' saved [1034232620/1034232620]

	root@crx-git01 sources #  ll
	total 1010000
	-rw-r--r-- 1 root root 1034232620 Jun  1  2022 download.deb
	root@crx-git01 sources # dpkg -i download.deb
		
	root@crx-git01 sources # dpkg -l |grep git
	ii  gitlab-ce                      14.9.5-ce.0                    amd64        GitLab Community Edition (including NGINX, Postgres, Redis)

apt-get install gitlab-ce=14.10.5-ce.0
--------------------------------------
Running configuration backup
Creating configuration backup archive: gitlab_config_1709462867_2024_03_03.tar
/etc/gitlab/
/etc/gitlab/trusted-certs/
/etc/gitlab/gitlab-secrets.json
/etc/gitlab/gitlab.rb
Configuration backup archive complete: /etc/gitlab/config_backup/gitlab_config_1709462867_2024_03_03.tar
Keeping all older configuration backups
Unpacking gitlab-ce (14.10.5-ce.0) over (14.9.5-ce.0) ...


root@crx-git01 sources # dpkg -l |grep git

iU  gitlab-ce                      14.10.5-ce.0                   amd64        GitLab Community Edition (including NGINX, Postgres, Redis)

apt-get install gitlab-ce=15.0.5-ce.0
--------------------------------------
...
root@crx-git01 sources # dpkg -l |grep git
ii  gitlab-ce                      15.0.5-ce.0                    amd64        GitLab Community Edition (including NGINX, Postgres, Redis)

apt-get install gitlab-ce=15.4.6-ce.0
--------------------------------------
...
root@crx-git01 sources # dpkg -l |grep git
ii  gitlab-ce                      15.4.6-ce.0                    amd64        GitLab Community Edition (including NGINX, Postgres, Redis)
...

apt-get install gitlab-ce=15.11.13-ce.0
--------------------------------------
root@crx-git01 sources # dpkg -l |grep git
iU  gitlab-ce                      15.11.13-ce.0                  amd64        GitLab Community Edition (including NGINX, Postgres, Redis)
...

apt-get install gitlab-ce=16.1.6-ce.0
--------------------------------------
root@crx-git01 sources # dpkg -l |grep git
iU  gitlab-ce                      16.1.6-ce.0                    amd64        GitLab Community Edition (including NGINX, Postgres, Redis)

...

apt-get install gitlab-ce=16.3.7-ce.0
--------------------------------------
root@crx-git01 sources # dpkg -l |grep git
ii  gitlab-ce                      16.3.7-ce.0                    amd64        GitLab Community Edition (including NGINX, Postgres, Redis)
...

apt-get install gitlab-ce=16.7.6-ce.0
--------------------------------------
...
root@crx-git01 sources # dpkg -l |grep git
ii  gitlab-ce                      16.7.6-ce.0                    amd64        GitLab Community Edition (including NGINX, Postgres, Redis)


apt-get install gitlab-ce=16.9.1-ce.0
--------------------------------------
...

 

Have fun with your gitlab updates !

Threat Hunting with PHP and BASH.

After testing fail2ban, I decided to create my own tool (MyIPSPHP) because I needed a tool that did not directly use IP lists (sometimes paid) and above all I needed a tool specific to my WEB applications.

The functioning of the tool that I propose to you here is based on PHP and BASH as well as on the GEOIP library. It also allows alerts to be sent to my phone via « ntfy.sh ». I used CHATGPT to improve the filters (add new shells/exploits).

Finally I use this tool on a mail server, an apache service, an nginx service and an iptables/ulog firewall, the operation is sensitively the same, we parse the logs and we detect possible alerts (via counting of DROP ports for example for iptables over a day).

Here is the code for NGINX log (for reverse proxy setup here), the APACHE version is very similar, note that I mix PHP and BASH calls, this does not pose a particular problem even if a « full » php or « full » bash version would be even better :  (here the date filter scope is 60min)

If you want to test, don’t forget to set RUNMODE to 0 to enable the no-action mode (only output the ban action).

#!/usr/bin/php
<?php
#MyIPSPHP (c) f4eyq@crx.cloud - v1.0
#sec_check_nginxlogs.php
error_reporting(E_ALL);
#sec_check_nginxlogs.php
############################################################
define('DEVICE_FW_NAME','myrp01');
define('NTFY_URI','ntfy.sh/mycustomalert1245');
define('NGINX_LOG','/var/log/nginx/*.log');
define('WHITELIST_IPS',array('192.168','82.99.99.99'));
define('BLOCK_TIME_S',3888000); // 45 days(86400*45)
define('RUNMODE',1);#Running mode : 1 => Real (detect and bloc IP adresse), 0 => Dry run.
############################################################
require_once('/opt/security/libs/geo/geoip2.phar');
use GeoIp2\Database\Reader;
require_once('/opt/security/libs/libfw.php');
define('IP_LIST_BL','/opt/masscan_ip.txt');
define('DB_GEOLITE2_COUNTRY','/opt/security/libs/geo/GeoLite2-Country.mmdb');
#Prepare date filter :
#ex:  24/Mar/2023:18:16
$date_apache_d=date('j');
$date_apache_m=date('M');
$date_apache_Y=date('Y');
$date_apache_h=date('H');
$filder_current_h="$date_apache_d/$date_apache_m/$date_apache_Y:$date_apache_h";
echo "Run security Nginx log monitoring : ".$filder_current_h.".\n";
if(RUNMODE == 1){
 echo "Running real mode. \n";
}
$log_path       =       NGINX_LOG;
function detect_vuln($log_path, $filder_current_h, $scan_vuln, $message,$plugin='Default') {
    $dos=false;
    $cmd = "sudo cat $log_path | grep '$filder_current_h' | grep -E '$scan_vuln' | awk '{ print $1}' | sort | uniq -c | sort | ".genPaternGrepv()." | grep -v '/'";

    #Scan all archives :
    #$cmd = "sudo zcat $log_path*gz | grep -E '$scan_vuln' | awk '{ print $1}' | sort | uniq -c | sort | ".genPaternGrepv()." | grep -v '/'";

    if($plugin=='Dos'){
        $cmd="sudo cat $log_path | grep '$filder_current_h' | awk '{ print $1}' | sort | uniq -c | sort | ".genPaternGrepv()." | grep -v '/'";
        $dos=true;
    }

    if($plugin=='Googlebot'){
        $scan_vuln = 'Googlebot';
        $ggrange = '66.249';
        $cmd = "sudo cat $log_path | grep '$filder_current_h' | grep -E -v '".$ggrange."' | grep -E '$scan_vuln' | awk '{ print $1}' | sort | uniq -c | sort | ".genPaternGrepv()." | grep -v '/'";
        #Scan all archives :
        #$cmd = "sudo zcat $log_path*gz | grep -E -v '".$ggrange."' | grep -E '$scan_vuln' | awk '{ print $1}' | sort | uniq -c | sort | ".genPaternGrepv()." | grep -v '/'";
    }

    $now      = time();
    $ban_end  = $now + BLOCK_TIME_S;

    $check = `$cmd`;
    $statsbrut = explode(PHP_EOL, $check ?? '');
    foreach($statsbrut as $k=>$line){
        preg_match('!\d+\.*\d*!', $line, $matches);
        if(isset($matches[0])){
           $hits=(int)$matches[0];
           preg_match('!\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}!', $line, $matches);
           if(isset($matches[0]) && !checkIfIPIsLog2($matches[0])){

              $ip=$matches[0];

              $t=0;

              if($dos)
                $t=8000;

              if($hits>$t){
                $str=dspMessage($hits,$ip,$message);
                if(RUNMODE == 1){

                        echo "$str \n";

                        logm($str);

                        sendAlert($str);
                        blockIp($ip);

                        $log="$ip|$ban_end";
                        addIPinLog($log);

                }
                else{
                        echo "Dry mode : \n";
                        echo $str."\n";
                }
              }
           }
        }
    }
}

###########################################
##Exploit/Vuln
# w00tw00 / mstshash / nmaplowercheck ...
# Detect  rdp/nmap call.
###########################################
$scan_vuln = '/boaform/admin|mstshash|nmaplowercheck|w00tw00t|\.\.\/.\.\/|/bin/sh|Apache/2|apache/2|cgi-bin/|/HNAP1|/Tri%6Eity.txt%2ebak';
$message = 'Alert try2call exploit on '.DEVICE_FW_NAME;
detect_vuln($log_path, $filder_current_h, $scan_vuln, $message);

###########################################
#Detect Webshell / autodiscover
# like  vuln.php, shell.php, alfashell.php
###########################################
$scan_vuln = '/IOptimize.php|/vuln.php|/marijuana.php|/shell.php|/alfashell.php|/autodiscover|/eval-stdin.php|/alfacgiapi/perl.alfa|/ALFA_DATA|/alfashell.php|/alfa.php|/c99.php|/r57.php|/wso.php|/b374k.php|/phpshell.php|/tryag.php|/FilesMan.php|/zehir.php|/izocin.php|/milw0rm.php|/cgitelnet.php|/darkmail.php|/GFS-webshell.php|/ANTICHAT_SHELL.php|/AntichatShell.php|/antichat.php|/php-backdoor.php|/php-backdoor2.php|/php-backdoor3.php|/php-webshells.php|/php-remoteview.php|/FSOCK.php|/jackal.php|/wsoshell.php|/php-spy-shells.php|/c99ud.php|/c100.php|/c99shell.php|/r57shell.php|/kacak.php|/ToolsBrasil.php|/cyber_shell.php|/WebShell.php|/simple-backdoor.php|/php-backdoor4.php';
$message = 'Alert try2call webshell on '.DEVICE_FW_NAME;
detect_vuln($log_path, $filder_current_h, $scan_vuln, $message);

####################################
# Detect webadmin Call :
####################################
$scan_vuln='/sqlbuddy/login.php|/phpma/|/phpMyAdmin/|/pmamy2/|/PHPMYADMIN/|/mymanage/|/manage/|/manager/|/mysql/|/mysql-admin/|/mysqladmin/|/mysqlmanager/|/myadmin/|/mydb/|/phpmyadmin2/|/phpmyadmin3/|/phpmyadmin4/|/phpMyAdmin-3/|/phpMyAdmin-4/|/phpMyAdmin-5/|/phpMyAdmin-6/|/phpmyadmin-old/|/phpmyadmin2/|/phpmyadmin3/|/phpmyadmin4/|/phpmyadmin5/|/phpMyExplorer/|/pma/|/PMA2/|/PMA3/|/PMA4/|/PMA5/|/PMA6/|/PMA2005/|/PMA2006/|/PMA2007/|/PMA2008/|/PMA2009/|/PMA2010/|/PMA2011/|/PMA2012/|/PMA2013/|/PMA2014/|/PMA2015/|/PMA2016/|/PMA2017/|/PMA2018/|/PMA2019/|/PMA2020/|/PMA2021/|/PMA2022/|/pma-old/|/pma2005/|/pma2006/|/pma2007/|/pma2008/|/pma2009/|/pma2010/|/pma2011/|/pma2012/|/pma2013/|/pma2014/|/pma2015/|/pma2016/|/pma2017/|/pma2018/|/pma2019/|/pma2020/|/pma2021/|/pma2022/|/PMA-old/|/adminer/|/dbadmin/|/sqladmin/|/myadmin/|/sqlyog/|/emysql/|/websql/|/adminsql/|/sqlweb/|/mysqlgui/|/dbtool/|/dbweb/|/sqleditor/|/sqlmanager/|/sqlbuddy/|/datadmin/|/dbVisualizer/|/sqlworkbench/|/heidiSQL/|/navicat/|/toad/|/phpsqliteadmin/|/sqliteadmin/|/SQLiteManager/|/adminer.php';

$message = 'Alert try2call web-admin on '.DEVICE_FW_NAME;
detect_vuln($log_path, $filder_current_h, $scan_vuln, $message);

####################################
# Detect Configuration collector
####################################
$scan_vuln='/phpinfo.php|/.env|/.env.bak|config.php.bak|settings.php.bak|wp-config.php.bak|settings.py|.sqlite|database.php.bak|config.inc.php.bak|config.yml.bak';
$message = 'Alert try2collect conf on '.DEVICE_FW_NAME;
detect_vuln($log_path, $filder_current_h, $scan_vuln, $message);

###########################
#Detect SQL injection :
###########################
$scan_vuln='SELECT%20|INSERT%20|UPDATE%20|UNION%20|AND%20|DROP%20|DESCRIBE%20|DELETE%20|TRUNCATE%20|SELECT%20INTO%20|OR%20';
$message = 'Alert detect SQL injection on '.DEVICE_FW_NAME;
detect_vuln($log_path, $filder_current_h, $scan_vuln, $message);

###########################
#Detect DDOS :
###########################
$plugin = 'Dos';
$message = 'Alert DDOS on '.DEVICE_FW_NAME;
detect_vuln($log_path, $filder_current_h, $scan_vuln, $message,$plugin);

##########################
#Detect fake google bot
##########################
$plugin  = 'Googlebot';
$message = 'Alert fake GoogleBot on '.DEVICE_FW_NAME;
detect_vuln($log_path, $filder_current_h, $scan_vuln, $message,$plugin);

###########################
#Uban process :
###########################
uBanProcess();
sec_check_nginxlogs.php

Here is the Firewall version :  (here the date filter scope is 24 hours)

<?php
#MyIPSPHP (c) f4eyq@crx.cloud - v1.0
#sec_check_fw.php
define('BLOCK_TIME_S',5184000); // 60 days ( 86400 x 60 )
define('TRIGGER_threshold_portscan',20);

#Prepare date filter :
##ex: Mar 27 09:43:47
$date_apache_d=date('j');
$date_apache_d=str_pad($date_apache_d,3,' ',STR_PAD_LEFT);
$date_apache_m=date('M');
$date_apache_Y=date('Y');
$filder_current_h = $date_apache_m.$date_apache_d;

#replay / all archives logs :
#$cmd = "zcat /var/log/auth.log*gz | grep 'invalid' | grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' |cut -d ':' -f 5 | cut -d ' ' -f 4 | sort | ".genPaternGrepv()." | uniq -c";

$cmd="cat $alog | grep '".$filder_current_h."' | grep 'DROP' | cut -d '=' -f 5 |cut -d ' ' -f 1 | ".genPaternGrepv()." | sort | uniq -c";

$check = `$cmd`;

$now      = time();
$ban_end  = $now + BLOCK_TIME_S;
$statsbrut = explode(PHP_EOL, $check ?? '');

#ex:Mar 28 05:53:51 server2343 znet-zfw DROP  IN=eno1 OUT= MAC=d0:30:99:d7:6b:fc:a0:b4:31:cf:1b:41:08:00 SRC=22.22.22.22 DST=23.23.23.23 LEN=28 TOS=00 PREC=0x00 TTL=34 ID=34354 PROTO=UDP SPT=21345 DPT=1194 LEN=8 MARK=0
foreach($statsbrut as $k=>$line){
        preg_match('!\d+\.*\d*!', $line, $matches);
        if(isset($matches[0])){
           $hits=(int)$matches[0];
           preg_match('!\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}!', $line, $matches);
           if(isset($matches[0]) && !checkIfIPIsLog2($matches[0])){
               if($hits>TRIGGER_threshold_portscan){
                 $ip=$matches[0];
                 #echo "$ip, $hits \n";
                 $log="$ip|$ban_end";
                 #echo "Ban end:".date('d/m/y H:i',$ban_end).' - '.$ip." - $hits \n";
                 if(RUNMODE == 1){
                        #now check if port is different / count uniq item ( DPT=(X) )
                        $cmd="cat /var/log/ulog/syslogemu.log | grep '".$filder_current_h."' | grep '$ip' | cut -d '=' -f 14 | cut -d ' ' -f 1 | sort | uniq | wc -l";
                        $check = `$cmd`;
                        $check = (int) $check;
                        if($check>=TRIGGER_threshold_portscan)  {
                                $message = 'Alert portscanning on '.DEVICE_FW_NAME;
                                $str=dspMessage($hits,$ip,$message);
                                echo "Ban end:".date('d/m/y H:i',$ban_end).' - '.$ip." - $hits => $check \n";
                                logm($str);
                                sendAlert($str);
                                blockIp($ip);
                                addIPinLog($log);
                        }
                 }
                 else{
                        echo "Dry mode : \n";
                        echo $str."\n";
                 }

               }
           }
        }
}

And the small php lib use for various task like ban/uban and new ip in blacklist db etc :

<?php
#MyIPSPHP (c) f4eyq@crx.cloud - v1.0
#libs/libfw.php
use GeoIp2\Database\Reader;
function logm($m){
   $m2=date('d/m/Y H:i:s') . ": \n" . $m;
   $e = `echo "$m2" >> /var/log/securitychecks.log`;
}
function genPaternGrepv(){
  $nb=count(WHITELIST_IPS);
  $str='';
  $i=1;
  foreach(WHITELIST_IPS as $k=>$ip){
     $str.="grep -v '$ip'";
     if($i<$nb){
       $str.=" | ";
     }
   $i++;
  }
  return $str;
}
function checkIfIPIsLog2($ip){
        $l=IP_LIST_BL;
        $test = trim(`cat $l |grep '$ip|';echo $1;`);
        if($test<>''){
          return true;
        }
        return false;
}
function addIPinLog($ip){
        $l=IP_LIST_BL;
        $test= `echo "$ip" >> $l`;
}
function remoteIPFromLog($ip,$ipl){
        $e=`grep -v '$ip' $ipl > temp && mv temp $ipl`;
}
function blockIp($ip){
        $a=`ip route add blackhole $ip`;
}
function uBanIp($ip){
        $a=`ip route del blackhole $ip`;
}
function sendAlert($str){
       $uri=NTFY_URI;
       $a=`curl -d "$str" $uri`;
}
function dspMessage($hits,$ip,$message){
        $str=$message."\nBlock Ip: $hits => $ip,";
        $str.="\nCountry : ".getIpInfo($ip,'cn').".\n";
        return $str;
}
function getIpInfo($ip,$t='cn'){
        $reader = new Reader(DB_GEOLITE2_COUNTRY);
        $record = $reader->country($ip);
        if($t=='cn')return $record->country->name;
        if($t=='iso')return $record->country->isoCode;
}
function uBanProcess(){
$now      = time();
#Uban process :
$ipl=IP_LIST_BL;
$cmd="cat $ipl";
$check=`$cmd`;
$statsbrut = explode(PHP_EOL, $check ?? '');
#Format :   141.98.10.172|1681208329
#              IP        |    UBAN time (end ban)
foreach($statsbrut as $k=>$line){
   $p=explode('|',$line);
   if(isset($p[0]))$p[0]=trim($p[0]);
   if(isset($p[0]) && $p[0]<>''){
        $ip=$p[0];
        $bt=(int)$p[1];
        if($bt<=$now){
          #delete ip route
          uBanIp($ip);
          #echo "Uban $ip\n";
          remoteIPFromLog($ip,$ipl);
        }
   }
}
}

?>
libs/libfw.php

Finaly i’m using a CRON to launch the script every 1min :

*/1 * * * * /opt/security/sec_check_nginxlogs.php >> /dev/null 2>&1

Configuration WSL/VISUALSTUDIO CODE.

Bonjour à tous,

Si votre éditeur vous renvoi un message indiquant que votre instance WSL n’est pas en V2, CTRL+MAJ+u  puis :
wsl_term

Lancez un powershell en tant qu’administrateur puis :

PS C:\Users\tux> wsl --list --verbose
NAME STATE VERSION
* Debian Stopped 1
PS C:\Users\bba>

Lancez ensuite cette commande pour convertir l’image WSL ici « Debian » :

PS C:\Users\tux> wsl --set-version Debian 2

Enfin vous pouvez décider que toutes vos images soient en V2 via cette commande :

PS C:\WINDOWS\system32> wsl --set-default-version 2
Pour plus d’informations sur les différences de clés avec WSL 2, visitez https://aka.ms/wsl2
L’opération a réussi.

Et voilà !

wsl --list --verbose
  NAME      STATE           VERSION
* Debian    Running         2

Sources :
https://docs.microsoft.com/fr-fr/windows/wsl/troubleshooting
https://aka.ms/wsl2

Gestion des mises à jour LINUX suite, cibler les mises à jour de sécurité

Bonjour à tous,

Suite à mon petit article d’introduction à ANSIBLE et les mises à jour LINUX ici : automatisation-de-la-gestion-des-utilisateurs-et-des-mises-a-jour
Je vous propose ici de gérer une ou plusieurs mises à jour de sécurité en mode « automatique » toujours avec ANSIBLE.

Dans mon exemple ici je pars du principe que j’ai un ensemble de serveurs à mettre à jour ( en cas de mise à jour urgente à faire ),
Que j’ai un accès SSH sur ceux-ci et que je dispose de la couche ANSIBLE opérationnelle :

Je commence par identifier la mise à jour à faire via cette commande :

# apt-cache policy php8.0-memcache
php8.0-memcache:
  Installed: 8.0+4.0.5.2+3.0.9~20170802.e702b5f9+-1+0~20210302.23+debian10~1.gbpff8707
  Candidate: 8.0+4.0.5.2+3.0.9~20170802.e702b5f9+-7+0~20220117.28+debian10~1.gbp8ceec4
  Version table:
     8.0+4.0.5.2+3.0.9~20170802.e702b5f9+-7+0~20220117.28+debian10~1.gbp8ceec4 500
        500 https://packages.sury.org/php buster/main amd64 Packages
 *** 8.0+4.0.5.2+3.0.9~20170802.e702b5f9+-1+0~20210302.23+debian10~1.gbpff8707 100
        100 /var/lib/dpkg/status

Je déduis donc que le paquet cible à déployer est :

php8.0-memcache:8.0+4.0.5.2+3.0.9~20170802.e702b5f9+-7+0~20220117.28+debian10~1.gbp8ceec4

Dans cet exemple, il s’agit d’une simple mise à jour, bien sur cela peut être une mise à jour de sécurité ou encore un paquet à installer
comme nous l’avons vu précédemment.

Maintenant, je peux donc utiliser ce playbook, notez ici l’utilisation du signe  » =  » comme mentionné dans la documentation ANSIBLE,
Voici mon code YAML :    crx-awx/upgrade_package.yml

---

- hosts: all
  become: yes
  tasks:
    - name: Install the package
      apt:
        name: php8.0-memcache=8.0+4.0.5.2+3.0.9~20170802.e702b5f9+-7+0~20220117.28+debian10~1.gbp8ceec4
        update_cache: yes

Je peux donc le lancer via cette commande :

bba@crx-ans01 ~ $ ansible-playbook crx-awx/upgrade_package.yml --limit crx-webng04.crxcluster.lan

PLAY [all] **********************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************
ok: [crx-webng04.crxcluster.lan]

TASK [Install the package] ******************************************************************************************************************************************************************************************************************
[WARNING]: Updating cache and auto-installing missing dependency: python3-apt
changed: [crx-webng04.crxcluster.lan]

PLAY RECAP **********************************************************************************************************************************************************************************************************************************
crx-webng04.crxcluster.lan : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

bba@crx-ans01 ~ $

Ensuite je contrôle que tout est bon :

# apt-cache policy php8.0-memcache
php8.0-memcache:
  Installed: 8.0+4.0.5.2+3.0.9~20170802.e702b5f9+-7+0~20220117.28+debian10~1.gbp8ceec4
  Candidate: 8.0+4.0.5.2+3.0.9~20170802.e702b5f9+-7+0~20220117.28+debian10~1.gbp8ceec4
  Version table:
 *** 8.0+4.0.5.2+3.0.9~20170802.e702b5f9+-7+0~20220117.28+debian10~1.gbp8ceec4 500
        500 https://packages.sury.org/php buster/main amd64 Packages
        100 /var/lib/dpkg/status

Ou je peux aussi le contrôler via cette commande ANSIBLE :

$ ansible crx-webng04.crxcluster.lan -a "apt-cache policy php8.0-memcache" | grep -- 'Installed\|Candidate'
  Installed: 8.0+4.0.5.2+3.0.9~20170802.e702b5f9+-7+0~20220117.28+debian10~1.gbp8ceec4
  Candidate: 8.0+4.0.5.2+3.0.9~20170802.e702b5f9+-7+0~20220117.28+debian10~1.gbp8ceec4
b

Et voilà j’ai pu mettre à jour simplement un paquet via un processus ANSIBLE.

 

A bientôt,

 

Automatisation de la gestion des utilisateurs et des mises à jour.

 

Ce petit article à pour but de présenter « une gestion des utilisateurs et des mises à jour système » ( ici sous LINUX/DEBIAN ),
avec un système centralisé appelé « ANSIBLE ».

ANSIBLE permet via le protocole SSH de gérer des configurations et d’automatiser des actions (comme des installations d’applications par exemple),
sur des serveurs « distants » ceci est aussi appelé « infrastructure as code ».

Prérequis :

ANSIBLE est installé sur ma machine locale et aussi sur mon serveur distant,
pour commencer j’ai créé le référentiel de mes machines  » /home/bba/hosts  » :

bba@crx-ans01 ~ $ cat hosts
[webserversdev]
crx-dev01.crxcluster.lan

Soit un serveur « crx-dev01.crxcluster.lan » qui se trouve dans un groupe appelé « webserversdev ».
On n’est pas obligé d’utiliser un FQDN, une IP suffit.

Voici ma configuration ANSIBLE :

bba@crx-ans01 ~ $ cat ansible.cfg
[defaults]
interpreter_python = auto_silent
inventory       =  /home/bba/hosts

bba@crx-ans01 ~ $ ansible-config dump --only-changed
DEFAULT_HOST_LIST(/home/bba/ansible.cfg) = [u'/home/bba/hosts']
INTERPRETER_PYTHON(/home/bba/ansible.cfg) = auto_silent

La commande « only-changed » m’assure que ANSIBLE a bien parsé mon fichier de configuration,
Et cela va m’afficher que les variables qui changent par rapport à la configuration globale ( /etc/ansible/ansible.cfg ).

Notez que :
-> interpreter_python = auto_silent   :   permet d’éviter les messages de ce type au lancement d’un playbook :

[WARNING]: Platform linux on host crx-dev01.crxcluster.lan is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.


1. Gestion des utilisateurs

L’objectif ici est de gérer mes utilisateurs avec ANSIBLE, les clés SSH sont dans ce dossier « ssh-keys ».
Je commence donc par créer ce dossier à la racine de mon projet :

ssh-keys-dep/

Ensuite j’ajoute la clé publique SSH pour chaque utilisateur que je vais déployer, ici mon utilisateur est « f4eyq » :

ssh-keys-dep/f4eyq.pub

Maintenant je vais créer un script ANSIBLE aussi appelé « playbook », pour utiliser ce dossier et créer / supprimer un utilisateur.
=> L’instruction « become: yes » va simplement exécuter les commandes en « root » :

bba@crx-ans01 ~ $ cat add-remote-user-ssh.yml
---
- name: Create new user
  hosts: all
  #  vars:
  #  - user_password: 'test'
  #  - user_login: 'f4eyq'

  gather_facts: no
  become: yes

  tasks:
    - name: Add a new user
      user:
          name: "{{ user_login }}"
          shell: /bin/bash

          password: "{{ user_password | password_hash('sha512') }}"
          groups: sudo

          #remove user :
          #state: absent
          #remove: yes

    - name: Deploy SSH Key
      authorized_key:
        user: "{{ user_login }}"
        key: "{{ lookup('file', 'ssh-keys-dep/{{ user_login }}.pub') }}"
        state: present
        exclusive: True

Je peux ensuite l’appeler pour créer mon utilisateur « f4eyq » avec mon mot de passe « test »,
cela va créer l’utilisateur le mettre dans le groupe que j’ai indiqué et cela va créer son home enfin déployer sa clé SSH :

bba@crx-ans01 ~ $ ansible-playbook add-remote-user-ssh.yml --limit webserversdev  --extra-vars "user_password=test user_login=f4eyq"

PLAY [Create new user] ****************************************************************************************************************************************************************************************

TASK [Add a new user] *****************************************************************************************************************************************************************************************
changed: [crx-dev01.crxcluster.lan]

TASK [Deploy SSH Key] *****************************************************************************************************************************************************************************************
changed: [crx-dev01.crxcluster.lan]

PLAY RECAP ****************************************************************************************************************************************************************************************************
crx-dev01.crxcluster.lan   : ok=2    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Si par le suite je dois mettre la clé à jour, j’édite simplement le fichier dans le dossier « ssh-keys-dep » et relance le playbook.
Enfin pour supprimer l’utilisateur je décommente ceci dans le playbook :

          #state: absent
          #remove: yes

Et je relance le tout.

Notez que :
-> le home de l’utilisateur est supprimé sur le serveur cible ainsi que toute existence sur le serveur ( passwd/ group ) donc faut bien contrôler vos commandes 🙂
-> pour changer le mot de passe de l’utilisateur rejouer simplement le playbook avec un nouveau mot de passe.

2. Gestion des mises à jour

Pour ce faire j’utilise le playbook suivant :

bba@crx-ans01 ~ $ cat debian_upgrade2.yml
---
 - name: Update servers OS
   hosts: all
   become: true
   tasks:
    - name: Update cache and packages
      register: updatesys
      apt:
        name: "*"
        state: latest
        update_cache: yes

    - name: Check status
      debug:
        msg: "{{updatesys.stdout_lines}}"
        #msg:  "{{updatesys.stdout_lines|last}}"

Ensuite pour lancer ma mise à jour uniquement sur mon serveur de dev qui dans le groupe « webserversdev »,
Je lance ceci :

bba@crx-ans01 ~ $ ansible-playbook debian_upgrade2.yml --limit webserversdev

PLAY [Update servers OS] **************************************************************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************************************************************************
ok: [crx-dev01.crxcluster.lan]

TASK [Update cache and packages] ******************************************************************************************************************************************************************************
ok: [crx-dev01.crxcluster.lan]

TASK [Check status] *******************************************************************************************************************************************************************************************
ok: [crx-dev01.crxcluster.lan] => {
    "msg": "Building tag database..."
}

PLAY RECAP ****************************************************************************************************************************************************************************************************
crx-dev01.crxcluster.lan   : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Pour afficher le détail et pas juste la dernière ligne j’indique simplement :

msg: "{{updatesys.stdout_lines}}"
à la place de :
msg: "{{updatesys.stdout_lines|last}}"
bba@crx-ans01 ~ $ ansible-playbook debian_upgrade2.yml --limit webserversdev

PLAY [Update servers OS] **************************************************************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************************************************************************
ok: [crx-dev01.crxcluster.lan]

TASK [Update cache and packages] ******************************************************************************************************************************************************************************
ok: [crx-dev01.crxcluster.lan]

TASK [Check status] *******************************************************************************************************************************************************************************************
ok: [crx-dev01.crxcluster.lan] => {
    "msg": [
        "Reading package lists...",
        "Building dependency tree...",
        "Reading state information...",
        "Reading extended state information...",
        "Initializing package states...",
        "Writing extended state information...",
        "Building tag database...",
        "No packages will be installed, upgraded, or removed.",
        "0 packages upgraded, 0 newly installed, 0 to remove and 0 not upgraded.",
        "Need to get 0 B of archives. After unpacking 0 B will be used.",
        "Writing extended state information...",
        "Reading package lists...",
        "Building dependency tree...",
        "Reading state information...",
        "Reading extended state information...",
        "Initializing package states...",
        "Writing extended state information...",
        "Building tag database..."
    ]
}

PLAY RECAP ****************************************************************************************************************************************************************************************************
crx-dev01.crxcluster.lan   : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

A partir de là, il est possible via une CRON d’automatiser complétement les mises à jour de serveurs, si vous souhaitez un outil graphique,
ANSIBLE-AWX permet de gérer cela via une interface WEB.

Bonne automatisation à tous !

Configuration de l’hyperviseur XEN sous Ubuntu.


Bonjour à tous,

je vous propose ici un petit guide d’utilisation de XEN sur UBUNTU,

Bonne lecture !


1. Configuration de l’hyperviseur sous UBUNTU 

Ici j’utilise la version Focal (20.04.2 LTS).

1.1. Installation de XEN

Je commence par installer XEN, l’outil de création de VM et aussi l’outil qui permet de créer des ponts réseau :

# sudo apt-get install xen-hypervisor-amd64 xen-tools bridge-utils

1.2. Configuration du démarrage de XEN

Je configure 2G de RAM dédié au serveur (appelé ici Domain-0), c’est la peine de mettre trop de RAM car c’est utilisé uniquement pour gérer les machines virtuelles qui vont tourner,
Tout le reste de la RAM sera disponible pour les machines virtuelles :

# sudo vim /etc/default/grub.d/xen.cfg

#Je change cette ligne : 
GRUB_CMDLINE_XEN_DEFAULT="dom0_mem=2048M,max:2048M"

#Puis je met à jour GRUB : 
sudo update-grub

#Et reboot le tout : 
#sudo reboot

1.3. Configuration réseau de l’hyperviseur

La configuration réseau est effectuée via NETPLAN (qui remplace le classique /etc/network/interfaces)
voir ici : https://netplan.io/

Pour que XEN fonctionne il faut activer un pont entre les VM et le réseau LAN, par défaut c’est xenbr0, ici je l’appel br0,
Je viens donc ajouter le bloc « br0 », celui ci va prendre la configuration de l’interface eno1 ( équivalent à eth0 avant ), du coup
je passe la configuration d’en0 à br0.

#configuration avec NETPLAN : 
# cat /etc/netplan/00-installer-config.yaml
network:
 version: 2
 ethernets:
    eno1:
     dhcp4: false
     dhcp6: false
 bridges:
    br0:
      interfaces: [eno1]
      addresses: [192.168.1.233/24]
      gateway4: 192.168.1.1
      mtu: 1500
      nameservers:
        addresses: [8.8.8.8,8.8.4.4]
      parameters:
        stp: true
        forward-delay: 4
      dhcp4: no
      dhcp6: no

Une fois en place, j’applique la configuration NETPLAN et je redémarre le tout :

# netplan generate 
# netplan --debug apply


2.1 Création et configuration de la VM LINUX

J’installe ici une machine virtuelle UBUNTU 18 (Bionic), j’aurai pu prendre une DEBIAN, mais c’est plus simple à gérer côté KERNEL LINUX vu qu’on a un fichier KERNEL local disponible sur l’hyperviseur.

Je lance la création de la VM  » vmlinux1  » grâce à cette commande :

# xen-create-image --dist=bionic --hostname vmlinux1 --randommac --netmask=255.255.255.0 --ip=192.168.1.77 --gateway=192.168.1.1 --dir /vmroot/vmlinux1 --size=18G --role=udev

Si vous chercher la liste des distributions disponibles c’est ici :

/usr/share/xen-tools/
artful.d/         common/           etch.d/           fedora-core-17.d/ gentoo.d/         lucid.d/          raring.d/         trusty.d/         zesty.d/
bionic.d/         common.sh         fedora-core-10.d/ fedora-core-4.d/  gutsy.d/          maverick.d/       sarge.d/          unstable.d/
bookworm.d/       cosmic.d/         fedora-core-11.d/ fedora-core-5.d/  hardy.d/          natty.d/          saucy.d/          utopic.d/
bullseye.d/       dapper.d/         fedora-core-12.d/ fedora-core-6.d/  intrepid.d/       oldoldstable.d/   sid.d/            vivid.d/
buster.d/         debian.d/         fedora-core-13.d/ fedora-core-7.d/  jaunty.d/         oldstable.d/      squeeze.d/        wheezy.d/
centos-4.d/       devel.d/          fedora-core-14.d/ fedora-core-8.d/  jessie.d/         oneiric.d/        stable.d/         wily.d/
centos-5.d/       disco.d/          fedora-core-15.d/ fedora-core-9.d/  karmic.d/         precise.d/        stretch.d/        xenial.d/
centos-6.d/       edgy.d/           fedora-core-16.d/ feisty.d/         lenny.d/          quantal.d/        testing.d/        yakkety.d/

Pour ma VM, j’utilise un stockage fichier et non LVM, une fois la commande lancée, je fais quelques ajustements côté configuration, le fichier suivant est créé automatiquement à la création de la VM :

/etc/xen/vmlinux1.cfg

J’indique simplement que ma VM va utiliser l’interface « br0 » comme bridge en ajoutant « bridge=br0 », puis démarre la VM :

vif         = [ 'ip=192.168.1.77 ,mac=00:16:3E:3A:92:12, bridge=br0' ]
#démarrage de la VM : 
#xl create /etc/xen/vmlinux1.cfg

#listage des VM qui tourne via : 
#xl list 


2.2 Problèmes rencontrés et opérations diverses :

Sur l’hyperviseur :

j’ai du désactiver la sécurité du KERNEL le temps de faire la configuration, pour ce faire :

sudo systemctl disable apparmor
sudo reboot

Puis j’ai tout réactiver, une fois ma VM en place :

sudo systemctl enable apparmor
sudo systemctl start apparmor

Pour la VM, ici c’est la distribution UBUNTU « minimale » qui est installée (l’éditeur vim se lance via la command editor),
la configuration réseau se fait via :

# sudo editor /etc/netplan/01-netcfg.yaml
# sudo netplan generate 
# sudo netplan --debug apply

Cela me donne :

# cat /etc/netplan/01-netcfg.yaml

# Arno: Set static IP for VM interface eth0
network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      addresses: [192.168.1.77/24]
      gateway4: 192.168.1.1
      nameservers:
          addresses: [8.8.8.8]

Une fois la VM installée, il faut refaire la configuration via NETPLAN et tester la configuration DNS via :

#Test DNS : 
# systemd-resolve --status

Enfin pour lancer la VM automatiquement je fais ceci sur l’hyperviseur :

mkdir -p /etc/xen/auto/
ln -s /etc/xen/vmlinux1.cfg /etc/xen/auto/vmlinux1.cfg

Le dossier « auto » est scanné par le script : /etc/init.d/xendomains et sa configuration : /etc/default/xendomains.

Voilà j’espère que cela vous aura été utile !

HAM – Web-sdr setup

Date : 17/11/2020
Update : 18/11/2020

Hello everybody,

In this article i want to present my SDR setup, it run with Whip Antenna by OK2ZI,
An SDR Dongle with a frequency convertor and a simple Raspberry PI.

Here is my SDR installation directly on my terrace (I brought in 5V and 12V):

[Whip-Antenna] ——— [ Alim/Adaptator]——–[down-converter]——-[sdr-dongle]——–[PI4]———[ethernet+12V/5V]

Here I soldered the connection cable directly to the card with the SDR USB key
and all equipment takes place in a waterproof case :

valise etanche sdrsdr soudure pictail

Here is the active antenna that we see in gray attached to the top of my mast :

antenne active

In next article i will show how to configure software with Raspberry and SDR on Windows.

73 s

Sources :

Equipement SDR and converter come from :
https://www.passion-radio.fr/

Active Antenna come from Bangood :
« ANTENNE ACTIVE 10KHZ À 30MHZ MINI FOUET HF LF VLF VHF SDR RX AVEC CÂBLE PORTABLE »
Based on OK2ZI work : http://www.ok2zi.cz/whipkit.pdf

Rack project :
https://www.peli.com

HAM – SETUP RASPBERRY PI for remote station via installer script.

Hello to all,

Configure your RASPBERRY PI 4 with CRX-COM + VOIP and FLRIG,
via these « installer » scripts : https://git.crx.cloud/f4eyq/crx-com/tree/master/scripts

See SETUP here :  https://git.crx.cloud/f4eyq/crx-com/blob/master/scripts/README.md
Setup is done via the single line :  ( it download and launch the DEBIAN installer ) :

wget --output-document /tmp/setupcrx.bash https://git.crx.cloud/f4eyq/crx-com/raw/master/scripts/setup_server.bash;chmod +x /tmp/setupcrx.bash;/tmp/setupcrx.bash;

The configuration work via a single file : « station.conf » :

pi@rmtrpi4f4eyq remote $ ll
total 16
-rw-r--r-- 1 root root 47 sept. 30 11:43 station.conf
lrwxrwxrwx 1 root root 36 sept. 30 11:49 voip.conf -> /opt/crx/conf/remote/voip_hight.conf
-rw-r--r-- 1 root root 33 sept. 30 11:49 voip_hight.conf
-rw-r--r-- 1 root root 31 sept. 30 11:49 voip_low.conf
-rw-r--r-- 1 root root 29 sept. 30 11:49 voip_mid.conf
pi@rmtrpi4f4eyq remote $ pwd
/opt/crx/conf/remote
pi@rmtrpi4f4eyq remote $ cat station.conf
SOUND_CARD="plughw:0,0"
STATION_NAME="f4eyq-1"
pi@rmtrpi4f4eyq remote $

You can edit your VOIP profile ( low / mid / hight ) via the command :

The VOIP is start via the rc.local file on the PI with this single line :

sudo su - pi -c "screen -dm -S pistartup /opt/crx/seren/voip.bash --start";

The SYSTEMD part for command used two scripts :

=> tcp_serial_catsystem.service
=> crx_com_tcp.service

sudo systemctl start crx_com_tcp.service
sudo systemctl stop crx_com_tcp.service

sudo systemctl start tcp_serial_catsystem.service
sudo systemctl stop tcp_serial_catsystem.service

=> with the first script you can use FLRIG, with second CRX-COM.

Tnx to @f4goh for his help,
Good weekend to all 73 s

PS: it work on all Raspberry PI version, Debian , Ubuntu, also into VMWARE Workstation/VIRTUALBOX.

HAM – Programmation d’un bouton VFO USB.

Update 22/09/2020 : mise à jour du script pour le support de CRX-COM ( alt+t, alt+o, alt + l ).

Je vous propose la programmation d’un bouton USB « Cooidea USB Volume Control » en bouton VFO. L’idée est d’utiliser un bouton USB de contrôle de volume pour piloter un VFO radio. Cette idée m’est venue il y a quelques mois et voyant une console remote sur un transceiver SDR « haut de gamme ». J’ai décidé d’investir dans un périphérique identique mais pour l’audio (qui coute 30 euros environ) et ensuite de créer une macro pour le contrôler.

Pré requis : disposer d’un bouton USB de contrôle du volume, ici je suis parti sur un « Cooidea USB Volume Control », n’importe quel bouton USB de contrôle de volume fera l’affaire. On le tourne pour le volume et on appuie dessus pour couper ou pas le son.

Comment ça marche ? Ici mon logiciel « CAT SYSTEM » FLRIG ne dispose pas du support de ce bouton nativement, j’ai donc créé un script « MACRO » qui permet de le faire. Ce script fonctionne avec AUTOHOTKEY qui est un petit langage de macro super pratique.

Afin d’optimiser les choses, je mémorise la position du curseur de souris et la fenêtre active quand le bouton est utilisé afin de ne pas modifier votre fenêtre active et votre souris (je remets tout en place une fois le scroll/commande PTT faite).

1. Installer AUTOHOTKEY :  ( pour nos amis pingouins, utiliser AutoHotkeyX )

Rendez vous ici : https://www.autohotkey.com/

2. Mon script AUTOHOTKEY  « cooidea4Ham.ahk » :

La première étape va être de lancer le logiciel de contrôle CAT SYSTEM ( ici FLRIG ).

Une fois lancé on va repérer 2 choses :
– la position X,Y du digit KHZ ( là où l’on peut avec la souris faire un scroll up/down ).
– la position X,Y du bouton PTT ( là où l’on va cliquer pour passer en émission ).

Pour ce faire, j’ai inclus un mode « configuration » dans le script, vous permettant de récupérer les coordonnées X et Y.
Ensuite on va simplement éditer le script avec ces coordonnées.

C’est ce que je vous propose à l’étape 3.

3. Configurer le script : 

Commencez par installer mon script là ou vous voulez ( il est disponible tout en bas de l’article ).
Ensuite on peut passer à sa configuration :

Editez le script avec votre bloc note favoris :
– passez la variable ci-dessous à 1
– on la passera à 0 une fois la configuration terminée :

;Enable only for coordination conf :
global CfgMode := 1

Ensuite lancez le script (double-clic dessus ou clic-droit : Run script).

Ensuite disposez votre logiciel là ou vous le souhaitez, notez que FLRIG mémorise sa position,
donc il sera de nouveau là lorsque vous le relancerez.

Ici je vous ai indiqué les 2 points que nous allons contrôler avec le bouton,
le digit « Khz » et le bouton « PTT » :

On va cliquer sur la fenêtre de notre logiciel « CAT SYSTEM » ici FLRIG.
– On se place avec la souris sur le digit des Khz dans le logiciel ( voir schéma C1 )
– Puis l’on va avec notre bouton VFO USB, le tourner vers le haut et regarder la popup qui s’affiche ici (juste en dessous du curseur de la souris) :

Current cursor position: 885, 75

– Même chose on va aller avec la souris sur la bouton « PTT » et récupérer les coordonnées X et Y (voir schéma C2 ) :

Current cursor position: 1640, 123

Il ne nous reste plus qu’à configurer le script avec ces valeurs,
Pour ce faire éditez celles-ci :

;Mouse position for Khz control :
; screen1 : 885,75 (flrig in full size top of screen here).
; screen2 : 728,88
global TwcX := 885
global TwcY := 75
;Mouse position for button PTT control :
; screen1 : 1633,123 (flrig in full size top of screen here).
; screen2 : 1317,123
global TwxX := 1633
global TwxY := 123

Enfin on va repasser la variable « CfgMode » à 0, on sauvegarder le script.

Ensuite on ferme et on exécute de nouveau notre script « cooidea4Ham.ahk »,
Et voilà vous pilotez maintenant le VFO via un bouton USB !

Bien sûr si vous utilisez un autre logiciel pour le pilotage (HRD par exemple ou n’importe quel logiciel SDR),
Il vous suffira d’adapter les variables du script :

;Window SDR/CAT class name :
global Twc := "Flrig"

Qui correspond à la valeur « ahk_class » d’AUTOHOTKEY.

4 Autre exemple, pilotez le WEB SDR

Voici un autre exemple pour piloter le SDR WEB avec le bouton USB :  http://websdr.ewi.utwente.nl:8901/
Faite une copie mon script, nommez là par exemple : « WEBSDR.ahk »

Ensuite, lancez le SDR, puis repérez le X, Y ( en activant : global CfgMode := 1  comme je l’ai indiqué avant ),
Pour ce faire lancez alors le script « WEBSDR.ahk », le debug va nous donner la valeur C1 ici :

Fermez le programme (clic droit sur l’icône H en vert dans la barre de tâche),
Editez la variable : CfgMode  et passez là à 0.

Renseignez alors les 2 variables X, Y avec par exemple :
global TwcX := 650
global TwcY := 760

Relancez le script, et voilà vous pouvez piloter le WEB SDR avec votre VFO USB !

73 à tous,
Bastien

PS: Voici mon script (à copier/coller quelque part sur votre PC, par exemple votre bureau)

;-----------------------------------------------------------------
; Control CRX/SDR/FLRIG by F4EYQ
; File			 : cooidea4Ham.ahk
;
; Description 	 : AutoHotkey script to map Volume UP/DOWN to Mousse Whell
; 				   and Mute/Unmute action (press on sound button) to PTT control.
;
; Hardware 		 : Cooidea USB Volume Control
;
; Date 			 : 08/2020
; Update		 : 22/09/2020 add CRX Control short key.
;
;-----------------------------------------------------------------
;Configuration : 
;-----------------------------------------------------------------
;Window SDR/CAT class name  :
global Twc := "Flrig"

;Enable only for coordination conf :
global CfgMode := 0

;Mouse position for Khz control :
; screen1 : 885,75 (flrig in full size top of screen here).
; screen2 : 728,88
global TwcX := 885
global TwcY := 75

;Mouse position for button PTT control : 
; screen1 : 1633,123 (flrig in full size top of screen here).
; screen2 : 1317,123
global TwxX := 1633
global TwxY := 123

;-----------------------------------------------------------------
;Global VARS: 
;-----------------------------------------------------------------
;Transceiver PTT status : 
global TwcTX := 0

;---------------------------
;Configure device mapping : 
;---------------------------
Volume_Up::MousseWheelUpDown("UP")
Volume_Down::MousseWheelUpDown("DOWN")
Volume_Mute::ControlTX()
;---------------------------
ControlTX()
{
	if TwcTX=0
	{
	 Send !t
	 TwcTX=1
	 WinActivate, ahk_class %Twc%
	 ;click on "PTT button"
	 MouseClick, left,%TwxX%,%TwxY%
	 MouseMove, %TwcX%, %TwcY%, 0
	}
	else 
	{
	  Send !t
	  TwcTX=0
	  WinActivate, ahk_class %Twc%
	  ;click on "PTT button"
	  MouseClick, left,%TwxX%,%TwxY%
	  MouseMove, %TwcX%, %TwcY%, 0
	}
}

MousseWheelUpDown(direction)
{
	;get current active window ID and class :
	Awc := WinExist("A")
	WinGetClass, class, A
	
	;need to retreive initial frequency cursor position :
	MouseGetPos,xpos,ypos,id,control
	
	;debug/conf if needed : 
	if(CfgMode=1){
		ToolTip, Current window Class:`n%class%`nCurrent cursor position:`n%xpos%`n%ypos%
	}
	;get current mouse pos:
	;MouseGetPos,xpos,ypos,id,control
	
	;set scroll on the flrig window:
	;WinActivate, ahk_class %Twc%
	;MouseMove, %TwcX%, %TwcY%, 0
	
	if(direction="UP"){
		Send !o
		;Send, {WheelUp}
	}
	
	if(direction="DOWN"){
		Send !l
		;Send, {WheelDown}
	}
	
	;set old position:
	;WinActivate, ahk_id %Awc%
	;MouseMove, %xpos%, %ypos%, 0
}
Control CRX/SDR/FLRIG by F4EYQ