nov 27 2008

Limiter le temps d’exécution d’une requête MySQL

Vous est-il déjà arrivé de voir un de vos serveurs de base de données MySQL mis à genoux par la faute de développeurs incompétents qui effectuent des requêtes sur des tables sans index composées de dizaines de millions de tuples ?
Si la réponse est oui, voici ma solution « one line » pour les calmer un peu ! :)

Logiciels utilisés :

  • GNU Awk 3.1.5
  • MySQL Client 5.0.51a
root@gnusquad:~# mysql -e 'SHOW PROCESSLIST' | awk 'BEGIN { MAX_TIME = 60 ; USERS = "boulet1|boulet2" } $6 > MAX_TIME && $5 == "Query" && $2 ~ USERS {print "KILL " $1 ";"}' | mysql

Petites explications sur le code « awk » :

  • $1 contient l’ID de la requête SQL
  • $2 contient le nom de l’utilisateur
  • $5 contient le type de commande (Query, Sleep, …)
  • $6 contient le temps d’exécution de la requête SQL en secondes
  • MAX_TIME contient le temps en secondes à partir duquel une requête doit être tuée
  • USERS contient une expression rationnelle indiquant les utilisateurs concernés par cette sanction

Il ne vous reste plus qu’à mettre ce script dans le « crontab » en pensant à vous connecter avec un utilisateur MySQL ayant le droit « SUPER » pour pouvoir tuer les connexions si besoin est. :)

À lire :


nov 22 2008

Mettez de la couleur dans votre « prompt » !

Tag: Debian GNU/Linux, SystèmeSylvain @ 18:26

Le « prompt », que l’on désigne par « invite de commande » en français est une chaîne de caractères indiquant que l’ordinateur est prêt à recevoir une saisie au clavier.

Les informations qui suivent concernent le shell livré par défaut avec la plupart des distributions, le bien nommé « Bash ».

Le « prompt » est défini dans une variable d’environnement nommée « PS1 », celle-ci peut contenir des données statiques mais également des « séquences d’échappement » spéciales permettant d’afficher des données dynamiques comme le nom d’utilisateur courant, le répertoire courant, etc. Il est également possible de mettre de la couleur afin d’égayer un peu votre terminal et surtout de vous retrouvez dans vos différents comptes utilisateurs ou dans vos différentes machines.

Voici la liste des séquences d’échappement intéressantes :

\h : le nom de la machine (hostname) jusqu'au premier point
\H : le nom de la machine complet
\j : le nombre de processus fils lancés en arrière plan
\e : caractère d'échappement (utile pour les couleurs)
\n : nouvelle ligne
\r : retour chariot
\u : le nom d'utilisateur courant
\w : le chemin complet du répertoire de travail courant
\W : le répertoire de travail courant
\$ : affiche un # si l'utilisateur est root sinon affiche un $
\[ : début d'une séquence de caractères non imprimables
\] : fin d'une séquence de caractères non imprimables
\D{format} : la date selon le format passé en paramètre (cf. la syntaxe de « strftime »)

