Archives pour janvier, 2012

Nginx : configuration pour site PHP Symfony

http://www.symfony-project.org/

server {
   listen        192.168.0.1:80;
   server_name   www.site.fr;
   root          /home/site.fr/web/;

   location / {
      index index.php;
      try_files $uri $uri/ /index.php?$args;
   }

   location ^~ /sf/ {
      alias /home/site.fr/lib/vendor/symfony/data/web/sf/;
   }

   location ~ "^(.+\.php)($|/)" {
      fastcgi_split_path_info   ^(.+\.php)(.*)$;
      fastcgi_param             SCRIPT_FILENAME $document_root$fastcgi_script_name;
      fastcgi_param             SCRIPT_NAME $fastcgi_script_name;
      include                   fastcgi_params;
      fastcgi_pass              unix:/var/run/php-site_fr.sock;
      fastcgi_index             index.php;
   }
}

Thunderbird : suppression des fichiers index

bhuisgen$ cd ~/Library/Thunderbird/Profiles/
bhuisgen$ find . -name '*.msf' -print0 | xargs -0 rm

Debian : utilisation des cgroups sur un serveur web PHP mutualisé

Les cgroupsgroupes de contrôle – ont pour but de contrôler les ressources systèmes utilisées par un ou plusieurs processus. Les processus sous contrôle sont affectés dans des groupes sur lequels agissent des contrôleurs de ressources. Chaque contrôleur gère un type de ressources :

  • cpuset : allocation CPU (numéro CPU/core CPU).
  • cpuacct :  consommation CPU (nombre de cycles).
  • memory : contrôle de la mémoire vive et de la mémoire swap.
  • devices : contrôle l’accès aux périphériques.
  • blkio : contrôle l’accès aux périphériques de type bloc (ex disque dur).
  • net_cls : contrôle l’accès aux périphériques réseau.

Par défaut, la configuration s’effectue manuellement, ce qui est fastidieux et à réserver en cas d’état de saturation des ressources. Deux démons peuvent ainsi prendre la main pour automatiser la gestion :

  • cgconfig : qui créée la hiérarchie des cgroups.
  • cgrulesengd : qui classe les processus dans les cgroups en fonction de régles spécifiques.

Dans le cadre d’un serveur web, les cgroups sont utiles pour prioritiser les processus du serveur web, de MySQL, PHP (ou tout autre interpréteur), afin de garantir une réactivité du serveur. Ils peuvent également restreindre les ressources CPU de chaque utilisateur afin de garantir un partage équitable des ressources CPU entre chaque processus utilisateur (php, cron, ssh) et éviter une consommation anormale des ressources mémoire et bande passante.

Mon article détaille ainsi la mise en place d’un serveur web mutualisé sous cgroups avec les objectifs suivants :

  • garantir la priorité de toutes les tâches système.
  • limiter les ressources CPU de toutes les tâches des utilisateurs.
  • limiter l’utilisation mémoire vive des tâches utilisateurs et réserver 4 Go pour le système.
  • interdire l’utilisation de la mémoire swap pour les tâches utilisateurs.

Au niveau logiciel, la configuration est la suivante :

  • distribution Debian 6 Squeeze.
  • serveur web Nginx.
  • PHP 5.3.9 en configuration FPM (packages fournis par dotdeb).
  • accès SSH chrooté pour chaque utilisateur.

Chaque utilisateur (client1, client2, etc …) possède son pool de processus PHP attribué, processus qui s’exécutent donc sous son identité. L’ensemble des utilisateurs appartient au groupe secondaire clients. Ainsi, les cgroups vont s’appliquer sur ce groupe secondaire clients. Quant à Nginx, il fait partie automatiquement du cgroup par défaut ; il sera traité et prioritisé comme toute autre tâche système.

Compilation du noyau avec support cgroups

Le noyau fourni avec squeeze n’étant pas configuré pour la gestion des cgroups, il convient d’en compiler un spécifiquement, en veillant à ce que les options suivantes soient identiques. Je précise bien ne pas compiler en module mais en statique :

root@skinner:~# grep -e CONNECTOR -e PROC_EVENTS -e CGROUP /boot/config-2.6.32-bhuisgen
CONFIG_CGROUPS=y
CONFIG_CGROUP_NS=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_MEM_RES_CTLR=y
CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
CONFIG_CGROUP_SCHED=y
CONFIG_NET_CLS_CGROUP=y
CONFIG_CONNECTOR=y
CONFIG_PROC_EVENTS=y

Pour la procédure de compilation noyau sous Debian, je vous renvoie à mon article précédent. J’ai également mis en ligne le noyau utilisé pour ce serveur, vous pouvez le télécharger ici.

