Archives de catégorie : Informatique

Programmer ImageMagick avec Powershell

ImageMagick permet le traitement d’image en ligne de commande. Il supporte notamment la création de calques auxquels on peut ajouter des masques. J’en ai profité pour programmer un optimiseur de tonalité photo en associant à ImageMagick Powershell.  

Role du  script

Optimiser les tons d’une photo en contrôlant ses hautes lumières, tons moyens et ombres. Le script pourra servir de canevas à la création de nouveaux traitements grâce à une procédure de test.

Description

Schématiquement le script effectue les actions suivantes : 

  1. Affectation des préférences utilisateur et initialisation de 3 masques de luminances. 
  2. Placer une première image comme arrière-plan.
  3. Dupliquer l’ arrière-plan et placer cette copie au-dessus en tant que calque.   
  4. Modifier l’aspect du calque (repeindre le calque en rouge en mode test, modifier luminosité, contraste et saturation en mode optimisation)   
  5. Définir la transparence du calque à partir du premier masque de luminance. Tout ce qui est noir dans le masque rendra le calque totalement transparent et blanc totalement opaque.  
  6. Répéter les étapes 3 à 5 en utilisant 2 autres calques qui seront associés aux 2 autres masques.
  7. En mode optimisation : fusionner l’arrière-plan et les 3 calques pour créér une image optimisée. En mode test : créer 3 images qui montreront l’action des 3 calques) .  

Le code

# optimiseur_photo.ps1
# Traitement d'image : Optimiseur de la tonalité
# Testé sous Windows 8.1 et 10 avec ImageMagick 7.0.10 

# Pour créer des png qui montrent l'action des masques
# Traite la première image puis quitte. 
$test_mode = 0

# Indique le répertoire contenant les images a optimiser 
$dossier_source = "C:\votre\dossier\images\a optimiser"
# Particule ajoutée au nom  des images résultantes pour les différencier
$distinctif ="_optim_out"

# Options pour la création des masques 
$canal = "-colorspace Lab -channel r -separate -delete '1,2'"
$flou = "-blur 0x5"

# Créations des masques. Si modification faire 
# attention aux `` qui permettent d'échapper les parenthèses 
# et d'écrire les chaines sur plusieurs lignes 
 
$hautes_lumieres = " ``( -clone 0 $canal -level '50%,100%' ``
+channel $flou -depth 8 -write mpr:masque.png  -delete 0 ``) " 

$tons_moyens = " ``( -clone 0 ``( -clone 0 $canal  ``
-level '50%,100%' +channel ``) ``( -clone 0 $canal  -negate  ``
-level '50%,100%'  +channel ``) -delete 0  ``
-compose blend -composite -negate $flou -depth 8 ``
-write mpr:masque.png  -delete 0 ``) " 

$ombres = " ``( -clone 0 $canal  -negate -level '50%,100%'  ``
+channel $flou -depth 8 -write mpr:masque.png  -delete 0 ``) " 

# Options pour les calques 
if ($test_mode)
{$action_hl= $action_tm = $action_o  = "-fill red -colorize '100%'" }  
else { $action_hl = "-brightness-contrast '-23,23'"  
       $action_tm = "" 
       $action_o = "-sigmoidal-contrast '5,0%' " }

# Création des calques 
$calque_hl = "``( -clone 0 $action_hl  mpr:masque.png ``
-compose copy_opacity   -composite  ``)"
$calque_tm= "``( -clone 0 $action_tm  mpr:masque.png ``
-compose copy_opacity   -composite ``)"
$calque_o= "``(  -clone 0 $action_o  mpr:masque.png  ``
-compose copy_opacity   -composite ``)"

# Traitement des images 
$listes_image = Get-ChildItem $dossier_source -File |
where { $_.name -notmatch ".*$distinctif.*" }

