Mnoho dnešních služeb využívá protokol HTTP/HTTPS. V .NET Frameworku pro vytváření takových služeb nyní máme k dispozici hned dvě technologie: WCF (Windows Communication Foundation) a ASP.NET Web API. Obě tyto technologie umožňují hostování buď na IIS (Internet Information Services) nebo jako Self host (service host). V druhém případě pak služba není vůbec na IIS závislá a hostování se provádí přímo kódem v naší aplikaci.
Pokud nějakou takovou (a nejen .NET) službu rozjíždíme, můžeme provést její nasazení na šifrované verzi protokolu HTTP - HTTPS přesněji řečeno TLS. Pokud se jedná o službu hostovanou na IIS, je nastavení díky IIS Manageru docela jednoduché, v případě Self host služeb je to ale o něco složitější. Podíváme se jak HTTP/S binding funguje a jak ho ve Windows nastavit.
IIS
Předpokládám, že jak nastavit HTTPS přes IIS asi znáte, takže jen stručně pro zopakování. V IIS Manageru vybereme Web Site, který chceme nastavit pro HTTPS a zvolíme volbu Bindings.
Zde přidáme (Add) nový binding a zvolíme:
- Schema https
- Port – výchozí port pro HTTPS je 443, ale můžeme podle potřeby zvolit i jiný, na kterém bude Web Site dostupná.
- Vybereme Web Server certifikát – certifikát je nabízen z úložiště počítače (Local computer) a to z Personal nebo Web Hosting (Windows 2012) storu, případně ze souboru na filesystému (Central Certificate Store na Windows 2012).
Dále, aby byla SSL/TLS komunikace správně ověřená, musí platit jedna z variant:
- jméno v URL adrese musí odpovídat Subject Name jménu (Subject Common Name - CN) certifikátu
- jméno v URL adrese musí odpovídat jednomu z DNS jmen v SAN (Subject Alternative Name) certifikátu
- musí odpovídat doména pro hvězdičkový certifikát (Wildcard certificate)
Certifikát si buď opatříme u nějaké veřejné certifikační autority (jako například startssl.com), nebo si ho vydáme ze své CA (záleží na scénáři), o tom se můžete dočíst v mém článku Vydávání certifikátů na Windows platformě.
Publikace Více HTTPS Web site
Ještě si musíme uvědomit, že normálně je možné použít pouze jeden certifikát pro jeden endpoint tj. kombinaci IP Adresa + Port. Pokud tedy potřebujeme publikovat na serveru více HTTPS Web Sites, tak máme tyto možnosti:
Použít pro různá jména více certifikátu a:
- Použít více veřejných IP adres
To může být u některých providerů nedostupné nebo nákladné. - Použít jiné porty než výchozí port 443
To ovšem může být špatné pro uživatele, kteří nejsou zvyklí port zadávat do URL. Také nestandardní porty mohou být blokovány firewally.
Nebo můžeme použít jeden certifikát na všechny Web Sites s více jmény a to:
- Certifikát s více jmény DNS v SAN (Subject Alternative Name)
Pokud si certifikát vystavujeme sami z vlastní CA, tak to nemusí být problém, ale pokud si pořizujeme takový certifikát z veřejné CA, tak to většinou není možné, nebo může být certifikát nákladný. Druhou nevýhodou je to, že některé (starší) zařízení (mobily, tablety) nemusí být schopné alternativní jména načíst. - Hvězdičkový certifikát (Wildcard certificate)
Musí se jednat o stejnou doménu, certifikát může být nákladný.
Poslední možností je použít technologii SNI (Server Name Indication) (dostupná od Windows Server 2012)
SNI umožňuje u Web Site nastavit host name a mít tedy více jmen (hlaviček) pro stejný endpoint, tak jako je to možné u klasického HTTP. Problém zde je ale s tím, že technologii musí klient podporovat. Konkrétně jí nemusí umět některé (starší) mobilní zařízení a na desktopu je asi největší problém Windows XP s prohlížečem IE, kde technologie podporována není (jiné browsery na Windows XP SNI podporují).
Tak toto bylo na úvod (uf) a nyní už k nastavení bez IISka.
HTTP.SYS
Abychom mohli HTTPS pro naše služby nastavit, je dobré nejprve rozumět tomu, jak ve Windows fungují HTTP/S bindingy. Ve Windows Vista / Windows Server 2008 (i když tuším základ byl již i ve Windows Server 2003) se o veškeré http/s komunikace stará služba HTTP Service – HTTP.SYS driver zabudovaný přímo v jádře. HTTP.SYS přijímá příchozí http požadavky a rozhazuje je mezi jednotlivé zaregistrované služby. K tomu, aby jsme přijímali HTTP komunikaci tedy IIS nepotřebujeme, ani nemusí být na počítači vůbec nainstalované. IIS (Služba World Wide Web Publishing) je pouze jedna z těchto služeb zaregistrovaných v HTTP.SYS, další známé služby jsou například SSTP VPN, IP-HTTPS tunel, SQL Server Reporting services, Powershell WinRM a nebo právě jakákoliv naše self-hosted WCF nebo ASP.NET Web API služba.
Tím je tedy možné, aby jeden port používalo více služeb. Můžeme například mít na počítači IIS na HTTP (tj. binding na TCP 80) a zároveň naší self-hosted službu také na standardním HTTP portu 80. Musí ovšem platit, že každá služba bude mít zaregistrované jedinečné URL tzv. base address. Podle té pak HTTP.SYS rozhodne, kam příchozí požadavek přehodit.
Toto URL se zapisuje jako HTTP URL namespace ve formátu scheme://host:port/relativeURI (například http://+:80/vroot/) – kde jako host se nejčastěji používá znak + - Strong wildcard.
Na zaregistrované služby se můžeme podívat příkazem:
NETSH http show servicestate
tak například registrace Default Web Site (s jedním virtuálním adresářem CertSrv) na IIS může vypadat takto:
Server session ID: FD00000020000003
Version: 2.0
State: Active
Properties:
Max bandwidth: 4294967295
Timeouts:
Entity body timeout (secs): 120
Drain entity body timeout (secs): 120
Request queue timeout (secs): 65535
Idle connection timeout (secs): 120
Header wait timeout (secs): 120
Minimum send rate (bytes/sec): 240
URL groups:
URL group ID: FC00000040000003
State: Active
Request queue name: DefaultAppPool
Properties:
Max bandwidth: inherited
Max connections: 4294967295
Timeouts:
Entity body timeout (secs): 120
Drain entity body timeout (secs): 120
Request queue timeout (secs): 65535
Idle connection timeout (secs): 120
Header wait timeout (secs): 0
Minimum send rate (bytes/sec): 0
Logging information:
Log directory: C:\inetpub\logs\LogFiles\W3SVC1
Log format: 0
Authentication Configuration:
Authentication schemes enabled:
Number of registered URLs: 2
Registered URLs:
HTTPS://*:443/
HTTP://*:80/
URL group ID: F900000040000003
State: Active
Request queue name: DefaultAppPool
Properties:
Max bandwidth: inherited
Max connections: inherited
Timeouts:
Timeout values inherited
Authentication Configuration:
Authentication schemes enabled:
Number of registered URLs: 2
Registered URLs:
HTTPS://*:443/CERTSRV/
HTTP://*:80/CERTSRV/
a takto moje self-hosted WCF služba:
Server session ID: D900000020000025
Version: 2.0
State: Active
Properties:
Max bandwidth: 4294967295
Timeouts:
Entity body timeout (secs): 120
Drain entity body timeout (secs): 120
Request queue timeout (secs): 120
Idle connection timeout (secs): 120
Header wait timeout (secs): 120
Minimum send rate (bytes/sec): 150
URL groups:
URL group ID: D40000004000002B
State: Active
Request queue name: Request queue is unnamed.
Properties:
Max bandwidth: inherited
Max connections: inherited
Timeouts:
Timeout values inherited
Number of registered URLs: 1
Registered URLs:
HTTP://+:80/TESTSERVICE/
Registrace služeb (bindingu) se provede buď sama automaticky a nemusíme se o ní starat, to ale jen za předpokladu, že službu pouštíme s administrátorskými právy. Pokud tomu tak není, tak můžeme registraci provést ručně nebo vlastním kódem například při instalaci, kde na to administrátorská práva dostupná jsou (o tom někdy příště).
Ještě upozorňuji, že některé aplikace tento HTTP.SYS driver používat nemusí. Tím se pak dostaneme do situací, že port, může být již používán jinou aplikací (například Skype si v defaultním nastavení zabere port 80 a 443 pokud jsou volné a tím je při spuštění obsadí).
HTTPS
Konečně se dostáváme k nastavení HTTPS komunikace. Je potřeba nastavit SSL X.509 certifikát pro příslušný HTTPS binding, a to už pro HTTP.SYS driver. Některé služby toto nastavení umožňují provést pomoci nějakého UI rozhraní (například již popsané nastavení v IIS Manageru pro IISko), tím se nastavení zároveň provede i na úrovní HTTP.SYS driveru.
Pro vypsání aktuálních nastavení slouží příkaz:
NETSH HTTP show sslcert
Takto například vypadá nastavený HTTPS binding z IISka:
C:\Users\Administrator>netsh http show sslcert
SSL Certificate bindings:
-------------------------
IP:port : 0.0.0.0:443
Certificate Hash : 39f00ad53376b00bbdf9636deb003beac3348a96
Application ID : {4dc3e181-e14b-4a21-b022-59fc669b0914}
Certificate Store Name : My
Verify Client Certificate Revocation : Enabled
Verify Revocation Using Cached Client Certificate Only : Disabled
Usage Check : Enabled
Revocation Freshness Time : 0
URL Retrieval Timeout : 0
Ctl Identifier : (null)
Ctl Store Name : (null)
DS Mapper Usage : Disabled
Negotiate Client Certificate : Disabled
Vidíme zde Certificate Hash, což je Thumbprint nastaveného certifikátu z uložiště Certificate Store Name. A dále je důležité Application ID. Application ID (nebo AppID) určuje, pro kterou službu je HTTPS binding nastavený. Pro konkrétní služby jsou IDčka pevně zvolená. Seznam některých z nich můžete najít zde http://www.sevecek.com/Lists/Posts/Post.aspx?ID=9.
Poznámka: Na vývojovým počítači zde uvidíte spoustu portu pro certifikát Localhost, to jsou zaregistrované porty pro službu IIS Express.
Nastavení HTTPS bindingu
Po službu, která žádné UI pro nastavení certifikátu nemá (sem budou nejspíše patřit i naše vlastní služby) je možné binding nastavit buď přímo pomoci příkazu NETSH HTTP nebo nějakou utilitou - HttpCfg.exe nebo grafický HttpConfig.exe.
Nastavení přes NETSH HTTP se provádí takto:
netsh http add sslcert ipport=0.0.0.0:443 certhash=39f00ad53376b00bbdf9636deb003beac3348a96 appid={D0428069-D694-49D6-8B80-3B2C64AE972D}
kde určíme port (0.0.0.0:443), a dále určíme certifikát parametrem certhash, což je thumbprint certifikátu bez mezer. Posledním parametrem je pak appid – jedná se o GUID, který pro naší službu můžeme vygenerovat například pomoci nástroje Create Guid z Visual Studia (zvolíme Registry format).
Druhou možností, kterou používám je pomoci utility HttpConfig.exe (utilita je dostupná zde http://www.stevestechspot.com/downloads/httpconfig.zip).
Na záložce SSL zvolíme Add a navolíme:
IP Address: 0.0.0.0 a námi požadovaný port.
Zvolíme New GUID
Tlačítkem Browse vybereme naimportovaný certifikát ze store.
Potvrdíme tlačítkem OK
Pozor ale, že zde platí již výše uvedená podmínka, že jeden certifikát je pouze pro jeden endpoint. Lehce se vám tak může stát, že nastavením jedné služby “rozbijete” nastavení službě jiné (například binding, který tam mělo IISko zapsané z IIS konzole).
Závěr
Co by jste si z článku měli odnést je hlavně toto:
- HTTP/ HTTPS služby dnes nemusí být závislé na IISku, IISko na počítači ani nemusí být (platí pro Windows Server 2003 a víš).
- Každá takováto HTTP/ HTTPS služba má svojí base adresu registrovanou v HTTP.SYS driveru. Registrace vyžaduje administrátorská práva.
- Pokud zvolíme pro svojí službu jedinečnou base adresu, tak není problém hostovat více služeb na stejném portu, nebo dohromady s IISkem na počítači.
- Pokud potřebujeme rozjet naší službu na protokolu HTTPS (TLS), musíme jí pro zvolený port ručně nakonfigurovat HTTPS binding pomoci NETSH HTTP, HttpCfg nebo HttpConfig.exe.
- Při nastavení HTTPS bindingů dejte pozor, které HTTPS endpointy (IP + Port) již mají vytvořené jiné služby a to zejména ty systémové jako IIS, WinRM, SSTP apod.