Pour cette partie, il est impératif de maîtriser les technique de routage avec netfilter.
Le but est d'installer un service proxy minimal, configurer les clients et de tester le fonctionnement de l'accès à internet à partir de ces derniers.
La première étape consistera à configurer les ACLs permettant un contrôle d'accès aux données externes, ensuite l'on fera évoluer la configuration vers un serveur proxy transparent.
Le service proxy sera installé sur le routeur.
On dispose d'un routeur en interface entre l’accès internet et un client qui représente un segment de réseau privé. L’ensemble doit fonctionner (accès à internet, résolution de nom, masquage d’adresse).
Pour ce TP, nous utiliserons à nouveau Netkit en employant deux hôtes : le client et le routeur-proxy. Voici une schématisation de la mise en pratique :
L'internet sera accessible à travers l'interface eth1 du routeur. On utilisera pour cela la fonctionnalité tap de Netkit. On renseignera le fichier /etc/resolv.conf pour y mettre l'adresse IP des serveurs DNS.
adminbdd lab_proxy # cat lab.conf LAB_DESCRIPTION="Utilisation d'un proxy HTTP Squid" LAB_VERSION=1.0 LAB_AUTHOR="Vanvincq Clément" LAB_EMAIL=vanvincq.clement@gmail.com LAB_WEB=http://www.eof.eu.org/ client[eth0]=interne proxy[eth0]=interne proxy[eth1]=tap,10.0.0.1,10.0.0.2
adminbdd lab_proxy # cat client.startup ifconfig eth0 192.168.0.10 netmask 255.255.255.0 broadcast 192.168.0.255 up route add default gw 192.168.0.254 echo "nameserver 192.168.10.21" > /etc/resolv.conf echo "nameserver 192.168.10.22" >> /etc/resolv.conf
Juste en guise de rappel, l'IP FORWARDING est déjà activé par défaut sous netkit.
adminbdd lab_proxy # cat proxy.startup ifconfig eth0 192.168.0.254 netmask 255.255.255.0 broadcast 192.168.0.255 up echo "nameserver 192.168.10.21" > /etc/resolv.conf echo "nameserver 192.168.10.22" >> /etc/resolv.conf iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j MASQUERADE
adminbdd lab_proxy # linfo ====================== Lab information ========================== Lab directory: /home/lab_proxy Version: 1.0 Author: Vanvincq Clément Email: vanvincq.clement@gmail.com Web: http://www.eof.eu.org/ Description: Utilisation d'un proxy HTTP Squid The lab is made up of 2 virtual machines (client proxy). =================================================================
Bien, on peut maintenant démarrer le laboratoire et procéder à quelques vérifications.
client:~# ifconfig; route eth0 Link encap:Ethernet HWaddr ee:ba:7b:99:bc:a5 inet addr:192.168.0.10 Bcast:192.168.0.255 Mask:255.255.255.0 inet6 addr: fe80::ecba:7bff:fe99:bca5/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:26 errors:0 dropped:0 overruns:0 frame:0 TX packets:26 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:2206 (2.1 KiB) TX bytes:2162 (2.1 KiB) Interrupt:5 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:2 errors:0 dropped:0 overruns:0 frame:0 TX packets:2 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:100 (100.0 B) TX bytes:100 (100.0 B) Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.0.0 * 255.255.255.0 U 0 0 0 eth0 default 192.168.0.254 0.0.0.0 UG 0 0 0 eth0
client:~# ping -c 3 eof.eu.org PING eof.eu.org (86.64.63.108) 56(84) bytes of data. 64 bytes from ns1.beaupeyrat.com (86.64.63.108): icmp_seq=1 ttl=52 time=80.4 ms 64 bytes from ns1.beaupeyrat.com (86.64.63.108): icmp_seq=2 ttl=52 time=35.3 ms 64 bytes from ns1.beaupeyrat.com (86.64.63.108): icmp_seq=3 ttl=52 time=148 ms --- eof.eu.org ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2014ms rtt min/avg/max/mdev = 35.352/88.096/148.511/46.515 ms
proxy:~# ifconfig; route eth0 Link encap:Ethernet HWaddr e6:2b:9c:bd:e5:25 inet addr:192.168.0.254 Bcast:192.168.0.255 Mask:255.255.255.0 inet6 addr: fe80::e42b:9cff:febd:e525/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:33 errors:0 dropped:0 overruns:0 frame:0 TX packets:36 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:2231 (2.1 KiB) TX bytes:3699 (3.6 KiB) Interrupt:5 eth1 Link encap:Ethernet HWaddr 82:ee:9e:c5:3f:ee inet addr:10.0.0.2 Bcast:10.255.255.255 Mask:255.0.0.0 inet6 addr: fe80::80ee:9eff:fec5:3fee/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:54 errors:0 dropped:0 overruns:0 frame:0 TX packets:56 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:5142 (5.0 KiB) TX bytes:4687 (4.5 KiB) Interrupt:5 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:2 errors:0 dropped:0 overruns:0 frame:0 TX packets:2 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:100 (100.0 B) TX bytes:100 (100.0 B) Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.0.0 * 255.255.255.0 U 0 0 0 eth0 10.0.0.0 * 255.0.0.0 U 0 0 0 eth1 default 10.0.0.1 0.0.0.0 UG 0 0 0 eth1
proxy:~# ping -c 3 eof.eu.org PING eof.eu.org (86.64.63.108) 56(84) bytes of data. 64 bytes from ns1.beaupeyrat.com (86.64.63.108): icmp_seq=1 ttl=53 time=38.1 ms 64 bytes from ns1.beaupeyrat.com (86.64.63.108): icmp_seq=2 ttl=53 time=35.0 ms 64 bytes from ns1.beaupeyrat.com (86.64.63.108): icmp_seq=3 ttl=53 time=32.6 ms --- eof.eu.org ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2034ms rtt min/avg/max/mdev = 32.654/35.263/38.106/2.231 ms
En un mot, formidable. Nous allons procéder de façon très brutale en interdisant le forwarding du routeur afin d'empêcher le client de sortir. Il n'aura alors d'autre choix que de passer par le proxy interne :)
Sans cela, si le client voulait aller sur internet en utilisant son navigateur favori, lynx, pour aller sur google il obtenait ceci :
proxy:~# iptables -A FORWARD -j DROP proxy:~# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination DROP all -- anywhere anywhere Chain OUTPUT (policy ACCEPT) target prot opt source destination
Maintenant que la règle a été ajoutée, le client n'a plus accès à l'extérieur.
client:~# lynx google.fr Looking up 'google.fr' first ^C client:~# ping -c 3 8.8.8.8 PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. --- 8.8.8.8 ping statistics --- 3 packets transmitted, 0 received, 100% packet loss, time 2011ms
Avant de modifier le fichier de configuration de squid, il est conseillé d'en faire une sauvegarde.
proxy:~# cp /etc/squid/squid.conf /etc/squid/squid.conf.bak
À la place, je vais mettre le fichier de configuration précisé dans l'énoncé :
proxy:/etc/squid# cat squid.conf http_port 3128 #We recommend you to use the following two lines. acl QUERY urlpath_regex cgi-bin \? no_cache deny QUERY cache_mem 8 MBM maximum_object_size_in_memory 8 KB cache_dir ufs /var/spool/squid 100 16 256 cache_access_log /var/log/squid/access.log cache_log /var/log/squid/cache.log cache_store_log /var/log/squid/store.log # Put your FQDN here visible_hostname freeduc-sup.foo.org pid_filename /var/run/squid.pid #Recommended minimum configuration: acl all src 0.0.0.0/0.0.0.0 acl manager proto cache_object acl localhost src 127.0.0.1/255.255.255.255 #Recommended minimum configuration: http_access allow manager localhost http_access allow all
Reste à initialiser le cache :
proxy:/etc/squid# squid -z 2012/04/27 09:35:27| Creating Swap Directories proxy:/etc/squid# /etc/init.d/squid start Starting Squid HTTP proxy: squid.
On vérifie que le service est bien en cours d'exécution et que le port 3128 est en écoute :
proxy:/etc/squid# ps aux | grep [s]quid root 635 0.0 1.9 4816 616 ? Ss 09:35 0:00 /usr/sbin/squid -D -YC proxy 637 0.3 14.1 7104 4504 ? S 09:35 0:00 (squid) -D -YC proxy:/etc/squid# netstat -atup | grep LISTEN tcp 0 0 *:sunrpc *:* LISTEN 354/portmap tcp 0 0 *:3128 *:* LISTEN 637/(squid)
Afin que le client puisse à nouveau naviguer sur l'Internet, il est nécessaire de configurer le client web du client pour qu'il prenne en compte notre proxy. Pour cela nous allons simplement modifier le fichier de configuration /etc/lynx-cur/lynx.cfg de Lynx pour y ajouter notre proxy.
client:~# grep http_proxy /etc/lynx-cur/lynx.cfg # wget) in a subsidiary role, it can be useful to add http_proxy and other #http_proxy:http://some.server.dom:port/ http_proxy:http://192.168.0.254:3128/
Vérifions maintenant le fonctionnement :
client:~# lynx eof.eu.org Looking up 'eof.eu.org' first ^C
Cela ne fonctionne pas mais c'est normal car les requêtes DNS (comme tout d'ailleurs) sont bloquées à cause de la règle brutale d'iptables. Réessayons en indiquant directement l'adresse IP du serveur cible :
client:~# lynx 86.64.63.108
Vérification des logs d'accès :
proxy:~# tail -f /var/log/squid/access.log 1335520007.903 1734 192.168.0.10 TCP_MISS/200 6891 GET http://86.64.63.108/ - DIRECT/86.64.63.108 text/html 1335527993.324 1664 192.168.0.10 TCP_MISS/200 6891 GET http://86.64.63.108/ - DIRECT/86.64.63.108 text/html 1335528688.463 23 192.168.0.10 TCP_MISS/200 6901 GET http://86.64.63.108/ - DIRECT/86.64.63.108 text/html 1335528712.147 2 192.168.0.10 TCP_MISS/200 6901 GET http://86.64.63.108/ - DIRECT/86.64.63.108 text/html
Interdisons maintenant tous les accès avec la règle http_access deny all (sans oublier de redémarrer squid) :
proxy:~# /etc/init.d/squid restart Restarting Squid HTTP proxy: squid.
client:~# lynx 86.64.63.108
Interdisez l’accès à un serveur (google.fr) par exemple. Vérifiez le fonctionnement.
On va réactiver tout d'abord le http_access pour tout pour ensuite y ajouter la règle d'interdiction aux serveurs google. De plus, on va changer la règle brutale en quelque chose de plus doux (notamment pour faciliter les requêtes DNS) :
Suppression des anciennes règles :
proxy:~# iptables -F proxy:~# iptables -X proxy:~# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
Interdiction de forwarder les requêtes HTTP :
proxy:~# iptables -A FORWARD -p TCP --dport 80 -j DROP proxy:~# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination DROP tcp -- anywhere anywhere tcp dpt:www Chain OUTPUT (policy ACCEPT) target prot opt source destination
Ajoutons maintenant la nouvelle entrée dans le fichier /etc/squid/squid.conf (attention à bien rajouter la règle AVANT le http_access allow all) :
proxy:~# tail -n 7 /etc/squid/squid.conf #Définition d'un nouveau ACL acl GOOGLE dstdomain .google.fr http_access deny GOOGLE #Recommended minimum configuration: http_access allow manager localhost http_access allow all proxy:~# /etc/init.d/squid restart Restarting Squid HTTP proxy: squid.
Tout est fin prêt pour de nouveaux tests !
client:~# lynx google.fr
client:~# lynx google.de
Exercice : Construisez deux fichiers, l’un qui permettra de stocker des adresses IP, l’autre des mots clés. Construisez une ACL qui interdit l’accès en sortie aux machines qui ont les adresses IP déterminées dans le premier fichier, et une ACL qui empêche l’accès aux URL qui contiennent les mots clés stockés dans le second fichier.
# Exemple de ce que le fichier "adresse_ip" contient : # Mettez dans la liste des adresses celle de votre client pour tester 192.168.0.2 192.168.0.10 # Exemple de ce que le fichier "mot_cle" contient : jeu game # Exemple d’ACL acl porn url_regex "/etc/squid/mot_cle" acl salleTP_PAS_OK src "/etc/squid/adresse_ip" http_access deny porn http_access deny salleTP_PAS_OK
Tester le fonctionnement de ces deux ACLs. (Utiliser comme url de destination par exemple http://games.yahoo.com/)
Comme précisé dans l'exemple ci-dessus, nous allons commencer par renseigner les deux fichiers.
proxy:/etc/squid# cat mot_clef windows microsoft apple mac tf1 iphone imac macbook
proxy:/etc/squid# cat squid.conf [...] acl CENSURE url_regex "/etc/squid/mot_clef" http_access deny CENSURE #Recommended minimum configuration: http_access allow manager localhost http_access allow all
Le client ne pourra pas accéder à une url contenant la chaîne "microsoft". Cependant, la casse est prise en compte alors pour une solide configuration, il faudra la prendre en compte tous les cas possibles.
Exercice : Configurez Squid pour qu’il affiche des pages (messages d’erreur) en Français. Vérifiez le fonctionnement.
error_directory /usr/share/squid/errors/French
Identifiez la page qui est retournée lors d’un refus d’accès. Modifiez la page et le message retourné, puis vérifiez le fonctionnement.
Après avoir ajouté la ligne indiquée, vérifions déjà ce que contient le fichier qui nous intéresse :
proxy:/etc/squid# cat /usr/share/squid/errors/French/ERR_ACCESS_DENIED <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> <TITLE>ERREUR : L'URL demandée n'a pu être chargée</TITLE> <STYLE type="text/css"><!--BODY{background-color:#ffffff;font-family:verdana,sans-serif}PRE{font-family:sans-serif}--></STYLE> </HEAD><BODY> <H1>ERREUR</H1> <H2>L'URL demandée n'a pu être chargée</H2> <HR noshade size="1px"> <P> En essayant de charger l'URL : <A HREF="%U">%U</A> <P> L'erreur suivante a été rencontrée : <UL> <LI> <STRONG> Accès interdit. </STRONG> <P> La configuration du contrôle d'accès interdit à votre requête d'être acceptée à cette heure-ci. Veuillez contacter votre prestataire de service si vous pensez que ceci n'a pas lieu d'être. </UL> </P>
J'avoue que sur lynx est un peu limitée mais on fera avec. Pour le fun, voici la nouvelle mise en page :
On remarquera au passage un problème avec les caractères accentués mais cela doit fort probablement être réglable.
Exercice : Créez un fichier ".pac" pour la configuration des clients Mozilla. Vous en avez un complet dans la FAQ de squid. Celui-ci fait le minimum.
Moteur de recherche des HOWTOs (par contre, je n'arrive pas à accéder aux pages freenix).
Fichier minimal pour Squid :
http_port 3128 #Ne pas "cacher" les données des formulaires acl QUERY urlpath_regex cgi-bin \? no_cache deny QUERY cache_mem 8 MBM maximum_object_size_in_memory 8 KB cache_dir ufs /var/spool/squid 100 16 256 cache_access_log /var/log/squid/access.log cache_log /var/log/squid/cache.log cache_store_log /var/log/squid/store.log # Ici mettez le nom de votre machine visible_hostname uranus.freeduc-sup.org pid_filename /var/run/squid.pid #Recommended minimum configuration: acl all src 0.0.0.0/0.0.0.0 acl manager proto cache_object acl localhost src 127.0.0.1/255.255.255.255 # Test des fichiers @ip et mots clés acl porn url_regex "/etc/squid/mot_cle" acl salleTP_PAS_OK src "/etc/squid/adresse_ip" http_access deny porn http_access deny salleTP_PAS_OK # Authentification auth_param basic program /usr/lib/squid/ncsa_auth /etc/squid/users auth_param basic realm Squid proxy-caching web serve auth_param basic children 5 acl foo proxy_auth REQUIRED http_access allow foo #Default: #http_access deny all #Messages d’erreurs en FR error_directory /usr/share/squid/errors/French # Pour le proxy cache transparent httpd_accel_host virtual httpd_accel_port 80 httpd_accel_with_proxy on httpd_accel_uses_host_header on
acl salleTP_OK src "/etc/squid/salleTP_OK.txt" acl porn url_regex "/etc/squid/porn.txt" acl salleTP_PAS_OK src "/etc/squid/salleTP_PAS_OK.txt" http access salleTP_OK http access porn http deny salleTP_PAS_OK
Utilisation d’une authentification simple similaire à celle mise en oeuvre dans les .htaccess. Créer le fichier par script ou manuellement avec htpasswd.
authenticate_program /usr/bin/ncsa_auth /etc/squid/users authenticate_children 5 acl_authenticate_users REQUIRED http_access authenticate_users
Combinaison par "ET" logique des plages horaire et des salles. Mettre la machine à l’heure avec ntpdate par exemple.
# Interdire les accès en dehors des plages horaires 8h-12h et 14h-18h S Sunday M Monday T Tuesday W Wednesday H Thrusday F Friday A Saturday acl am time MTWHF 08:00-12:00 acl PM time MTWHF 14:00-18:00 http_access allow am salleTP_PAS_OK http_access allow pm salleTP_PAS_OK