Les couleurs quant à elles sont des « séquences d’échappement ANSI » entourées d’un début et d’une fin de séquence de caractères non imprimables. Ces séquences ont un format bien déterminé : celui-ci commence par « ESC[ » et se termine par « m ». Entre ces deux parties, il faut indiquer un code de mise en forme (gras, souligné, clignotement, etc) ainsi qu'un code pour la couleur désirée, les deux champs étant séparés par un point-virgule.

Voici la liste des mises en forme les plus courantes :

 0 : normal
 1 : gras
 4 : souligné
 5 : clignotement
 7 : négatif
22 : désactivation du gras
24 : désactivation du souligné
25 : désactivation du clignotement

Et la liste des couleurs :

0 : noir
1 : rouge
2 : vert
3 : jaune
4 : bleu
5 : magenta
6 : cyan
7 : blanc

À ces dernières doit être additionné un nombre afin de définir si l'on veut modifier la couleur du fond ou du texte tout en réglant l'intensité :

 30 : couleur du texte, intensité normale
 40 : couleur du fond, intensité normale
 90 : couleur du texte, intensité élevée
100 : couleur du fond, intensité élevée

Pour voir votre PS1 actuel, tapez simplement dans un shell :

user@gnusquad:~$ echo $PS1
\[\e[1;42m\]\u@\H\[\e[0;40m\]:\w\$

Décortiquons cette ligne :

\[   : début d'une séquence de caractères non imprimables (pour la couleur)
\e[  : début d'une séquence ANSI
1;42 : mise en forme grasse avec une couleur de fond verte intensité normale
m    : fin d'une séquence ANSI
\]   : fin d’une séquence de caractères non imprimables
\u   : nom d'utilisateur courant
@    : signe @
\H   : nom de la machine complète
\[   : début d'une séquence de caractères non imprimables
\e[  : début d'une séquence ANSI
0;40 : mise en forme normale avec une couleur de fond noir intensité normale
m    : fin d'une séquence ANSI
\]   : fin d’une séquence de caractères non imprimables
:    : signe :
\w   : chemin complet du répertoire de travail courant
\$   : caractère # si l'utilisateur est root sinon caractère $

Pour tester vos créations (ici un fond rouge qui peut être pratique pour l'utilisateur « root »), il vous suffira de taper dans un shell :

user@gnusquad:~$ PS1='\[\e[1;41m\]\u@\H\[\e[0;40m\]:\w\$'
user@gnusquad:~$

Une fois satisfait de votre « PS1 », vous n'aurez plus qu'à le mettre dans le fichier « /etc/bash.bashrc » (pour tous les utilisateurs) ou dans votre fichier « ~/.bashrc » (pour vous uniquement).

Notez au passage qu'il existe aussi trois autres variables d'environnement « PS2 », « PS3 » et « PS4 » que je vous laisse découvrir dans le man de bash ! ;-)

N'hésitez pas à proposer vos « prompt » en commentaires ! :)

À lire :


sept 05 2008

Automatiser une compilation après l’installation d’un nouveau noyau

Tag: Debian GNU/Linux, SystèmeSylvain @ 06:25

Quoi de plus énervant que de devoir lancer systématiquement la compilation d’un module après l’installation d’un nouveau noyau ? Une solution simple pour contourner ce problème est d’utiliser le fichier « /etc/kernel-img.conf » qui est consulté par les différents scripts d’installation des paquets pour les noyaux.

Voici le contenu typique de ce fichier :

# Kernel image management overrides
# See kernel-img.conf(5) for details
do_symlinks = yes
relative_links = yes
do_bootloader = yes
do_bootfloppy = no
do_initrd = yes
link_in_boot = no
postinst_hook = update-grub
postrm_hook = update-grub

La variable qui nous intéresse est postinst_hook, elle contient le programme à lancer après l’installation du noyau. À celui-ci est passé deux paramètres : en premier la version du noyau et en second le chemin vers le noyau lui-même. Par défaut, update-grub est lancé permettant la mise à jour du menu de démarrage (« /boot/grub/menu.lst »).

Prenons pour l’exemple, la compilation du module propriétaire Nvidia.

Il nous faut donc créer un script effectuant la mise à jour de GRUB ainsi que cette compilation grâce à « module-assistant ». En théorie, ce n’est pas plus compliqué que ça, mais en pratique, on se rend compte que ça ne fonctionne pas, tout simplement parce que « module-assistant » a besoin d’installer des paquets et qu’une instance de « dpkg » est déjà en route pour l’installation du noyau… Une solution est donc de créer un script qui s’exécutera ultérieurement, j’ai choisi de créer un service qui sera lancé dès que la machine changera de niveau d’exécution (ce qu’on appelle le « runlevel »).

Voici le script, à adapter à vos besoins, qui générera le service :

root@gnusquad:~# vi /usr/local/sbin/postinst_kernel.sh

#!/bin/sh

FILE=/etc/init.d/update-kernel

# On switche de VT pour que l'utilisateur suive ce qu'il se passe
echo "chvt 7" >> $FILE

# Compilation du module Nvidia pour la version $1 du noyau
echo "m-a a-i nvidia -l $1" >> $FILE

# Mise à jour de grub
echo "update-grub $@" >> $FILE

# Suppression du script une fois son travail terminé
echo "update-rc.d -f update-kernel remove" >> $FILE
echo "rm $FILE" >> $FILE

# Ajout des permissions d'exécution sur le script
chmod +x $FILE

# Ajout du script dans les différents runlevel
update-rc.d update-kernel defaults

Rendons le exécutable :

root@gnusquad:~# chmod +x $_

Et mettons à jour la variable « postinst_hook » du fichier de configuration :

root@gnusquad:~# vi /etc/kernel-img.conf

# See kernel-img.conf(5) for details
do_symlinks = yes
relative_links = yes
do_bootloader = yes
do_bootfloppy = no
do_initrd = yes
link_in_boot = no
postinst_hook = /usr/local/sbin/postinst_kernel.sh
postrm_hook = update-grub

Désormais, à l’installation d’un nouveau noyau, ce script sera lancé, celui-ci générera le fichier « /etc/init.d/update-kernel » qui sera, pour sa part, exécuté lors du prochain changement de niveau d’exécution (généralement lors du redémarrage ou de l’arrêt de la machine).

Voilà, c’était pas plus dur que ça grâce à Debian ! :-)
Pour information, d’autres hooks sont disponibles (postrm, preinst, prerm, …), il ne vous reste plus qu’à en faire bon usage ! ;)

À lire :


mai 29 2008

Faire du SFTP dans un chroot avec scponlyc

Tag: Debian GNU/Linux, SystèmeSylvain @ 06:39

Commençons tout d’abord par expliquer les quelques termes alambiqués du titre de ce billet pour les néophytes :

  • SFTP signifie « Secure File Transfer Program », c’est un programme permettant de transférer des fichiers en utilisant une liaison chiffrée par SSH (Secure SHell) ; attention à ne pas confondre SFTP avec FTPS qui signifie pour sa part « File Transfer Protocol over SSL » !
  • chroot est un programme permettant de changer le répertoire racine d’un processus afin que ce dernier n’ai accès qu’à une partie limitée de l’arborescence.
  • scponlyc est un shell limité destiné uniquement aux transferts de fichiers dans un chroot.

Le but du jeu est donc de permettre à un utilisateur de transférer des fichiers sur un serveur de manière sécurisée sans qu’il n’obtienne pour autant un shell et sans qu’il lui soit permit de voir l’arborescence du serveur. Nous utiliserons pour l’exemple, la version 4.7 d’OpenSSH livrée avec Debian Testing.

Démarrons par l’installation du paquet scponly :

root@gnusquad:~# aptitude install scponly

Un script permettant de créer un compte utilisateur destiné au SFTP chrooté a été installé dans le répertoire « /usr/share/doc/scponly/setup_chroot/ », exécutons le en utilisant les réponses par défaut aux questions :

root@gnusquad:~# cd /usr/share/doc/scponly/setup_chroot/
root@gnusquad:/usr/share/doc/scponly/setup_chroot# gunzip setup_chroot.sh.gz
root@gnusquad:/usr/share/doc/scponly/setup_chroot# chmod +x setup_chroot.sh
root@gnusquad:/usr/share/doc/scponly/setup_chroot# ./setup_chroot.sh

Next we need to set the home directory for this scponly user.
please note that the user's home directory MUST NOT be writeable
by the scponly user. this is important so that the scponly user
cannot subvert the .ssh configuration parameters.

for this reason, a writeable subdirectory will be created that
the scponly user can write into.

Username to install [scponly]
home directory you wish to set for this user [/home/scponly]
name of the writeable subdirectory [incoming]

creating  /home/scponly/incoming directory for uploading files

Your platform (Linux) does not have a platform specific setup script.
This install script will attempt a best guess.
If you perform customizations, please consider sending me your changes.
Look to the templates in build_extras/arch.
 - joe at sublimation dot org

please set the password for scponly:
Enter new UNIX password:
Retype new UNIX password:
passwd : le mot de passe a été mis à jour avec succès
if you experience a warning with winscp regarding groups, please install
the provided hacked out fake groups program into your chroot, like so:
cp groups /home/scponly/bin/groups

Un compte utilisateur contenant les fichiers nécessaires au chroot a été créé dans « /home/scponly/ », celui-ci est presque complet, il ne lui manque que le fameux « /dev/null » que nous allons créer à la main :

root@gnusquad:/usr/share/doc/scponly/setup_chroot# cd ~scponly
root@gnusquad:/home/scponly# mkdir dev
root@gnusquad:/home/scponly# mknod -m 666 dev/null c 1 3

Dernière étape avant que ça ne fonctionne : pour pouvoir utiliser le programme « scponlyc », il faut que celui-ci soit exécuté avec les droits root ; pour cela, il faut placer le « sticky bit » sur l’exécutable « scponlyc » :

root@gnusquad:/home/scponly# chmod u+s $(which scponlyc)

Il est maintenant temps de tester notre compte chrooté : nous allons créer un fichier et l’envoyer à l’utilisateur « scponly » grâce au répertoire accessible en écriture « incoming » :

root@gnusquad:/home/scponly# cd
root@gnusquad:~#  echo "coucou" > test.txt
root@gnusquad:~#  scp test.txt scponly@localhost:incoming
scponly@localhost's password:
test.txt                                                           100%    7     0.0KB/s   00:00

Vérifions maintenant que le chroot fonctionne bien en utilisant « sftp » :

root@gnusquad:~# sftp scponly@localhost
Connecting to localhost...
scponly@localhost's password:
sftp> ls
bin       dev       etc       incoming  lib       usr
sftp> cd incoming
sftp> ls
test.txt
sftp> quit

Voilà, tout fonctionne correctement ! Notez cependant que toute cette procédure ne sera bientôt plus nécessaire avec les futures releases d’OpenSSH qui inclueront la possibilité de définir des chroot directement dans le fichier de configuration ce qui évitera par la même occasion de devoir mettre à jour son chroot lors de mise à jour de sécurité touchant les fichiers de celui-ci si l’on s’intéresse un tant soit peu à la sécurité ! :-)

À lire :


« Page précédentePage suivante »