Tuesday, March 30, 2010

Optymalizacja zapory dzięki mechanizmowi filtrowania z pamięcią stanu

Jedną z najważniejszych technologii wdrożonych do zapory ogniowej iptables przez netfilter.org jest filtrowanie z pamięcią stanu SPI (ang. Stateful Packet Inspection). Jest to mechanizm charakteryzujący rozwiązania programowe z najwyższej półki w tej dziedzinie informatyki. Dlatego warto przyjrzeć mu się bliżej.
Sam cel wprowadzenia takiej techniki wiązał się z optymalizacją filtrowania. Dzięki śledzeniu stanów połączeń zapora może podejmować decyzje na podstawie tylko pierwszego pakietu, kolejne odziedziczą ją i nie będą musiały być również sprawdzane (mechanizm ten nie ogranicza się tylko do sesji TCP).
Aby uzmysłowić sobie jaki to krok na przód w wydajności zapory należy przeanalizować statystyki zapory działającej dłuższy czas w średniej wielkości sieci. Służy do tego opcje:

iptables -L -nv --line-numbers

Z moich wyliczeń (statystyki pochodzą z wdrożonej na serwerze produkcyjnym zapory dla sieci ok. 100 komputerów) wynika, że 97,87% pakietów jest dopasowywanych do pierwszej reguły, która przepuszcza pakiety należące do sesji/połączeń już nawiązanych. Czyli tylko 2.13% pakietów jest dopasowywanych do kolejnych reguł. Daje to duże przyzwolenie na bardziej złożone filtrowanie. Sprawdzanie ok. 2% wszystkich pakietów nawet przez setkę reguł w takiej sytuacji nie powinno rzucać cienia na wydajność zapory. Oczywiście wyniki te w dużej mierze zależne są od specyfiki sieci i usług, z których przeważnie się w niej korzysta.

Ponadto okazuje się, że zbiegiem okoliczności wcale nie powinno nam zależeć na szybkość przetwarzania nowych połączeń. Dobrym tego przykładem jest limitowanie pakietów TCP z ustawioną flagą SYN w celu ochrony przed atakami DoS, DDoS - czyli SYN flood. Tak więc w tej sytuacji czas jest po naszej stronie.

Optymalizacja zapory sprowadza się w znacznym stopniu do optymalnego wykorzystania mechanizmu stanu pakietów. Pokaże teraz przykład który moim zdaniem jest najoptymalniejszy. Najpierw jednak należy wymienić wszystkie stany jakie pakietowi mogą być przypisane:
  • NEW – pakiety, które tworzą nowe połączenie
  • ESTABLISHED – pakiety, które należą do nawiązanego połączenia
  • RELATED – pakiety tworzące nowe połączenie związane z już istniejącym połączeniem
  • INVALID – pakiety, które nie należą do żadnego nawiązanego połączenia lub poprawnego połączenia
Teraz przedstawię przykładową konfigurację optymalnej zapory dla łańcuch FORWARD jaką udało mi się opracować. Zapora została przetestowana na systemie testowym zainstalowanym na maszynie wirtualnej, który pracuje w roli routera dla drugiego systemu z maszyny wirtualnej. Zapora obejmuje tylko jedną usługę - HTTP (80/tcp) oraz niezbędny DNS (53/udp). Domyślna polityka łańcucha FORWARD ustawiona jest na DROP:

iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -A FORWARD -s 192.168.0.0/16 -p udp --dport 53 -m state --state NEW -j ACCEPT
iptables -A FORWARD -s 192.168.0.0/16 -p tcp --dport 80 --syn  -m state --state NEW -j ACCEPT

iptables -A FORWARD -p icmp -m state --state NEW -j ACCEPT
iptables -A FORWARD -m state --state INVALID  -j DROP
iptables -A FORWARD -j LOG --log-prefix "DROP_FORWARD " --log-tcp-options --log-ip-options --log-tcp-sequence

