Modifier le comportement à la fermeture de l’écran avec systemd-logind

logind est le composant en charge de la gestion des sessions sur les systèmes avec systemd. Il suit les utilisateurs connectés (systemd-loginctl list-users), les sessions ouvertes (systemd-loginctl list-sessions) et détermine le comportement lorsque l’on appuie sur le bouton d’alimentation (Power Key), ferme l’écran (Lid Switch) et en cas d’inactivité (Idle).

Sa configuration est située dans /etc/systemd/logind.conf :

[Login]
#NAutoVTs=6
#ReserveVT=6
#KillUserProcesses=no
#KillOnlyUsers=
#KillExcludeUsers=root
#InhibitDelayMaxSec=5
#HandlePowerKey=poweroff
#HandleSuspendKey=suspend
#HandleHibernateKey=hibernate
#HandleLidSwitch=suspend
#HandleLidSwitchDocked=ignore
#PowerKeyIgnoreInhibited=no
#SuspendKeyIgnoreInhibited=no
#HibernateKeyIgnoreInhibited=no
#LidSwitchIgnoreInhibited=yes
#IdleAction=ignore
#IdleActionSec=30min
#RuntimeDirectorySize=10%
#RemoveIPC=no

La variable qui nous intéresse aujourd’hui s’intitule HandleLidSwitch et détermine l’action à effectuer lorsque l’on ferme / rabat l’écran. Sa valeur par défaut est suspend (mise en veille).

Les valeurs acceptées sont les suivantes :

Can be one of "ignore", "poweroff", "reboot",
"halt", "kexec", "suspend", "hibernate", "hybrid-sleep", and "lock"

Mettons de côté « poweroff » (arrêt), « reboot » (redémarrage), « halt » et « kexec » et regardons les valeurs réellement utiles pour HandleLidSwitch :

  • « ignore » : Faire comme si de rien n’était. Si la session ne se verrouille pas après X minutes d’inactivité, elle restera ouverte.
  • « hibernate » : Mise en hibernation
  • « hybrid-sleep » : Mise en hibernation avec conservation des données en mémoire (pour reprendre plus rapidement).
  • « lock » : Verrouillage de la session
  • « suspend » : Mise en veille. Le comportement par défaut.

Pour verrouiller la session, ce sera donc :

HandleLidSwitch=lock

Une fois la modification faîte, inutile de redémarrer, il suffit de relancer le service systemd-logind :

systemctl restart systemd-logind

Sources :

Dockerfile & yum check-update : returned a non-zero code: 100

La commande yum check-update retourne le code 100 lorsque des mises à jour sont disponibles, ce que Docker interprète comme un code d’erreur lors de la construction d’une image (docker build) :

The command '/bin/sh -c yum check-update' returned a non-zero code: 100

N’ayant réussi ni à trouver une option pour l’ignorer côté Docker ni pour désactiver ce comportement côté Yum, la seule solution reste de forcer la commande à retourner 0 avec la syntaxe suivante :

RUN (yum check-update || true)

Qui se traduit par : retourne true (soit 0) si yum check-update retourne un code d’erreur.

dockerd: Error initializing network controller: list bridge addresses failed: no available network

Contexte : CentOS 7. Package docker-engine fraichement installé depuis le repository officiel.

Erreur lors du lancement du service docker-engine :

$ sudo systemctl status -l docker.service 
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since sam. 2017-01-28 10:03:24 CET; 2min 33s ago
     Docs: https://docs.docker.com
  Process: 11478 ExecStart=/usr/bin/dockerd (code=exited, status=1/FAILURE)
 Main PID: 11478 (code=exited, status=1/FAILURE)

janv. 28 10:03:24 simon-laptop.home dockerd[11478]: Error starting daemon: Error initializing network controller: list bridge addresses failed: no available network
janv. 28 10:03:24 simon-laptop.home systemd[1]: docker.service: main process exited, code=exited, status=1/FAILURE
janv. 28 10:03:24 simon-laptop.home systemd[1]: Failed to start Docker Application Container Engine.
janv. 28 10:03:24 simon-laptop.home systemd[1]: Unit docker.service entered failed state.
janv. 28 10:03:24 simon-laptop.home systemd[1]: docker.service failed.

Même erreur en lançant manuellement docker :

$ sudo docker daemon -s overlay
Command "daemon" is deprecated, and will be removed in Docker 1.16. Please run `dockerd` directly.
INFO[0000] libcontainerd: new containerd process, pid: 12001 
WARN[0000] containerd: low RLIMIT_NOFILE changing to max  current=1024 max=4096
INFO[0001] Graph migration to content-addressability took 0.00 seconds 
INFO[0001] Loading containers: start.                   
INFO[0001] Firewalld running: true                      
Error starting daemon: Error initializing network controller: list bridge addresses failed: no available network