foreach ($srcitem in $listes_image )
  { $srcfullname = $srcitem.fullname    
    $dstbasename = $dossier_source +"\"+$srcitem.basename+"$distinctif"
    write-host "Traitement de l'image $srcitem ..."

    #assemblage de la commande et exécution
    if($test_mode) {
    $cmd = "magick convert '$srcfullname' $hautes_lumieres $calque_hl ``
    $tons_moyens $calque_tm $ombres $calque_o -delete 0 '$dstbasename%01d.png' "
    invoke-expression  -command $cmd
    exit
    }
    else  {    
    $cmd = "magick convert '$srcfullname' $hautes_lumieres $calque_hl ``
     $ombres $calque_o $tons_moyens $calque_tm -compose over ``
    -flatten '$dstbasename.jpg' " 
    invoke-expression  -command $cmd
    }
  }

Les images à traiter :

Le carrousel ci-dessous montre les 4 images jpg que j’ai placées dans un dossier spécifique. Elles présentent des écarts  de luminosité importants . L’ optimiseur sera chargé de corriger cet écart.

Utilisation

ImageMagick est installé sur ma machine Windows : https://imagemagick.org/script/download.php

J’ouvre le script (l’extension .ps1 est importante) par un clic droit puis je choisi Modifier. L’ ISE  (Integrated Scripting Environment ) s’ouvre et affiche le script en haut (sinon vérifier Afficher -> Afficher le volet de script) . Je renseigne la variable $dossier_source avec le chemin du dossier qui contient mes images.

En mode test

Ce mode va créer une image distincte pour chaque calque. Une seule image source est traitée dans ce mode.

Pour exécuter le script dans ce mode, j’ai placé la variable $test_mode à 1. Puis j’exécute le script (icone lecture ou touche F5). Dans mon dossier apparaissent 3 nouvelles images png représentant les 3 calques. Les zones qui restent contrôlées par le calque après application du masque sont en rouge. L’intensité de la couleur nous donne une indication sur la prépondérance du calque sur l’arrière plan. Dans l’ordre le carrousel ci-dessous montre le calque hautes lumières, puis tons moyens, et enfin ombres.

En mode Optimisation

J’ai replacer $test_mode à 0. Le script peux maintenant traiter toutes les images placées dans le dossier $dossier_source (un filtre exclut les images qu’il a lui-même générées) . Le carrousel montre le résultat au terme de l’exécution du script. L’image d’origine suivi de sa version optimisée.

Pour aller plus loin

On pourra modifier les variables Powershell qui définissent les options de création des masques et des calques. Cela implique de connaitre un minimum la syntaxe d’imageMagick. Voici quelques liens pour bien débuter.

Identifier l’adresse MAC Wifi d’un appareil.

Avec la multiplication des OS installés sur les appareils pouvant se connecter à un réseau wifi un pense-bête peut s’avérer utile. De quoi organiser la réservation d’adresse ip ou créer une  liste pour contrôler l’accès au réseau. Vous trouverez en fin d’article des ressources pour faire face aux adresses mac aléatoires.

Windows en mode graphique

Windows 8.1 ou 10

Clic gauche  sur la l’icone de connexion réseau dans zone de notification  de la barre des tâches (en bas à droite) puis : Afficher les paramètres réseaux (w8.1)  ou  Paramètres réseau (w10) et clic gauche sur la connexion wifi.

Windows 7

Un clic droit sur la l’icone de connexion réseau dans la zone de notification de la barre des tâches ->  Ouvrir le Centre de Réseau et partage -> Modifier les paramètres de la carte . Double clic sur la carte wifi puis Status -> Détails.

Windows en ligne de commande

ipconfig /all (mais retourne beaucoup d’informations et peut être difficilement lisible). Sinon getmac /v ou bien en powershell sous Windows 10 : Get-NetAdapter 

Android

Paramètres → Onglet GénéralÀ propos de l’appareilÉtat

IOS

Réglages -> Onglet Général, appuyez sur À propos

Linux (base Débian)

En ligne de commande : cat /proc/net/wireless pour déterminer le nom de l’interface wifi puis ip address show nom_interface 

Mac OS

Icône Pomme -> Préférences Système -> Réseau -> Avancé (coin inférieur droit)  -> onglet Matériel

Chrome OS

Ouvrir le navigateur, entrer chrome://system dans la barre d’adresse ,  développer  la section ifconfig

