http/s služby, HTTP.SYS a nastavení HTTPS bindingu

Jan Holan       21.05.2014       WCF/WS, ASP.NET/IIS, IT       16375 zobrazení

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ě.

image

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 ServiceHTTP.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

image

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.

 

hodnocení článku

0       Hodnotit mohou jen registrované uživatelé.

 

Nový příspěvek

 

Příspěvky zaslané pod tento článek se neobjeví hned, ale až po schválení administrátorem.

                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

Příspěvky zaslané pod tento článek se neobjeví hned, ale až po schválení administrátorem.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback