Doc provenant de www.bug-fr.org
Les développeurs d'OpenBSD sont de grands hackers dont l'imagination ne cessera
de nous étonner. Il est cependant un domaine où elle est particulièrement
active, c'est celui du firewall PF. Lors du hackathon 2003, ces braves
messieurs ont pensé à ajouter un mécanisme très innovant nommé synproxy. Ils
avaient déjà auparavant ajouté la fonction 'modulate state' qui permettait
d'utiliser le firewall pour réécrire l'ISN TCP de manière fortement aléatoire
en début de connexion pour des hôtes, du réseau protégé par PF, dont l'OS
n'offrirait pas de PRNG suffisamment puissant. En combinant cette fonction au
classique 'keep state', ils ont alors eu l'idée d'ajouter, à partir d'OpenBSD
3.4, un mécanisme de synproxy dont le concept rejoint en tout point les
fonctions mises en oeuvre par Cisco dans TCP Intercept.
Le principe de fonctionnement est simple. Lorsqu'un hôte TCP décide
d'initialiser une transmission TCP, c'est-à-dire qu'il est l'extrêmité active,
PF, au lieu de faire suivre le segment SYN en conservant en mémoire l'état de
la connexion pour laisser passer la réponse, va terminer le 3WHS au nom du
destinataire original, l'extrêmité passive, en y ajoutant une meilleure
randomization de l'ISN (comportement hérité de 'modulate state'). Dans le même
temps, PF va également lancer un 3WHS complet vers l'extrêmité active, au nom
de l'extrêmité active, toujours en faisant profiter d'un renforcement du choix
de l'ISN. Vous le voyez, PF applique donc une véritable attaque de type
man-in-the-middle (MITM) entre les deux hôtes.
La protection provient du fait que PF ne laisser effectivement passer les
données que si l'extrêmité active répond correctement en complétant le 3WHS
depuis l'adresse donnée dans le segment SYN. Ainsi, si l'extrêmité passive
était en réalité menacée d'un SYN flood, celui-ci sera intercepté par PF qui,
ne parvenant pas à conclure le 3WHS, rejettera la demande de connexion. De
cette façon, l'extrêmité passive ne prend à aucun instant part à
l'initialisation de la transmission, conservant toutes ses ressources mémoire
et processeur pour des connexions légitimes.
Même sur le firewall lui-même peu de ressources supplémentaires sont utilisées.
En effet, le mécanisme mis en oeuvre pour faire suivre les segments, une fois
le 3WHS réussi des deux côtés de la transmission, est le même que pour
'modulate state', c'est-à-dire une simple différence sur 32 bits entre les ISN
des paires active/firewall et firewall/passive. Vous ajoutez même ici à la
protection contre les DoS et le spoofing, un renforcement de la génération
d'ISNs.
Pour appliquer ce mécanisme à vos transmission TCP, il suffit d'utiliser le
mot-clé 'synproxy state' comme ci-dessous :
pass in proto tcp from any to any flags S/SA synproxy state
Une limitation introduite et évidente est que cette technique ne peut pas
fonctionner si vous utilisez PF en tant que bridge firewall. Cela casserait
toute logique de tout pouvoir envoyer des segments depuis une machine dont le
code au-dessus du layer 2 a été inhibé. Il peut par contre être intéressant
de faire varier les valeurs de timeouts pour l'initialisation de la
transmission en fonction de la position de l'interface, interne ou externe
(en utilisant éventuellement des tags pour simplifier le ruleset). Vous
pourrez ainsi décider de laisser suffisament de temps aux machines
internes tout en utilisant des timeouts agressifs vis-à-vis du monde
extérieur afin de ne pas laisser votre firewall attendre trop longtemps.
pass in on $extif proto tcp from any to any flags S/SA synproxy state \
{ set timeout tcp.first 10 } tag extOK
pass on ! $extif tagged extOK
pass in on $intif proto tcp from any to any flags S/SA synproxy state \
{ set timeout tcp.first 30 } tag intOK
pass on ! $intif tagged intOK