1 Administration Linux - Proxy 2014 tv - v produit le 12 mai 2014 Sommaire Mise en situation 2 Serveur mandataire (proxy) 2 Proxy inverse (reverse pro...
Un compte-rendu au format texte (UTF-8) devra être rédigé et envoyé à l’adresse [email protected] La convention de nommage pour les compte-rendus est la suivante : admin-linux-parefeu-nom.txt
1
SERVEUR MANDATAIRE (PROXY)
Mise en situation Vous devez disposer d’un PC possédant un système d’exploitation Linux ou Windows et du logiciel de virtualisation VirtualBox. Le système invité sera une installation du serveur Ubuntu 12.10.
Serveur mandataire (proxy) Un serveur mandataire (proxy) est une fonction informatique client-serveur qui a pour rôle de relayer des requêtes entre un client et un serveur. Un proxy est alors un programme servant d’intermédiaire pour faciliter ou surveiller leurs échanges.
Les serveurs mandataires sont notamment utilisés pour assurer les fonctions suivantes : – accélération de la navigation : mémoire cache, compression de données, filtrage des publicités ou des contenus lourds (java, flash) ; – la journalisation des requêtes (log) ; – la sécurité du réseau local ; – le filtrage et l’anonymat.
Le proxy est généralement placé dans une DMZ. Une DMZ (zone démilitarisée) est un sous-réseau séparé du réseau local et isolé de celui-ci et d'Internet par un pare-feu.
Proxy inverse (reverse proxy) Un proxy inverse (reverse proxy) est un type de serveur, habituellement placé en frontal de serveurs web. Contrairement au serveur proxy qui permet à un utilisateur d’accéder au réseau Internet, le proxy inverse permet à un utilisateur d’Internet d’accéder à des serveurs internes.
Cette technique permet notamment : – Mémoire cache : le proxy inverse peut décharger les serveurs Web de la charge de pages/objets statiques (pages HTML, images) par la gestion d’un cache web local. La charge des serveurs Web est ainsi généralement diminuée. – Intermédiaire de sécurité : le proxy inverse protège un serveur Web des attaques provenant de l’extérieur. Mais cette architecture permet surtout le filtrage en un point unique des accès aux ressources Web. – Répartition de charge : le proxy inverse peut distribuer la charge d’un site unique sur plusieurs serveurs Web applicatifs. Selon sa configuration, un travail de ré-écriture d’URL sera donc nécessaire, – Compression : le proxy inverse peut optimiser la compression du contenu des sites.
Le reverse proxy est généralement placé dans une DMZ. Une DMZ (zone démilitarisée) est un sous-réseau séparé du réseau local et isolé de celui-ci et d'Internet par un pare-feu.
Conclusion Il faut bien distinguer les différents types de cache qui existent et qui peuvent être sollicités lors d’un accès à une ressource. En effet, lorsque l’utilisateur tente de se connecter à un serveur distant pour récupérer une page, il peut, sans le savoir, passer par plusieurs machines intermédiaires et interroger différents serveurs de cache. – Le tout premier niveau de cache est géré par le navigateur Internet. Il s’agit d’un cache local et non partagé. Le comportement lié à ce cache local est propre à chaque navigateur. Il ne sera pas détaillé dans ce document. – Le second niveau de cache est géré par le proxy web. Il est généralement partagé par les utilisateurs du réseau local qui se connectent à Internet à travers lui. Ce cache est administré par le responsable du réseau local. – Le troisième niveau de cache est celui maintenu par les différents reverse proxy auxquels peuvent s’adresser un poste client. Ces serveurs de cache sont mis en place par les administrateurs des sites distants pour répondre au mieux à leurs utilisateurs et exploiter leurs serveurs le plus efficacement possible.
Squid Introduction Un serveur Squid est un serveur mandataire (proxy) et un mandataire inverse (reverse proxy) capable d’utiliser les protocoles FTP, HTTP, Gopher, et HTTPS. C’est un logiciel libre distribué sous licence GNU GPL. Squid garde les meta-données et plus particulièrement les données les plus fréquemment utilisées en mémoire (cache) pour utiliser moins de bande passante. Il conserve aussi en mémoire les requêtes DNS, ainsi que les requêtes ayant échoué.
Il est généralement utilisé dans certaines entreprises et universités pour des fonctions de ltrage d'URL ou en tant que tampon (cache). Site officiel : http ://www.squid-cache.org/ En résumé, Squid est un proxy cache : – proxy (mandataire) : un agent intermédiaire qui agit pour un autre – cache : un espace où l’on stocke les informations les plus demandées
Installation Il suffit d’installer le paquet squid : // En fait, installe squid3 : # apt-get install squid ... // Affiche le numéro de version : # squid3 -v Squid Cache: Version 3.1.20
// Démarre le service : # service squid3 start // Arrête le service : # service squid3 stop
Pour les tests, on installera aussi les programmes squidclient et curl : # apt-get install squidclient curl
Configuration par défaut Par défaut Squid est configuré et fonctionnel. Le fichier de configuration de Squid est /etc/squid3/squid.conf. // Tester le fichier de configuration # squid3 -k parse // En cas de modification, il faut recharger le fichier de configuration # squid3 -k reconfigure
Voici la définition de quelques options de configuration de base : – http_port : permet de définir le port sur lequel se lance Squid. Par défaut, Squid se lance sur le port 3128. Il est également possible de définir plusieurs ports : par exemple 8080. – cache_effective_user : permet de définir sous quel utilisateur (user) fonctionne Squid (par défaut proxy) – cache_effective_group : permet de définir sous quel groupe (group) fonctionne Squid (par défaut proxy) – cache_mgr : permet d’indiquer l’adresse courriel de l’administrateur de Squid. – visible_hostname : permet d’indiquer le nom du serveur proxy. // Les valeurs par défaut de quelques options de base : # cat /etc/squid3/squid.conf | grep http_port http_port 3128 # cat /etc/squid3/squid.conf | grep cache_effective cache_effective_user proxy # ls -ld /var/spool/squid3/ drwxr-xr-x 2 proxy proxy 4096 janv. 31 2013 /var/spool/squid3/ # cat /etc/squid3/squid.conf | grep cache_mgr cache_mgr webmaster # cat /etc/squid3/squid.conf | grep visible_hostname visible_hostname localhost
Pour la suite des manipulations, il est préférable de sauvegarder le fichier de configuration de base et de repartir sur un fichier de configuration “propre” : // On conserve le fichier de configuration d’origine # mv /etc/squid3/squid.conf /etc/squid3/squid.conf.bak // On crée un nouveau fichier de configuration en ne conservant que les directives de base # cat /etc/squid3/squid.conf.bak | grep -v "^#" | grep -v ^$ > /etc/squid3/squid.conf
La plupart de ces directives seront étudiées plus loin dans ce document.
Fonctionnement La première activité de Squid est de relayer les requêtes clientes et de mettre en cache la réponse si celle-ci est éligible au cache. Pour savoir si la réponse peut être mise en cache, Squid analyse les données présentes dans l’en-tête HTTP. Voici les règles qui sont suivies pour décider de la mise en cache : – Si des instructions interdisant la mise en cache sont rencontrées (Cache-Control: private) alors la ressource n’est pas mise en cache. – Si la connexion est sécurisée ou authentifiée alors la ressource n’est pas mise en cache. – Si aucune directive de validation n’est présente (Last-Modified ou Etag) alors la ressource n’est pas mise en cache. – Sinon la ressource est considérée comme éligible au cache et Squid décide de la stocker. Si Squid reçoit une requête qui a déjà donné lieu à la mise en cache de la ressource, celui-ci va valider la donnée afin de savoir si elle est assez récente et si elle peut être renvoyée à l’utilisateur en l’état ou bien si au contraire, elle est considérée comme trop ancienne et nécessite d’être redemandée au serveur d’origine.
SQUID Cette étape de validation s’appuie sur les directives d’expiration et de validation contenues dans l’en-tête HTTP (Expires, max-age, Last-Modified et Etag). Le serveur procède de la sorte : – Vérification de la validité de la ressource en cache à l’aide des directives d’expiration (Expires et max-age). Cette étape consiste en un calcul de date aboutissant à la péremption ou non d’un objet du cache. Si ces directives ne sont pas présentes, la réponse est considérée comme étant valide à tout moment. – Si la ressource est considérée comme encore valide, elle est renvoyée au poste client sans contacter le serveur source. – Si la réponse est périmée, une requête conditionnelle (If-Modified-Since ou If-None-Match) basée sur les directives Last-Modified ou Etag est envoyée au serveur source qui répond soit en envoyant la nouvelle ressource soit en envoyant un code HTTP 304-Not Modified.
Le protocole HTTP fournit de nombreuses commandes permettant au poste client de communiquer avec le serveur. Certaines d'entre elles (OPTIONS, TRACE, POST, PUT et DELETE) ne nécessitent pas de mettre en cache la réponse du serveur. Squid distingue les diérents types de requêtes qui transitent pour ne traiter que les commandes HTTP qui peuvent aboutir à la mise en cache de la réponse serveur (GET, HEAD et CONNECT). La directive principale de cache dans la version 1.1 du protocole HTTP est la directive Cache-Control. Elle peut prendre plusieurs options qui influent directement sur le comportement du serveur cache. La directive de cache HTTP peut aussi bien être présente dans la requête que dans la réponse. Utilisée dans la requête, elle permet au poste client de piloter certains aspects du serveur cache en signifiant par exemple de ne retourner une réponse que si celle-ci est dans le cache. Dans la réponse, c’est le serveur source qui pilote le comportement du serveur cache. Dans une requête adressée par un utilisateur, la directive Cache-Control peut prendre les valeurs suivantes : – no-cache : cette option va forcer le serveur à recharger la page auprès du serveur d’origine. – max-age : utilisée dans la requête du poste client, cette option permet de fournir une valeur (en secondes) correspondant à l’âge maximum accepté pour la ressource retournée par le proxy cache. Sauf si l’option max-stale est également fournie, cela signifie que le poste client ne désire pas recevoir de réponse périmée. – max-stale : permet d’indiquer au serveur de cache que le poste client est prêt à accepter une réponse éventuellement périmée mais dont le délai d’expiration n’excède toutefois pas la valeur passée en paramètre. Si aucune valeur n’est passée, toute réponse périmée est acceptée par le poste client. – min-fresh : permet d’indiquer au serveur de cache que le poste client est prêt à accepter toute réponse qui sera encore considérée comme valide dans la période passée en paramètre. A la réception de ce type de requête, si la ressource est présente dans le cache, le serveur additionne la valeur de l’option min-fresh à l’âge de la ressource et regarde si le total est inférieur à la valeur de l’option max-age. Si c’est le cas, la ressource est renvoyée au poste client, sinon, le serveur source est contacté. – only-if-cached : cette option permet de récupérer dans le cache une ressource uniquement si celle-ci est déjà présente dans le cache. Si ce n’est pas le cas, une réponse HTTP 504-Gateway timeout est renvoyée au poste client. Au sein d’une réponse serveur, les valeurs possibles sont les suivantes : – public : permet d’indiquer aux serveurs de cache que la réponse est éligible à la mise en cache (valable aussi bien pour les caches partagés que les caches privés). – private : cette option permet d’indiquer au serveur de cache que tout ou partie de la réponse est destiné à un unique utilisateur et que par conséquent la réponse ne doit pas être mise en cache. – no-cache : indique que la ressource doit être revalidée chaque fois qu’elle est redemandée. Administration Linux - Proxy
SQUID – no-store : cette option permet de ne pas stocker la réponse sur le disque. La réponse peut être mise en cache mais ne doit pas être enregistrée sur des volumes de stockage non volatiles. – no-transform : cette option permet d’empêcher le serveur cache de modifier le paquet HTTP, que ce soit l’en-tête HTTP ou le contenu lui-même. Certains serveurs de cache convertissent ou compressent les données pour économiser de l’espace mémoire. – must-revalidate : cette option peut être utilisée par les serveurs source pour forcer la validation des données mises en cache. – proxy-revalidate : cette option permet de réaliser la même chose que l’option must-revalidate à ceci prêt qu’elle n’est utilisée que par les serveurs de cache. – max-age : cette option sert de validateur et implique que la ressource est éligible au cache. Lorsque cette option a pour valeur « -1 », elle équivaut à l’option no-cache et indique au serveur qu’elle ne doit pas être stockée. Si la directive Expires (HTTP/1.0) est également présente dans l’en-tête HTTP, l’option max-age (HTTP/1.1) est utilisée en priorité. – s-maxage : cette option permet de combiner les propriétés des options max-age et must-revalidate. Le paramètre fourni permet de contrôler la date d’expiration de la ressource envoyée par le serveur et de forcer la revalidation par le serveur cache. Cette option surcharge les options Expires et max-age.
Pour plus de détails sur le sujet, il est possible de consulter la RFC 2616 d'où sont issues la plupart de ces informations. Les Etags (Entity Tag) sont arrivés avec la version 1.1 du protocole HTTP. Ils ont été pensés afin d’améliorer le processus de validation qui était auparavant basé sur l’option Last-Modified pour envoyer une requête IMS (If-Modified-Since) au serveur source. Un Etag est en fait une empreinte (ou hash) qui est associée à une ressource et qui permet de l’identifier de manière plus ou moins unique. Celui-ci est généré par le serveur source et apporte un autre mécanisme de détection des modifications basé sur l’utilisation des directives HTTP If-Match et If-None-Match.
Dans la version 3 de Squid, le support des Etags n'est pas encore complet. Squid est capable de traiter les requêtes clientes contenant les directives If-Match et If-Non-Match de l'en-tête HTTP et de détecter si l'Etag de la version en cache est diérent de celui passé dans la requête an de décider si la ressource doit être récupérée auprès du serveur d'origine. Toutefois, les requêtes générées par Squid pour la validation des données en cache auprès du serveur d'origine ne se basent pas sur les Etags mais toujours sur la directive Last-Modified. Pour vérifier la validité d’une ressource en cache, Squid utilise trois types de variables : des variables correspondant à l’objet enregistré, une variable fournie par le client et des variables du fichier de configuration. Les variables associées à l’objet enregistré sont calculées d’après les données relatives à l’enregistrement de l’objet dans le cache : – AGE correspond au temps écoulé depuis son entrée dans le cache. – LM_AGE correspond au temps écoulé entre la dernière modification de l’objet sur le serveur d’origine et son entrée dans le cache. – LM_FACTOR est le rapport entre AGE et LM_AGE. Plus ce facteur est grand, plus l’objet a de chances d’être périmé. – EXPIRES est la valeur éventuellement fournie par le serveur au moment de l’entrée de l’objet dans le cache. Comme son nom l’indique, cette variable contient la date d’expiration de l’objet. Squid tient également compte de la variable de contrôle de cache CLIENT_MAX_AGE éventuellement fournie par le client, s’il utilise la version 1.1 d’HTTP. Cette variable indique l’âge maximal de l’objet accepté par le client. Administration Linux - Proxy
SQUID Les variables du fichier de configuration sont fixées par la directive refresh_pattern qui permet gérer le rafraichissement du cache. Sa syntaxe est la suivante : refresh_pattern [-i] MIN_AGE PERCENT MAX_AGE
Le drapeau optionnel -i permet de ne pas tenir compte de la casse des caractères dans l'expression régulière de description de l'URL. Il peut y avoir plusieurs directives refresh_pattern dans le chier de conguration. Les variables qui permettent de régler le comportement du rafraichissement du cache sont : – MIN_AGE indique la durée en minutes pour laquelle un objet sans expiration explicite doit être conservé – PERCENT représente le pourcentage de l’objet (temps depuis sa dernière modification) – MAX_AGE indique la durée maximale en minutes d’un objet sans expiration explicite ... refresh_pattern refresh_pattern refresh_pattern refresh_pattern refresh_pattern
Ici, les valeurs de MAX_AGE, PERCENT et MIN_AGE pour les requêtes HTTP sont donc respectivement 0, 20% et 4320 (unité de temps en minutes).
La variable MAX_AGE éventuellement fournie par le client prévaut sur celle du chier de conguration. Par contre, MIN_AGE du chier de conguration est prioritaire devant la variable EXPIRES éventuellement fourni par le serveur. Une fois les variables nécessaires déterminées, Squid observe les règles suivantes pour déterminer la fraîcheur de l’objet dans le cache : – Si MAX_AGE est défini et que AGE > MAX_AGE, l’objet est déclaré « périmé » – Si EXPIRES est défini et dépassé, l’objet est déclaré « périmé » – Si AGE <= à MIN_AGE, l’objet est déclaré « frais » – Si EXPIRES est défini mais pas encore dépassé, l’objet est déclaré « frais » – Si LM_FACTOR est inférieur à PERCENT, l’objet est déclaré « frais » – Sinon celui-ci est déclaré « périmé ». // Exemple pour les pages web : une fois par jour pendant 7 jours refresh_pattern ^http 1440 20% 10080 // ou pour les pages web (html) : refresh_pattern -i \.html$ 1440 20% 10080
Tests Pour définir la taille de la mémoire cache allouée en RAM, il faut utiliser la directive cache_mem. Par défaut, celle-ci est fixée à 256 Mo. On va lui attribuer une taille de 100 Mo : # vim /etc/squid3/squid.conf cache_mem 100 MB
Afin que le serveur cache possède une zone de stockage sur disque, il est nécessaire d’activer la directive cache_dir : Administration Linux - Proxy
# vim /etc/squid3/squid.conf cache_dir ufs /var/spool/squid3 100 16 256
Ici le cache a une taille de 100MO répartis sur 16 répertoires de premier niveau contenant chacun 256 répertoires de second niveau. Cette arborescence permet de constituer un index rapide d'accès. Il faut maintenant initialiser les répertoires de cache : # squid3 -z 2014/04/28 09:54:06| 2014/04/28 09:54:06| 2014/04/28 09:54:06| 2014/04/28 09:54:06| 2014/04/28 09:54:06| 2014/04/28 09:54:06| 2014/04/28 09:54:06| 2014/04/28 09:54:06| 2014/04/28 09:54:06| 2014/04/28 09:54:06| 2014/04/28 09:54:06| 2014/04/28 09:54:06| 2014/04/28 09:54:06| 2014/04/28 09:54:06| 2014/04/28 09:54:06| 2014/04/28 09:54:06| 2014/04/28 09:54:06| 2014/04/28 09:54:06|
Creating Swap Directories /var/spool/squid3 exists Making directories in /var/spool/squid3/00 Making directories in /var/spool/squid3/01 Making directories in /var/spool/squid3/02 Making directories in /var/spool/squid3/03 Making directories in /var/spool/squid3/04 Making directories in /var/spool/squid3/05 Making directories in /var/spool/squid3/06 Making directories in /var/spool/squid3/07 Making directories in /var/spool/squid3/08 Making directories in /var/spool/squid3/09 Making directories in /var/spool/squid3/0A Making directories in /var/spool/squid3/0B Making directories in /var/spool/squid3/0C Making directories in /var/spool/squid3/0D Making directories in /var/spool/squid3/0E Making directories in /var/spool/squid3/0F
On vérifie les options de configuration, puis on relance le service Squid : // Vérifie les options de configuration : # squid3 -k parse 2014/04/28 10:23:11| Processing Configuration File: /etc/squid3/squid.conf (depth 0) 2014/04/28 10:23:11| Processing: acl manager proto cache_object 2014/04/28 10:23:11| Processing: acl localhost src 127.0.0.1/32 ::1 2014/04/28 10:23:11| Processing: acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1 2014/04/28 10:23:11| Processing: acl SSL_ports port 443 2014/04/28 10:23:11| Processing: acl Safe_ports port 80 # http 2014/04/28 10:23:11| Processing: acl Safe_ports port 21 # ftp 2014/04/28 10:23:11| Processing: acl Safe_ports port 443 # https 2014/04/28 10:23:11| Processing: acl Safe_ports port 70 # gopher 2014/04/28 10:23:11| Processing: acl Safe_ports port 210 # wais 2014/04/28 10:23:11| Processing: acl Safe_ports port 1025-65535 # unregistered ports 2014/04/28 10:23:11| Processing: acl Safe_ports port 280 # http-mgmt 2014/04/28 10:23:11| Processing: acl Safe_ports port 488 # gss-http 2014/04/28 10:23:11| Processing: acl Safe_ports port 591 # filemaker 2014/04/28 10:23:11| Processing: acl Safe_ports port 777 # multiling http 2014/04/28 10:23:11| Processing: acl CONNECT method CONNECT 2014/04/28 10:23:11| Processing: http_access allow manager localhost 2014/04/28 10:23:11| Processing: http_access deny manager 2014/04/28 10:23:11| Processing: http_access deny !Safe_ports 2014/04/28 10:23:11| Processing: http_access deny CONNECT !SSL_ports 2014/04/28 10:23:11| Processing: http_access allow localhost 2014/04/28 10:23:11| Processing: http_access deny all 2014/04/28 10:23:11| Processing: http_port 3128 2014/04/28 10:23:11| Processing: coredump_dir /var/spool/squid3 2014/04/28 10:23:11| Processing: refresh_pattern ^ftp: 1440 20% 10080 2014/04/28 10:23:11| Processing: refresh_pattern ^gopher: 1440 0% 1440 Administration Linux - Proxy
// Arrête le service : # service squid3 stop squid3 stop/waiting // Démarre le service : # service squid3 start squid3 start/running, process 2262 // Vérifie que le port du serveur cache est en écoute : # netstat -tlunp | grep squid tcp6 0 0 :::3128 :::* udp 0 0 0.0.0.0:58070 0.0.0.0:* udp6 0 0 :::58720 :::*
LISTEN
2262/squid3 2262/squid3 2262/squid3
On peut maintenant effectuer quelques tests avec le programme squidclient (et curl) : // On demande l’accès à une ressource : # squidclient http://tvaira.free.fr/ HTTP/1.0 200 OK Date: Mon, 28 Apr 2014 08:04:05 GMT Server: Apache/ProXad [Apr 20 2012 15:06:05] Last-Modified: Wed, 19 Mar 2014 09:12:32 GMT ETag: "23cb6d8-b509-53295f80" Accept-Ranges: bytes Content-Length: 46345 Content-Type: text/html X-Cache: MISS from gw.intra.esimed.fr X-Cache-Lookup: MISS from gw.intra.esimed.fr:8756 X-Cache: MISS from localhost X-Cache-Lookup: MISS from localhost:3128 Via: 1.0 localhost (squid/3.1.20) Connection: close ... // On consulte le fichier de log des requêtes relayées par le serveur cache : // TCP_MISS : l’objet n’est pas dans le cache et squid va le chercher sur le serveur d’origine # cat /var/log/squid3/access.log 1398694029.359 0 127.0.0.1 TCP_MISS/200 46820 GET http://tvaira.free.fr/ - DIRECT/212.27.63.112 text/html // On redemande la même ressource (en mode silencieux) : # squidclient -s http://tvaira.free.fr/ // On consulte le fichier de log : // TCP_HIT : l’objet est présent dans le cache disque et squid le renvoie au client // ou // TCP_MEM_HIT : l’objet est présent dans le cache RAM et squid le renvoie au client # cat /var/log/squid3/access.log 1398694034.890 0 127.0.0.1 TCP_HIT/200 46820 GET http://tvaira.free.fr/ - NONE/- text/html // On force le serveur cache à recharger un objet (en mode silencieux) : # squidclient -s -r http://tvaira.free.fr/ // On consulte le fichier de log : // TCP_CLIENT_REFRESH_MISS : le client sollicite une mise à jour de la ressource Administration Linux - Proxy
# cat /var/log/squid3/access.log 1398694998.504 90 127.0.0.1 TCP_CLIENT_REFRESH_MISS/200 46809 GET http://tvaira.free.fr/ - DIRECT /212.27.63.112 text/html // On force le serveur cache à recharger un objet (avec curl) : # curl -I http://tvaira.free.fr/ -x http://localhost:3128 -H ’Cache-Control: max-age=0’ HTTP/1.0 200 OK Last-Modified: Tue, 29 Apr 2014 10:12:07 GMT Accept-Ranges: bytes Content-Length: 48005 Content-Type: text/html Date: Mon, 05 May 2014 09:49:31 GMT Server: Apache/ProXad [Apr 20 2012 15:06:05] ETag: "23cb6d8-bb85-535f7af7" X-Cache: HIT from localhost X-Cache-Lookup: HIT from localhost:3128 Via: 1.0 localhost (squid/3.1.20) Connection: keep-alive // On consulte le fichier de log : // TCP_REFRESH_UNMODIFIED : le client sollicite une mise à jour de la ressource et squid est forcé de revalider son entrée qui n’est pourtant pas périmée. Le serveur a retourné un code 304-Not Modified et la version en cache est renvoyée au poste client. # cat /var/log/squid3/access.log 1398695098.938 130 127.0.0.1 TCP_REFRESH_UNMODIFIED/200 378 HEAD http://tvaira.free.fr/ - DIRECT /212.27.63.112 text/html // On force le serveur cache à recharger un objet (avec curl) : # curl -I http://tvaira.free.fr/ -x http://localhost:3128 -H ’Cache-Control:no-cache’ HTTP/1.0 200 OK Date: Mon, 05 May 2014 09:55:48 GMT Server: Apache/ProXad [Apr 20 2012 15:06:05] Last-Modified: Tue, 29 Apr 2014 10:12:07 GMT ETag: "23cb6d8-bb85-535f7af7" Accept-Ranges: bytes Content-Length: 48005 Content-Type: text/html X-Cache: MISS from localhost X-Cache-Lookup: HIT from localhost:3128 Via: 1.0 localhost (squid/3.1.20) Connection: keep-alive // On consulte le fichier de log : // TCP_CLIENT_REFRESH_MISS : indique ici que le serveur cache a dû recontacter le serveur d’origine sur demande du client # cat /var/log/squid3/access.log 1398695208.970 96 127.0.0.1 TCP_CLIENT_REFRESH_MISS/200 379 HEAD http://tvaira.free.fr/ - DIRECT /212.27.63.112 text/html
Le premier appel montre que la ressource n’était pas présente dans le cache (TCP_MISS/200) et que la requête a été envoyée au serveur d’origine (DIRECT/212.27.63.112). Lors de la seconde tentative, le cache est sollicité et cette fois l’objet est trouvé, Squid renvoie un code TCP_HIT/200 (ou TCP_MEM_HIT/200) signifiant que l’objet a été trouvé et qu’il est encore valide. Aucune connexion n’est alors faite avec le serveur d’origine (NONE/).
L'option no-cache utilisée dans la requête va forcer le serveur à recharger la page auprès du serveur d'origine. Quand cette option est présente dans la réponse, cela indique que la ressource doit être revalidée chaque fois qu'elle est redemandée. Administration Linux - Proxy
SQUID On commence par récupérer une ressource éligible au cache : # curl -I http://tvaira.free.fr/ -x http://localhost:3128 HTTP/1.0 200 OK Last-Modified: Tue, 29 Apr 2014 10:12:07 GMT Accept-Ranges: bytes Content-Length: 48005 Content-Type: text/html Date: Mon, 05 May 2014 10:04:29 GMT Server: Apache/ProXad [Apr 20 2012 15:06:05] ETag: "23cb6d8-bb85-535f7af7" Age: 116 X-Cache: HIT from localhost X-Cache-Lookup: HIT from localhost:3128 Via: 1.0 localhost (squid/3.1.20) Connection: keep-alive
Il y a une information importante ici, l’âge de la ressource dans le cache (Age: 116), ce qui signifie aussi que la ressource était déjà présente dans le cache avant la requête. On envoie maintenant les requêtes suivantes au serveur : // Pas encore périmé : 400 > 116 # curl -I http://tvaira.free.fr/ -x http://localhost:3128 -H ’Cache-Control: max-age=400’ # cat /var/log/squid3/access.log 1398696801.368 0 127.0.0.1 TCP_MEM_HIT/200 388 HEAD http://tvaira.free.fr/ - NONE/- text/html // Périmé : 40 < 116 # curl -I http://tvaira.free.fr/ -x http://localhost:3128 -H ’Cache-Control: max-age=40’ # cat /var/log/squid3/access.log 1398697004.111 69 127.0.0.1 TCP_REFRESH_UNMODIFIED/200 378 HEAD http://tvaira.free.fr/ - DIRECT /212.27.63.112 text/htm
L'option max-age utilisée dans la requête du poste client permet de fournir une valeur (en secondes) correspondant à l'âge maximum accepté pour la ressource retournée par le proxy cache. Pour mettre en pratique Squid sur un réseau local, il suffit simplement de configurer les navigateurs web client afin d’utiliser un proxy, ayant pour adresse celle de la machine Squid.
Squid écoute par défaut sur le port 3128. Exemple de paramétrage du navigateur Firefox sur un réseau local 192.168.52.0/24 :
Il sera possible d'outrepasser la conguration du navigateur car Squid dispose d'une option de conguration lui permettant de fonctionner en proxy transparent (cf. manipulations). Vous risquez d’obtenir ceci :
On peut vérifier dans le journal des accès : # cat /var/log/squid3/access.log 1399285277.443 0 192.168.52.2 1399285277.537 0 192.168.52.2 NONE/- text/html 1399285277.600 0 192.168.52.2 text/html 1399285277.600 0 192.168.52.2 text/html 1399285832.949 1 192.168.52.2 html
TCP_DENIED/403 3804 GET http://192.168.52.9/ - NONE/- text/html TCP_DENIED/403 3884 GET http://www.squid-cache.org/Artwork/SN.png TCP_DENIED/403 3805 GET http://192.168.52.9/favicon.ico - NONE/TCP_DENIED/403 3837 GET http://192.168.52.9/favicon.ico - NONE/TCP_DENIED/403 3642 CONNECT accounts.google.com:443 - NONE/- text/
Ceci est dû à la conguration actuelle des acl et de la directive http_access allow ...
Manipulations Séquence 1 : mise en tampon (cache web) Question 1. Installer squid puis réaliser les tests de base. La mise en cache des objets est une des fonctionnalités principales d’un serveur mandataire sur un réseau local. Squid utilise deux zones de cache pour stocker les données issues des pages web : – la mémoire RAM : plus rapide mais limité – le disque dur : plus lent mais plus d’espace possible Afin d’obtenir de bonnes performances, il faut dimensionner correctement ces deux espaces. On distingue trois types d’objets : – les objets en transit (in-tansit objects) : des requêtes que le serveur traite à un instant précis. Ils ont une priorité élevée et doivent être conservés dans la zone cache de la RAM – les objets chauds (hot objects) : les plus régulièrement demandés. Ils ont une priorité inférieure aux objets en transit. Si l’espace de stockage dans la RAM devient insuffisant, ils sont déplacés dans la zone cache du disque dur. – les objets cachés négativement (negative-cache objects) : des requêtes qui n’ont pas abouti (message d’erreurs ...). Ils ont la même priorité que les objets chauds. Pour définir la taille de la mémoire cache allouée en RAM, il faut utiliser la directive cache_mem. Par défaut, celle-ci est fixée à 256 Mo : # cat /etc/squid3/squid.conf.bak | grep cache_mem cache_mem 256 MB
Les objets ont en moyenne un poids de 13 Ko. Chaque objet est référencé par une métadonnée de 72 octets dans la base. Il est ensuite possible de limiter la taille des objets mis en cache avec la directive maximum_object_size_in_memory (par défaut à 512 Ko) : # cat /etc/squid3/squid.conf.bak | grep maximum_object_size_in_memory maximum_object_size_in_memory 512 KB
Il est aussi possible de limiter la taille des objets stockés sur le cache disque dur avec la directive maximum_object_size (combiné avec la directive minimum_object_size). On peut aussi contrôler le mode utilisé pour la mise en cache dans la RAM avec la directive memory_cache_mode : – always : permet de mettre en cache tous les objets les plus récemment récupérés – disk : objet d’abord stocké dans le cache disque dur puis s’il est appelé une seconde fois, il sera stocké dans la RAM – network : seuls les objets récupérés à partir du réseau (serveurs d’origine et caches voisins) sont stockés en RAM
La directive
memory_cache_mode n'est disponible qu'à partir de la version 3.2 de Squid. Administration Linux - Proxy
MANIPULATIONS Lorsque le cache est (presque) plein, Squid met en place une politique de remplacement (avec la directive memory_replacement_policy) pour qu’il puisse se vider : – lru (Least Recent Used) : supprime les objets les plus anciens de la RAM (choix par défaut) – GDSF (Greedy Dual Size Frequency) : supprime les objets en fonction de leur taille et de leur temps d’accès (les plus petits et les plus régulièrement appelés sont conservés) – LFUDA (Least Frequently Used With Dynamic Aging) : idem GDSF mais sans tenir compte de leur taille # cat /etc/squid3/squid.conf.bak | grep memory_replacement_policy memory_replacement_policy lru
La directive cache_replacement_policy dénit la manière dont les objets sont remplaçés sur le disque dur. Les seuils de déclenchement sont réglables avec cache_swap_low et cache_swap_high. Squid implémente trois systèmes de fichiers pour la zone cache du disque dur : – ufs (Unix File System) : choix par défaut – aufs (Asynchronous UFS ) : une version améliorée de ufs (e/s asynchrones en utilisant les threads) – diskd (Disk Daemon) : idem aufs mais sans les threads On utilise la directive cache_dir pour activer une zone de stockage sur disque : # vim /etc/squid3/squid.conf cache_dir ufs /var/spool/squid3/cache 150 16 256
Ici le cache a une taille de 150 MO répartis sur 16 répertoires de premier niveau contenant chacun 256 répertoires de second niveau. // On crée le répertoire de cache # mkdir -p /var/spool/squid3/cache // On lui attribue le user (cache_effective_user) et le group (cache_effective_group) propriétaires # chown -R proxy:proxy /var/spool/squid3/cache2 // On initialise la zone de cache # squid3 -z
Il est conseillé de sauvegarder son chier de conguration de Squid /etc/squid3/squid.conf et de réaliser chaque séquence à partir d'un chier vierge. Question 2. Réaliser la configuration suivante : - définir l’espace alloué en RAM à 128 Mo - limiter la taille des objets en RAM à 1 Mo - définir un deuxième cache disque de type aufs de 100 Mo - limiter la taille des objets sur le disque à 2 Mo Il est préférable de modifier la valeur de la directive error_directory qui indique à Squid dans quel répertoire aller chercher les messages d’erreur. // Répertoire qui contient les messages d’erreurs personnalisés par langue # ls -l /usr/share/squid3/errors/
MANIPULATIONS Question 3. Ajuster la valeur de la directive error_directory pour obtenir des messages d’erreur en français et vérifier le bon fonctionnement. Question 4. Modifier le message d’erreur ERR_ACCESS_DENIED et vérifier la prise en compte de la modification.
Séquence 2 : la journalisation Squid génère des fichiers de journalisation (log). Par défaut, il utilise les deux fichiers journaux access.log et cache.log situés dans /var/log/squid3/. # cat /etc/squid3/squid.conf.bak | grep "_log" access_log /var/log/squid3/access.log squid cache_log /var/log/squid3/cache.log
Le fichier /var/log/squid3/cache.log recense les différentes informations concernant le fonctionnement du service et les possibles erreurs contenues dans le fichier de configuration de Squid (/etc/squid3/squid.conf). On peut le visualiser avec les commandes cat ou tail : # cat /var/log/squid3/cache.log 2014/04/30 14:45:01| Starting Squid Cache version 3.1.20 for x86_64-pc-linux-gnu... 2014/04/30 14:45:01| Process ID 2932 ...
Le fichier /var/log/squid3/access.log permet de recenser toutes les requêtes HTTP relayées par le serveur mandataire. Chaque ligne correspond à une requête cliente. Une ligne peut prendre la forme suivante : Timestamp Elapsed Client Action/Code Size Method URI Ident Hierarchy/From Content with: - Timestamp : The time when the request is completed (socket closed). The format is " Unix time" (seconds since Jan 1, 1970) with millisecond resolution. - Elapsed : The elapsed time of the request, in milliseconds. This is the time between the accept() and close() of the client socket. - Client : The IP address of the connecting client, or the FQDN if the ’log_fqdn’ option is enabled in the config file. - Action : The Action describes how the request was treated locally (hit, miss, etc). - Code : The HTTP reply code taken from the first line of the HTTP reply header. For ICP requests this is always "000." If the reply code was not given, it will be logged as "555." - Size : For TCP requests, the amount of data written to the client. For UDP requests, the size of the request. (in bytes) - Method : The HTTP request method (GET, POST, etc), or ICP_QUERY for ICP requests. - URI : The requested URI. - Ident : The result of the RFC931/ident lookup of the client username. If RFC931/ident lookup is disabled (default: ‘ident_lookup off’), it is logged as - . - Hierarchy : A description of how and where the requested object was fetched. - From : Hostname of the machine where we got the object. - Content : Content-type of the Object (from the HTTP reply header).
# tail /var/log/squid3/access.log 1398862154.102 27 127.0.0.1 TCP_MISS/200 1215 GET http://tvaira.free.fr/test.htm - DIRECT /212.27.63.112 text/html 1398862185.822 0 127.0.0.1 TCP_MEM_HIT/200 1222 GET http://tvaira.free.fr/test.htm - NONE/- text /html 1398862468.194 0 127.0.0.1 TCP_MEM_HIT/200 1223 GET http://tvaira.free.fr/test.htm - NONE/- text /html 1398862528.779 32 127.0.0.1 TCP_MISS/200 1814 GET http://127.0.0.1/ - DIRECT/127.0.0.1 text/html 1398862538.579 2 127.0.0.1 TCP_MISS/200 1814 GET http://127.0.0.1/ - DIRECT/127.0.0.1 text/html 1398863281.363 0 127.0.0.1 TCP_MEM_HIT/200 1224 GET http://tvaira.free.fr/test.htm - NONE/- text /html 1398863309.331 27 127.0.0.1 TCP_CLIENT_REFRESH_MISS/200 1214 GET http://tvaira.free.fr/test.htm DIRECT/212.27.63.112 text/html 1398863356.203 0 127.0.0.1 TCP_MEM_HIT/200 1222 GET http://tvaira.free.fr/test.htm - NONE/- text /html 1398864434.785 0 127.0.0.1 TCP_MEM_HIT/200 1224 GET http://tvaira.free.fr/test.htm - NONE/- text /html 1398864451.138 57 127.0.0.1 TCP_MISS/200 508 GET http://tvaira.free.fr/erreur.html - DIRECT /212.27.63.112 text/html
Concernant le code Action renvoyé par Squid pour chaque requête, on donne ici les principaux d’entre eux. Les codes préfixés par ’TCP_’ font référence aux requêtes reçues sur le port HTTP, les codes préfixés par ’UDP_’ faisant eux référence aux requêtes reçues sur le port ICP (Inter Cache Protocol utilisé pour communiquer avec d’autres serveurs cache) : – TCP_HIT : une copie valide de l’objet demandé a été trouvée dans le cache. – TCP_MISS : l’objet demandé n’a pas été trouvé dans le cache. – TCP_REFRESH_HIT : l’objet demandé a été trouvé dans le cache mais est considéré comme périmé. La requête IMS (If-Modified-Since) a renvoyé un code 304-Not Modified et la ressource mise en cache est retournée. – TCP_REFRESH_FAIL_HIT : l’objet demandé a été trouvé dans le cache mais est considéré comme périmé. La requête IMS (If-Modified-Since) a échoué et le contenu périmé a été délivré au client. – TCP_REFRESH_MISS : l’objet demandé a été trouvé dans le cache mais est considéré comme périmé. La requête IMS (If-Modified-Since) a retourné le nouvel objet. – TCP_DENIED : l’accès a été refusé pour cette demande.
Les diérents tags : http ://www.linofee.org/ jel/proxy/Squid/accesslog.shtml. Le fichier /var/log/squid3/store.log est aussi très utile pour décrire l’activité d’écriture sur le disque de Squid. Dans ce journal, il est possible de voir quels objets ont été stockés ou rechargés. Le fichier /var/log/squid3/store.log est structuré de la manière suivante : Timestamp Tag Code Date LM Expire Content Expect/Length Methode Key with: - Timestamp : The time this entry was logged. (millisecond resolution since 00:00:00 UTC , January 1, 1970) - Tag : SWAPIN (swapped into memory from disk), SWAPOUT (saved to disk) or RELEASE ( removed from cache) - Code : The HTTP reply code when available. For ICP requests this is always "0". If the reply code was not given, it will be logged as "555." The following three fields are timestamps parsed from the HTTP reply headers. All are expressed in Unix time (i.e.(seconds since 00:00:00 UTC, January 1, 1970). A missing Administration Linux - Proxy
MANIPULATIONS header is represented with -2 and an unparsable header is represented as -1. - Date : Time from the HTTP Date reply header. If the Date header is missing or invalid, the time of the request is used instead. - LM : The value of the HTTP Last-Modified: reply header. - Expires : The value of the HTTP Expires: reply header. - Content : The HTTP Content-Type reply header. - Expect : The value of the HTTP Content-Length reply header. Zero if Content-Length was missing. - Length : The number of bytes of content actually read. If the Expect is non-zero, and not equal to the Length, the object will be released from the cache. - Method : The request method (GET, POST, etc). - Key : The cache key. Often this is simply the URL. Cache objects which never become public will have cache keys that include a unique integer sequence number, the request method, and then the URL. ( /[post|put|head|connect]/URI ) # cat /var/log/squid3/store.log 1398862154.102 SWAPOUT 01 00000000 714B61D97FF0021350BD10E8AEA675DD 200 1398862156 1292248126 -1 text/html 753/753 GET http://tvaira.free.fr/test.htm 1398862528.779 RELEASE -1 FFFFFFFF F533CA748CE8867E0727D8F34CE29ED4 200 1398862528 -1 -1 text/ html 1516/1516 GET http://127.0.0.1/ // Convertir un timestamp dans un format date # date --date=’@1398862156’ mercredi 30 avril 2014, 14:49:16 (UTC+0200) # date --date=’@1292248126’ lundi 13 décembre 2010, 14:48:46 (UTC+0100)
Question 5. Activer la journalisation (log) des fichiers access.log, cache.log et store.log situés dans /var/log/squid3/. Identifier les traces dans les journaux. Question 6. Personnaliser l’enregistrement des requêtes dans le fichier de journalisation access-tp.log avec la directive logformat en définissant le format "tp" qui respecte les spécifications suivantes : Client source IP address␣-␣User name␣[Local time]␣"Request method ␣Request URL␣ HTTP/Request protocol version"␣HTTP status code sent to the client␣ Sent reply size including HTTP headers␣Squid request status␣Squid hierarchy status
La documentation de la directive logformat : http ://www.squid-cache.org/
SARG est un outil qui permet d’analyser les requêtes effectuées sur le serveur mandataire et de créer des rapports détaillés au format HTML. // Installation de SARG # apt-get install sarg
Il faut ensuite éditer son fichier de configuration afin de définir le chemin d’accès au fichier de log de Squid et celui des rapports générés : # vim /etc/sarg/sarg.conf
Pour visualiser le rapport, il suffit d’utiliser un navigateur web en accédant à l’URL : http ://votreserveur/squid/
Question 7. Installer et tester l’outil SARG.
Séquence 3 : contrôle d’accès et authentification Ces limitations sont écrites à partir d’ACL (Access Control List). On construit un ensemble de règles nommées puis celles-ci pourront être utilisées dans d’autres directives (comme http_access et icp_access). La syntaxe d’une ACL est la suivante : acl http_access
aclname allow|deny
acltype [!]aclname
string[string2]
La directive acl prend trois arguments obligatoires : – le nom de la liste (aclname) – le type de contrôle (acltype) – le paramètre obligatoire au type de contrôle (string) Administration Linux - Proxy
MANIPULATIONS Quelques types d’acl : – src : basée sur l’adresse IP d’un client – dst : basée sur l’adresse IP demandée dans une requête – srcdomain : basée sur le nom de domaine du client – dstdomain : basée sur le nom de domaine du serveur contacté – port : basée sur le port de destination – proto : basée sur le protocole – url_regex : une chaîne sous forme d’expression rationnelle contenue dans l’URL (on peut utiliser les jokers ou un fichier) – urlpath_regex : une chaîne comparée avec le chemin de l’URL (on peut utiliser les jokers) – time : pour un contrôle de l’heure de connexion sous la forme de deux arguments (une lettre correspondant au jour de la semaine et une fourchette horaire par exemple 08:30-18:45) Exemple : // Création d’une acl de nom localhost basée sur l’adresse IPv4 et IPv6 de l’interface de loopback acl localhost src 127.0.0.1/32 ::1
Les listes une fois définies sont mises en oeuvre pour contrôler différents types d’accès : – l’accès au web avec la directive http_access – l’accès toujours direct au web avec la directive always_direct – l’accès jamais direct au web avec la directive never_direct – la mise en cache avec la directive cache Chacun de ces types d’accès prend au moins deux arguments : – le sort de la requête qui répond aux critères de la liste d’accès : allow (autorisation) ou deny (refus) ; – le nom (ou plusieurs) de la liste d’accès concernée. Exemple : // Accès autorisé pour l’acl localhost : http_access allow localhost // Et donc refusé pour les autres : http_access deny all
Question 8. Interdire tous les accès avec la règle : http_access deny all. Vérifier le fonctionnement. Question 9. Interdire l’accès à un serveur (google.fr par exemple). Vérifiez le fonctionnement. Question 10. Interdire la mise en cache des objets locaux. Question 11. Autoriser l’accès aux clients de votre réseau local. Vérifiez le fonctionnement. Question 12. Configurer alors un client du réseau local pour qu’il utilise le service proxy sur les requêtes HTTP. Vérifier le bon fonctionnement. Question 13. Automatiser la configuration des clients Mozilla/Firefox du réseau local en créant un fichier firefox.pac. // exemple de fichier .pac function FindProxyForURL(url, host) { return "PROXY 192.168.52.9:3128; DIRECT"; }
Question 14. Configurer et tester le bon fonctionnement d’un client. Administration Linux - Proxy
Pour que Squid fonctionne comme un serveur mandataire transparent, il faut ajouter dans le fichier /etc/squid3/squid.conf : http_port 3128 intercept
Puis, pour que chaque requête HTTP soit traitée par le service proxy, il faut rediriger le flux à destination du port 80 (http) vers le port 3128 (squid) :
// A modifier en fonction de votre configuration # IFACE=eth0 # LAN=10.0.0.0 # iptables -t nat -A PREROUTING -i $IFACE -s $LAN/8 -p tcp --dport 80 -j REDIRECT --to-port 3128
MANIPULATIONS Question 15. Modifier la configuration du client et du serveur afin que la configuration globale devienne celle d’un proxy tranparent.
Question 16. Arrêter les service proxy et vérifier que les requêtes HTTP des clients ne sortent plus. Question 17. Désactiver le mode transparent. Question 18. On vous demande de mettre en oeuvre une authentification NCSA (/usr/lib/squid3/basic_ncsa_auth) pour les utilisateurs de votre réseau local en leur autorisant un accès pour une durée d’1 heure.
Séquence 4 : mise en tampon (cache dns) Squid effectue des requêtes DNS qui sont « bloquantes ». Il démarre ainsi un certains nombre de processus pour répondre à ces requêtes. On spécifie leur nombre avec la directive dns_children. Si cette requête réussit, elle est placée en cache pendant le temps précisée par la directive positive_dns. Dans le cas contraire, le temps sera celui fixé par la directive negative_dns. # cat /etc/squid3/squid.conf.bak | grep "dns_" positive_dns_ttl 6 hours negative_dns_ttl 1 minutes dns_children 5
MANIPULATIONS Question 19. Modifier le temps de mise en tampon pour la résolution de nom "positive" à 8 heures et "négative" à 4 minutes. Il est possible d’ajouter avec la directive dns_nameservers des serveurs de noms DNS qui seront utilisés par Squid pour résoudre les noms de domaine correspondant à des demandes émanant des clients : // Exemple : # cat /etc/squid3/squid.conf.bak | grep "dns_nameservers" dns_nameservers 10.0.0.1 192.172.0.4
Séquence 5 : filtrage avec squidGuard Installer squidguard. Puis, télécharger avec wget des listes de filtrage pré-renseignées à partir de ftp ://ftp.ut-capitole.fr/pub/reseau/cache/squidguard_contrib/blacklists.tar.gz. Question 20. On vous demande de configurer squidGuard pour assurer un blocage des réseaux sociaux (tester avec flickr.com) pour les utilisateurs de votre réseau local et vous les redirigerez vers une page d’erreur (erreur.html).