29 Jul 2019, 00:00

Docker

Une source intéressante
Images, conteneurs et volumes
Dockerfile build

Installation sous Debian

  • On install avec

    sudo apt install docker.io
    

    à partir de buster ; sinon, utiliser le site docker.io.

  • Puis on peut faire

    sudo adduser user docker
    

    pour ne pas avoir à taper sudo à chaque commande.

Gestion des images

  • Chercher une image Debian officielle, en se basant sur le score de l’image

    docker search --filter=stars=1000 debian
    
  • Récupérer cette image en local (stocké dans /var/lib/docker/, en grosse partie sous forme de diff dans overlay2/ )

    docker pull debian:tag
    # si :tag est omis, docker cherchera :latest
    
  • Créer une image depuis un Dockerfile

    # In folder containing the Dockerfile
    docker build -t "my-image123:test" .
    
  • Pour supprimer une image

    docker rmi my-image123:test
    # on peut aussi utiliser l'id de l'image
    

docker build

Sert à génerer des images modifiées à partir d’images existantes.
Utilise un fichier Dockerfile (nom non négociable).
Celui-ci est formaté avec une instruction FROM qui définit l’image de base utilisée. Ce peut être un nom type debian ou un ID type 00bf7fdd8baf

On peut utiliser RUN pour lancer des instructions shell pour modifier notre image. Par exemple

docker build -t nom:tag /path/to/folder/with/Dockerfile

–rm=false : permet de ne pas supprimer les conteneurs intermédiaires (cache), même après un build successful

Gestion des conteneurs

Un conteneur est instancié à partir d’une image.

  • Créer un conteneur à partir de cette image

    # en version simple
    docker create debian
    # qui va chercher debian:latest
    # on peut aussi faire
    
    # en plus complet
    docker create -ti --name my-app123 --hostname app --net my-net123 debian:tag welcome-command
    # les options doivent être avant le nom de l'image de base
    # on peut spécifier, après le nom d'image, la commande à exécuter (typiquement bash)
    # -t pour --tty, ce qui permettra de lancer le conteneur avec un shell root@truc:/# . Sans ça, il se coupe si rien à faire
    # -i pour --interactive , ce qui laissera la porte ouverte au conteneur pour recevoir des commandes (STDIN ouvert)
    # si aucun nom s'est spécifié, Docker en génerera un poétique
    # si aucun hostname n'est spécifié, il sera géneré aléatoirement
    # --net ou --network permet d'attacher le conteneur à un réseau choisi
    # --link container-name:local-alias  ??
    
  • Démarrer ce conteneur

    docker start my-app123
    

    Le conteneur est lancé, mais ne s’affiche pas dans notre terminal (juste son nom).
    Il faut l’attacher, pour avoir le shell à l’écran et pouvoir interagir.

    docker attach my-app123
    

    On peut directement attacher le shell lors de la création du conteneur, mais il faut alors spécifier l’option -i pour pouvoir interagir avec le conteneur (taper des commandes).

    docker start -ia my-app123  # --interactive --attach
    # -a , --attach pour voir l'état du conteneur
    # -i pour pouvoir taper des commandes
    

    On peut ensuite détacher le conteneur avec Ctrl-P -> Ctrl-Q.

  • Éteindre ce conteneur

    docker stop my-app123
    
    docker kill my-app123 # pour forcer l'extinction
    
  • Lister les conteneurs

    docker ps
    # pour lister les conteneurs en cours d'éxécution
    
    docker ps -a
    # pour lister tous les conteneurs, même éteints.
    
  • Supprimer un conteneur précis

    docker container rm my-app123
    # on peut aussi utiliser l'id
    
  • Supprimer tous les conteneurs qui ne snt pas en train de tourner

    docker container prune
    # -f si on souhaite ne pas avoir de prompt de confirmation
    

docker run

Combine docker pull, docker create et docker start

