HTTPS to dobra rzecz. Dzięki ochronie kryptograficznej zapewnianej przez SSL/TLS dostajemy ochronę przed podsłuchaniem i modyfikacją a dodatkowo możemy potwierdzać tożsamość stron zaangażowanych w komunikację.
Wirtualne site'y (będę posługiwać się tym nieładnym słowem, bo znane mi polskie odpowiedniki są kulawe) to też dobra rzecz. Jeden serwer webowy może obsłużyć naprawdę dużo zupełnie niezależnych portali czy stron. Ruch do nich możemy rozseparować używając różnych adresów IP (kłopotliwe w realiach hostingu), różnych portów (kłopotliwe dla klientów) lub poprzez Host Headers, czyli dzięki wykorzystaniu nagłówka, który przeglądarka wysyła do serwera razem z każdym żądaniem. Serwer odczytuje ten nagłówek i wie, do którego site'u powinno zostać skierowane żądanie. Dzięki Host Headers, na jednym adresie IP i na jednym porcie możemy uruchomić ogromną ilość site'ów i kto pamięta rozgrzewkę przed Quiz2008, ten wie że siedmiocyfrowe liczby są tu zupełnie prosto osiągalne.
Problem jednak pojawia się w sytuacji, gdy wymienione powyżej zalety zechcemy połączyć. Jeżeli szyfrujemy transmisję, to szyfrowane będą i nagłówki Host. A rozszyfrować je umie tylko wirtualny site, dla którego są przeznaczone. Tyle, że póki ich nie rozszyfrujemy, to nie wiadomo, któremu je wysłać... W efekcie chcąc mieć na jednym serwerze kilka site'ów obsługujących HTTPS, musimy w praktyce używać wielu adresów IP a to zwykle nie jest OK choćby dlatego, że marnie się skaluje. Teoretycznie istnieje rozwiązanie ale praktyczne jego zastosowania są bardzo ograniczone i prawie na pewno nie sprawdzą się w scenariuszach hostingowych.
Istnieje też rozwiązanie drugie – przesłać ten jeden nagłówek w postaci niezaszyfrowanej. Da się tak zrobić przy wykorzystaniu rozszerzeń protokołu TLS. Nazywa się to Server Name Identification (SNI) i opisane jest w RFC6066.
Na przykład, dla serwera alice.sni.velox.ch, nawiązanie transmisji (TLS Client Hello) wygląda tak:
Jak widać, wśród listy rozszerzeń protokołu znalazł się rozszerzenie "Server Name" zawierające potrzebną serwerowi informację.
A gdybyśmy chcieli coś takiego zrobić na serwerze IIS? Używam IISa od wersji 2.0 i przyznam się, że nieraz mi tego brakowało. Nauczyłem się (jak to w IT) jakoś sobie radzić, ale od pewnego czasu mam do czynienia z IIS w wersji 8 i wbudowane wsparcie dla SNI jest naprawdę miłą funkcjonalnością. Aby skorzystać z jego dobrodziejstw, wystarczy domyślna instalacja IIS. Tworząc nowy site, wybieramy że ma być podpięty pod https, wskazujemy certyfikat, podajemy host header i gotowe. Działa od razu.
Oczywiście jak to bywa z szyfrowaniem w warstwie aplikacji, wszystkie funkcjonalności powinny być wspierane i przez serwer i przez przeglądarkę. A co, jeżeli nie jest, bo użytkownik nadal uważa, że nastoletni już Windows XP jest zupełnie OK? Który site dostanie żądanie? Ten, który pasuje adresem IP i portem, ale nie ma zaznaczonej opcji "Require Server Name Identification". Dla klienta prawdopodobnie skończy się to ostrzeżeniem o certyfikacie z niezgodną nazwą i raczej nieoczekiwaną stroną w przeglądarce, ale bez problemu da się to rozsądnie poukładać, jeżeli tylko ktoś ma taką potrzebę. Oczywiście odznaczenie tej opcji dla więcej niż jednego site'u na tym samym adresie i porcie nie jest możliwe.
Skoro już mowa o certyfikatach w IIS8, to wypada wspomnieć jeszcze kilka drobiazgów:
- dostępny w konsoli zarządzającej widok certyfikatów pozwala na ich pogrupowanie według daty wygaśnięcia. Jeżeli mamy jeden czy dwa site'y z SSLem, to da się żyć i bez tego. Jednak tam, gdzie są ich dziesiątki, funkcjonalność robi się całkiem użyteczna. Wiem, że da się inaczej, ale tak jest po prostu wygodnie.
- store certyfikatów komputera ma nowy kontener "Web Hosting" – certyfikaty, które tam się znajdują działają tak samo jak certyfikaty z "Personal", jednak różnica daje się zauważyć w wydajności. Kontener "Web Hosting" przygotowany jest do pracy z setkami albo tysiącami certyfikatów. "Personal" – niekoniecznie.
- certyfikaty ładowane są do pamięci wtedy, gdy są faktycznie potrzebne, bo ktoś używa ich do zabezpieczenia transmisji z konkretnym site. Brzmi to trywialnie, jednak w starszych IISach ładowane były wszystkie "na zapas". Ponieważ nie było SNI, to certyfikatów nie było zwykle dużo i nie było to kłopotem. W IIS8 podejście zostało zmienione i wydaje się, że ma to swój sens.
Ostatnia nowość to CCS czyli Central Certificate Store. W przeciwieństwie do SNI wymaga doinstalowania jako składnika roli IIS.
CCS to jeden centralny "worek" na certyfikaty w formacie *.pfx. Mogą do niego sięgać wszystkie skonfigurowane serwery i jeżeli tylko dla danego site da się połączyć nazwę hosta z nazwą pliku pfx – IIS sam skorzysta z certyfikatów w centralnym repozytorium. Jeżeli dany site ma korzystać z CCS, to oczywiście w jego przypadku ręczny wybór certyfikatu staje się niedostępny.
Jak się nietrudno domyśleć, użycie CCS wymaga, aby hasło do *.pfx było takie samo dla wszystkich plików.
Zalety Central Certificate Store wydają się interesujące: łatwa wymiana certyfikatów dla wszystkich serwerów na raz, proste tworzenie dostępnych przez HTTPS site'ów, uproszczone dodawanie certyfikatów i podłączanie ich do site'ów... Choć jest to ciekawe, to nie jestem osobiście przekonany czy bardzo użyteczne. Jeżeli mamy tak dużo site'ów że nie zarządzamy nimi "ręcznie" to mamy do tego zestaw skryptów i automaty. Dodanie w takim przypadku linijki albo dwóch po to, żeby zajęły się certyfikatami nie jest poważnym problemem. Ale funkcjonalność jest dostępna i może komuś się przyda.
Podsumowując nowości dotyczące wsparcia IIS8 dla HTTPS trzeba zwrócić uwagę na kierunek wprowadzonych zmian. Praktycznie wszystkie zorientowane są na wsparcie (funkcjonalnością, wydajnością albo wygodą zarządzania) dla dużych środowisk, gdzie działać może naprawdę wiele wirtualnych serwerów dostępnych przez ten protokół. Wydaje się to całkiem interesujące i z pewnością otwiera nowe możliwości. Warto przyjrzeć się bliżej.
Autor: Grzegorz Tworek [MVP]