Jak widzimy ostatecznie co nie jest przepuszczane zostanie zalogowane. Bardzo interesujące jest to, w którym miejscu została wstawiona reguła dot. pakietów z ustawionym stanem INVALID. Michael Rash (twórca takich projektów jak psad oraz fwsnort) w swojej książce "Bezpieczeństwo sieci w Linuksie. Wykrywanie ataków i obrona przed nimi za pomocą iptables, psad i fwsnort" w przykładowej polityce bezpieczeństwa, która jest bardzo podobna do tej przedstawionej regułę dot. pakietów INVALID umieścił na samym początku. Powoduje to, że wszystkie ok. 97% pakietów należących do już nawiązanych połączeń musi jeszcze przejść przez tą regułę, podczas gdy z moich statystyk wynika, że ilość pakietów w stanie INVALID to tylko nieco ponad 1% całego ruch. Czy zatem konieczne jest dodawanie kolejnego warunku dla 97% aby odrzucić 1% niepoprawnych pakietów na samym początku zapory? Okazuje się że nie, i jest na to sposób, który przedstawiłem w zaprezentowanym przykładzie. Jest tylko jeden warunek, który należy spełnić aby nie wprowadzić reguły dot. pakietów w stanie INVALID na samym początku. Warunkiem tym jest to, że każda reguła musi korzystać z modułu stat i mieć przypisany jeden ze stanów.
Co mogło by się stać, gdyby tak nie było? Prosty przykład. Załóżmy, że w regule trzeciej dot. protokołu HTTP nie określiliśmy stanu NEW. Pakiet, który np. niespodziewanie zawiera flagę FIN, na dodatek jego numer sekwencyjny nie pasuje do prowadzonych sesji przez stos TCP/IP został by przepuszczony, ponieważ kierowany jest na port 80/tcp. Tylko wprowadzenie do reguły stanu NEW powstrzymuje taki pakiet przed dopasowaniem i zmuszenie go do dalszej drogi po regułach. Ponieważ pakietów tych jest nieco ponad 1% wypadałoby im przebyć najdłuższa drogę po regułach. W przedstawionym przykładzie tak też się dzieje. Ponieważ na początku szukamy pakietów ze stanem ESTABLISHED i RELATED więc pakiet INVALID nie może zostać dopasowany. Następnie możemy posiadać całą setkę reguł ze stanem NEW i pakiety ze stanem INVALID nadal nie mogą być dopasowane - zmuszamy je do dalszej drogi.  Ostatecznie pakiety nienależące do żadnego znanego połączenia trafiają na swoją regułę i dopiero tu zostają odrzucone. Dzięki temu pakiety ESTABLISHED oraz RELATED, które stanowią ok. 97% ruchu oszczędzają jeden warunek.
Teraz spójrzmy na wyniki prostej testowej zapory:

brama:~# iptables -L -vn --line-numbers
Chain INPUT (policy ACCEPT 24072 packets, 2033K bytes)
num   pkts bytes target     prot opt in     out     source               destination          