Une fois le serveur redémarré avec le nouveau kernel, vous pouvez vérifier les contrôleurs de ressources disponibles :

root@skinner:/etc# cat /proc/cgroups
#subsys_name    hierarchy    num_cgroups    enabled
cpuset  0    1    1
ns      0    1    1
cpu     1    3    1
cpuacct 2    2    1
memory  4    3    1
devices 3    2    1
freezer 0    1    1
net_cls 0    1    1

Il reste à installer les démons userland pour gérer les cgroups :

root@skinner:~# apt-get install libcgroup cgroup-bin

Configuration des cgroups

root@skinner:~# more /etc/cgconfig.conf
# cgconfig.conf

mount {
   cpu = /mnt/cgroups/cpu;
   cpuacct = /mnt/cgroups/cpuacct;
   devices = /mnt/cgroups/devices;
   memory = /mnt/cgroups/memory;
}

group clients {

   cpu {
      cpu.shares = 512;
   }

   memory {
      memory.memsw.limit_in_bytes = 8G;
      memory.limit_in_bytes = 8G;
   }
}
root@skinner:~# more /etc/cgrules.conf
# /etc/cgrules.conf

@clients    cpu,memory    clients

Création d’un compte utilisateur

root@skinner:~# groupadd -g 2000 clients
root@skinner:~# groupadd -g 2001 client1
root@skinner:~# useradd -m client1 -p pa$$word -u 2001 -g 2001 -G clients -s /bin/false
root@skinner:~# mkdir -p /home/client1/www/{html,lib,logs,tmp}
root@skinner:~# chmod 755 /home/client1
root@skinner:~# chown -R root:root /home/client1
root@skinner:~# chown client1:client1/home/client1/www/html
root@skinner:~# chown client1:client1 /home/client1/www/lib
root@skinner:~# chown client1:client1 /home/client1/www/tmp
root@skinner:~# id client1
uid=2001(client1) gid=2001(client1) groups=2001(client1),2000(clients)

Configuration Nginx / PHP

root@skinner:~# more /etc/nginx/sites-available/client1
server {
    listen        192.168.1.173:80;
    server_name   client1.my.domain *.client1.my.domain;
    root          /home/client1/www/html/;
    access_log    /home/client1/www/logs/access.log main;
    error_log     /home/client1/www/logs/error.log;
    index         index.html index.php;

    location ~ \.php$ {
        fastcgi_pass  unix:/var/run/php-client1.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /home/client1/www/html$fastcgi_script_name;
        include       fastcgi_params;
    }
}
root@skinner:~# more /etc/php5/fpm/pool.d/client1.conf
[client1]
listen = /var/run/php-$pool.sock
listen.backlog = -1
listen.owner = www-data
listen.group = www-data
listen.mode = 0600
user = $pool
group = $pool

pm = static
pm.max_children = 4
pm.max_requests = 500
access.log = /home/$pool/www/logs/php-$pool.access.log
access.format = %R - %u %t "%m %r%Q%q" %s %f %{mili}d %{kilo}M %C%%
request_terminate_timeout = 35
request_slowlog_timeout = 15
slowlog = /home/$pool/www/logs/php-$pool.log.slow

php_admin_value[disable_functions] = dl, exec, highlight_file, fsockopen, passthru, pcntl_exec, phpinfo, pclose, popen, system, shell_exec, set_time_limit, show_source
php_admin_value[memory_limit] = 64M
php_admin_value[open_basedir] = /home/$pool/www/html:/home/$pool/www/lib:/home/$pool/www/tmp:/home/$pool/www/awstats
php_admin_value[session.save_path] = /var/lib/php5
php_admin_value[upload_tmp_dir] = /home/$pool/www/tmp

Lancement des démons

root@skinner:~# /etc/init.d/cgconfig start
root@skinner:~# /etc/init.d/cgred start
root@skinner:~# /etc/init.d/php-fpm

On peut à présent vérifier que les processus PHP de client1 sont bien attribués à notre cgroup clients au niveau des contrôleurs de ressources CPU et mémoire (RAM+swap) :

root@skinner:~# ps -u client1
PID TTY          TIME CMD
19507 ?        00:00:00 php5-fpm
19508 ?        00:00:00 php5-fpm
19509 ?        00:00:00 php5-fpm
19510 ?        00:00:00 php5-fpm
root@skinner:~# cat /proc/19507/cgroup
8:memory:/clients
7:devices:/sysdefault
6:cpuacct:/sysdefault
5:cpu:/clients

Il est également possible de manipuler à chaud les cgroups en parcourant sa hiérarchie, montée sous Debian dans /mnt/cgroups :

root@skinner~# cd /mnt/cgroups
 root@skinner:/mnt/cgroups# ls -l
