-15% na nową książkę sekuraka: Wprowadzenie do bezpieczeństwa IT. Przy zamówieniu podaj kod: 10000

Wysokodostępna i wydajna architektura dla LAMP – tutorial (cz. 3.)

04 grudnia 2013, 08:17 | Teksty | komentarzy 15
W tej części poświęconej budowaniu i konfigurowaniu wysokodostępnej i wydajnej architektury dla LAMP zaprezentuję kolejny testowany przeze mnie element:

  • serwery aplikacyjne – Apache, LightHTTPd, IIS, Nginx.

Zapraszam do lektury innych części cyklu (część 1., część 2.).

 

Serwery aplikacyjne – Apache, LightHTTPd, IIS, Nginx, NodeJS

Istotną częścią naszej układanki są serwery aplikacyjne, na których osadzone będą strony WWW. Ponieważ nie miałem z góry określonej technologii wykonania aplikacji WWW, postanowiłem podejść do tematu bardziej ogólnie i sprawdzić różne serwery HTTP dostępne na rynku oraz możliwość ich współpracy z haproxy.

1. Podział  zadań na konkretne serwery

Postanowiłem, że sprawdzę serwery, które umożliwiają serwowanie stron napisanych w językach / frameworkach takich jak: HTML, PHP, Django, JS, .NET.

Większość z Was na pewno spotkało się z tymi nazwami: Apache, Nginx, IIS oraz z trochę mniej popularnymi: LightHTTPd oraz NodeJS. Przetestowanie ich pod kątem działania z haproxy pozwoli mi na stwierdzenie, czy aplikacje napisane w dowolnej technologii będą działały w omawianym środowisku.

Celowo pominąłem aplikacje pisane w języku Java, ponieważ miałem pewność, że u mnie nie wystąpi taka aplikacja. Drugim powodem, dla którego nie testowałem stron WWW napisanych w tym języku, jest fakt, że serwery aplikacyjne: JBoss, Apache/Tomcat posiadają swoje mechanizmy do klastrowania.

Założyłem, że aplikacje napisane w PHP, Django będą serwowane przez Apache, pliki statyczne oraz HTML przez Nginxa lub LightHTTPd, aplikacje webowe napisane w ASP.NET zostaną uruchomione na serwerach IIS, natomiast strony w technologii JS będą serwowane przez NodeJS.

2.   Serwery HTTP i ich możliwości

  • Apache – jest najbardziej znanym i najczęściej stosowanym serwerem HTTP w Internecie. Posiada bardzo dużo modułów, działa stabilnie i pozwala na bardzo skomplikowane konfiguracje. Nadaje się idealnie do serwowania stron napisanych w PHP (niektóre strony nie działają dobrze z php jako fastcgi i wtedy chyba najlepszym rozwiązaniem jest właśnie użycie Apache) oraz Django, RoR itd.
  • Nginx – bardzo szybki, wymagający o wiele mniejszych zasobów sprzętowych niż Apache, pozwala na obsługę PHP w trybie fastcgi, głównie stosowany jest do serwowania kontentu statycznego.
  • LightHTTPd – bardzo lekki, szybki serwer HTTP, obsługujący PHP w trybie fastcgi oraz języki takie jak: Python, Perl, RoR, Lua. Obsługuje bardzo dużą liczbę jednoczesnych połączeń z jednym serwerem (około 10 000). Zdecydowałem się na użycie go jako zamiennika dla Nginxa.
  • IIS – jest zbiorem usług internetowych dla systemów z rodziny MS Windows pełniącym funkcje serwera FTP, HTTP, HTTPS, NNTP, SMTP. IIS HTTP/S. Stosowany jest głównie do serwowania storn napisanych w technologii ASP.NET i taką funkcję będzie pełnił w opisywanej architekturze.
  • Node.js – to środowisko programistyczne zaprojektowane do tworzenia wysoce skalowalnych aplikacji internetowych, szczególnie serwerów HTTP napisanych w języku JavaScript. Node.js umożliwia tworzenie aplikacji sterowanych zdarzeniami wykorzystującymi asynchroniczny system wejścia-wyjścia.

 3. Konfiguracja serwerów aplikacyjnych

Postanowiłem nie opisywać tutaj konfiguracji serwerów HTTP, bo nie o to chodzi w całym doświadczeniu. Ponadto zastosowane przeze mnie rozszerzenia, dodatki mogą być niepotrzebne w przypadku zastosowania innej aplikacji WWW. Chciałbym zwrócić uwagę na kilka szczegółów, które mogą mieć wpływ na szybkość działania samych serwerów oraz po części na bezpieczeństwo.

Jako dobrą praktykę proponuję wyłączyć wszystkie niepotrzebne moduły, dodatkowe ustawienia, z których nie korzystamy. Serwer dostaje wtedy skrzydeł (przynajmniej jest to zauważalne w przypadku Apache), zużywa o wiele mniej zasobów systemowych (RAM), daje napastnikowi mniejszą szansę na znalezienie podatności.