Gestion des MAC aléatoires :

Déactivation sur Android 10 :

Paramètres -> Wi-Fi et Internet Wi-Fi [Réseau wifi concerné] Confidentialité -> Adresse mac de l’appareil

Ressources

Etat des lieux mars 2020 par un ingénieur Cisco : https://community.cisco.com/t5/security-documents/random-mac-address-how-to-deal-with-it-using-ise/ta-p/4049321

Article de mars 2018 tirée de la revue MISC : https://connect.ed-diamond.com/MISC/MISC-096/MAC-Address-Randomization-tour-d-horizon

Installation de GLPI et FusionInventory (2)

Nous poursuivons l’installation débuté dans cet article avec l’agent fusionInventory qui sera installé sur notre serveur.

Nous utiliserons les paquets debian de la version 2.5.2-1 :
https://github.com/fusioninventory/fusioninventory-agent/releases/
Nous suivrons cette procédure :
http://fusioninventory.org/documentation/agent/installation/linux/deb.html

Un agent pour quoi faire ?

Pour disposer d’un inventaire du serveur chaque jour. Faire également des inventaires des switchs et des imprimantes du réseau. Pour les switchs nous voulons une mise à jour automatique de l’inventaire toutes les 10 minutes.

Activation du planificateur de GLPI

Au vue des tâches nous installerons l’agent en tant que service. L’action automatique taskscheduler (voir Configuration ->Actions automatiques) planifiera les taches d’inventaires réseau. Pour que cette action s’exécute nous allons activer le cron de glpi.

Ouvrons le crontab le l’utilisateur www-data (c’est lui qui exécute apache) :

#crontab -u www-data -e

Pour une exécution toute les 10 minutes on ajoute à la fin du fichier :

*/10 * * * * /usr/bin/php7.3 /var/www/html/glpi/front/cron.php &>/dev/null

La consultation des journaux système (avec journalctl -f) permet de vérifier la prise en compte de notre configuration (attendre 10 minutes). Les actions automatiques exécutées seront consignées dans le fichier cron.log de glpi. Pour le consulter :

#tail -f /var/www/html/glpi/files/_log/cron.log
Installation de l’agent

Dans notre cas nous avons seulement besoin des paquets agent et agent-task-network. Téléchargement :

#wget https://github.com/fusioninventory/fusioninventory-agent/releases/download/2.5.2/fusioninventory-agent_2.5.2-1_all.deb 
#wget https://github.com/fusioninventory/fusioninventory-agent/releases/download/2.5.2/fusioninventory-agent-task-network_2.5.2-1_all.deb

Installation des dépendances “générales” :

#apt-get install dmidecode hwdata ucf hdparm perl libuniversal-require-perl libwww-perl libparse-edid-perl libproc-daemon-perl libfile-which-perl libhttp-daemon-perl libxml-treepp-perl libyaml-perl libnet-cups-perl libnet-ip-perl libdigest-sha-perl libsocket-getaddrinfo-perl libtext-template-perl libxml-xpath-perl libyaml-tiny-perl

Installation des dépendances spécifiques aux taches de découverte et inventaire réseau :

#apt-get install libnet-snmp-perl libcrypt-des-perl libnet-nbname-perl libdigest-hmac-perl

Installation des paquets :

#dpkg -i fusioninventory-agent_2.5.2-1_all.deb
#dpkg -i fusioninventory-agent-task-network_2.5.2-1_all.deb

Edition du fichier de configuration de l’agent :

#nano /etc/fusioninventory/agent.cfg

On dé-commente et renseigne la variable server :


#send tasks results to a FusionInventory for GLPI server
server = http://127.0.0.1/glpi/plugins/fusioninventory/
#write tasks results in a directory
#local = /tmp

Création du service
#nano /etc/systemd/system/fusioninventory-agent.service

On ajoute :

[Unit]
Description=FusionInventory agent
Documentation=man:fusioninventory-agent
After=syslog.target network.target

[Service]
ExecStart=/usr/bin/fusioninventory-agent –daemon –no-fork
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target

On rend disponible le service :

#systemctl enable fusioninventory-agent