Le problème venait en fait la présence d’un nameserver IPv6 en lien local dans /etc/resolv.conf :

$ cat /etc/resolv.conf 
# Generated by NetworkManager
search home
nameserver 192.168.1.1
nameserver fe80::ba26:6cff:feb9:6e50%enp8s0

Nouvelle tentative en retirant la dernière ligne :

$ head -n -1 /etc/resolv.conf | sudo tee /etc/resolv.conf
$ sudo dockerd -s overlay
(...)
INFO[0001] Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used to set a preferred IP address 

Pour rendre la modification permanente, il faut, au choix :

  • Désactiver NetworkManager
  • Désactiver la configuration automatique du DNS sur IPv6
  • Désactiver complétement IPv6 sur l’interface (ici enp8s0)

IDA : This application failed to start because it could not find or load the Qt platform plugin « xcb »

Lors de l’installation d’IDA sous CentOS 7, j’ai été confronté à l’erreur suivante en lançant idaq :

This application failed to start because it could not find or load the Qt platform plugin "xcb"
in "".

Available platform plugins are: linuxfb, minimal, xcb.

Reinstalling the application may fix this problem.
Abandon (core dumped)

Version courte

Installation des dépendances manquantes :

yum install -y libSM.i686 libICE.i686 fontconfig.i686 freetype.i686 dbus-libs.i686 gtk2.i686

Version longue

Commençons par regarder avec strace la librairie que cherche IDA :