Jeżeli planujemy współdzielić źródła stron WWW z jednego miejsca pomiędzy serwery takie jak np.: Apache i Nginx, pamiętajmy o zablokowaniu dostępu do takich plików jak: .htaccess (serwer Nginx tych plików nie obsługuje). Podobnie sprawa wygląda z plikami i katalogami GIT, SVN itp. – mogą one zdradzić informacje wrażliwe dla napastnika (swoją drogą polecam też sekurakowy tekst o kilku prostych sposobach zabezpieczania aplikacji webowych + tag: websecurity).

Pragnę również zwrócić uwagę na to, że skonfigurowanie w podobny sposób wszystkich serwerów z jednej rodziny pozwoli nam na łatwiejsze zarządzanie całą infrastrukturą. Do zarządzania serwerami polecam użycie takich narzędzi jak Puppet. Do monitoringu świetnie sprawdzają się Nagios, Munin, Zabbix, które pozwolą na późniejsze dostrojenie parametrów serwerów.

4. NFS, SMB – współdzielenie źródeł aplikacji

Skoro mamy już zainstalowane i skonfigurowane całe środowisko do serwowania strony lub stron WWW,przyszedł czas, aby zastanowić się, w jaki sposób będziemy dystrybuować kod źródłowy na poszczególne serwery. Przyszły mi do głowy dwa sposoby:

  • wspólny zasób dla wszystkich serwerów,
  • przechowywanie źródeł lokalnie na każdym serwerze.

Pierwsze podejście jest dość ciekawe i kuszące, ponieważ ułatwia zarządzanie źródłami, czyli: wgrywanie nowych stron, aktualizowanie już działających, oszczędność przestrzeni dyskowej. Wadami, jakie zauważyłem, będzie dość duży problem w przypadku włamania na jeden z serwerów, ponieważ automatycznie wszystkie serwery zaczynają serwować zainfekowaną stronę. Kolejnym utrudnieniem będzie brak możliwości wgrania nowej wersji aplikacji na jeden z serwerów (lub zmiana konfiguracji samego serwera), wyłączenie ruchu klientów do niego i finalne przetestowanie w środowisku produkcyjnym, co może okazać się w niektórych przypadkach bardzo cenną zaletą.

Drugi z proponowanych sposobów do zarządzania źródłami aplikacji wydaje się o wiele lepszy niż wspólne źródła dla wszystkich serwerów, ale co w przypadku aplikacji z dużą liczbą np.: plików multimedialnych. Waga źródeł może dochodzić wtedy czasami nawet do wartości w okolicy kilkuset gigabajtów, duplikacja takiej ilości danych pomiędzy serwerami nie jest optymalnym rozwiązaniem.

Złotym środkiem wydaje się powielanie stron, które nie „ważą” zbyt wiele na każdym z serwerów, zaś strony ciężkie serwować z macierzy za pomocą NFS lub SMB. Można spróbować też oddzielić pliki multimedialne z cięższych stron, a sam kod aplikacji powielić, lecz w niektórych przypadkach może okazać się to dość skomplikowane w realizacji.

5. Testowanie poprawnej obsługi przez haproxy

