Skip to content

Linux Attitude

Le libre est un état d'esprit

Archive

Archive for October, 2007

Niveau :      
Résumé : kill -STOP ; kill -CONT

Lorsque vous lancez un programme, vous pouvez lui faire faire une pause. Vous savez tous comment faire :

$ sleep 10
ctrl-z
# et on relance
$ fg

Super, et maintenant si le soft a été lancé en arrière plan ?

$ sleep 10 &
# on le fait refenir au premier plan
$ fg
# pause
ctrl-z
# et on relance
$ fg

Bravo, vous avez passé le premier test. Maintenant, plus difficile. Et si le soft a été lancé depuis un autre terminal ? La réponse se trouve dans l'étude des signaux. Il existe un grand nombre de signaux, pour preuve :

$ kill -l

Mais une sélection précise permet de retrouver ceux qui sont derrière ctrl-z et fg. Il s'agit de STOP (19) et CONT (18). La réponse est donc :

# on pause
$ kill -19 1234
# et on relance
$ kill -18 1234

PS : Tant qu'on est dans les signaux, notez le signal sigalarm qui permet de réveiller un sleep qui dort (attention sa valeur de retour ne sera alors plus 0).

$ kill -14 1234

Niveau :      
Résumé : PROMPT_COMMAND=

Aujourd'hui vous avez découvert un problème sur une machine.
- "Mais que s'est-il passé ?"
- "Mais qui a fait ça ?"
- "Mais il faudrait stocker les dates dans les historiques !"

Ok, faisons comme ça ...

Première méthode, simple, exécutons une commande à chaque ligne exécutée qui va nous stocker cette information dans un nouvel historique. Notez qu'on ne peut pas mettre cette information dans .bash_history, ca mettrait le bazar.

$ export PROMPT_COMMAND='echo `date +"%F %T"` `history 1`>> ~/.bash_timestamp'

C'est bien, mais on peut faire beaucoup mieux : pas de sous-processus (vive les perfs), pas de duplication de ligne lorsqu'on tape une ligne vide, pas de No de séquence

$ H2=0
$ export PROMPT_COMMAND='H=`history 1` ; H1=${H:0:6} ; [ $H1 -eq $H2 ] || echo `date +"%F %T"` "${H:6}" >> ~/.bash_timestamp ; H2=$H1'

C'est bien, maintenant nous voudrions avoir l'historique de tous les utilisateurs. Mettons tout ça dans /etc/bash.bashrc, donc pour tout le monde, avec quelques adaptations :

$ H2=0
$ export PROMPT_COMMAND='H=`history 1` ; H1=${H:0:6} ; [ $H1 -eq $H2 ] || echo `date +"%F %T"` "$USER" "${H:6}" >> /var/log/bash_logs ; H2=$H1'

Pour que ça marche, il nous faut un fichier inscriptible par tout le monde.

$ touch /var/log/bash_logs
$ chmod 662 /var/log/bash_logs

Et nous allons nous préserver de la mauvaise foi des utilisateurs qui voudraient modifier ces logs a posteriori.

# en root
$ chattr +a /var/log/bash_logs

