8. L'interception du trafic Web

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