Archives auteur

Squid : gestion whitelist et redirection URL

Pour faire suite à mon précédent article de configuration Squid, je vous présente ici la configuration d’une whitelist afin de limiter les URL acceptées (vous pouvez aussi faire une liste de domaines) sur mon reverse proxy et la redirection des clients (redirection URL) depuis Squid.

Dans le premier cas, rien de bien compliqué, cela se joue sur deux ACL. Par la première, je vérifie les URL selon une liste d’expressions régulières regroupées dans un fichier texte et je bloque par une seconde ACL toutes celles n’y figurant pas :

acl ALLOW_URL url_regex -i "/etc/squid/allow_url.txt"
[...]
http_access allow ALLOW_URL
http_access deny !ALLOW_URL
http_access allow all

Exemple de liste :

# more allow_url.txt
www.monsite.fr
media.monsite.fr/img/

Seconde étape, le reverse proxy doit rediriger les clients selon certaines URL, plus précisément selon certains paramètres en GET. Pour ce faire,  Squid propose l’emploi d’un programme de redirection externe, dit redirecteur. Aucun redirecteur n’est activé par défaut, il faut donc en écrire un.  Le principe est assez simple : quelque soit le langage utilisé, l’URL demandée est soumise en entrée et Squid attend en retour l’URL ou l’erreur HTTP à renvoyer au client. Ainsi si l’URL est différente, le client est redirigé automatiquement.  Dans le cas d’une erreur, la chaîne est du type : 302:<URL>. Dernier point, le script ne doit pas rendre la main.

Pour ma part, j’ai fait le choix d’un script Perl, étant donné que j’ai seulement besoin de rediriger sur un domaine unique. Si vous avez plusieurs tests à effectuer, je vous invite plutôt à vous tourner vers Squirm.

# more redirector.pl
#!/usr/bin/perl
#
# Boris HUISGEN <bhuisgen@hbis.fr>
#

$|=1;

while (<>)
{
 my @X = split;
 my $url = $X[0];

 if ($url =~ /^http:\/\/www\.monsite\.fr\/\?url=(.[^\?]*)/)
 {
 print "$1\n";
 }
 else {
 print "$url\n";
 }
}
# chmod +x redirector.pl

Le test du redirecteur peut se faire en console (sans toucher à squid) en saisissant au moins en premier paramètre l’URL :

# perl redirector.pl
http://www.monsite.fr/?url=www.wikipedia.fr 127.0.0.1/- - GET
www.wikipedia.fr

Ici, le client est donc redirigé sur le site de Wikipédia.

Reste à activer le redirecteur dans la configuration Squid et à préciser le nombre d’instances à exécuter (10 est un bon début) :

redirector_program /etc/squid/redirector.pl
redirector_children 10

Fichier de configuration Squid : squid.conf

Nano : activer la coloration syntaxique

L’éditeur de texte nano supporte comme tout autre éditeur la coloration syntaxique. Pour l’activer, vérifiez où sont stockées les templates de format (/usr/share/nano ou équivalent) et chargez-les dans votre fichier de préférence ~/.nanorc :

# more .nanorc
set autoindent
include "/usr/local/share/nano/nanorc.nanorc"
include "/usr/local/share/nano/c.nanorc"
include "/usr/local/share/nano/html.nanorc"
include "/usr/local/share/nano/patch.nanorc"
include "/usr/local/share/nano/man.nanorc"
include "/usr/local/share/nano/perl.nanorc"
include "/usr/local/share/nano/python.nanorc"
include "/usr/local/share/nano/java.nanorc"
include "/usr/local/share/nano/sh.nanorc"

Et voilà le rendu sur un fichier Perl :

Squid : bloquer les clients selon leurs User-Agent

En configuration proxy ou reverse-proxy, squid permet par le biais de ses ACL de filtrer les clients pour autoriser/bloquer leurs requêtes selon des points précis. Il peut alors être intéressant de bloquer les user agents non désirés, en les regroupant sous la forme d’une liste, à laquelle il va comparer la valeur fournie par chaque client. Etant donné que l’user agent peut ne pas être renseigné, une ACL  supplémentaire est nécessaire pour vérifier sa présence.