total 0
drwxr-xr-x 4 root root 0 Jan 16 11:45 cpu
drwxr-xr-x 3 root root 0 Jan 16 11:45 cpuacct
drwxr-xr-x 3 root root 0 Jan 16 11:45 devices
drwxr-xr-x 4 root root 0 Jan 16 11:45 memory
root@skinner:/mnt/cgroups# ls -l cpu
total 0
-r--r--r-- 1 root root 0 Jan 16 11:45 cgroup.procs
drwxrwxr-x 2 root root 0 Jan 16 11:45 clients
-rw-r--r-- 1 root root 0 Jan 16 11:45 cpu.shares
-rw-r--r-- 1 root root 0 Jan 16 11:45 notify_on_release
-rw-r--r-- 1 root root 0 Jan 16 11:45 release_agent
drwxrwxr-x 2 root root 0 Jan 16 11:45 sysdefault
-rw-r--r-- 1 root root 0 Jan 16 11:45 tasks

Il suffit ensuite de faire les commandes echo appropriées selon les besoins.

Les cgroups représentent donc la brique logicielle indispensable à tout serveur afin de partager et limiter les ressources.

Roundcubemail : plugin rc-vacation 0.5

La version 0.5 du plugin rc-vacation est disponible. Outre la correction de quelques bugs, un driver d’intégration avec le panel de gestion Plesk est disponible. Cette version est compatible avec la version 0.7.1 de RoundCube.

Dépôt Git : http://github.com/bhuisgen/rc-vacation
Tarball : Se détacher d'une console Xen depuis un terminal Mac OS X (un téléchargement)

Gentoo : configuration dual-stack IPv4 / IPv6

burns ~ # more /etc/conf.d/net
config_eth0="10.0.0.13 netmask 255.0.0.0 brd 10.255.255.255
fdfe:cd5e:234c:8277::4/64"

routes_eth0="default gw 10.0.0.1
default via fdfe:cd5e:234c:8277::1"

Debian 6 : configuration dual-stack IPv4 / IPv6

root@skinner:~# more /etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address 10.0.0.11
    netmask 255.0.0.0
    network 10.0.0.0
    broadcast 10.255.255.255
    gateway 10.0.0.1
    up ip -6 addr add fdfe:cd5e:234c:8277::8/64 dev eth0
    up ip -6 route add default via fdfe:cd5e:234c:8277::1
    down ip -6 addr del fdfe:cd5e:234c:8277::8/64 dev eth0
    down ip -6 route del default via fdfe:cd5e:234c:8277::1

Debian 6 : forcer l’umask par défaut

/etc/pam.d/common-session :

session optional pam_umask.so umask=027

Debian 6 : kernel 2.6.32 avec gestion des cgroups

linux-headers-2.6.32-bhuisgen_2_amd64.deb
linux-headers-2.6.32-bhuisgen_2_amd64.deb.sha1
linux-image-2.6.32-bhuisgen_2_amd64.deb
linux-image-2.6.32-bhuisgen_2_amd64.deb.sha1

FreeBSD : fichier de règles PF

#
# pf.conf
#

# macros
ext_if = "re0"
int_if = "lo1"

# tables
table  persist {}

# options
set block-policy drop
set skip on lo0
set limit { states 20000, frags 5000, src-nodes 2000 }

# normalization
scrub in all fragment reassemble
scrub all reassemble tcp
scrub in all random-id

#
# redirection
#

nat on $ext_if from !($ext_if) to any -> ($ext_if)

# jail dns
rdr pass on $ext_if proto tcp from any to port 53 -> 172.16.0.1 port 53
rdr pass on $ext_if proto udp from any to port 53 -> 172.16.0.1 port 53
# jail www
rdr pass on $ext_if proto tcp from any to port 80 -> 172.16.0.2 port 80
rdr pass on $ext_if proto tcp from any to port 443 -> 172.16.0.2 port 443
rdr pass on $ext_if proto tcp from any to port 2222 -> 172.16.0.2 port 22

#
# rules
#

block in log
block out log
block quick from
antispoof quick for lo0

pass quick on $int_if

pass out proto tcp all keep state
pass out proto udp all keep state

pass in on $ext_if inet proto icmp from any to any keep state
pass out on $ext_if inet proto icmp from any to any keep state

pass in on $ext_if inet6 proto icmp6 from any to any keep state
pass out on $ext_if inet6 proto icmp6 from any to any keep state

pass in on $ext_if proto tcp from any to any port 22 flags S/SA keep state \
(source-track rule, max-src-conn 4, max-src-conn-rate 4/30, \
overload  flush global)

IPv6 : générer un range IPv6 privé

http://www.simpledns.com/private-ipv6.aspx

Haut de page