Konfiguracja serwera Apache - serwery wirtualne

Zobacz jeszcze ten artykuł

Piotr Tęczyński

Niniejszy tekst prezentuje podstawowe pojęcia i jedną z metod konfiguracji serwerów wirtualnych w oparciu o serwer Apache w środowisku Unix. Wybór serwera Apache został podyktowany jego popularnością, wybór zaś środowiska Unix jest oczywisty i naturalny.

Cel ćwiczenia
Hydra, czyli szczypta teorii
Wakeman, czyli podróż do wnętrza... serwera
Listonosz vel pocztowy agent transportowy
Literatura zalecana

Cel ćwiczenia

Cel ćwiczenia jest jasno określony i pozornie prosty: ustawienie i konfiguracja serwerów wirtualnych na serwerze Apache. Pozorna łatwość wynika z faktu, iż konfiguracja takiego miejsca wykracza poza konfigurację samego serwera Apache. Innymi słowy, by miejsce takie poprawnie i sprawnie funkcjonowało, trzeba skonfigurować również i np. interfejsy kart sieciowych (jeśli wybierzemy takie rozwiązanie) czy pocztę elektroniczną. W większym ośrodku czynności te należą zwykle do zadań administratora danego systemu, w mniejszym czy też zwyczajnie w domowym zaciszu webmaster(ka) sam(a) będzie musiał(a)... dobra, my tu gadu gadu, a pora wreszcie zakasać rękawy do pracy.

Precyzyjniej zatem rzecz ujmując chcemy, by nasz serwer umożliwiał nadanie naszemu oczku Pajęczyny wielu nazw:

http://www.firma1.com/   # Pierwsza firma...
http://www.firma2.com/   # I następna...
. . .                    # O to niech się już martwi dział marketingu :-)

Na zakończenie tej części dwie uwagi techniczne:

Hydra, czyli szczypta teorii

Serwery wirtualne to metoda umożliwiająca pojedynczej instancji serwera (nie tylko Apache) Pajęczyny udostępnienie wielu adresów URI, przy czym każde takie miejsce posiada własny adres domenowy. Idea ta przypomina tę znaną z sieci jako NAT (Network Address Translation), która w świecie linuksowym znana jest bardziej pod nazwą masqueradingu. Innymi słowy, za pomocą serwerów wirtualnych dana instancja serwera Apache "maskuje" rzeczywiste odniesienia, co w konsekwencji daje złudzenie, iż w rzeczywistości mamy do czynienia z większą liczbą różnych serwerów dostępnych pod różnymi adresami domenowymi.

Historycznie rzecz biorąc, "klasyczne" podejście polegało na tym, iż albo instalowało się pojedynczą instancję serwera na odzielnych komputerach, albo też uruchamiało się wiele instancji pojedynczego serwera na jednej maszynie.

Oczywiście, można zastosować i podejście takie:

http://www.domena.com/firma/

Inną metodą było stosowanie podejścia "stron domowych". URI takiego miejsca przedstawiało się następująco:

http://www.domena.com/~firma/

O ile podejście takie może być stosowne względem lokalnych użytkowników, podejście to jest całkiem nie do przyjęcia z punktu widzenia firm i korporacji (także marketingowo). Rzecz jasna, z wielu względów takie podejście było również zwyczajnie nieefektywne.

By rozwiązać te niedogodności, opracowano metodę serwerów wirtualnych w oparciu o adres IP. Przy tej metodzie dany serwer może odpowiadać na zapytania skierowane do wielu adresów IP. Z drugiej jednak strony wirtualne serwery oparte o adres IP wymagają (poza konfiguracją samego serwera Apache) umieszczenia w maszynie wielu kart sieciowych (i/lub stworzenia stosownej liczby dowiązań do już posiadanej liczby owych kart), przypisaniu im różnych adresów IP, ewentualnie ustawieniu trasowania, w końcu zaś powiadomieniu DNS-a o tym fakcie:

. . .
www.firma1.com   IN  A 192.168.0.1
www.firma2.com   IN  A 192.168.0.2
. . .

W Sieci/intranecie powyższe odwzorowanie przyjmuje nastepującą postać:

http://192.168.0.1/   # http://www.firma1.com/
http://192.168.0.2/   # http://www.firma2.com/
. . .                 # Mozolna praca admina... :-)

Wirtualne serwery oparte o adress IP oznaczają zatem dwie rzeczy. Po pierwsze, dana maszyna musi posiadać różne adresy IP dla każdego wirtualnego hosta. Po wtóre zaś, przy tym podejściu większość pracy wykonuje administrator systemu, nie zaś sam webmaster.

