Nginx : Activer la compression GZIP

gzip_compress

C’est toujours dans une approche d’optimization de notre serveur ainsi que de l’expérience utilisateur que nous allons aborder la mise en place de la compression Gzip des requêtes http sur Nginx. Nous avons déjà vu comment mettre en cache nos fichiers statiques pour rendre notre site plus rapide.  Ici nous allons voir comment compresser nos requêtes.

Vous devez avoir le module ngx_http_gzip_module de compiler sur votre nginx. C’est généralement le cas par défaut.

Les paramètres gzip sont à mettre dans le bloc « http » généralement ce bloc se trouve dans le fichier nginx.conf.

On y ajoute les paramètres suivants :

gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 4 32k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/x-font-ttf application/javascript font/eot font/opentype image/svg+xml image/x-icon text/plain;

Et l’on redémarre nginx.
Les lignes les plus importantes sont gzip on; et gzip_types.

Quelques explications :

  • gzip on : active la compression
  • gzip_types : permet de spécifier quel type de fichiers doit être compressé.
  • gzip_vary : permet d’ajouter dans le header « Vary: Accept-Encoding” ce qui permet au proxy de stocker une version compressée et non compressée du fichier.
  • gzip_proxied : permet de compresser les requêtes venant de proxies.
  • gzip_comp_level : determine le niveau de compression. Plus la compression sera élevée plus la requête sera petite mais le client perdra un peu plus de temps à la décompresser.
  • gzip_buffers 4 32k : le premier chiffre (4) correspond au nombre et le deuxième à la taille du buffer utilisés pour compresser la requête.
  • gzip_http_version : permet de spécifier la version http qui doit être compressée.

On peut surcharger nos paramètres en le mettant dans le bloc « server ».
Par exemple si l’on met gzip off dans un bloc « server » cela désactivera la compression gzip sur notre domaine.

Test

Nous allons tester à l’aide de curl si nos paramètres sont bien pris en compte.

$ curl -I --header "Accept-Encoding: gzip" https://www.cloud-devops.fr/
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 05 Feb 2016 14:32:20 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
Content-Encoding: gzip

Si vous voyez « Vary: Accept-Encoding » et « Content-Encoding: gzip » c’est que votre serveur est bien paramétré.

Pour plus d’infos sur le module gzip voici le documentation nginx officiel gzip 

Nginx: mise en cache des fichiers statiques

nginx

Il est très important de bien configurer votre serveur nginx pour servir correctement les fichiers statiques (images, javascript, css, texte …).
Cela vous permet d’économiser la bande passante de votre serveur et également d’améliorer l’expérience utilisateur. L’utilisateur aura l’impression que votre site se charge plus vite.
L’utilisateur n’aura pas besoin de télécharger de nouveau ce fichier js ou l’image car son navigateur l’aura déjà dans son propre cache.

La mise en cache des fichiers statiques, coté du navigateur, se fait à l’aide des headers renvoyés par le serveur.
Il faut être sur d’avoir le module ngx_http_headers_module compilé avec nginx. C’est le cas par défaut.
Il y a plusieurs paramètres à mettre en place pour configurer correctement nos headers.

Prenons l’exemple suivant :

location ~* \.(png|jpg|jpeg|gif|ico|woff|otf|ttf)$ {
  root /var/www/static/;
  access_log off;
  log_not_found off;
}

1. expires

Ce paramètre permet de contrôler la durée de mise en cache. Il est par défaut à off. La directive expires permet d’agir sur les headers http Expires et Cache-Control
Ce paramètre peut prendre différents paramètres epoch,max,une durée, off ou une heure.

  • off: désactive les headers http Expires et Cache-Control
  • epoch: met le header Expires à la date du 1 January, 1970 00:00:01 GMT.
  • max: met le header Expires à la date du Thu, 31 Dec 2037 23:55:55 GMT et le Cache-Control au maximum c’est à dire à 10ans
  • une durée: met le cache à une durée relatif par rapport à l’accès au fichier. Par exemple expires 10d; signifie que votre navigateur conservera cette version de fichier pendant 10 jours.
  • une heure: met une heure à partir de laquelle de fichier expire dans la journée. Il doit être préfixé par un @. Par exemple expires @12:10; signifie que votre fichier va expiré à 12h10