Dans l’interface web de GLPI on va augmenter provisoirement la fréquence des inventaires.
(FusionInventory -> Configuration générale) et choisir 1 heure. Cela nous permettra d’observer plus facilement le comportement du service.

On force un premier inventaire :

#fusioninventory-agent

Dans l’interface web l’agent (Administration ->FusionInventory ->Agent) et son inventaire (Parc ->Ordinateurs) vont apparaître. En cas de problème on pourra consulter le syslog et relancer l’inventaire en mode débogage (option –debug)

Si tout est ok on démarre cette fois l’agent en tant que service :

#systemctl start fusioninventory-agent

Un nouvel inventaire sera exécuté dans une fourchette de temps comprise entre 50% et 100% de la fréquence des inventaires. Dans notre cas 30 minutes et 1 heures. Lorsque cela a été vérifié on peut refixer la fréquence des inventaires à la valeur souhaitée, 24 pour un inventaire du serveur chaque jour.

Dans un prochain article nous verrons comment réaliser un inventaire réseau.

Installation de GLPI et FusionInventory (1)

Installation sur une Debian 10.3 montée pour l’occasion dans une VM Vitualbox. Je me suis inspiré de cet article : https://garintheophile.fr/glpi-debian-10/

Installation des dépendances
#apt-get install apache2 mariadb-server mariadb-client php build-essential perl libapache2-mod-perl2 libxml-simple-perl libio-compress-perl libdbi-perl libapache-dbi-perl libdbd-mysql-perl libnet-ip-perl libsoap-lite-perl libxml-libxml-perl libmojolicious-perl nmap snmp php7.3-mysql php7.3-gd php7.3-mbstring php-ldap php-imap php-apcu php-xmlrpc php-soap php-cas php7.3-xml

Mariadb va poser quelques questions qui vont notament permettrent de définir un mot de passe pour l’utilisateur root (utile pour la suite).

Téléchargement et décompression de GLPI dans /var/www/html
#cd /var/www/html
#wget https://github.com/glpi-project/glpi/releases/download/9.4.6/glpi-9.4.6.tgz
#tar -zxvf glpi-9.4.6.tgz
#rm glpi-9.4.6.tgz
Configuration du serveur Apache.

Création d’un fichier virtual host. Le serveur pointera par défaut vers
le répertoire glpi :

#nano /etc/apache2/sites-available/glpi.conf

On ajoute dans le fichier :

<VirtualHost *:80>
  ServerName glpi.lan
  DocumentRoot /var/www/html/glpi/
 <Directory /var/www/html/glpi>
        AllowOverride All
        Order allow,deny
        Options Indexes
        Allow from all
 </Directory>
 ErrorLog  ${APACHE_LOG_DIR}/glpi-error.log
 CustomLog ${APACHE_LOG_DIR}/glpi-access.log combined
</VirtualHost>

ServerName est le nom de ma machine et devrais faire l’objet d’une configuration DNS. On pourra cependant accéder à glpi en utilisant l’adresse ip du serveur.

L’utilisateur www-data qui lance apache doit être propriétaire du dossier glpi :

#chown -R www-data:www-data /var/www/html/glpi

Activation du site glpi, désactivation du site par défaut et rechargement de la configuration :

#a2ensite glpi
#a2dissite 000-default
#systemctl reload apache2
Création de la base de donnée glpi et de son utilisateur
#mysql_secure_installation
#mysql -u root -p
#create user 'glpi'@'%' identified by 'mon_mot_de_passe';
#create database glpi;
#grant all privileges on glpi.* TO 'glpi'@'%';
Installation de GLPI

Se connecter à l’interface web. Le setup est trivial. Etape 3 choisir pour Serveur SQL, localhost.

Effacer la page d’installation :

#rm glpi/install/install.php
Installation de fusionInventory
#cd glpi/plugins/
#wget https://github.com/fusioninventory/fusioninventory-for-glpi/releases/download/glpi9.4%2B2.4/fusioninventory-9.4+2.4.tar.bz2
#tar jxvf fusioninventory-9.4+2.4.tar.bz2
#rm fusioninventory-9.4+2.4.tar.bz2