docker run name # télécharge si nécessaire l'image "name:latest", crée un container avec un nom aléatoire, et le lance
# on peut passer à docker run les mêmes arguments que docker create
docker run --name="my-app123" -p 80:80 -e TERM=xterm -d --net my-net123 --ip 172.18.0.23 demo-docker

Réseau

Doc chez docker

Docker crée une interface virtuelle pour chaque réseau créé. Par défaut, c’est la carte docker0 qui crée le réseau bridgé 172.17.0.0/24 avec l’adresse 172.17.0.1.
Il y’a différents types de réseau : bridge (réseau virtuel “simple”, choix par défaut), host (le conteneur se connecte directement via la pile réseau de la carte de l’hôte), overlay (surtout pour le swarm), macvlan.

On peut créer des réseaux (bridgés) définis sur mesure. Ces réseaux se comporteront différemment du réseau par défaut. Notamment, les machines pourront communiquer entre elles via leur adresse IP, mais également via le nom de conteneur. De plus, tous les ports de chaque conteneur seront ouverts vers tous les autres conteneurs sur le même réseau (et, par défaut, aucun port ouvert vers l’extérieur). Un conteneur peut être connecté à plusieurs réseaux.
Chaque conteneur lancés aura aussi une interface virtuelle type veth1234567.

  • lister les réseaux

    docker network ls
    
  • voir le détail d’un réseau

    docker network inspect network-name
    
  • créer un réseau

    docker network create --subnet 172.18.0.0/24 my-net123
    
  • lancer un container sur un network

    docker run --net my-net123 --ip 172.18.0.23
    
  • Connecter un conteneur sur un réseau (peut être fait à la volée pour un réseau déifni, mais le conteneur doit être éteint pour le faire sur le réseau par défaut docker0)

    docker network connect my-net123 my-app123
    
  • Déconnecter un conteneur d’un réseau (peut être fait à la volée pour un réseau déifni, mais le conteneur doit être éteint pour le faire sur le réseau par défaut docker0)

    docker network disconnect my-net123 my-app123
    
  • Supprimer un réseau

    docker network rm my-net123
    
  • retirer les réseaux inutiles

    docker network prune
    

Exposer un port sur un conteneur déjà lancé

Troubleshooting

Error starting userland proxy: listen tcp 0.0.0.0:80: bind: address already in use

Signifie que le port sur lequel on essaye de lancer une machine est déjà pris par une autre machine.

19 Jun 2019, 00:00

Désactiver la mise en veille de la carte son sous Linux

Sous Linux, il arrive que, pour économiser de l’énergie, la carte son se mette en veille après quelques temps d’inactivité. Ceci génère chez moi des craquements assez désagréables lors de sa remise en fonctionemment, ou parfois un craquement très régulier tout le long de la veille.

Pour voir si la mise en veille est activée :

cat /sys/module/snd_hda_intel/parameters/power_save

S’il contient autre chose que 0, alors le mode powersave est activé.

Pour le désactiver, on peut ajouter le fichier /etc/modprobe.d/snd_disable_powersave.conf et entrer dedans la ligne suivante :

options snd_hda_intel power_save=0

Puis redémarrer, ou bien décharger/recharger le module.

10 Feb 2019, 00:00

Notes sur fail2ban

Généralités

2 articles qui m’ont inspiré :
http://xmodulo.com/configure-fail2ban-apache-http-server.html
https://www.digitalocean.com/community/tutorials/how-to-protect-ssh-with-fail2ban-on-centos-7

fail2ban se base sur l’analyse des logs pour bannir des adresses ip (via, par défaut, la création de règles iptables) qui auraient enfreint certaines règles.
Les expressions régulières qui servent à analyser les fichiers de conf se trouvent dans le dossier /etc/fail2ban/filter.d/.

Les fichiers de conf sont lus dans l’ordre suivant, sachant que c’est la dernière mention d’un paramètre redondant qui sera prise en compte :