Dans la plupart des cas un expires max; ou expires 1y; sera bien efficace. Dans notre exemple cela donne :

location ~* \.(png|jpg|jpeg|gif|ico|woff|otf|ttf)$ {
  root /var/www/static/;
  access_log off;
  log_not_found off;
  expires 1y;
}

2. add_header

Cette directive prend des options libres c’est à nous de renseigner ce que l’on veut. Nos paramètres doivent correspondre aux standard du protocol http pour être interprété par l’ensemble des navigateurs et proxies.

Nous allons intervenir sur le header Cache-Control. Avec le paramètre expires nous sommes déjà intervenu sur le cache-control pour mettre max-age=31536000. Il faut maintenant décrire la façon dont cela doit être conserver. Plusieurs options sont à notre disposition :

  • no-cache : cela indique que la prochaine requête sur la même url devra être validé par le serveur pour confirmer qu’elle n’a pas changé.
  • no-store : interdit de stocker la réponse. On ne l’utilise pas pour les fichiers statiques mais généralement sur des urls qui contiennent des données confidentielles (mon compte par exemple).
  • private: ne sera mis en cache que par les navigateurs et jamais par les serveurs proxies.
  • public: peut être stocké par n’importe qui. Ce paramètre est implicite si le paramètre max-age est déjà en place.

Nous allons donc de notre coté mettre le paramètre add_header Cache-Control « public »; qui va permettre de mettre nos fichiers en cache pour tout le monde et de les stocker. Dans notre exemple cela donne :

location ~* \.(png|jpg|jpeg|gif|ico|woff|otf|ttf)$ {
  root /var/www/static/;
  access_log off;
  log_not_found off;
  expires 1y;
  add_header Cache-Control "public"; 
}

3. Test

A l’aide d’un curl nous allons tester que cela fonctionne.

$ curl -I https://www.cloud-devops.fr/wp-content/uploads/2016/02/log_nginx.jpg
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 05 Feb 2016 12:07:27 GMT
Content-Type: image/jpeg
Content-Length: 181406
Last-Modified: Thu, 04 Feb 2016 21:31:59 GMT
Connection: keep-alive
ETag: "56b3c34f-2c49e"
Expires: Sat, 04 Feb 2017 12:07:27 GMT
Cache-Control: max-age=31536000
Pragma: public
Cache-Control: public
Vary: Accept-Encoding
Accept-Ranges: bytes

Nous avons le header Cache-Control à public, le Cache-control max-age à 365 jours et un Expires à la date du Sat, 04 Feb 2017 12:07:27 GMT. Tout fonctionne parfaitement !

Nginx: exclure un user agent de nos logs

log nginx

Nous avons vu précédemment que nous pouvions exclure des logs nginx une url spécifique et même une adresse ip.

Nous allons voir ici, comment exclure de nos logs un user agent spécifique. Par exemple nous ne voulons pas avoir dans nos logs le user agent de notre monitoring « mymonitoringBot » ou encore celui de « Googlebot ».

Nous allons créer un bloc « map » pour y mettre nos règles :

map $http_user_agent $log_useragent {
  ~Googlebot 0;
  ~mymonitoringBot 0;
  default 1;
}

On assigne la valeur 0 aux user agent Googlebot et mymonitoringBot. Toutes les autres user agent auront la valeur 1.
Il suffit ensuite de mettre cette condition dans notre bloc « server« .

server {
   ...
access_log /var/log/nginx/access.log main if=$log_ua;

}

N’entrerons dans les logs que la valeur 1 qui correspond à la valeur par défaut. Notre fichier access.log ne contiendra pas les user agent Googlebot et mymonitoringBot.

Nginx : exclure une ip des logs

log nginx

Pour des raisons pratiques, on peut vouloir exclure de nos logs nginx une ou plusieurs adresses ip.

Nginx déconseille d’utiliser le « if » dans la configuration de nginx et le considère comme le mal !

1. Nise en place d’un bloc map

Nous allons créer un bloc « map » pour y mettre la liste des adresses ips.  Ce bloc « map »  doit être créer en dehors du bloc « server« .

Vous pouvez avoir envie d’exclure le localhost ou encore l’ip de votre monitoring.