Se connecter à l’interface web , aller dans configuration ->plugin, choisir :
Actions : installer puis Action : activer

Arriver au terme de cette installation la VM occupe 2,23 Go d’espace disque. Pour la compléter il faudrait installer un agent fusion inventory sur le serveur. Cet agent peut se voir confier de multiples taches qui feront l’objet d’un prochain article.

Modifier la largeur du contenu dans wordpress

Pour ce site j’utilise le thème Twenty Thirteen sans side-bar. Dans ce cas le contenu laisse sur chaque coté des marges vides inutiles. j’ai modifié la classe .entry-content dans le fichier style.css en conséquence.

J’ai pu accéder au fichier style.css en ftp dans le répertoire /wp-content/themes/twentythirteen.

Les valeurs d’origines de la classe .entry-content :

.entry-header,
.entry-content,
.entry-summary,
.entry-meta {
	margin: 0 auto;
	max-width: 604px;
	width: 100%;
}

Ma modification :

.entry-header,
.entry-content,
.entry-summary,
.entry-meta {
	margin: 0 auto;
	width: 800px;
	}

Il faut bien vérifier que le thème n’active pas la side-bar. Dans mon cas j’avais placé un widget vide dans ma zone secondaire. Bien qu’invisible ma side-bar était donc active. La modification de style.css n’avait pas d’effet. J’ai enlevé ce widget et tout est rentré dans l’ordre.

IPTables, les chaînes INPUT, OUTPUT et FORWARD

Dans le pare-feu Iptables le module (la  table) filter comprend 3 chaînes. Ces chaînes vont accueillir nos règles de filtrage. Comment déterminer quelle chaîne utiliser ? Aidons-nous des logs pour le découvrir. Nous utiliserons les machines pc-maison, srv-linux et pc-tiny de ce réseau Lab.

mon réseau lab

Notre pare-feu iptables est installé sur la machine srv-linux (sous debian 10). Nous allons configurer iptables pour qu’il produise des logs  à partir de requêtes icmp entre pc-maison et pc-tiny  et  entre srv-linux et pc-tiny. Mais notre box internet n’ayant aucune règle de routage concernant le LAN2 nous devons d’abord ajouter une route statique à pc-maison.

route ADD 192.168.56.0 MASK 255.255.255.0  172.16.0.253

Regardons sur  srv-linux l’état de la table filter d’iptables avec iptables -t filter -L. Filter étant la table par défaut on peut simplifier la commande à iptables -L.

root@srv-linux:~# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Les 3 chaînes sont vides (aucune règles).  Si dans une chaîne un paquet ne correspond à aucune règle alors ici iptables laissera passer le paquet (policy ACCEPT) .  Le champs target correspond à l’action que doit effectuer la règle. Les cibles les plus utilisée pour la table filter sont  ACCEPT, DROP et REJECT

Dans le terminal nous allons ajouter une règle pour chacune de ces chaînes (iptables -A nom_de_la_chaine).

iptables -A INPUT -p icmp --icmp-type any -j LOG --log-prefix "ping input :" 
iptables -A FORWARD  -p icmp --icmp-type any -j LOG --log-prefix "ping forward :"
iptables -A OUTPUT -p icmp --icmp-type any -j LOG --log-prefix "ping output :"

Pour toutes communications icmp (-p icmp –icmp-type any) nous déterminons une cible  (-J) ici  écrire dans un fichier de log (LOG). Par défaut la cible LOG sur debian 10 va écrire dans   /var/log/syslog ,  /var/log/kern.log et /var/log/messages !  L’écriture sera précédée d’un préfixe (–log_prefix) destiné à taguer les logs pour en simplifier la consultation . 

Consultons à nouveau l’état de la table filter :

root@srv-linux:~# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
LOG        icmp --  anywhere             anywhere             icmp any LOG level warning prefix "ping input :"

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
LOG        icmp --  anywhere             anywhere             icmp any LOG level warning prefix "ping forward :"

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
LOG        icmp --  anywhere             anywhere             icmp any LOG level warning prefix "ping output :"

