Více SSL certifikátů na jediné IP adrese
Dříve bylo nutností vyhradit pro každou zabezpečenou doménu vlastní IP adresu. To ovšem bylo velmi nepraktické zejména pro poskytovatele hostingových služeb, kteří museli přiřadit vlastní IP adresu pro každý VirtualHost, který chtěl zákazník zabezpečit SSL certifikátem. Na sdílené IP adrese pak bylo možné zabezpečit více VirtualHostů jen za předpokladu, že byl použit jiný (nestandardní) port než 443 (HTTPS) — to je ovšem také nepraktické, protože by uživatel musel na danou stránku přistupovat se znalostí konkrétního čísla portu (například https://www.alpiro.cz:12345/). Zároveň by přístup vůbec nebyl možný například v internetových kavárnách a na firemních sítích, kde jsou nestandardní porty blokovány.
Navíc dnes, kdy již IPv4 adresy prakticky nejsou nazbyt, mohou roční náklady na vlastní IPv4 adresu překročit náklady na samotné SSL certifikáty dokonce až několikanásobně. Lze to však vyřešit i s jedinou sdílenou IP adresou, a přitom to není žádná novinka ani žádná velká věda — je to velice jednoduché.
Rozšíření SSL protokolu
Řešení přichází s rozšířením SSL protokolu nazývaném SNI (Server Name Indication se specifikací v RFC 4366), které klientskému počítači umožňuje na začátku komunikace se serverem připojit název hostitele. Použitím SNI rozšíření (Apache mod_ssl) tedy můžete na jedné IP adrese sdílet více VirtualHostů a pro každý mít vlastní SSL certifikát.
Co potřebuji pro SNI řešení?
Na straně serveru toho moc dělat nemusíte — níže uvedené nastavení je předpokladem a ve valné většině případů postačí výchozí nastavení aktuálních verzí Apache a OpenSSL.
- OpenSSL verze 0.9.8k, která již má ve výchozí konfiguraci povolené TLS rozšíření. Podpora TLS je možná již u OpenSSL verze 0.9.8f, ovšem s ruční konfigurací. Verzi OpenSSL zjistíte jednoduchým příkazem openssl version.
- Apache server musí být nakofigurován s podporou mod_ssl a běžet jako run-time (init.d) proces.
Podpora SNI je potřeba i ze strany webového prohlížeče na klientském počítači. SNI podporují:
- Google Chrome,
- Firefox 2.0 a novější,
- Safari 3.2.1 a novější,
- Internet Explorer 7.0 a novější (na operačním systému XP musí být nainstalován Service Pack 3) i
- Opera 8.0 s povolenou podporou TLS a novější.
Jak ověřím podporu SNI na serveru?
Nejprve vytvořte dva různé VirtualHosty se sdílenou IP adresou a přiřaďte každé svůj vlastní SSL certifikát. Jak to udělat, se dočtete ve článku Instalace SSL.
Ověření podpory SNI na serveru pak závisí na typu chybové hlášky. Pakliže server při startu hlásí "You should not use name-based virtual hosts in conjunction with SSL!", pak byl Apache nakonfigurován bez podpory SNI rozšíření. Naopak pokud je Apache správně nakonfigurován s podporou SNI, mělo by se objevit varovné hlášení ve znění podobnému tomuto: "[warn] Init: Name-based SSL virtual hosts only work for clients with TLS server name indication support (RFC 4366)".
Jiným problémem by bylo, kdyby se v Apache log souboru objevilo "[error] No hostname was provided via SNI for a name based virtual host" — to by šlo o chybějící podporu SNI ve webovém prohlížeči klientského počítače. S tím bychom se dnes ovšem již setkat neměli, nanejvýš by se jednalo o uživatele zastaralých Internet Explorer na již nepodporovaném systému Windows XP (Windows Vista, 7 a 8 mají plnou podporu SNI zabudovanou). V takovém případě bude požadavek při výchozí konfiguraci Apache zpracován jako kdyby SNI podporu neměl (tedy standardním způsobem bez SNI).
Konfigurace serveru s podporou SNI
Ujistěte se, že Apache naslouchá na portu 443 (HTTPS) a že naslouchá pro všechny VirtualHosty na portu 443:
Listen 443
NameVirtualHost *:443
Ujistíme se, že server bude přijímat i požadavky od webových prohlížečů bez podpory SNI přidáním následující direktivy:
SSLStrictSNIVHostCheck off
První definovaný VirtualHost je výchozí — ten bude vyřizovat požadavky, které neodpovídají ServerName žádného jiného VirtualHosta:
<VirtualHost *:443>
DocumentRoot /public_html/www.alpiro.cz
ServerName www.alpiro.cz
# Ostatní direktivy...
</VirtualHost>
Následovat pak mohou ostatní VirtualHosty:
<VirtualHost *:443>
DocumentRoot /public_html/www.alpiro.info
ServerName www.alpiro.info
# Ostatní direktivy...
</VirtualHost>
Jak to spojení vůbec probíhá?
Ze všecho nejdříve Apache na základě požadavku klientského počítače standardní cestou ověří přítomnost nastavení odpovídající IP adresy a portu standardní cestou bez SNI rozšíření (na bázi IP/port).
Poté Apache ověří přítomnost NameVirtualHost, který musí být uveden před prvním VirtualHost. Pokud odpovídající NameVirtualHost není přítomný, Apache nemůže pokračovat ve výběru z VirtualHostů pomocí SNI.
Pakliže TLS požadavek na spojení od klientského počítače obsahuje i název hostitele, Apache jej porovná s hodnotami direktiv ServerName a ServerAlias ve VirtualHostech a následně vybere první odpovídající VirtualHost.
Takové spojení tedy neprobíhá na základě požadavku v HTTP hlavičce, ale na základě informací v TLS požadavku. Za poznámku stojí skutečnost, že se při tomto procesu nedbá na obsah samotných SSL certifikátů — ověření validity SSL certifikátu probíhá až potom.