Protokół HTTP/1.1 wprowadził metodę umożliwiającą serwerowi Pajęczyny określenie, jakiego adresu dotyczy zapytanie przeglądarki. Innymi słowy, serwer Pajęczyny wie, pod jakim adresem postrzega go przeglądarka. Począwszy od wersji 1.1 serwer Apache obsługuje to podejście, zwane zwykle metodą serwerów wirtualnych w oparciu o nazwę. Waro jednak mieć na uwadze, iż niektóre (nie tylko) co starsze przeglądarki nie będą udostępniały możliwości dostępu do serwera Apache skonfigurowanego do obsługi serwerów opartych o nazwę.

I to właśnie podejście stanie się przedmiotem dalszego naszego zainteresowania. Zwróćmy uwagę na pewne pozytywne strony omawianego podejścia:

Wakeman, czyli podróż do wnętrza... serwera

Powróćmy do naszego sprawdzonego schematu sprzed miesiąca. Po wprowadzeniu zmian stosownych do realizacji celu naszego ćwiczenia będzie się on obecnie przedstawiał następująco (w nawiasach podano oznaczenia skrótowe):

/usr/local/apache       # ServerRoot (APACHE)
. . .
/www/firma1/htdocs      # http://www.firma1.com/
/www/firma2/htdocs      # http://www.firma2.com/
. . .
/var/log/www            # pliki rejestracyjne (LOG)
. . .

Tak jak i poprzednio będziemy stosowali wyłącznie i tylko jeden plik konfiguracyjny, mianowicie $APACHE/conf/httpd.conf. Uczyńmy zatem stosowne wpisy dla naszych wirtualnych serwerów:

. . .
NameVirtualHost 192.168.0.1:80

<VirtualHost 192.168.0.1>
ServerName www.firma1.com
DocumentRoot /www/firma1/htdocs
TransferLog /var/log/www/access_log.firma1
ErrorLog /var/log/www/error_log.firma1
</VirtualHost>

<VirtualHost 192.168.0.1>
ServerName www.firma2.com
DocumentRoot /www/firma2/htdocs
TransferLog /var/log/www/access_log.firma2
ErrorLog /var/log/www/error_log.firma2
</VirtualHost>
. . .

NameVirtualHost
Dyrektywa wymagana przy konfiguracji w oparciu o metodę nazw symbolicznych. Określa ona adres do którego odnoszą się wirtualne serwery (w powyższym przykładzie 192.168.0.1). Choć adres można podawać w postaci symbolicznej zalecane jest stosowanie adresów IP. Jeśli przydziela się wirtualne serwery do wielu adresów IP, wówczas należy powtórzyć tę dyrektywę oddzielnie dla każdego adresu IP.
Uwaga: zastosowanie tej dyrektywy podwoduje, iż wszystkie zapytania skierowane pod ten adres będą się odnosiły wyłącznie i tylko do serwerów wirtualnych o parametrach określonych przez <VirtualHost . . . > . . . </VirtualHost>. Innymi słowy, trzeba dodać sekcję <VirtualHost> dla wszystkich zarządzanych serwerów, włączając w to "serwer główny".

<VirtualHost . . . > . . . </VirtualHost>
Deklaracja ta wskazuje na początek i koniec sekcji poświęconej danemu serwerowi wirtualnemu (jego definicja). Atrybutem w tej sekcji jest adres wirtualnego serwera. Adresem może być adres IP lub adres symboliczny. Z pewnych względów zaleca się stosowanie adresów IP. Opcjonalnie można zastosować numer portu.

ServerName
Dyrektywa przypisująca symboliczną nazwę wirtualnego serwera. Opcjonalna, choć również z pewnych istotnych względów zalecana.

TranswerLog

ErrorLog
Dyrektywy te zostały omówione na łamach Webmastera w poprzednim miesiącu, nie mam zatem potrzeby ich ponownego przedstawiania. Zauważmy jedynie, iż każdy wirtualny serwer może posiadać własne pliki rejestracyjne.

I... to wszystko, a nawet i więcej niż jest niezbędne do podstawowej konfiguracji. Może z wyjątkiem jednego, mianowicie poprawych wpisów w DNS-ie, co jednak wykracza poza ramy niniejszego tekstu.