Voici la configuration que j’ai donc dû mettre en place :

acl HAS_USERAGENT browser ^.+$
acl BAD_USERAGENT browser -i "/etc/squid/bad_useragent.txt'

[...]

http_access deny !HAS_USERAGENT
http_access deny BAD_USERAGENT
http_access allow all

La liste des user agent bloqués est de ce type:

# more /etc/squid/bad_usergent.txt
# Misc
^C:
^Skype
^Notepad
^Wget
^ZmEu
woozweb-monitoring
^Shazam
^PS3Update-agent
^MailRuSputnik
^ebay_api
^PPTVUpdate
^EoAgence
^Facebook
^Shasta
^AOLToolbarMetric
^LineUp2
^DING
^ISUA
^android-sports
^sacore
^jupdate
^MPFv
^SCSDK
^DotMacKit
^Android-GData-Calendar
^Kontiki
^SeaPort
^Messenger
^Raptr
^Kontiki
^YahooMobileMessenger
^YahooMobileMail
^Windows-Update-Agent
^Windows-Media-Player
^Windows-RSS-Platform
^MSDW
Microsoft NCSI
^iTunes
^iPhoto
^GrowlHelperApp
^Apple-PubSub
^AppleSyndication
^AppleTV
^CaptiveNetworkSupport
^AntiVir
^AVGINET
^ZoneAlarm
^COMODO Internet Security
^Azureus
^MailRuSputnik

La requête SQL eZ publish du jour