$ strace ./idaq 2>&1|grep xcb
open("/opt/ida/plugins/platforms/libqxcb.so", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
open("/opt/ida/plugins/platforms/libqxcb.so", O_RDONLY|O_CLOEXEC) = 3
open("/opt/ida/plugins/platforms/../../libX11-xcb.so.1", O_RDONLY|O_CLOEXEC) = 3
stat64("/opt/ida/plugins/platforms/libqxcb.so", {st_mode=S_IFREG|0775, st_size=9812, ...}) = 0
write(2, "This application failed to start"..., 211This application failed to start because it could not find or load the Qt platform plugin "xcb"
Available platform plugins are: linuxfb, minimal, xcb.

On peut voir que le fichier réclamé s’appelle libqxcb.so. Celui-ci est d’abord recherché dans /opt/ida/plugins/platforms/libqxcb.so et… il existe (open() aurait retourné -1 si ce n’était pas le cas) !

Le problème n’est donc pas sa présence (inutile de chercher à installer des packages).

Continuons avec un ldd pour voir ses dépendances sur libqxcb.so :

$ ldd /opt/ida/plugins/platforms/libqxcb.so | grep 'not found'
        libSM.so.6 => not found
        libICE.so.6 => not found
        libfontconfig.so.1 => not found
        libfreetype.so.6 => not found

Problème: il lui manque quatre fichiers, qu’il s’agit cette fois d’installer par packages :

yum install -y libSM.i686 libICE.i686 fontconfig.i686 freetype.i686

Les dépendances étant à présent résolues, cela devrait fonctionner… ou pas :

Failed to create dbus connection. Are dbus libraries properly installed?

Nouveau coup de strace :

open("/lib/i686/libdbus-1.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/lib/libdbus-1.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 10
(...)
write(1, "Failed to create dbus connection"..., 73Failed to create dbus connection. Are dbus libraries properly installed?

Cette fois, il a beau chercher, libdbus-1.so est introuvable. On peut voir qu’il s’attends à le trouver dans le système, voyons le package correspondant :

$ yum whatprovides libdbus-1.so*|grep i686
1:dbus-libs-1.6.12-17.el7.i686 : Libraries for accessing D-BUS
1:dbus-libs-1.6.12-17.el7.i686 : Libraries for accessing D-BUS

Application 32-bits oblige, ce sera dbus-lib.i686.

Nouvel essai et erreur cette fois côté GTK. On voit par strace que le fichier est /opt/ida/plugins/platformthemes/libqgtk2.so :

stat64("/opt/ida/plugins/platformthemes/libqgtk2.so", {st_mode=S_IFREG|0775, st_size=363008, ...}) = 0

Contrôle des dépendances :

$ ldd /opt/ida/plugins/platformthemes/libqgtk2.so | grep 'not found'
	libgtk-x11-2.0.so.0 => not found
	libgdk-x11-2.0.so.0 => not found
	libpango-1.0.so.0 => not found

Toutes ces librairies sont fournies directement ou en dépendance du package gtk2 :

yum install -y gtk2.i686

IDA est à présent fonctionnel 🙂

Windows Subsystem for Linux Distribution Switcher

Windows Subsystem for Linux (WSL) intègre par défaut l’environnement utilisateur d’Ubuntu suite à un partenariat avec Canonical.

Concrètement, lorsque WSL est installé et que bash est lancé pour la première fois, le rootfs d’Ubuntu 16.04 est décompressé dans le répertoire utilisateur (%AppLocalData%\lxss\rootfs). Exactement comme le ferait un OpenVZ ou (à peu près) Docker.

Le projet Windows Subsystem for Linux Distribution Switcher – indépendant de Microsoft – permet de remplacer le rootfs d’Ubuntu par celui d’autres distributions. Il ne s’agit uniquement de remplacer des fichiers pour l’utilisateur courant, cela ne touche pas à WSL lui-même et peut aussi se faire manuellement (voir la procédure avec OpenSuSE).

Voici une liste des distributions disponibles à ce jour :

debian – 8.5, 8, jessie, latest | jessie-backports | oldstable | oldstable-backports | sid | stable | stable-backports | stretch | testing | unstable | 7.11, 7, wheezy | wheezy-backports | rc-buggy | experimental
ubuntu – 12.04.5, 12.04, precise-20160707, precise | 14.04.5, 14.04, trusty-20160802, trusty | 16.04, xenial-20160809, xenial, latest | 16.10, yakkety-20160806.1, yakkety, devel
fedora – latest, 24 | 23 | 22 | 21 | rawhide | 20, heisenbug
centos – latest, centos7, 7 | centos6, 6 | centos5, 5 | centos7.2.1511, 7.2.1511 | centos7.1.1503, 7.1.1503 | centos7.0.1406, 7.0.1406 | centos6.8, 6.8 | centos6.7, 6.7 | centos6.6, 6.6 | centos5.11, 5.11
opensuse – 42.1, leap, latest | 13.2, harlequin | tumbleweed
mageia – latest, 5
oraclelinux – latest, 7, 7.2 | 7.1 | 7.0 | 6, 6.8 | 6.7 | 6.6 | 5, 5.11
alpine – 3.1 | 3.2 | 3.3 | 3.4, latest | edge
crux – latest, 3.1
clearlinux – latest, base

Voyons sa mise en place.

Pour commencer, il faut Python 3.6 d’installer sur la machine à télécharger sur le site officiel :

python-3-6-0-32-bit-setup

Récupérer ensuite la dernière version de WSL-Distribution-Switcher à l’adresse suivante : https://github.com/RoliSoft/WSL-Distribution-Switcher/releases/download/v0.1.0/WSL-Distribution-Switcher_v0.1.0.zip

Extraire l’archive dans C:\ (cela donne C:\WSL-Distribution-Switcher) et ouvrir une ligne de commande dedans :

wsl-distribution-switcher

Installer de nouvelles distributions

Télécharger le ou les distributions – on va voir qu’il est possible de passer d’une à l’autre – :

get-source.exe centos:latest
get-source.exe fedora:latest

c__windows_system32_cmd-exe

Lorsqu’une nouvelle distribution est téléchargée, il faut l’installer une fois. Je précise que bash doit être fermé.

install.exe centos:latest
rootsimon-laptop_-_mnt_c_wsl-distribution-switcher
Bienvenue sur CentOS 7 !

Passer de l’une à l’autre

Pour switcher de l’une à l’autre, on utilisera le script switch.exe. Les distributions disponibles sont listées s’il est appelé sans argument :

000002-c__windows_system32_cmd-exe

Exemple avec OpenSuSE 42.2 :

switch.exe opensuse:42.2

000003-rootsimon-laptop_-_mnt_c_wsl-distribution-switcher

Docker !

Attention : cela ne fonctionne pas avec toutes les images, loin de là.

WSL-Distribution-Switcher permet également de partir d’une image Docker en allant chercher sur Docker Hub grâce au script get-prebuild.exe :

get-prebuild.exe kalilinux/kali-linux-docker
install.exe kalilinux/kali-linux-docker

Note : J’ai régulièrement l’erreur Accès refusé avec install.exe. Il suffit d’insister un peu (= le relancer) et cela a toujours fini par passer.

Dans le cas d’une erreur 0x80070002, il s’agirait d’une erreur de permissions (source et source) mais je suis preneur d’une solution…

C’est cassé !

Si l’installation part en cacahuète, il est possible de repartir de zéro avec les trois commandes suivantes :

lxrun /uninstall /full /y
lxrun /install /y
lxrun /setdefaultuser root /y

Il faudra ensuite réinstaller ses distributions.

Git : exécuter des commandes sur toutes les branches

Voici un script que j’utilise pour fetch + merge récursivement tous les repos git à partir du répertoire courant. Il traite toutes les branches locales :

git for-each-ref --format='%(refname:short)' refs/heads/ | while read -r branch
do
    # Changement de branche
    git checkout "${branch}"

    # Code à exécuter sur cette branche
    # Exemple avec un git pull
    git pull
done

Exemple de script que j’utilise pour mettre à jour toutes les branches d’un repo Git :

current_branch="$(git rev-parse --abbrev-ref HEAD)"
echo " * Current branch : ${current_branch}"

echo " * Fetching all changes from Git..."
git fetch --all

git for-each-ref --format='%(refname:short)' refs/heads/ | while read -r branch
do
    if git diff --exit-code "${branch}" "origin/${branch}"
    then
        echo " * No change"
    else
        echo " * Moving to branch ${branch}..."
        git checkout "${branch}"
        echo " * Merging with origin branch..."
        git merge "origin/${branch}" "${branch}"
    fi
done

echo " * Moving back to ${current_branch}..."
git checkout "${current_branch}"

Sortie :

 * Current branch : master
 * Fetching all changes from Git...
Fetching origin
(...)
Already on 'master'
Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)
 * Merging with origin branch...
Updating dfb2637..78c0d21
Fast-forward
 doc/syntastic-checkers.txt | 9 ++++++++-
 plugin/syntastic.vim       | 2 +-
 2 files changed, 9 insertions(+), 2 deletions(-)
 * Moving back to master...
Already on 'master'

Source : fait maison 🙂

Extraire les scripts pre/post-install d’un RPM

Lorsque l’on extrait un RPM avec la commande rpm2cpio, seuls les fichiers du package sont extraits :

simon@simon-daas:[~/tmp]: ls
puppetlabs-release-pc1-el-7.noarch.rpm
simon@simon-daas:[~/tmp]: rpm2cpio puppetlabs-release-pc1-el-7.noarch.rpm | cpio -dium
12 blocs
simon@simon-daas:[~/tmp]: ls
etc  puppetlabs-release-pc1-el-7.noarch.rpm  usr

Pour récupérer les scripts pre/post-(un)install/update d’un RPM, on utilisera :

rpm -qp --scripts [chemin du RPM]

Lequel retournera l’intégralité des scripts :

simon@simon-daas:[~/tmp]: rpm -qp --scripts puppetlabs-release-pc1-el-7.noarch.rpm
preinstall scriptlet (using /bin/sh):
# Save state so we know later if this is an upgrade or an install
mkdir -p /var/lib/rpm-state/puppetlabs-release-pc1
if [ "$1" -eq 1 ] ; then
  touch /var/lib/rpm-state/puppetlabs-release-pc1/install
fi
if [ "$1" -gt 1 ] ; then
  touch /var/lib/rpm-state/puppetlabs-release-pc1/upgrade
fi


# Run preinstall scripts on install if defined
if [ "$1" -eq 1 ] ; then
  :
fi

# Run preinstall scripts on upgrade if defined
if [ "$1" -gt 1 ] ; then
  :
fi
postinstall program: /bin/sh
preuninstall scriptlet (using /bin/sh):
# Run pre-uninstall scripts on upgrade if defined
if [ "$1" -eq 1 ] ; then
  :
fi

# Run pre-uninstall scripts on removal if defined
if [ "$1" -eq 0 ] ; then
  :
fi
postuninstall scriptlet (using /bin/sh):
# Run post-uninstall scripts on upgrade if defined
if [ "$1" -eq 1 ] ; then
  :
fi

# Run post-uninstall scripts on removal if defined
if [ "$1" -eq 0 ] ; then
  :
fi
posttrans scriptlet (using /bin/sh):
# Run post-transaction scripts on install if defined
if [ -e /var/lib/rpm-state/puppetlabs-release-pc1/install ] ; then
  :
  rm /var/lib/rpm-state/puppetlabs-release-pc1/install
fi

# Run post-transaction scripts on upgrade if defined
if [ -e /var/lib/rpm-state/puppetlabs-release-pc1/upgrade ] ; then
  :
  rm /var/lib/rpm-state/puppetlabs-release-pc1/upgrade
fi

On peut également les obtenir pour un package déjà installé :

rpm -q --scripts [nom du RPM]

Source : https://blog.packagecloud.io/eng/2015/10/13/inspect-extract-contents-rpm-packages/