map $remote_addr $log_ip {
     "127.0.0.1" 0;
     "1.2.3.4" 0;
    default 1;
}

On assigne la valeur 0 aux adresses ip 127.0.0.1 et 1.2.3.4. Toutes les autres adresses ip auront la valeur 1.

2. Mise en place du filtre

Il suffit ensuite de mettre dans le bloc « server » notre condition sur nos logs.

server {
     ...

     access_log /var/log/nginx/access.log main if=$log_ip;
}

Les adresses ip 127.0.0.1 et 1.2.3.4 n’apparaitront plus dans le log access.log.

Nginx: exclure une url des logs

nginx exclure url

On peut vouloir exclure des urls spécifiques dans nos logs. Cela facilitera les futurs recherches par exemple.

Dans la config de nginx, on utilise très souvent le bloc « location »  pour définir les paramètres d’un type d’url, par exemple pour servir les fichiers statiques.

Vous avez sans doute ce type de configuration :

location ~* \.(png|jpg|jpeg|gif|ico|js|css)$ {
   root /var/www/static/;
   expires max; 
}

Pour que les urls de nos images, js ou css n’apparaissent pas dans nos logs, il suffit d’ajouter l’option « access_log off; »
Comme ceci :

location ~* \.(png|jpg|jpeg|gif|ico|js|css)$ {
   root /var/www/static/;
   expires max; 
   access_log off;
   log_not_found off;
}

Vous pouvez noter que j’ai également ajouter l’option « log_not_found off; » qui permet de ne pas écrire dans le fichier « error_log » les fichiers manquants.

Synchronisation d’un rep local vers un ftp distant

Voici le problème : Je souhaite sauvegarder mon répertoire local sur un ftp (par exemple free).

Le plus pratique aurait été rsync me direz vous ! mais il faut que rsync soit installé sur le serveur distant

J’ai trouvé un script perl, voici le lien du script :

mirror.pl

Vous l’enregistez sur le disque dur à l’endroit de votre choix, ensuite cela s’utilise comme cela :

lftp -e "open ftpperso.free.fr ; user minitux ; 
mirror -n -R ton_dossier_local1 ton_dossier_distant1 ; bye"

Si vous voulez optimisez cela avec un script bash, voici un exemple :

# Script Bash # 
#!/bin/sh 
mirror='CHEMIN OU SE TROUVE LE SCRIPT MIRROR '

syncFTP () { 
lftp << EOF
open -u 'minitux.password' ftpperso.free.fr 
mirror -n -R $1 $2; 
bye;
EOF
}
syncFTP REP_LOCAL REP_DISTANT

Vous enregistrez ceci sous un fichier .sh avec un chmod +x et vous pourrez synchronisez votre répertoire aussi souvent que vous le souhaitez avec les fichiers qui ont changés.

Yum update par email

Il peut être très intéressant de recevoir un email lorsque des mise à jour sont disponibles. Sur cet article nous partons du principe que l’envoi de mail fonctionne déjà.

  • Installation 

Nous allons utiliser le package yum-cron.

# yum install yum-cron
  • Configuration

Il faut pour cela éditer le fichier /etc/sysconfig/yum-cron et ajouter l’adresse email à MAILTO

MAILTO=email@address.com

Regardez le reste du fichier et soyez sur d’avoir désactivé les mises à jour automatique

  • Démarrage 

On choisit de l’activer automatiquement et on démarre le service

chkconfig yum-cron on
service yum-cron start

C'est tout !

Sudo sans mot de passe

Juste une petite astuce qui peut s’avérer bien pratique si vous avez souvent à taper votre mot de passe pour le sudo.

Grâce à ceci vous n’aurez plus à rentrer de mot de passe.

root~# sudoedit /etc/sudoers

Ajoutez ensuite ceci :

monuser ALL = NOPASSWD: ALL

Remplacer juste l’utilisateur monuser par le votre.
Enregistrez puis quittez !

Petite précision car ceci ne respecte aucune norme de sécurité … Si vous devez le faire sur des serveurs il faut choisir un programme :

monuser ALL = NOPASSWD: /usr/bin/shutdown  par ex

Si vous souhaitez en savoir plus sur la commande sudo :

sudo sur wikipedia