Chain FORWARD (policy DROP 79 packets, 4198 bytes)
num   pkts bytes target     prot opt in     out     source               destination        
1    15376 8512K ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED
2      653 40697 ACCEPT     udp  --  *      *       192.168.0.0/16       0.0.0.0/0           udp dpt:53 state NEW
3      497 24700 ACCEPT     tcp  --  *      *       192.168.0.0/16       0.0.0.0/0           tcp dpt:80 flags:0x17/0x02 state NEW    
4        2   120 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           state NEW          
5       12   480 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0           state INVALID
6       79  4198 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0           LOG flags 7 level 4 prefix `DROP_FORWARD '

Chain OUTPUT (policy ACCEPT 17478 packets, 4444K bytes)
num   pkts bytes target     prot opt in     out     source               destination

Możemy tu zauważyć jak optymalna jest konfiguracja reguł. są ułożone w kolejności od najczęściej dopasowanych oraz najważniejszych do najmniej dopasowanych i najmniej ważnych. Żaden pakiet nie przybierze stanu, którego nie użyliśmy. Ponieważ każda z reguł posiada przypisany stan, to stan ten wyklucza wszystkie pozostałe zmuszając je do dalszej wędrówki po regułach w celu dopasowania. Wśród reguł dot. usług HTTP oraz DNS można zauważyć, że ta druga powinna mieć zdecydowanie wyższy priorytet niż pierwsza.
Ostatecznym celem było skonfigurowanie zapory w taki sposób, aby pakiety występujące najczęściej miały najkrótszą drogę do przebycia przez reguły w danym łańcuchu. Wygląda na to, że udano nam się zminimalizować tą drogę i tym samym zoptymalizować zaporę ogniową dzięki mechanizmowi filtrowania z pamięcią stanu.

Saturday, March 27, 2010

Compiz Fusion - trzy najefektywniejsze pluginy

Compiz Fusion od dawna nie jest niczym nadzwyczajnym, wręcz przeciwnie stał się pospolitą paczką. Jednak na początku 2007 r. za sprawą filmów umieszczonych na YouTube, głównie jednego z pierwszych pt. "Compiz Fusion: A Quick Demonstration" Compiz Fusion stał się przedmiotem pożądania niemal wszystkich linuksiarzy (zwłaszcza tych nieszczęśliwców posiadających karty graficzne ATI) oraz przedmiotem zazdrości użytkowników systemu Windows, którzy jak dotychczas wyśmiewali się z tych pierwszych, przynajmniej do 2007 r. i premiery Visty.
Dziś, gdy emocje już opadły, a użytkownikom systemów GNU/Linux oraz innych UNIX-ów np. *BSD efekty oferowane przez technologię 3D za pośrednictwem OpenGL przejadły się, migracje pseudo linuksiarzy zakończyła się, projekt przyhamował z rozwojem - nie głównie przez przepisywanie go w nowym języku C++ - nadszedł najwyższy czas, aby luźnym okiem ocenić co rzeczywiście osiągnięto.
Sam jestem użytkownikiem Compiz Fusion od dwóch lat. W początkowej fazie oswajania się z oferowanymi "cudami" - bo inaczej tego nie nazwę - dążyłem do otrzymania najefektywniejszego pulpitu. Jednak, czy o to w tym wszystkim chodzi? Oczywiście, że nie. Gdy już człowiek się nasyci tym, o czym niegdyś mógł tylko śnić (pamiętajmy, że większość efektów pierwotnie została wymyślona w interfejsie graficznym Mac OS X) zaczyna się zastanawiać czy trzęsące się jak garaleta okna rzeczywiście komuś do czegoś służą i pomagają. Osobiście w swojej konfiguracji wyłączyłem niemal wszystkie efekty oprócz kilku najistotniejszych, głównie są nimi:
  1. Scale Addons - skalowanie okien: jest to chyba zdecydowanie najczęściej używany przeze mnie plugin, przyznaje mu ostara za skrócenie czasu pracy z wieloma oknami. Dzięki niemu praca w takim środowisku, zwłaszcza gdy musimy się przełączać między aplikacjami np. aby sprawdzić wyniki naszej pracy, rzucić okiem kto jest dostępny na GG lub wybrać kolejny kawałek w Rhythmbox użytkowanie pulpitu staje się szybsze i wygodniejsze.
  2. Expo - ekspozycja pulpitów: ten plugin powinien otrzymać dwa oskary, a właściwie jeden - za połączenie efektywności z użytecznością. Jego przydatność jest tak samo argumentowana jak skalowania okien. Różnica polega tylko na tym, że robi on to na poziomie trochę wyższym, pozawala przełączać się między pulpitami, a nie oknami w obrębie jednego pulpitu. Najczęściej używam go do przełączania się miedzy macierzystym pulpitem mojego systemu a pulpitem systemu uruchomionego na wirtualnej maszynie jaką jest VirtualBox, trwa to dosłownie 2 sekundy i już jestem na Win 7 lub po prosu zajmuję się czym innym na odrębnym pulpicie.

  3. Enhanced Zoom Desktop - powiększanie pulpitu: ostatnio wymieniony plugin otrzymuje oskara za dbanie o zdrowie moich oczu. Zamiast przysuwać głowę do monitora, można zrobić zuma. Jeżeli czytasz jakiś tekst, który na ekranie zajmuje zazwyczaj ok. 60% szerokości twojego ekranu nie ma żadnego powodu aby nie wcisnąć klawisza super i ruszyć skrolem do przodu. W końcu tyle czasu spędzamy przed komputerem przeglądając treści oferowane przez internet.

Oczywiście nie są to wszystkie pluginy, których używam. Zaraz, zaraz. To są wszystkie, pozostałe trzy mam tylko włączone. Niemniej jednak, mimo iż używam zdecydowanej mniejszości dostępnych pluginów uważam, że są one tak ważne, że projektowi Compiz Fusion należy się oskar za największy krok do przodu w dziedzinie ergonomii oraz efektów pulpitów użytkowników domowych systemów UNIX na przestrzeni 3 ostatnich lat.
Nie da się ukryć, że rewolucji której dokonał ten projekt uwidoczniła drzemiące możliwości niedocenianego środowiska graficznego jakim jest GNOME. Brakuje mi takich możliwości w pracy, gdzie zajmuje się wieloma wątkami jednocześnie, że tak powiem i oddzielny pulpit byłby jak najlepszy prezent od Microsoftu, ale oni nie dają prezentów, sami wymuszają na programistach/użytkownikach systemu, aby zrobili to za nich.
Ciekaw jestem waszych najefektywniejszych pluginów oraz nowych wersji mojego ulubionego menadżera okien jakim jest Compiz Fusion.