SELECT ezcontentobject_attribute.*, ezcontentclass_attribute.identifier
as identifier FROM ezcontentobject_attribute, ezcontentclass_attribute
WHERE ezcontentclass_attribute.version = '0' AND
ezcontentclass_attribute.id =
ezcontentobject_attribute.contentclassattribute_id AND ( (
ezcontentobject_attribute.version = '1' AND
ezcontentobject_attribute.contentobject_id = '4361' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '4' AND
ezcontentobject_attribute.contentobject_id = '4187' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '3' AND
ezcontentobject_attribute.contentobject_id = '3954' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '2' AND
ezcontentobject_attribute.contentobject_id = '3936' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '1' AND
ezcontentobject_attribute.contentobject_id = '3651' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '4' AND
ezcontentobject_attribute.contentobject_id = '3649' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '4' AND
ezcontentobject_attribute.contentobject_id = '3647' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '4' AND
ezcontentobject_attribute.contentobject_id = '3646' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '5' AND
ezcontentobject_attribute.contentobject_id = '3645' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '6' AND
ezcontentobject_attribute.contentobject_id = '3644' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '4' AND
ezcontentobject_attribute.contentobject_id = '3643' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '2' AND
ezcontentobject_attribute.contentobject_id = '3384' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '11' AND
ezcontentobject_attribute.contentobject_id = '3379' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '2' AND
ezcontentobject_attribute.contentobject_id = '3253' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '10' AND
ezcontentobject_attribute.contentobject_id = '3215' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '3' AND
ezcontentobject_attribute.contentobject_id = '3179' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '2' AND
ezcontentobject_attribute.contentobject_id = '2988' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '4' AND
ezcontentobject_attribute.contentobject_id = '2894' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '1' AND
ezcontentobject_attribute.contentobject_id = '2887' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '2' AND
ezcontentobject_attribute.contentobject_id = '2810' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '11' AND
ezcontentobject_attribute.contentobject_id = '2809' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '3' AND
ezcontentobject_attribute.contentobject_id = '2778' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '4' AND
ezcontentobject_attribute.contentobject_id = '2688' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '4' AND
ezcontentobject_attribute.contentobject_id = '2657' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '10' AND
ezcontentobject_attribute.contentobject_id = '2076' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '4' AND
ezcontentobject_attribute.contentobject_id = '1989' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '4' AND
ezcontentobject_attribute.contentobject_id = '1989' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.versi7# on = '1' AND
ezcontentobject_attribute.contentobject_id = '1754' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '2' AND
ezcontentobject_attribute.contentobject_id = '1753' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '3' AND
ezcontentobject_attribute.contentobject_id = '1706' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '1' AND
ezcontentobject_attribute.contentobject_id = '1695' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '1' AND
ezcontentobject_attribute.contentobject_id = '1692' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '5' AND
ezcontentobject_attribute.contentobject_id = '1661' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '3' AND
ezcontentobject_attribute.contentobject_id = '1409' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '25' AND
ezcontentobject_attribute.contentobject_id = '1307' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '9' AND
ezcontentobject_attribute.contentobject_id = '1253' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '321' AND
ezcontentobject_attribute.contentobject_id = '1221' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '7' AND
ezcontentobject_attribute.contentobject_id = '1199' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '6' AND
ezcontentobject_attribute.contentobject_id = '1194' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '2' AND
ezcontentobject_attribute.contentobject_id = '1193' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '16' AND
ezcontentobject_attribute.contentobject_id = '1189' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '4' AND
ezcontentobject_attribute.contentobject_id = '1181' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '10' AND
ezcontentobject_attribute.contentobject_id = '1177' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '2' AND
ezcontentobject_attribute.contentobject_id = '1176' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '4' AND
ezcontentobject_attribute.contentobject_id = '1173' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '2' AND
ezcontentobject_attribute.contentobject_id = '1170' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '22' AND
ezcontentobject_attribute.contentobject_id = '1102' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '33' AND
ezcontentobject_attribute.contentobject_id = '1001' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '1' AND
ezcontentobject_attribute.contentobject_id = '877' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '2' AND
ezcontentobject_attribute.contentobject_id = '828' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '15' AND
ezcontentobject_attribute.contentobject_id = '765' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '1' AND
ezcontentobject_attribute.contentobject_id = '760' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '1' AND
ezcontentobject_attribute.contentobject_id = '742' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '3' AND
ezcontentobject_attribute.contentobject_id = '741' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '10' AND
ezcontentobject_attribute.contentobject_id = '720' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '57' AND
ezcontentobject_attribute.contentobject_id = '713' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '3' AND
ezcontentobject_attribute.contentobject_id = '637' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '17' AND
ezcontentobject_attribute.contentobject_id = '494' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '14' AND
ezcontentobject_attribute.contentobject_id = '492' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '65' AND
ezcontentobject_attribute.contentobject_id = '461' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '152' AND
ezcontentobject_attribute.contentobject_id = '455' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '1' AND
ezcontentobject_attribute.contentobject_id = '438' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '2' AND
ezcontentobject_attribute.contentobject_id = '215' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '3' AND
ezcontentobject_attribute.contentobject_id = '213' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '12' AND
ezcontentobject_attribute.contentobject_id = '128' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '6' AND
ezcontentobject_attribute.contentobject_id = '125' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '3' AND
ezcontentobject_attribute.contentobject_id = '100' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '3' AND
ezcontentobject_attribute.contentobject_id = '99' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '2' AND
ezcontentobject_attribute.contentobject_id = '98' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '4' AND
ezcontentobject_attribute.contentobject_id = '97' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '7' AND
ezcontentobject_attribute.contentobject_id = '95' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '97' AND
ezcontentobject_attribute.contentobject_id = '94' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '10' AND
ezcontentobject_attribute.contentobject_id = '91' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '8' AND
ezcontentobject_attribute.contentobject_id = '87' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '22' AND
ezcontentobject_attribute.contentobject_id = '84' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '65' AND
ezcontentobject_attribute.contentobject_id = '83' AND
ezcontentobject_attribute.language_code = 'eng-GB' )  OR (
ezcontentobject_attribute.version = '37' AND
ezcontentobject_attribute.contentobject_id = '81' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '80' AND
ezcontentobject_attribute.contentobject_id = '80' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '16' AND
ezcontentobject_attribute.contentobject_id = '79' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '105' AND
ezcontentobject_attribute.contentobject_id = '78' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '48' AND
ezcontentobject_attribute.contentobject_id = '76' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '61' AND
ezcontentobject_attribute.contentobject_id = '74' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '35' AND
ezcontentobject_attribute.contentobject_id = '60' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  OR (
ezcontentobject_attribute.version = '4' AND
ezcontentobject_attribute.contentobject_id = '58' AND
ezcontentobject_attribute.language_code = 'fre-FR' )  )
ORDER BY
ezcontentobject_attribute.contentobject_id,
ezcontentclass_attribute.placement ASC

MySQL : détecter et lister les tables fragmentées

Suite aux suppressions/insertions, les tables de données peuvent se fragmenter et occuper plus d’espace que nécessaire. La requête suivante permet de lister les tables fragmentées, que le moteur de stockage soit MyISAM ou InnoDB :

SELECT CONCAT(TABLE_SCHEMA, '.', TABLE_NAME) AS Name,Data_free FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema','mysql') AND Data_free > 0;

Vous pouvez ensuite optimiser chaque table par une requête OPTIMIZE.

Exemple :

mysql >SELECT CONCAT(TABLE_SCHEMA, '.', TABLE_NAME) AS Name,Data_free FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema','mysql') AND Data_free > 0;
+------------------------------------------------+-----------+
| Name                                           | Data_free |
+------------------------------------------------+-----------+
| my_blog.wp_options                             |       384 |
+------------------------------------------------+-----------+
1 row in set (1.36 sec)
mysql> OPTIMIZE TABLE my_blog.wp_options;
+-----------------------+----------+----------+----------+
| Table                 | Op       | Msg_type | Msg_text |
+-----------------------+----------+----------+----------+
| my_blog.wp_options    | optimize | status   | OK       |
+-----------------------+----------+----------+----------+
1 row in set (0.00 sec)

Le tag du jour

Monit : monitorer son serveur LAMP

Monit est un logiciel de monitoring dédié à la surveillance locale d’un serveur et de ses services.  Il peut effectuer des tests précis et effectuer des actions en retour, comme le redémarrage d’un logiciel si la charge CPU est trop importante. Bref, c’est simple et çà marche.

Je vous colle la configuration pour une installation LAMP sous Debian, regroupant les tests de disponibilité réseau SSH / Apache / MySQL, la vérification de l’espace disque, contrôle de la charge système et de l’utilisation CPU.

set logfile /var/log/monit.log
set mailserver localhost
set mail-format { from: monit@my.domain }
set alert admin@my.domain
set eventqueue
 basedir /var/monit
 slots 100

set httpd port 2812 and
 ssl enable
 pemfile /etc/monit/monit.pem
 allow admin:pa$$word

check system localhost
 if loadavg (1min) > 4 then alert
 if loadavg (5min) > 2 then alert
 if memory usage > 75% then alert
 if cpu usage (user) > 70% then alert
 if cpu usage (system) > 30% then alert
 if cpu usage (wait) > 20% then alert

check device rootfs with path /
 if space usage > 90% then alert

check directory bin with path /bin
 if failed permission 755 then unmonitor
 if failed uid 0 then unmonitor
 if failed gid 0 then unmonitor

check process cron with pidfile /var/run/crond.pid
 group system
 start program = "/etc/init.d/cron start"
 stop  program = "/etc/init.d/cron stop"
 if 5 restarts within 5 cycles then timeout
 depends on cron_rc
check file cron_rc with path /etc/init.d/cron
 group system
 if failed checksum then unmonitor
 if failed permission 755 then unmonitor
 if failed uid root then unmonitor
 if failed gid root then unmonitor

check process syslog with pidfile /var/run/rsyslogd.pid
 group system
 start program = "/etc/init.d/rsyslog start"
 stop program = "/etc/init.d/rsyslog stop"
 if 5 restarts within 5 cycles then timeout
check file syslog_file with path /var/log/syslog

check process sshd with pidfile /var/run/sshd.pid
 group system
 start program  "/etc/init.d/ssh start"
 stop program  "/etc/init.d/ssh stop"
 if failed port 22 protocol ssh then restart
 if 5 restarts within 5 cycles then timeout
check file ssh_bin with path /usr/sbin/sshd
 group system
 if failed checksum then unmonitor
 if failed permission 755 then unmonitor
 if failed uid root then unmonitor
 if failed gid root then unmonitor
check file ssh_rc with path /etc/init.d/ssh
 group system
 if failed checksum then unmonitor
 if failed permission 755 then unmonitor
 if failed uid root then unmonitor
 if failed gid root then unmonitor

check process apache with pidfile /var/run/apache2.pid
 group web
 start program = "/etc/init.d/apache2 start"
 stop program  = "/etc/init.d/apache2 stop"
 if failed host 127.0.0.1 port 80 protocol http and request "/index.html" then restart
 if cpu is greater than 60% for 2 cycles then alert
 if cpu > 80% for 5 cycles then restart
 if children > 250 then restart
 if 3 restarts within 5 cycles then timeout
check file apache_bin with path /usr/sbin/apache2
 group apache
 if failed checksum then unmonitor
 if failed permission 755 then unmonitor
 if failed uid root then unmonitor
 if failed gid root then unmonitor
check file apache_rc with path /etc/init.d/apache2
 group apache
 if failed checksum then unmonitor
 if failed permission 755 then unmonitor
 if failed uid root then unmonitor
 if failed gid root then unmonitor

check process mysql with pidfile /var/run/mysqld/mysqld.pid
 group database
 start program = "/etc/init.d/mysql start"
 stop program = "/etc/init.d/mysql stop"
 if failed host 127.0.0.1 port 3306 protocol mysql then restart
 if 5 restarts within 5 cycles then timeout
 depends on mysql_bin
 depends on mysql_rc
check file mysql_bin with path /usr/sbin/mysqld
 group database
 if failed checksum then unmonitor
 if failed permission 755 then unmonitor
 if failed uid root then unmonitor
 if failed gid root then unmonitor
check file mysql_rc with path /etc/init.d/mysql
 group database
 if failed checksum then unmonitor
 if failed permission 755 then unmonitor
 if failed uid root then unmonitor
 if failed gid root then unmonitor

Un petit screenshot pour présenter le résultat :

Glassfish 3 : créer un pool de connexions JDBC

Cet exemple couvre la création d’un pool de connexions JDBC pour un serveur MySQL,

En premier lieu, ne pas oublier d’installer le driver JDBC de MySQL dans le domaine d’exécution :

$ cd $GLASSFISH_HOME
$ ./bin/asadmin stop-domain
$ cp ~/mysql-connector-java-5.1.13-bin.jar glassfish/domains/domain1/lib/
$ ./bin/asadmin start-domain

La création du pool de connexions (en veillant aux caractères d’échappement dans l’URL) :

$ ./bin/asadmin create-jdbc-connection-pool --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlDataSource --restype javax.sql.DataSource --property User=myuser:Password=mypwd:URL=jdbc\\:mysql\\://127.0.0.1/mydb mydb_pool
Command create-jdbc-connection-pool executed successfully.

Un test rapide pour valider la connexion au serveur MySQL :

$ ./bin/asadmin ping-connection-pool mydb_pool
Command ping-connection-pool executed successfully.

Reste à créer la ressource jdbc/mydb à utiliser dans l’application Java :

$ ./bin/asadmin create-jdbc-resource --connectionpoolid=mydb_pool jdbc/mydb
Command create-jdbc-resource executed successfully.

Roundcubemail : plugin rc-vacation 0.4

La version 0.4 du plugin rc-vacation est disponible. Au programme, l’inclusion d’un driver pour maildrop. Niveau interface, il est possible de configurer une date d’activation et d’expiration du message d’absence.  L’installation du plugin jquery-ui est d’ailleurs conseillée afin de bénéficier des sélecteurs de date jQuery. Plusieurs adresses de redirection sont acceptées. Suite aux nombreuses demandes, des exemples de configuration sont fournis, notamment les schémas SQL.

Dépôt Git : http://github.com/bhuisgen/rc-vacation
Tarball : rc-vacation-0.4.tar.gz

nginx-etag-module : module de gestion des etags pour Nginx

Le protocole HTTP définit un mécanisme de cache par validation des ressources Web : les Entity Tags. Son intérêt est d’autoriser les requêtes conditionnelles afin d’optimiser la gestion de la bande passante des clients et des serveurs Web. Ainsi, à chaque requête, le serveur calcule et ajoute un Etag, matérialisé par un identifiant unique associé à la ressource et à sa version.

En pratique, la première requête envoie le statut HTTP 200 – OK et l’etag calculé par le serveur. Si le client demande à nouveau la ressource et s’il soumet en information l’etag précédent, le serveur est capable de déterminer sa validité. Si les etags matchent, la ressource est à jour côté client et le serveur renvoie un statut HTTP 304 – Content Not Modified sans les données. Les Etags sont donc un moyen simple et fiable de gestion cache des ressources.

Je vais vous présenter le module que j’ai développé pour effectuer ce job sous Nginx : ngx-http-etag-module. Le calcul de l’etag est indépendant du filesystem afin de permettre une utilisation en cluster. A cela, j’y ai couplé une option permettant de forcer le calcul sur un fichier précis, quelque soit la ressource statique demandée. C’est cette raison qui m’a incité à développer ce module, car elle me permet de conserver le cache des proxys frontaux suite à une mise à jour des fichiers. Seul un touch sur le fichier permet d’invalider l’ensemble du cache et propager les modifications.

Installation

$ git clone git://github.com/bhuisgen/nginx-etag-module.git ./nginx-etag-module
Initialized empty Git repository in /private/tmp/nginx-etag-module/.git/
remote: Counting objects: 21, done.
remote: Compressing objects: 100% (21/21), done.
remote: Total 21 (delta 6), reused 0 (delta 0)
Receiving objects: 100% (21/21), 4.62 KiB, done.
Resolving deltas: 100% (6/6), done.
$ cd nginx-etag-module/

Le code de Nginx doit également être récupéré, compilation statique oblige :

$ wget http://nginx.org/download/nginx-0.7.67.tar.gz
--2010-09-03 20:35:46--  http://nginx.org/download/nginx-0.7.67.tar.gz
Résolution de nginx.org (nginx.org)... 81.19.68.137
Connexion vers nginx.org (nginx.org)|81.19.68.137|:80...connecté.
requête HTTP transmise, en attente de la réponse...200 OK
Longueur: 608462 (594K) [application/octet-stream]
Sauvegarde en : «nginx-0.7.67.tar.gz»
100%[===================================================================
=======================>] 608.462     64,9K/s   ds 8,5s
2010-09-03 20:35:54 (70,0 KB/s) - «nginx-0.7.67.tar.gz» sauvegardé [608462/608462]
$ tar xzf nginx-0.7.67.tar.gz
$ cd nginx-0.7.67
$ ./configure --add-module=../

Le script configure doit détecter la présence du module :

adding module in ../
 + ngx_http_etag_module was configured

Comme d’habitude, compilation puis installation :

$ make
$ sudo make install

Configuration

Pour activer la prise en charge des etags :

server {
   listen       8000;
   server_name  localhost;
   root /usr/local/www/html;
   index index.php;

   location / {
      etag on;
   }
   location ~ \.php$ {
      include        fragments/php.conf;
   }
}

Pour rediriger le calcul des etags sur un unique fichier :

server {
   listen       8000;
   server_name  localhost;
   root /usr/local/www/html;
   index index.php;

   location / {
      etag on;
      etag_file /opt/local/var/www/etag_file
   }
   location ~ \.php$ {
      include        fragments/php.conf;
   }
}

Exemple :

Haut de page