Apache i wirtualne hosty – czyli dyrektywy Listen, NameVirtualHost, VirtualHost, DocumentRoot, DirectoryIndex, Directory, Allow, Deny i Order

Serwer Apache umożliwia przyjazną administratorowi konfigurację wirtualnych hostów. Jest ona nie tylko przyjazna, ale również banalnie prosta i niezwykle elastyczna. Ale jest jeden warunek – żeby skonfigurować wirtualne hosty trzeba wiedzieć, czym one w ogóle są. Dlatego zaczniemy od początku…

Przeanalizujmy najpierw sytuację, w której nie istniało by coś takie jak wirtualne hosty. Sytuacja ta odpowiada temu, jak laicy widzą łączenie się ze stroną WWW. Przeglądarka chce się połączyć ze stroną o adresie www.stronka.pl, więc najpierw zamienia za pomocą serwerów DNS adres na numer IP (przykładowo 123.123.123.123), a następnie łączy się z tym serwerem na porcie 80 i w odpowiedzi otrzymuje stronę WWW – np. oficjalną stronę jakiejś firmy. Sytuacja ta jest łatwa do wyobrażenia i przejrzysta, lecz ma jedną bardzo dużą wadę – jest bardzo niepraktyczna, gdyż dla każdej kolejne strony WWW trzeba by stawiać kolejny serwer z kolejnym adresem IP. Dlatego właśnie powstała koncepcja wirtualnych hostów.

Gdy przeglądarka chce połączyć się z serwerem WWW, aby pobrać stronę (np. http://www.stronka.pl/index.html) wysyła do niej żądanie, które może wyglądać podobnie do poniższego.

GET /index.html HTTP/1.1
Host: www.stronka.pl

Jak widać, przeglądarka podaje plik, który chce pobrać oraz podaje adres (host) strony, z jaką się właśnie łączy. Po co przeglądarka podaje serwerowi informację o tym, pod jakim adresem ten serwer jest, skoro sam pewnie dysponuje takową informacją? Ano po to, gdyż inna przeglądarka może do tego samego serwera wysłać zapytanie o innej postaci.

GET /index.html HTTP/1.1
Host: www.inna_stronka.pl

Czyli do tego samego serwera dociera żądanie wyświetlenia strony o adresie http://www.inna_stronka.pl/index.html. Taka konstrukcja zapytań sprawia, że na jeden serwer (o jednym numerze IP) można przekierować kilka różnych domen i każda będzie rozróżniana właśnie dzięki polu Host w zapytaniu.

Żeby zobrazować to, co chcę pokazać, posłużymy się lokalnie ustawionym serwerem WWW, czyli localhost. W tym celu wprowadzimy małą modyfikację w pliku hosts. Dopiszemy do niego (o ile ich tam nie ma) dwie linie o poniższej postaci.

127.0.0.1       localhost
127.0.0.1       local

Dzięki temu, system zamiast odpytywać serwery DNS o dwa powyższe adresy, od razu będzie łączyć się z lokalnym hostem, czyli sam ze sobą. Tyle tytułem wstępu. Teraz przechodzimy do skonfigurowania przykładowych wirtualnych hostów na serwerze Apache. Poniższe wpisy umieszczamy oczywiście w pliku httpd.conf (np. na jego końcu), który znajduje się w folderze Apacha, w podkatalogu \conf. Po każdej zmianie należy oczywiście zresetować serwer (nie komputer, ale serwer WWW).

Listen 127.0.0.1:80
NameVirtualHost 127.0.0.1:80
 
<VirtualHost 127.0.0.1:80>
	ServerName localhost
	DocumentRoot "C:\wamp\www\strona1"
	DirectoryIndex index.php
</VirtualHost>
 
<VirtualHost 127.0.0.1:80>
	ServerName local
	DocumentRoot "C:\wamp\www\strona2"
	DirectoryIndex index.html
</VirtualHost>

Polecenie Listen nakazuje Apachowi nasłuchiwanie na porcie 80 żądań kierowanych na adres IP 127.0.0.1. Dyrektywa ta jest pomocna, gdy mamy więcej kart sieciowych o różnych adresach IP. Drugie polecenie NameVirtualHost nakazuje włączenie obsługi wirtualnych hostów na tym samym IP i tym samym porcie. Dalej mamy już konfigurację wirtualnych hostów.

Gdy żądanie będzie skierowane do hosta localhost to żądane pliki będą poszukiwane w podfolderach katalogu C:\wamp\www\strona1, a jeżeli nie będzie podany żadny konkretny plik (czyli zażądamy http://localhost) to zwrócony zostanie nam plik index.php, czyli plik C:\wamp\www\strona1\index.php.

Gdy żądanie będzie skierowane do hosta local to żądane pliki będą poszukiwane w podfolderach katalogu C:\wamp\www\strona2, a jeżeli nie będzie podany żadny konkretny plik (czyli zażądamy http://local) to zwrócony zostanie nam plik index.html, czyli plik C:\wamp\www\strona1\index.html.

Możemy to teraz sprawdzić w przeglądarce. Gdy wpiszemy adres http://localhost to otrzymamy jeden plik, a gdy zażądamy http://local to otrzymamy drugi plik. Teraz bardziej rozbudowana wersja.

Listen 127.0.0.1:80
NameVirtualHost 127.0.0.1:80
 
<VirtualHost 127.0.0.1:80>
	ServerName localhost
	DocumentRoot "C:\wamp\www\strona1"
	DirectoryIndex index.php
	<Directory "C:\wamp\www\strona1">
		Order deny,allow
		Deny from All
		Allow from 127.0.0.1
	</Directory>
</VirtualHost>
 
<VirtualHost 127.0.0.1:80>
	ServerName local
	DocumentRoot "C:\wamp\www\strona2"
	DirectoryIndex index.html
	<Directory "C:\wamp\www\strona2">
		Allow from All
	</Directory>
</VirtualHost>

W pierwszym przypadku doszedł poniższy fragment.

<Directory "C:\wamp\www\strona1">
	Order deny,allow
	Deny from All
	Allow from 127.0.0.1
</Directory>

Oznacza on, że dla tego wirtualnego hosta w kolejności – najpierw zakazy, później zezwolenia – zabraniamy wszystkim dostępu do podanego folderu, ale zezwalamy na taki dostęp nam – czyli z adresu IP 127.0.0.1. W drugim przypadku doszedł krótszy fragment.

<Directory "C:\wamp\www\strona2">
	Allow from All
</Directory>

Tym rozkazem, zezwalamy wszystkim na dostęp do tego folderu niezależnie z jakiego adresu IP się łączą. Jest to oczywiście tylko w ramach przykładu, gdyż i tak nikt inny nie połączy się z naszym serwerem wirtualnym, gdyż nasłuchuje on na lokalnym numerze IP 127.0.0.1.

Oczywiście rozkazów i możliwości jest o wiele więcej, ale przedstawione powyżej pozwolą na podstawową konfigurację.