Nos règles sont enregistrées. Source ou de destination n’ont pas été renseignées dans nos règles d’où la valeur par défaut et anywhere. Ouvrons une nouvelle console sur srv-linux pour pouvoir consulter syslog en temps réel. 

tail -f /var/log/syslog | grep -i -n “ping “
root@srv-linux:~# tail -f /var/log/syslog | grep -i -n "ping "
11:May  1 17:05:39 srv-linux kernel: [ 8091.946210] ping input :IN=enp0s8 OUT= MAC=08:00:27:1d:0c:4f:08:00:27:be:e8:25:08:00 SRC=192.168.56.100 DST=172.16.0.253 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=27197 DF PROTO=ICMP TYPE=8 CODE=0 ID=44550 SEQ=2
12:May  1 17:05:39 srv-linux kernel: [ 8091.946245] ping output :IN= OUT=enp0s8 SRC=172.16.0.253 DST=192.168.56.100 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=53146 PROTO=ICMP TYPE=0 CODE=0 ID=44550 SEQ=2

Ce sont les règles des chaînes  INPUT et OUTPUT qui ont traité les paquets. La chaîne INPUT est utilisée lorsqu’une requête est à destination du firewall (IN=enp0s8) . La chaîne OUTPUT lorsqu’une requête est générée par une des interfaces  du firewall (OUT=enp0s8 )

Depuis pc-tiny  je ping maintenant pc-maison  :

11:May  1 18:15:58 srv-linux kernel: [12310.781758] ping forward :IN=enp0s8 OUT=enp0s3 MAC=08:00:27:1d:0c:4f:08:00:27:be:e8:25:08:00 .168.56.100 DST=172.16.0.10 LEN=84 TOS=0x00 PREC=0x00 TTL=63 ID=54253 DF PROTO=ICMP TYPE=8 CODE=0 ID=16647 SEQ=0
12:May  1 18:15:58 srv-linux kernel: [12310.781967] ping forward :IN=enp0s3 OUT=enp0s8 MAC=08:00:27:e9:56:f7:00:8c:fa:8b:55:2b:08:00 .16.0.10 DST=192.168.56.100 LEN=84 TOS=0x00 PREC=0x00 TTL=127 ID=10672 PROTO=ICMP TYPE=0 CODE=0 ID=16647 SEQ=0

C’est la règle de la chaîne FORWARD qui a traité les paquets .  Cette chaîne est donc à utiliser lorsqu’on souhaite filtrer les paquets qui vont traverser le firewall. 

En conclusion ce sont la source et la destination du paquet qui vont déterminer la chaîne que nous devons  utiliser pour le filtrage. 

Pour terminer remettons la table  filter dans son état initial.  Il existe plusieurs solutions. Dans le terminal nous pouvons entrer à nouveau nos règles mais avec l’option -D (delete) au lieu de -A.  

 
iptables -D INPUT -p icmp --icmp-type any -j LOG --log-prefix "ping input :" 
iptables -D FORWARD  -p icmp --icmp-type any -j LOG --log-prefix "ping forward :"
iptables -D OUTPUT -p icmp --icmp-type any -j LOG --log-prefix "ping output :"

Si les chaînes ne contenaient initialement aucune règle  nous pouvons vider entièrement la chaîne avec    iptables -F NOM_DE_LA_CHAINE

On efface la route statique créé sur pc-maison : route delete 192.168.56.0

Pour aller plus loin

Disposer d’un fichier de log spécifique pour iptables en créant un fichier de configuration dans /etc/rsyslog.d/ :  

https://unix.stackexchange.com/questions/96484/how-can-i-configure-syslog-conf-file-to-log-iptables-messages-in-a-separate-fil

Organiser la rotation de ce fichier de  logs :

 https://www.svennd.be/rotate-rsyslog-logs-using-logrotate/

Tutoriel Iptables : https://www.nbs-system.com/blog/howto-iptables

Autre tutoriel : https://www.malekal.com/tutoriel-iptables

Consulter les règles en temps réels avec watch : watch -n 1 iptables -vnL

http://man7.org/linux/man-pages/man1/watch.1.html