Il existe plusieurs techniques pour intercepter le trafic Web sortant d'un périmètre en fonction des équipements utilisés. Ces techniques sont résumées dans le document Transparent Proxy with Linux and Squid mini-HOWTO. Si ce document date un peu, les principes restent les mêmes. Dans l'architecture présentée plus haut, le service mandataire est exécuté directement sur la passerelle de routage. L'interception du trafic Web vers le service mandataire doit donc se faire sur le même système.
En utilisant le système de filtrage réseau netfilter/iptables sur un système GNU/Linux, la règle de base de l'interception est la suivante :
# iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 3128
Avec cette règle de la table de traduction d'adresses
(NAT), tout paquet entrant par
l'interface eth1
utilisant le protocole
TCP avec le port destination
80
est redirigé vers le processus local
en écoute sur le port 3128
. Dans ce
contexte, le processus local correspond au numéro de port défini
dans la configuration du service Web mandataire : squid. Il faut aussi préciser que l'interface
eth1
doit être située du côté interne
de la passerelle d'interface avec le réseau du Campus.
Il faut aussi noter que le routage des paquets IP doit être activé sur le système. Dans le
contexte présenté, cette condition est déjà remplie puisqu'il
s'agit justement d'un routeur. On valide le routage au niveau du
noyau Linux dans l'arborescence /proc/
ou via le fichier /etc/sysctl.conf
s'il s'agit d'une configuration
permanente.
$ cat /proc/sys/net/ipv4/ip_forward 1 $ cat /etc/sysctl.conf |grep ip_forward net/ipv4/ip_forward=1 #net/ipv6/ip_forward=1
À partir de ces deux conditions de base, il faut intégrer l'interception de trafic dans le fonctionnement global du système de filtrage. Voici un exemple fonctionnel de script iptables restreint à l'interception Web.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # NAT #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *nat :PREROUTING ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] :OUTPUT ACCEPT [0:0] #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # P O S T R O U T I N G #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A POSTROUTING -o eth0 -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1400:1536 -j TCPMSS --clamp-mss-to-pmtu -A POSTROUTING -o eth0 -j SNAT --to-source aaa.bbb.ccc.ddd #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # P R E R O U T I N G #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # NTP postes clients -A PREROUTING -i eth1+ -p udp --dport 123 -j REDIRECT --to-port 123 # Interception du trafic Web des postes clients -A PREROUTING -i eth1+ -p tcp --dport 80 -j REDIRECT --to-port 3128 COMMIT #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # N e t f i l t e r #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # I N P U T #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Suivi de communication chaîne INPUT -A INPUT -p icmp -m conntrack --ctstate ESTABLISHED -j ACCEPT -A INPUT -p icmp --icmp-type destination-unreachable -m conntrack --ctstate RELATED -j ACCEPT -A INPUT -p icmp --icmp-type time-exceeded -m conntrack --ctstate RELATED -j ACCEPT -A INPUT -p ospf -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -p igmp -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -p udp -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp ! --syn -m conntrack --ctstate ESTABLISHED -j ACCEPT -A INPUT -p tcp --syn -m conntrack --ctstate RELATED -j ACCEPT # Boucle locale -A INPUT -i lo -j ACCEPT # NTP -A INPUT -i eth1+ -p udp --dport 123 -m conntrack --ctstate NEW -j ACCEPT # WWW -A INPUT -i eth1+ -p tcp --syn --dport 80 -m conntrack --ctstate NEW -j ACCEPT -A INPUT -i eth1+ -p tcp --syn --dport 443 -m conntrack --ctstate NEW -j ACCEPT # proxy Web -A INPUT -i eth1+ -p tcp --syn --dport 3128 -m conntrack --ctstate NEW -j ACCEPT # Poubelle -A INPUT -m conntrack --ctstate INVALID -m limit --limit 5/min -j LOG --log-prefix "INPUT/rejected.iptables: " -A INPUT -m conntrack --ctstate INVALID -j DROP -A INPUT -p tcp -j REJECT --reject-with tcp-reset -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable -A INPUT -j LOG --log-prefix "INPUT/poubelle: " #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # F O R W A R D #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Suivi de communication chaîne FORWARD -A FORWARD -p icmp -m conntrack --ctstate ESTABLISHED -j ACCEPT -A FORWARD -p icmp -m conntrack --ctstate RELATED --icmp-type destination-unreachable -j ACCEPT -A FORWARD -p icmp -m conntrack --ctstate RELATED --icmp-type time-exceeded -j ACCEPT -A FORWARD -p ospf -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -p udp -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -p tcp -m conntrack --ctstate ESTABLISHED -m tcp ! --syn -j ACCEPT -A FORWARD -p tcp -m conntrack --ctstate RELATED -m tcp --syn -j ACCEPT # Boucle locale -A FORWARD -i lo -j ACCEPT # Salles de TP -A FORWARD -i eth1+ -p tcp -m tcp --syn --sport 1024: -m conntrack --ctstate NEW -j ACCEPT -A FORWARD -i eth1+ -p udp --sport 1024: -m conntrack --ctstate NEW -j ACCEPT -A FORWARD -i eth1+ -p icmp --icmp-type echo-request -m limit --limit 5/sec -m conntrack --ctstate NEW -j ACCEPT # Poubelle -A FORWARD -m conntrack --ctstate INVALID -m limit --limit 5/min -j LOG --log-prefix "FORWARD/rejected.iptables: " -A FORWARD -m conntrack --ctstate INVALID -j DROP -A FORWARD -p tcp -j REJECT --reject-with tcp-reset -A FORWARD -p udp -j REJECT --reject-with icmp-port-unreachable -A FORWARD -j LOG --log-prefix "FORWARD/poubelle: " #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # O U T P U T #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Règles anti-fuites -A OUTPUT -o eth0 -p tcp --dport 135:139 -j DROP -A OUTPUT -o eth0 -p tcp --dport 445 -j DROP -A OUTPUT -o eth0 -p udp --dport 135:139 -j DROP -A OUTPUT -o eth0 -p udp --dport 445 -j DROP -A OUTPUT -o eth0 -p tcp --dport 25 -j DROP -A OUTPUT -o eth0 -p tcp -m multiport --sports 20,21,23,25,53,80,110,113 -j DROP -A OUTPUT -o eth0 -s 127.0.0.0/8 -j LOG --log-prefix "OUTPUT/rejected.nat: " -A OUTPUT -o eth0 -s 127.0.0.0/8 -j DROP -A OUTPUT -o eth0 -s 10.0.0.0/8 -j LOG --log-prefix "OUTPUT/rejected.nat: " -A OUTPUT -o eth0 -s 10.0.0.0/8 -j DROP -A OUTPUT -o eth0 -s 172.16.0.0/12 -j LOG --log-prefix "OUTPUT/rejected.nat: " -A OUTPUT -o eth0 -s 172.16.0.0/12 -j DROP -A OUTPUT -o eth0 -s 192.168.0.0/16 -j LOG --log-prefix "OUTPUT/rejected.nat: " -A OUTPUT -o eth0 -s 192.168.0.0/16 -j DROP -A OUTPUT -o eth0 -s 224.0.0.0/8 -j DROP -A OUTPUT -m conntrack --ctstate INVALID -j LOG --log-prefix "OUTPUT/rejected.iptables: " -A OUTPUT -m conntrack --ctstate INVALID -j DROP COMMIT
Sur le système illustré, ce script nommé active
est placé dans le répertoire /var/lib/iptables/
. On applique les règles
contenues dans ce fichier à l'aide de la commande
.#
iptables-restore
</var/lib/iptables/active
Pour plus de détails sur la rédaction de ce genre de script, on peut consulter le support Introduction au filtrage réseau et surtout le Tutoriel Iptables.
Pour valider le fonctionnement de l'interception de trafic Web, il suffit de visualiser les compteurs de paquets pour lesquels il y a eu correspondance avec une règle de filtrage.
-
Pour la règle d'interception proprement dite, le compte des paquets traités dans la chaîne
PREROUTING
doit évoluer.# iptables -t nat -vL PREROUTING | grep REDIRECT 16 1216 REDIRECT udp -- eth1+ any anywhere anywhere udp dpt:ntp redir ports 123 11 528 REDIRECT tcp -- eth1+ any anywhere anywhere tcp dpt:www redir ports 3128
-
Pour l'utilisation du service mandataire Web proxy, on doit retrouver le même compte du nombre de paquets dans la chaîne
INPUT
.# iptables -vL INPUT |grep 3128 11 528 ACCEPT tcp -- eth1+ any anywhere anywhere tcp dpt:3128 flags:FIN,SYN,RST,ACK/SYN state NEW
-
Enfin, les journaux doivent montrer qu'il y a bien eu sollicitation du service.
# tail /var/log/squid3/access.log 1226421464.379 60869 172.16.48.64 TCP_MISS/200 925 POST \ http://update.microsoft.com/v6/UpdateRegulationService/UpdateRegulation.asmx \ - DIRECT/207.46.17.93 text/xml 1226422061.838 48 172.16.48.65 TCP_MISS/200 407 HEAD \ http://download.windowsupdate.com/v8/windowsupdate/redir/muv3wuredir.cab? \ - DIRECT/204.160.98.121 application/octet-stream 1226422062.528 670 172.16.48.65 TCP_MISS/200 407 HEAD \ http://update.microsoft.com/v8/windowsupdate/selfupdate/wuident.cab? \ - DIRECT/65.55.184.93 application/octet-stream 1226422062.563 24 172.16.48.65 TCP_MISS/200 408 HEAD \ http://download.windowsupdate.com/v8/windowsupdate/a/selfupdate/WSUS3/x86/Other/wsus3setup.cab? \ - DIRECT/204.160.98.121 application/octet-stream 1226422062.680 114 172.16.48.65 TCP_MISS/200 25492 GET \ http://download.windowsupdate.com/v8/windowsupdate/a/selfupdate/WSUS3/x86/Other/wsus3setup.cab? \ - DIRECT/204.160.98.121 application/octet-stream 1226422065.039 24 172.16.48.65 TCP_REFRESH_UNMODIFIED/200 405 HEAD \ http://download.windowsupdate.com/v8/windowsupdate/redir/muv3wuredir.cab? \ - DIRECT/204.160.98.121 application/octet-stream 1226422069.106 35 172.16.48.65 TCP_REFRESH_UNMODIFIED/200 406 HEAD \ http://download.windowsupdate.com/v8/windowsupdate/redir/muv3wuredir.cab? \ - DIRECT/205.128.69.124 application/octet-stream