Pour faire court, cet ACK a été envoyé alors que la socket n'appartenait à personne. Au lieu d'autoriser les paquets appartenant à un socket appartenant à l'utilisateur x
, autorise les paquets qui se rapportent à une connexion initiée par un socket de l'utilisateur x
.
L'histoire plus longue.
Pour comprendre le problème, il est utile de comprendre comment wget
et les requêtes HTTP fonctionnent en général.
Dans
wget http://cachefly.cachefly.net/10mb.test
wget
établit une connexion TCP à cachefly.cachefly.net
, et une fois établi envoie une requête dans le protocole HTTP qui dit :"Veuillez m'envoyer le contenu de /10mb.test
(GET /10mb.test HTTP/1.1
) et au fait, pourriez-vous s'il vous plaît ne pas fermer la connexion une fois que vous avez terminé (Connection: Keep-alive
). La raison en est que si le serveur répond avec une redirection pour une URL sur la même adresse IP, il peut réutiliser la connexion.
Maintenant, le serveur peut répondre soit "Voici les données que vous avez demandées, attention elles font 10 Mo (Content-Length: 10485760
), et oui OK, je laisse la connexion ouverte". Ou s'il ne connaît pas la taille des données, "Voici les données, désolé je ne peux pas laisser la connexion ouverte mais je te dirai quand tu pourras arrêter de télécharger les données en fermant ma fin de connexion".
Dans l'URL ci-dessus, nous sommes dans le premier cas.
Donc, dès que wget
a obtenu les en-têtes de la réponse, il sait que son travail est terminé une fois qu'il a téléchargé 10 Mo de données.
En gros, qu'est-ce que wget
fait est de lire les données jusqu'à ce que 10 Mo aient été reçus et de quitter. Mais à ce stade, il y a plus à faire. Et le serveur ? Il a été dit de laisser la connexion ouverte.
Avant de quitter, wget
ferme (close
appel système) le descripteur de fichier pour le socket. Sur, le close
, le système termine l'acquittement des données envoyées par le serveur et envoie un FIN
dire :"Je n'enverrai plus de données". À ce stade close
renvoie et wget
sorties. Il n'y a plus de socket associé à la connexion TCP (du moins pas un socket appartenant à un utilisateur). Cependant ce n'est pas encore fini. Dès réception de ce FIN
, le serveur HTTP voit fin de fichier lors de la lecture de la prochaine requête du client. En HTTP, cela signifie "plus de requête, je ferme ma fin". Il envoie donc également son FIN, pour dire :"Je n'enverrai rien non plus, cette connexion s'en va".
Dès réception de ce FIN, le client envoie un "ACK". Mais, à ce stade, wget
est révolu depuis longtemps, de sorte que ACK ne provient d'aucun utilisateur. C'est pourquoi il est bloqué par votre pare-feu. Parce que le serveur ne reçoit pas l'ACK, il va envoyer le FIN encore et encore jusqu'à ce qu'il abandonne et vous verrez plus d'ACK abandonnés. Cela signifie également qu'en supprimant ces ACK, vous utilisez inutilement les ressources du serveur (qui doit maintenir un socket dans l'état LAST-ACK) pendant un certain temps.
Le comportement aurait été différent si le client n'avait pas demandé "Keep-alive" ou si le serveur n'avait pas répondu par "Keep-alive".
Comme déjà mentionné, si vous utilisez le suivi de connexion, ce que vous voulez faire est de laisser passer chaque paquet dans les états ESTABLISHED et RELATED et de ne vous soucier que de NEW
paquets.
Si vous autorisez NEW
paquets de l'utilisateur x
mais pas les paquets de l'utilisateur y
, puis d'autres paquets pour les connexions établies par l'utilisateur x
passera, et parce qu'il ne peut pas y avoir de connexions établies par l'utilisateur y
(puisque nous bloquons le NEW
paquets qui établiraient la connexion), il n'y aura pas de paquet pour l'utilisateur y
connexions en cours.
Cela autorise le port 80 en sortie uniquement pour le compte "useraccount"
- eh bien, au moins les règles que vous avez montrées n'impliquent pas cela, en fait.
Il y a aussi une salle pour les conseils - ne faites pas de vérification utilisateur sur les flux ESTABLISHED, faites simplement cette vérification sur NEW. Je ne vois pas non plus l'intérêt de vérifier le port source lors de la vérification de Incoming ESTABLISHED, quelle est la différence de quel port il s'agissait, il est déjà dans l'état ESTABLISHED du PoV de conntrack. Le pare-feu doit être aussi simple que possible mais efficace, c'est pourquoi l'approche rasoir d'Occam est la meilleure solution.