Abych to zkrátil, ACK bylo odesláno, když zásuvka nikomu nepatřila. Místo povolení paketů, které se týkají soketu, který patří uživateli x
, povolit pakety, které se týkají připojení, které bylo iniciováno soketem od uživatele x
.
Delší příběh.
Abyste problému porozuměli, pomůže vám pochopit, jak wget
a požadavky HTTP obecně fungují.
V
wget http://cachefly.cachefly.net/10mb.test
wget
naváže TCP spojení na cachefly.cachefly.net
a po vytvoření odešle v protokolu HTTP požadavek, který říká:„Pošlete mi prosím obsah /10mb.test
(GET /10mb.test HTTP/1.1
) a mimochodem, mohl byste prosím neuzavírat připojení poté, co budete hotovi (Connection: Keep-alive
). Důvodem je to, že v případě, že server odpoví přesměrováním na URL na stejné IP adrese, může znovu použít připojení.
Nyní může server odpovědět buď:"zde jsou data, která jste požadovali, pozor, jsou velká 10 MB (Content-Length: 10485760
), a ano OK, nechám připojení otevřené." Nebo pokud nezná velikost dat, "Tady jsou data, omlouvám se, nemohu nechat připojení otevřené, ale řeknu vám, kdy budete moci zastavit stahování dat uzavřením mého konce připojení."
Ve výše uvedené adrese URL jsme v prvním případě.
Takže, jakmile wget
získal záhlaví pro odpověď, ví, že jeho úloha je hotová, jakmile stáhne 10 MB dat.
V podstatě co wget
čte data, dokud není přijato 10 MB a ukončí se. Ale v tu chvíli je třeba udělat víc. A co server? Bylo řečeno, aby připojení zůstalo otevřené.
Před ukončením wget
zavře (close
systémové volání) deskriptor souboru pro soket. Poté close
, systém dokončí potvrzení dat odeslaných serverem a odešle FIN
říci:„Nebudu posílat žádná další data“. V tom okamžiku close
vrátí a wget
východy. K připojení TCP již není přidružen žádný soket (alespoň ne žádný, který by vlastnil žádný uživatel). Ještě však není hotovo. Po obdržení tohoto FIN
, HTTP server vidí konec souboru při čtení dalšího požadavku od klienta. V HTTP to znamená „žádný další požadavek, zavřu svůj konec“. Odešle tedy také své FIN, aby řekl:"Taky nebudu nic posílat, to spojení končí."
Po obdržení tohoto FIN klient odešle "ACK". Ale v tom okamžiku wget
je dávno pryč, takže ACK není od žádného uživatele. To je důvod, proč je blokován vaším firewallem. Protože server nepřijímá ACK, bude posílat FIN znovu a znovu, dokud to nevzdá a neuvidíte více vynechaných ACK. To také znamená, že zrušením těchto ACK zbytečně nějakou dobu využíváte prostředky serveru (který potřebuje udržovat soket ve stavu LAST-ACK).
Chování by bylo jiné, kdyby klient nepožadoval „Keep-alive“ nebo server neodpověděl „Keep-alive“.
Jak již bylo zmíněno, pokud používáte tracker připojení, co chcete udělat, je nechat projít každý paket ve stavu ESTABLISHED a RELATED a starat se pouze o NEW
pakety.
Pokud povolíte NEW
pakety od uživatele x
ale ne pakety od uživatele y
, pak další pakety pro navázaná spojení uživatelem x
projde a protože uživatel nemůže navázat spojení y
(protože blokujeme NEW
pakety, které by navázaly spojení), pro uživatele y
nebude žádný paket spojení procházející.
To umožňuje port 80 ven pouze pro účet "useraccount"
— No, alespoň pravidla, která jste ukázal, to ve skutečnosti nenaznačují.
Je zde také prostor pro radu – neprovádějte uživatelskou kontrolu u ESTABLISHED streamů, ale pouze u NOVÝCH. Také nevidím smysl v kontrole zdrojového portu při kontrole Incoming ESTABLISHED, jaký je rozdíl, který port to byl, ten je již ve stavu ESTABLISHED z PoV conntracku. Firewall by měl být co nejjednodušší, ale přesto efektivní, takže Occamův přístup jako břitva je nejvhodnější.