Hard reboot à distance
Voici une astuce bien utile si votre serveur est complètement planté.
Il faut néanmoins pouvoir se connecter en SSH sur la machine et avoir un shell en root.
Dans mon cas, il s’agissait d’un problème d’accès disque, la plupart des commandes exécutées renvoyaient des erreurs d’entrée/sortie, y compris la commande reboot, qui a besoin d’exécuter les scripts d’init de niveau 6.
Mais tout n’est pas perdu, si vous n’avez pas d’accès physique à la machine ! On va passer par le pseudo système de fichier /proc pour parler directement au noyau et lui dire de redémarrer la machine.
Avant tout (et si il ne s’agit pas d’un problème disque), on tente de forcer la synchronisation du cache vers le disque :
syncOn active ensuite les magic sysrq key si elles ne le sont pas déjà :
echo 1 > /proc/sys/kernel/sysrq
Puis on modifie l’état de la machine :
echo b > /proc/sysrq-trigger
Cette dernière action a exactement le même effet que la combinaison
Après cela, priez pour que la machine redémarre correctement
Tout récemment, j’ai installé sur mon serveur StatusNet, le moteur de microblogging libre, utilisé notamment par Identi.ca. Dans l’ensemble, l’installation est bien documentée dans le README. Un fichier htaccess d’exemple est présent contenant les règles de réécriture d’URL. Si vous utilisez Apache, pas de problème, renommez le fichier en .htaccess et c’est parti. Seulement, si on utilise un autre serveur web, il faudra adapter ces règles à la syntaxe de son serveur. Voici comment faire avec Lighttpd.
Fichiers de configuration
Un petit rappel du contenu du htaccess de StatusNet :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <IfModule mod_rewrite.c> RewriteEngine On # NOTE: change this to your actual StatusNet base URL path, # minus the domain part: # # http://example.com/ => / # http://example.com/mublog/ => /mublog/ # RewriteBase /mublog/ ## Uncomment these if having trouble with API authentication ## when PHP is running in CGI or FastCGI mode. # #RewriteCond %{HTTP:Authorization} ^(.*) #RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule (.*) index.php?p=$1 [L,QSA] </IfModule> |
Et voici son adaptation à la sauce lighty :
1 2 3 4 5 6 | # Si mod_rewrite n'est pas activé, on l'active server.modules += ( "mod_rewrite" ) # Équivalent de RewriteBase base_url = "/" # La règle de redirection url.rewrite-if-not-file = ( "^" + base_url + "(\w+)" => base_url + "index.php/$1" ) |
C’est plutôt… court
Explications
- Sous Lighttpd, il n’existe pas vraiment d’équivalent à RewriteBase, on utilise alors une simple variable, nommée ici base_url ;
- Conditions de réécriture : on utilise la directive url.rewrite-if-not-file. Cela a pour effet de réécrire seulement si l’URL pointe sur un fichier inexistant. Cependant, cela ne prend pas en compte les répertoires (pour remplacer RewriteCond %{REQUEST_FILENAME} !-d d’Apache).
C’est là que je me suis posé la question de la présence de cette directive dans le htaccess. Je ne vois vraiment aucun cas où l’application aurait besoin d’accéder (donc de lister) un répertoire. De toute manière, le dir-listing est désactivé par défaut, donc le problème est clos ; - Règle de réécriture et flags : Avant tout, on ne va pas s’embêter avec les paramètres GET dans l’URL, l’index.php permet convertir les URL du style /index.php/toto en /index.php?p=toto, et lighttpd le supporte.
La regex ne change pas vraiment, en revanche pour ce qui est des flags Apache : [L] permet d’arrêter le traitement de réécriture d’URL, c’est le comportement par défaut du coté de lighty (sinon on aurait utilisé url.rewrite-repeat-if-not-file). Pour le flag [QSA], qui permet de ne pas tronquer l’URL en cas de paramètres GET multiples, il ne sert à rien puisqu’on utilise pas ce genre d’URL (Sinon la réponse se trouve dans le second lien en fin d’article).
Liens utiles
[1] Apache mod_rewrite
[2] Adaptation des règles de rewrite Apache -> Lighttpd
[3] Lighttpd mod_rewrite
Compter le nombre de connections par IP
Aujourd’hui au boulot, j’ai été confronté à un petit problème : sur un serveur victime d’une attaque DDoS (visiblement), je voulais savoir quelles IP ouvraient le plus de connections. Ne trouvant rien de bien intéressant dans les commandes Unix, j’ai écris un petit script en Perl.
Il se charge de récupérer la sortie de netstat (la commande est à adapter à votre besoin) et compte le nombre de lignes identiques (donc d’IP), qu’il se charge ensuite de trier par ordre décroissant et d’afficher.
Voici le script en question :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #!/usr/bin/perl use strict; use warnings; my %addrs = (); my @netstatOut = split( /\n/, `netstat -taupen | grep SYN | tr -s " " | cut -d" " -f 5 | cut -d: -f1` ); for (@netstatOut) { chomp $_; $addrs{$_} += 1; } for my $key ( sort {$addrs{$b} <=> $addrs{$a}} keys %addrs ) { print $addrs{$key}."\t$key\n"; } |
Le script retourne alors son résultat sous la forme :
nbConnection IP1 nbConnection IP2 ...
Il ne vous reste plus qu’à blacklister les IP les plus actives avec la commande
iptables -I INPUT -s IP -j DROP
Astuce : démarrer un screen + irssi au boot
Pour continuer dans la série des articles courts, en voici un autre, qui tient plus de l’astuce qu’autre chose
Avoir un irssi dans un screen sur un serveur, c’est pratique, le problème c’est que quand le serveur reboot, le client IRC restera arrêté jusqu’à ce que je m’en rende compte et le relance. Par cette nuit orageuse, et en prévision d’un second reboot de mon serveur, j’ai décidé de chercher une solution.
Dans ses scripts de démarrage, Debian exécute le fichier /etc/rc.local (via /etc/rc*.d/S99rc.local) qui ne contient rien par défaut, mais qui est là pour pouvoir lancer des commandes diverses au boot. Il nous suffit donc de l’éditer pour y mettre une ligne du type :
sudo -u romain /usr/bin/screen -d -m irssi
ou bien, sans utiliser sudo :
su romain -c /usr/bin/screen -d -m irssi
L’option -m permet en gros de lancer screen hors d’un TTY (il ne lit pas la variable $STY), et l’option -d permet de le lancer directement en mode détaché.
Et voila, ça devrait limiter un peu plus quelques messages perdu sur IRC