/etc/fail2ban/jail.conf
/etc/fail2ban/jail.d/*.conf
/etc/fail2ban/jail.local
/etc/fail2ban/jail.d/*.local

Il est conseillé de ne pas toucher aux fichier .confs (ce qui permet entre autres de ne pas perturber les mises à jour système) mais de rajouter nos propres règles dans des fichiers .local.

On voit dans jail.conf des paramètres par défaut (sous la balise [DEFAULT]) :

# "bantime" is the number of seconds that a host is banned.
bantime  = 600

# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime  = 600

# "maxretry" is the number of failures before a host get banned.
maxretry = 5

On voit que si une ip échoue à se connecter 5 fois de suite (maxretry) en moins de 600 secondes (findtime), alors elle sera bannie pendant 600 secondes (bantime).
Il y’a aussi dans cette même section un nom fichier de filtre par défaut, qui reprend le nom de la jail :

filter = %(__name__)s

Cela dit que le fichier de filtre qui sera récupéré est le même que le nom de la jail.

Plus bas, on voit des exemples de jails, de type

[sshd]

port    = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s

Ces jails sont définies par défaut, mais non activées. Pour ceci, il faut leur donner le paramètre enabled = true. Par défaut, sous Debian, seul le service sshd est protégé par fail2ban, via le fichier /etc/fail2ban/jail.d/defaults-debian.conf.

Installation et configuration

Pour installer :

sudo apt install fail2ban

On peut ensuite créer par exemple un fichier /etc/fail2ban/jail.d/ssh.local qui contiendra :

[sshd]
enabled = true
port = 12345
findtime  = 60
maxretry = 5

afin de spécifier un port custom, et laisser le droit à 5 essais par minute.

On peut aussi créer /etc/fail2ban/jail.d/apache.local pour activer fail2ban pour apache :

# detect password authentication failures
[apache-auth]
enabled  = true
port     = http,https
findtime  = 60
maxretry = 5

pour un fail2ban sur l’authentification par mot de passe.

02 Feb 2019, 00:00

Notes sur dm-crypt et LUKS

Source principale : la FAQ (ou en tout cas un mirroir) de cryptsetup

dm-crypt et LUKS

dm-crypt chiffre/déchiffre à la volée les données grâce à la master key, qui est directement dérivée du mot de passe fourni. Aucune structure spéciale n’est visible sur le disque, c’est un pur chiffrement 1:1. Si des secteurs sont corrompus, cela n’affectera aucunement les autres secteurs. Il n’y a aucun garde-fou intégré ; si on se trompe dans la clé entrée, ou dans les paramètres de chiffrement, les données seront lues/écrites avec la mauvaise clé, donc risque non-négligeable de perte de données si fausse manipulation.

LUKS est une surcouche à dm-crypt qui stocke la master key salées puis chiffrée dans une en-tête LUKS, qui précède les données chiffrées. Cette clé est déchiffrable grâce à plusieurs mots de passe (jusqu’à 8 différents) stockés dans des “key slots”, situés dans le header également. On peut donc ajouter/supprimer des mots de passe différents pour un même volume. Avec un mauvais mot de passe, LUKS ne nous laissera pas lire/écrire des données incorrectes.
Il est essentiel de backuper ce header à part, car sans lui, il sera impossible d’utiliser les données chiffrées. Il “décrit” la manière dont les données doivent être déchiffrées. Notamment grâce au sel, qui est cryptographiquement non-retrouvable.

Installation et chiffrement

On installe

apt install cryptsetup

Il faut consacrer un périphérique (disque, partition…) à LUKS. Toutes les données dessus seront bien sûr détruites. Ici, c’est sdX.
Il est conseillé d’effacer tous les headers d’anciens FS sur la cible, pour être sûr de ne pas avoir de fsck automatique ou autres joyeusetés qui détruiraient les données chiffrées :

sudo wipefs -a /dev/sdX

On crée le conteneur luks

sudo cryptsetup -y -v luksFormat /dev/sdX

-y : double check du mot de passe
-v : verbose

On déverrouille et mappe le conteneur :

sudo cryptsetup open /dev/sdX c1

Le conteneur sera accessible sur /dev/mapper/c1 (plus tard, lorsque udisks reconnaitra tout seul le conteneur (ou le FS dessus ?), ce sera typiquement /dev/mapper/luks-bla-bla-uuid)

On formate en ext4

sudo mkfs.ext4 /dev/mapper/c1

On peut ensuite monter la partition

sudo mount /dev/mapper/c1 /mnt

Et on a une partition chiffrée, qui s’utilise comme n’importe quel périphérique !

On peut la fermer avec

sudo cryptsetup close c1

Sauvegarde et restauration de l’en-tête !

Une fois que l’on compte se servir du périphérique pour stocker durablement des vraies données, il est indispensable de backuper le header du conteneur. Sans lui (corruption, création d’une table de partition sur le disque…), plus de données !

cryptsetup luksHeaderBackup /dev/sdX --header-backup-file /path/to/backup.img

Et pour restaurer en cas de besoin :

cryptsetup luksHeaderRestore /dev/sdX --header-backup-file /path/to/backup.img

Gestion des clés

À voir !

luksKeyAdd / luksAddKey
luksKillSlot
luksRemoveKey

Divers

Pour voir des infos sur le conteneur LUKS :

cryptsetup luksDump /dev/sdX

Pour voir des infos sur un conteneur LUKS une fois mappé (dans cet exemple sur /dev/mapper/c1) :

cryptsetup -v status c1

Voir la master key lorsque le périphérique est déverrouillé (attention aux yeux trop curieux)

sudo dmsetup table --target crypt --showkey /dev/mapper/c1

Selon plusieurs témoignages sur forum, il faut faire attention à certains installers d’OS qui proposent LUKS, et qui créent un nouveau container par-dessus l’ancien, avec un message trop peu explicite.

02 Feb 2019, 00:00

Usage du .htaccess dans Apache 2

Le fichier .htaccess est un fichier en texte clair, qui permet de définir le message affiché lors de la demande de mot de passe, ainsi que le fichier dans lequel Apache ira vérifier que l’utilisateur/mot de passe est correct (le .htpasswd).
Dans mon cas, je choisis de faire un fichier .htpasswd par répertoire, car tous les répertoires ne doivent pas être accessibles aux mêmes utilisateurs.

Je crée le .htpasswd :

cd /path/to/site/files
htpasswd -c .htpasswd user1

L’option -c sert à créer/réécrire le fichier. Si on ne la spécifie pas, ça rajoute une nouvel utilisateur qui pourra lire ce répertoire.

Ensuite, on ajoute le .htaccess, qui va directement protéger le répertoire

nano .htaccess

Dans lequel on met :

AuthType Basic
AuthUserFile "/path/to/site/files/.htpasswd"
AuthName "Identification pour ce dossier ?"
Require valid-user

Il semble indispensable d’indiquer le chemin complet vers le .htpasswd, sans quoi le serveur retourne une erreur 500.

Dans le cas où le repértoire est en dehors des répertoires standards de Apache (/usr/share ou /var/www), il faut les ajouter à la main dans le /etc/apache2/apache2.conf ou dans /etc/apache2/sites-available/00X-mon-site.conf :

<Directory /path/to/site/files/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
</Directory>

Ceci permet respectivement de suivre les liens symboliques (utile pour mon setup), de permettre d’outrepasser les droits localement (et donc d’utiliser le htaccess), et permet à tout le monde (toutes les IPs notamment) d’accéder au site.

07 Jan 2019, 00:00

Notes rapides sur récupération mdadm

Disques tous en spare

Après une panne d’éléctricité, un RAID6 de 12 disques (dégradé, avec 1 disque manquant) a refusé de se remettre en route. Après vérification (par live-cd) via un cat /proc/mdstat, les 11 disques étaient tous en spare (se manifeste par un [S] ).
Pour ce raid sont utilisées les 2e partitions de chaque disque de sda -> sdk. J’ai vérifié l’état de synchronisation de tous les volumes : sudo mdadm --examine /dev/sd[abcdefghijk]2 | grep Events

Events : 2845752
Events : 2845752
Events : 2845752
Events : 2845752
Events : 2845752
Events : 2845752
Events : 2845752
Events : 2845752
Events : 2845752
Events : 2845752
Events : 2845752

Ils sont bien synchronisés, mais pas assemblés. J’ai alors testé
sudo mdadm --assemble --force /dev/md126 /dev/sd[abcdefghijk]2
mais ai obtenu 11 jolis “Device or ressource busy”. Ce qui est normal, les disques étant intégrés dans le RAID, mais en spare. J’ai alors lancé
sudo mdadm --stop /dev/md126
suite à quoi la commande d’assemblage précédemment citée a bien fonctionné, le RAID s’est resynchronisé sans perdre de données, en prenant toutefois son temps.

RAID fonctionnel qui ne se synchronise pas tout seul

Dans un autre cas, où le RAID était resté fonctionnel mais dans lequel un volume manquait (sdl2, détecté mais non intégré/synchronisé), j’ai pu le réintégrer avec la commande sudo mdadm --re-add /dev/md126 /dev/sdl2 (si re-add ne fonctionne pas, add devrait fonctionner mais prendre plus de temps).

Dans encore un autre cas, un seul disque était intégré au RAID, mais non synchronisé, car il restait en “spare”. J’ai pu forcer la réintégration avec la commande
echo check > /sys/block/md126/md/sync_action
De la lecture intéressante se trouve sur cette page.

Ici aussi : https://robbat2.livejournal.com/231207.html?nojs=1

06 Jan 2019, 00:00

Ripper des cd audio avec abcde et intégrer l'image dans les fichiers

Suite à quelques soucis de recherche dans la base CDDB avec Asunder, voici un mini-tuto pour abcde. Déjà,

sudo apt install abcde lame eyed3 glyrc imagemagick cdparanoia

Les préférences d’extraction se définissent dans le fichier /etc/abcde.conf ou bien dans un fichier user qui outrepassera le précédent, et que nous éditons ici : pluma ~/.abcde.conf

# VBR bonne qualité
LAMEOPTS='-V 0'
# On extrait la couverture
ACTIONS=default,getalbumart
# On range les fichiers finaux dans ce dossier :
OUTPUTDIR="/path/to/music/dir"
# On encode en mp3
OUTPUTTYPE=mp3
# Arborescence type Artiste/Album/01 - Morceau.mp3
OUTPUTFORMAT='${ARTISTFILE}/${ALBUMFILE}/${TRACKNUM} - ${TRACKFILE}'
# On ne remplace PAS les espaces par des underscores (et autres modifs)
mungefilename ()
{
echo "$@"
}

On peut ensuite lancer abcde ou encore abcde -d /dev/sr1 si on spécifie manuellement le lecteur CD.

Enfin, dans le dossier final, si on souhaite intégrer la pochette au fichier :

for i in *.mp3
do
eyeD3 --add-image cover.jpg:FRONT_COVER "$i"
done

(cf cette page)

30 Dec 2018, 00:00

Freeze du poste avec Optimus lorsque bumblebee est installé

Habituellement, lorsque je souhaite installer une Debian sur un pc avec double carte graphique Intel-Nvidia (système Optimus), il suffit d’installer bumblebee via apt install bumblebee bumblebee-nvidia (ou simplement bumblebee si on souhaite essayer avec les pilotes libres Nouveau, ce qui m’a semblé fonctionner moins souvent).
La configuration des paquets met en place toute la configuration nécessaire (glx, alternatives, modprobe/blacklist etc). Ceci installe également un module noyau bbswitch, dont le but est d’éteindre ou d’allumer à la demande la carte graphique dédiée.

Cependant, sur un poste, après avoir installé ces paquets, le pc freezait au démarrage, que le pilote soit nouveau ou nvidia. Comme le pc démarrait correctement en mode recovery, j’ai désactivé le lancement automatique du gestionnaire de connexion graphique. Ainsi, le pc démarrait correctement, je pouvais me connecter, mais dès le moindre service lightdm start ou startx, il freezait à nouveau. Après pas mal de lecture, j’ai appris que le fichier /proc/acpi/bbswitch contenait entre autre l’état de la carte graphique (ON ou OFF), et que la commande tee /proc/acpi/bbswitch <<<ON permettait de l’allumer à la demande.
Et j’ai constaté que la carte était en OFF à chaque démarrage, que si on essayait de lancer un programme graphique (même une interface graphique qui tourne sur la carte intégrée au CPU) alors que la carte dédiée était OFF, alors ça freezait. Si par contre on allumait manuellement la carte avant, on pouvait lancer l’interface, et ensuite ça fonctionnait, même si la carte était coupée. Mais si on souhaitait simplement se déconnecter, comme ceci coupe puis relance l’interface graphique, alors ça freezait à nouveau…

Mais avec le détail des cas où ca plantait, j’ai facilement trouvé ce rapport de bug, et après moult tests, modifier la ligne dans le fichier /etc/default/grub pour qu’elle ressemble à ceci :

GRUB_CMDLINE_LINUX_DEFAULT="quiet acpi_osi=! acpi_osi='Windows 2009'"

suivi d’un update-grub a bien fonctionné ! Les graphiques standards sont bien lancés sur le gpu intégré, le gpu dédié est éteint la plupart du temps, allumé correctement lorsqu’on lance un programme avec optirun, et bien éteint lorsque ce programme se termine.

23 Nov 2018, 00:00

Appliquer un fichier .patch à une source Debian

La version du programme disper disponible dans les dépôts Debian stretch segfault dès qu’on lui demande quelque fonction que ce soit.
Ceci a été discuté et corrigé sur le bugtracker de Debian. La version des dépôts n’est toutefois toujours pas corrigée. Comme c’était mon premier ( \o/ ), voici comment appliquer le patch.

On commence par vérifier/ajouter le dépôt source au sources.list
deb-src http://deb.debian.org/debian/ stretch main contrib non-free

On crée un dossier de travail, et on y récupère les sources de disper.

mkdir disper-patch && cd disper-patch
apt source disper

On prépare les paquets nécessaires à la construction du paquet.

## permet l'installation automatique des paquets nécessaires pour compiler disper
sudo apt build-dep disper
## contient des outils pour construire et maintenir des paquets Debian. Pas sûr que ce soit nécessaire
sudo apt install packaging-dev devscripts

On récupère ensuite le patch, on l’applique, et on reconstruit le paquet

## ce fichier est une copie inchangée du fichier disponible dans la mailing-list
wget -c raphaelguetta.fr/files/disper-patch.diff

## Applique le patch à l'arborescence. L'option -p0 permet de conserver entiers les chemins fournis par le patch, sachant que le programme patch ne conserve par défaut que les noms de fichiers
patch -p0 < disper-patch.diff

## ce dossier contient directement la source upstream, et un dossier debian qui contient les modifs made-in Debian
cd disper-0.3.1
debuild -b -us -uc

Le paquet .deb doit normalement être disponible dans le dossier parent (ici disper-patch). On peut l’installer avec dpkg -i.

23 Nov 2018, 00:00

crng init done

Dans les versions du noyau disponibles dans stretch-backports, il m’est arrivé sur plusieurs machines d’avoir un démarrage très long (1 à 2 minutes sans activité visible), avec un blocage tant que la phrase “crng init done” n’est pas apparue.
Visiblement, certaines fonctions/pilotes nécessitent d’avoir le pool d’entropie rempli, ce qui peut dorénavant prendre plusieurs minutes.

Pour corriger ceci, il semblerait que les paquets haveged, rng-tools et/où rng-tools5 améliorent la vitesse d’acquisition de l’entropie, à défaut de trouver une solution plus pérenne.