Na jedno wszak zagadnienie chciałbym jeszcze zwrócić uwagę. Czasami istnieje potrzeba, by dany serwer wirtualny był widoczny pod wieloma nazwami (np. pajeczyna.firma1.com). Potrzeba taka może być podyktowana choćby względami marketingowymi czy przyzwyczajeniami klientów. Druga strona medalu (zwłaszcza w intranetach) jest taka, iż użytkownicy przyzwyczaili się wpisywać krótką nazwe (bez domeny, np. www). Rozwiązanie tego problemu stanowi dyrektywa ServerAlias. Stanowi ona ogólny sposób określania wielu nazw dla jednego i tego samego serwera wirtualnego. Przykładowo:

<VirtualHost 192.168.0.1>
. . .
ServerName www.firma1.com
ServerAlias www pajeczyna.firma1.com
. . .
</VirtualHost>

<VirtualHost 192.168.0.1>
. . .
ServerName www.firma2.com
ServerAlias *.firma2.com
. . .
</VirtualHost>

Drugi z wpisów ilustruje zasadę, iż równie dobrze można stosować znaki globalne. Rzecz jasna, dla każdego dowiązania trzeba posiadać stosowne wpisy w plikach konfiguracyjnych DNS-a. W zaciszu domowym jako namiastkę możemy zastosować odpowiednie wpisy w pliku /etc/hosts.

Listonosz vel pocztowy agent transportowy

Nie będę owijał w bawełnę: konfiguracja poczty elektronicznej to nie przelewki. Teoretycznie rzecz ujmując, nasze zadanie sprowadza się do odwzorowania adresów poczty elektronicznej z określonych domen serwerów wirtualnych na odpowiednie "rzeczywiste" skrzynki pocztowe. Zatem do dzieła.

Uwaga techniczna: wszystkie poniższe przykłady opierają się o program sendmail V8 z tego mianowicie powodu, iż wydaje się on być zwyczajnie najpopularniejszy. Ponadto nie należy zapominać, iż poniższe rozwiązanie jest skrajnie uproszczone w stosunku do zwykle rzeczywistych wymagań. Jednakże jest ono kompletne i daje przedsmak tego, co może czekać webmastera...

Na początek zauważmy, iż dla wirtualnych serwerów możemy posiadać nastepującą deklarację:

<VirtualHost 192.168.0.1>
. . .
ServerAdmin webmaster@firma1.com   # webmaster@serwer.domena.com
. . .
</VirtualHost>

Ponadto chcemy jeszcze uzyskać następujące odwzorowania:

boss@firma1.com  --> szef@serwer.domena.com  # Adres naszego serwera
biuro@firma2.com --> biuro@inny.serwer.com   # Obcy :-)

Zakładam, iz dokonano odpowiednich wpisów w DNS-ie lub choćby ćwiczebnie w pliku /etc/hosts. Tak zatem najpierw utworzymy plik (powiedzmy /etc/sendmail.cw) zawierający wszystkie dowiązania do naszego serwera (serwer.domena.com):

# echo firma1.com  >> /etc/sendmail.cw
# echo firma2.com  >> /etc/sendmail.cw

Zwykle jest to ustawienie domyślne, jednakże upewnijmy się, iż plik konfiguracyjny sendmaila zawiera następujący wpis (jeśli nie, umieśćmy go w nim):

$ grep Fw/etc/sendmail.cw /etc/sendmail.cf

Tworzymy plik (powiedzmy /etc/mail/virtusertable) odwzorowujący identyfikatory "wirtualnych" klientów na klientów "rzeczywistych":

# echo "webmaster@firma1.com webmaster@serwer.domena.com" >> /etc/mail/virtusertable 
# echo "boss@firma1.com boss@serwer.domena.com" >> /etc/mail/virtusertable 
# echo "biuro@firma2.com biuro@inny.serwer.com" >> /etc/mail/virtusertable

Następnie tworzymy zindeksowaną bazę o nazwie virtusertable.db:

# makemap hash virtusertable.db < virtusertable

Użytkownik boss jest tak postrzegany wyłącznie i tylko dla świata zewnętrznego - u nas nosi on nazwę szef. Musimy zatem odwzorować jeden identyfikator na drugi. Uczynimy to za pomocą pliku /etc/aliases. Kwestię co począć z identyfikatorem webmaster pozostawiam do własnych przemyśleń.

# echo "boss: szef" >> /etc/aliases

Prawie gotowe. Pozostaje jeszcze zrestartować program sendmail:

# killall -HUP sendmail

Referencje

Doskonałym punktem wyjścia jest sam podręcznik dostarczany razem z serwerem Apache. Proponuje zatem zacząć od przeczytania dokumentu $APACHE/htdocs/manual/vhosts/index.html. I eksperymentować. I doskonale się przy tym wszystkim bawić!



Piotr Tęczyński