Notez qu'on ne se préserve que de leur mauvaise foi mais qu'il est impossible de se préserver de la malveillance, car il suffit de redéfinir son PROMPT_COMMAND (ou d'utiliser autre chose que bash ...) pour que rien ne soit loggué.

Niveau :      
Résumé : mysleep

Si vous gérez plusieurs serveurs, il est probable que vous ayez des crons sur un certain nombre d'entre eux. Il est aussi probable qu'un certain nombre aient des cron en commun. Lorsque ces cron impactent d'autres serveurs (serveur NFS, ftp ...) il vaut mieux éviter de lancer toutes ces crons en même temps.

Mais il et dommage de devoir gérer et envoyer des configurations différentes pour chaque serveur. D'autre part, les lancer de façon aléatoire pose le problème qu'elles peuvent encore se lancer en même temps, mais aussi qu'il sera plus difficile de débugger un éventuel problème .

Je vous propose dons un outil qui pourra être commun à toutes les machines et qui lancera ces cron à des moments presque tous différents mais invariables, appelons-le mysleep.

#!/bin/sh

# choix d'une durée
DURATION=$((0x`hostid`%$1*$2))

# debug
[ "$DEBUG" == "1" ] && echo $DURATION

# et on attend
sleep $DURATION

Il s'utilise alors de la façon suivante dans vos cron :

# 5 machines, lancement séparé de 60 secondes
0 12 * * * /usr/local/bin/mysleep 5 60 && /path/to/cron/script

Attention, ce script se base sur le hostid. Rien ne garantit qu'il soit unique, il est d'abord lu comme le premier entier de 32 bits de /etc/hostid, et s'il n'existe pas comme l'ip correspondant au hostname. Et enfin s'il n'existe pas il vaut 0. En cas de problème vérifiez donc la distribution de vos hostid.

En cas de problème vous pouvez faire afficher au script la valeur de son sleep :

$ DEBUG=1 /usr/local/bin/mysleep 5 60

Ensuite ce script prend 2 paramètres le premier indique le nombre de valeurs différentes qu'on veut obtenir et le second l'écart entre ces valeurs. Le produit des 2 indique donc l'écart maximum entre la première et la dernière cron.

Attention, rien ne garanti que la répartition soit uniforme et donc que 2 machines ne se lanceront jamais en même temps. Mais si vos machines sont distribuées sur un réseau local, il est probable que les ip se suivent et donc que les valeurs de sleep soient toutes différentes.

Niveau :      
Résumé : cat /dev/vcs1

Parfois, vous voulez lire le contenu de la console d'une machine, par exemple si vous êtes sur une machine distante et que vous vouliez vérifier ce qui se passe, ou que vous êtes une grosse feignasse qui refuse de taper ctrl-alt-f1. Enfin vous pourrez aussi lire ce qui se passe sur le terminal qui est derrière votre serveur X (en général rien). Alors je vais tout vous expliquer.

Linux propose plusieurs device pour lire ses terminaux. Ils s'appellent /dev/vcsX et /dev/vcsaX. Selon les systèmes, il peuvent aussi se trouver dans le répertoire /dev/vc/X (X étant le numéro du terminal).

Il existe plusieurs méthodes pour en lire le contenu, il faut dans tous les cas être root pour le lire (ls -l /dev/vcs* pour vérifier). Tout d'abord intéressons-nous à vcs1, celui-ci contient uniquement le texte du terminal.

À l'ancienne :

# 1 pour le premier terminal et fd/1 pour stdout
$ setterm -dump 1 -file /proc/self/fd/1

Méthode ultra simple, attention, il faut que votre terminal en cours fasse la même largeur que le terminal à lire (en général 80 colonnes) :

$ cat /dev/vcs1

Même chose mais sans les inconvénients :

$ fold -w 80 /dev/vcs1 && echo -e "n"

Mais tout ceci n'inclue pas les couleurs ni la position du curseur. vcsa1 contient ces informations. Pour les afficher proprement je vous ai préparé un petit script perl.


continue reading...

Niveau :      
Résumé : subjectAltName

On vous a toujours dit qu'il n'était pas possible de faire des virtualhost en https. En gros vous devriez avoir une ip par site. Mais réveillez vous camarade, on vous ment, on vous spolie ... En effet tout est possible en informatique, ou presque, c'est juste une question de temps passé à mettre à jour les navigateurs du monde entier.

TLS

Tout d'abord, faut-il vraiment faire du SSL ? C'est une vraie question. En effet, il existe le TLS, "successeur" du SSL qui permet une négociation de la couche de sécurité après une connexion normale. Il existe déja une RFC pour faire du HTTP sur TLS (2817 et 2818) mais pour permettre les virtualhost, il faut une extension supplémentaire (SNI, RFC 3546). C'est probablement une solution d'avenir, mais :

  • SNI is supported in Firefox 2, IE 7 on Vista, Opera 7.6+ and other modern browsers. For Apache, mod_gnutls supports it, but not mod_ssl (OpenSSL). I'm not sure about IIS.
  • Le support dans lighthttpd en est encore au stade du patch

Certificats SSL

Supposons que vous vouliez donc rester en SSL classique. Alors la bonne solution, celle qui marche pour tous les navigateurs est d'utiliser des certificats avec "SubjAltNames".

Openssl étant codé un peu bizarrement, il ne propose pas de modifier ce paramètre en ligne de commande. Il faut donc modifier le fichier de configuration. Comme nous ne somme pas root et que sous sommes fainéants, nous allons recopier la configuration par défaut dans notre répertoire de travail :

$ cp /etc/ssl/openssl.cnf .
$ vi openssl.cnf

Il faut avoir une section req demandant d'utiliser les extensions et une section spéciale pour l'extension. Et c'est dans cette extension que nous mettrons nos différents virtualhosts.

[ req ]
req_extensions = toto
...

[ toto ]
subjectAltName     = DNS:wiki.toto.fr, DNS:blog.toto.fr

continue reading...

Bonjour à tous,

Aujourd'hui un article totalement hors sujet. Ce blog est un succès personnel, je ne pensais pas être capable de tenir le rythme de 4 articles par semaines, même si faiblis un peu.

Et je fête mon 115e article (sisi c'est un nombre rond). YEAH ! Kikoo, lol, toussa ...

Alors l'horoscope des utilisateurs :

  • vous êtes plutôt des gens fidèles (peu de referer)
  • vous êtes toujours au courant de tout (nombreux utilisateurs de netvibes)
  • vous aimez vous sentir différents (referer en linuxfr.org)
  • vous faites quand même comme tout le monde (toutes vos recherches sur google)
  • vous avez du temps libre au boulot (lecture rapide de l'article de la veille)

Côté Guiness book :

  • plus grand nombre de visiteurs en une journée 140
  • plus grand nombre de pages vues : 1150

Alors parlez en à vos voisins, mon objectif est d'environ 1 million de pages vues à la fin du mois.

Pour parler de moi, hé bien je suis grand, fort, athlétique et si tu es blonde à forte poitrine envoi moi ta photo. Sinon pour ceux qui veulent vraiment en savoir plus, je suis sysadmin, développeur et toutes sortes de choses sympa, alors n'hésitez pas à me téléphoner pour me proposer 50% d'augmentation.

--
Benoît
Vanitas, vanitum, omnia vanita

Niveau :      
Résumé : ~/.bash_logout ; pgrep ; time

Pour éviter de laisser traîner des infos dans une console ouverte :

$ echo clear >> ~/.bash_logout

Pour récupérer rapidement un process sans tomber sur grep :

$ ps aux | grep "[t]oto"
$ pgrep -l toto

Comptage des connexions http et mail :

$ exec 3>&1 && ( netstat -putan | tee /dev/stderr |  echo http: $(grep -c ":80 .*ESTABLISHED") ) 2>&1 1>&3| echo smtp: $(grep -c ":25 .*ESTABLISHED" )

Lorsque vous faites une modification sur un serveur ssh, pensez à garder un ssh connecté. En effet, celui-ci restera ouvert même si le serveur ssh tombe. Faites vos modifications, puis un test avec un 2e client ssh et c'est seulement là que vous serez assez courageux pour fermer le premier client.

Mesurer une durée dans un script shell :

$ begin=$(date +%s)
$ [...]
$ duration=`date +%T  -d "01/01/1970 +$(($(date +%s)-begin)) seconds "`
$ echo $duration

Mesurer une durée dans un script shell (bis) :

# attention, ce n'est pareil, l'information est écrite directement dans le terminal
$ time [...]