Gdy całe środowisko już działa, przyszedł czas na testy. Znalazłem proste sposoby, aby sprawdzić skuteczność działania tak zainstalowanego środowiska. Narzędzia, których użyłem do realizacji tego celu, to: FireBug oraz CookiEditor, dodatki dostępne dla przeglądarki Firefox. Przed przystąpieniem do testowania należy pamiętać o umieszczeniu plików check.txt w głównym katalogu strony – to z ich pomocą haproxy będzie badał, czy serwer działa poprawnie.

  1. Pierwszy test polegał na wyłączaniu backendów oraz sprawdzaniu ich statusów na stronie monitoringu wbudowanej w HAProxy, w plikach konfiguracyjnych, które załączone zostały do poprzedniej części, oraz zalogowaniu się na: root:toor. Oczywiście wystarczy zatrzymać serwer HTTP, a HAProxy powinno oznaczyć serwer jako nieaktywny oraz zaprzestać kierowania do niego ruchu klientów. Po ponownym włączeniu serwera HTTP HAProxy wykrywa poprawne działanie serwera i zaczyna ponownie wysyłać do niego klientów.
  2. Drugi test to sprawdzenie w dodatku Firebug, z jakiego serwera są serwowane różne rodzaje plików. Jeżeli konfiguracja działa poprawnie, w nagłówkach zapytań o pliki PHP w polu Server powinna widnieć nazwa Apache, natomiast przy plikach takich jak .js,css,png,jpg itp. powinniśmy zauważyć, że w polu Server widnieje nazwa Nginx lub LightHTTPd. Jeżeli zaobserwowaliście działanie opisane powyżej, oznacza to, że HAProxy(ACL) zostało skonfigurowane poprawnie i ruch jest dzielony w taki sposób, jak to sobie założyliśmy, czyli skrypty PHP/Django itp. obsługuje Apache, a pliki statyczne Nginx/LightHTTPd.
  3. Ostatnim testem było sprawdzenie, czy sesja jest powiązana z jednym serwerem i co się stanie w przypadku wyłączenia serwera, do którego jesteśmy przypisani. Zrealizować to można w łatwy sposób przez edycję plików cookie. Można tu wykorzystać dodatek do przeglądarki Firefox o nazwie Cookie Editor. W plikach konfiguracyjnych dołączonych do części poświęconej HAProxy możemy zauważyć, że HAProxy rozróżnia serwery przy pomocy wstrzykiwanego ciasteczka o parametrze: IDA: A01/A02/… dla serwerów aplikacyjnych oraz IDS:S01/S02/… Aby sprawdzić, czy jesteśmy powiązani z jednym serwerem, wystarczy odwiedzić witrynę kilka razy, przeklikać ją i monitorować, czy wartość ciasteczka się nie zmieniła. Jeżeli ciasteczko ma taką samą wartość przez cały czas, oznacza to, że HAProxy trzyma sesję użytkownika z dobranymi przy pierwszych odwiedzinach serwerami. Aby sprawdzić, co się stanie, gdy nagle serwer, na którym pracujemy, przejdzie w tryb offline, wystarczy zmienić wartość ciasteczka, np. z IDA:A01 na IDA:02, i obserwować, jak zareaguje nasza witryna.

Musze przyznać, że nie testowałem konfiguracji HAProxy w połączeniu z serwerem IIS, jednak w Internecie są dostępne artykuły na ten temat. Jeżeli ktoś stosuję taką konfigurację, proszę o opinię na temat jej działania w komentarzach.

 

W następnej części podzielę się informacjami na temat testów i obserwacji o serwerze DB oraz sposobie konfiguracji NFS oraz napiszę kilka słów o instalacji WordPressa w omawianej infrastrukturze.

– OiSiS [oisisk<sekurak>gmail.com]

Spodobał Ci się wpis? Podziel się nim ze znajomymi:



Komentarze

  1. Dawid

    Nie zapomnij napisać gdy już piszesz o wspolnym storagu, o glusterfs, unionfs itp.

    Odpowiedz
  2. Przemek

    „Przetestowanie ich pod kontem działania”

    tak na szybko: kątem :)

    Odpowiedz
    • Poprawione, dzięki i proszę o więcej ;)

      Odpowiedz
  3. Darek

    Fantastyczna seria! Czekam na kolejną część :)

    Odpowiedz
  4. KAMIL

    Django to nie język programowania tylko webowy framework do pythona. PS. świetny tekst, czekam na więcej :)

    Odpowiedz
  5. OiSiS

    @józek
    To nie ja :). Zmiana planu juz dawno a kopalnia juz odpalona LTC. Nic gorszego niz marnujaca sie moc :).

    Odpowiedz
  6. józek

    @OiSiS
    O czyli widzę, że moje zdanie tutaj się jednak choć troszkę liczy ;)
    Mogę dorzucić jakiegoś laptopa, albo ze trzy (ewentualnie siedem) do LTC. Daj znać jeśli byłbyś wannable, to napiszę Ci na maila, bo w sumie minerowanie Lite w Polsce leży i kwiczy, więc w sumie czemu by z tego nie uszczknąć ;)

    Odpowiedz
  7. OiSiS

    @józek
    Czekam na maila(oisiskgmail.com). Kopalnia już pracuje od tygodnia. Bloku nie ma ale rusza z kopyta w od pon-wto(czekam na sprzęt).

    Odpowiedz
  8. kulu

    Nie wszedzie nginx nie obsluguje .htaccess…na mydevil.net i 2ap.pl maja obsluge .htaccess i to bez „trybu” nginx jako proxy dla apache.

    Odpowiedz
  9. OiSiS

    @kulu
    No ok ale to raczej mało spotykana konfiguracja dlatego pojawiło się takie info.

    Odpowiedz
  10. Andrew

    Kawał dobrej roboty. Nawet jeśli nie zastosuje tej wiedzy w praktyce, dobrze mieć świadomość tego jak skonstruowana jest architektura, która serwuje mój kod.
    P.S.
    „czy sesja jest powiązana do jednego serwer” – chyba „z jednym serwerem”.

    Odpowiedz
  11. Eryk

    Widze ze temat poszedl na boczny tor ad akta? :)

    Odpowiedz
  12. OiSiS

    @Eryk:
    Jeżeli będzie zainteresowanie tematem, to może „po latach” uda mi się znaleźć trochę czasu i dokończyć arta.

    Odpowiedz

Odpowiedz na józek