Automatické přihlašování (SSO) pro RDP a RD GW a jeho zabezpečení

Článek se zabývá implementací Kerberos KDC proxy a SSO (single-sign-on) pro RDP vzdálenou tak, aby se nemuselo vůbec zadávat přihlašovací heslo a to jak na intranetu, tak i vzdáleně z internetu přes RD Gateway (RDG, dříve TS Gateway).

Na LAN intranetu funguje SSO i pro Windows 7, Windows Vista a novější, pokud máte RDP server Windows 2008 a novější. Z venku z internetu přes RD Gateway je možné zařídit SSO na Windows 7 jenom pro lokální účty (pokud máte na stanici stejný lokální účet jako na RDP serveru), ale už ne pro doménové. Novinka je ve Windows 8 a za předpokladu, že máte Windows 2012 RD gateway, kde je SSO pro všechny díky nové KDC proxy!

Ale začněme pomaleji na intranetu

Remote desktop (RDP, dříve Terminal Services) vyžaduje zaslat po uživateli plné přihlašovací údaje - tedy zejména plné heslo (samozřejmě pokud nepoužíváte RestrictedAdmin režimpro správce). To znamená, že RDP je vlastně něco jako basic authentication. Z toho důvodu se vás klient mstsc pokaždé ptá a uživatele pak láká hesla si ukládat na lokále:

sev1sev2

Zadávání je otravné, ale ukládání je nebezpečné. Od Windows 7 jsou hesla uložena v operačním systému v tzv. credentials manageru (podobně jako v případě Internet Exploreru), tedy v plné formě, chráněná přihlašovacím heslem uživatele (ochrana pomocí DPAPI).

sev3sev4

Problém je v tom, že po přihlášení si libovolná aplikace může toto heslo vytáhnout. Jestli si uživatelé spustí nějaký čmuchací prográmek, hesla vybere a pošle si je do internetu (o posílání věcí do internetu přes DNS můj nedávný článeček). Je tedy vhodné ukládání hesel úplně zakázat. Jenže tím zase uživatele nutíte je opakovaně zadávat. Zakázat se ukládání dá přes Group Policy (GPO), máte na to dvě položky:

sev5

sev6sev7

Časté zadávání přihlašovacích údajů je také nebezpečné, protože ho může někdo odpozorovat, zachytit keyloggerem a podobně. I norma ISO/IEC 27002vám radí, že byste měli pro všechno implementovat SSO (single-sign-on) - tedy automatické přihlašování bez opětovného zadávání hesla.

RDP SSO na intranetu za pomocí Kerberos před-ověření serveru (NLA)

Možná jste si všimli, že na intranetu se identita RDP serveru mnohdy ověří pomocí Kerberos. Upozorňuji, že se jedná o identitu serveru, nikoliv o ověření uživatele. Jde o to, abyste věděli jistě s jakým serverem hovoříte, aby to plné heslo nešlo odposlouchávat. Tohle funguje od RDP serveru Windows 2008 a od klientů Windows Vista a Windows 7, pakliže jste v Active Directory doménovém prostředí.

Tomuhle před-ověření serveru se říká NLA (network level authentication) a je možné to dokonce vynutit na RDP serveru. Oproti starší metodě ověřování RDP Security Layer máte jistotu, s kým hovoříte a komu tedy posíláte svoje plnotextové heslo.

sev8

Pokud máte ověřenu identitu serveru, komunikační kanál je dostatečně zabezpečen, aby byl RDP client (mstsc) ochoten poslat vaše plné přihlašovací heslo na RDP server automaticky, aniž by se vás ptal. Vaše přihlašovací heslo je po celou dobu přihlášení v paměti LSASS procesu v plné formě. Pokud se to RDP clientovi a LSASS povolí pomocí Group Policy (GPO), budou ochotni to heslo vzít a poslat ho na RDP server.

Technologie se jmenuje credentials delegation, neboli CredSSP. Funguje taktéž od Windows 2008 a Windows 7 nebo Windows Vista. Povolit to musíte v Group Policy object v položce Computer Configuration - Policies - Administrative Templates - System - Credentials Delegation - Allow delegating default credentials takto:

sev9sev10

V nastavení v obrázku je vidět, že musíte definovat Kerberos SPN pro TERMSRV službu. Můžete použít i hvězdičkovou konvenci. A vyjmenujete všechny RDP servery, do kterých by měli být mstsc klienti a jejich LSASS ochotni poslat plnotextové heslo uživatele. Výsledek ověříte ze stanice rovnou na první pohled - mělo by to hlásit your Windows logon credentials will be used to connect:

sev11sev12

A samozřejmě nebudete muset nic dalšího zadávat.

Přístup na RDP Gateway z internetu a SSO

Z internetu budeme přistupovat do firmy přes RD Gateway (dříve TS Gateway) - tedy přes normální HTTPS tunel ve kterém prochází RDP komunikace přímo na RDP server. MSTSC client potom hovoří vlastně přímo s cílovým RDP serverem po normálním TCP 3389, ale celé je to tunelované v HTTPS mezi klientem a RD Gateway.

RDP gateway je normální HTTPS server, který potřebuje normální HTTPS/TLS serverový certifikát. V mém případě je samozřejmě důvěryhodný, lze mu ověřit CRL apod. Nastavení RD Gateway není v tomto článku podstatné, kromě kvality jejího certifikátu. Takže pouze screenshoty z certifikátu - normální parametry, takový certifkát potřebujete jen jeden, můžete si ho klidně koupit od nějaké veřejné autority (například StartSSLje nejlevnější a přitom důvěryhodná od cca roku 2008):

sev000

sev13sev14sev15

Na klientovi je pouze podstatné, aby bylo možno i z internetu ověřit CRL - certificate revocation list, nebo OCSP. Tedy aktuální platnost certifikátu RD Gateway. Stačí certifikát vyexportovat do nějakého .CER souboru a z klientského počítače spustit z příkazové řádky následující:

sev0

Na konci se musí objevit hláška leaf certificate revocation passed. Potom je certifikát v pořádku. A samozřejmě nesmíte vidět žádné žluté varování od mstsc klienta.

Pokud se na gateway připojíte bez problémů, tak už se s tím dále zabývat nemusíme a přesuneme se na problém s koncovým RDP serverem samotným.

Dále už nastává základní problém pro SSO, které jsme zkoušeli v předchozím kroku. To vyžadovalo ověřit identitu RDP serveru pomocí Kerberos. V případě klientů Windows 7 to nejde. K tomu bychom potřebovali RD Gateway alespoň na Windows 2012 a klienty Windows 8, kteří dohromady umí používat Kerberos Proxy - detaily dále.

RDP SSO přístup přes RD Gateway z internetu pro klienty už od Windows 7

Pokud nám z internetu nejede Kerberos, což z Windows 7 nejede :-) musíme identitu RDP serveru ověřit jinak. Certifikátem. Upozorňuji, že pro doménové účty budete muset heslo do RDP serveru zadávat vždy. SSO můžeme mít jen při lokálních účtech. Ale certifikát je ta správná cesta i pro novější Windows 8.

Použijeme k tomu opět certifikáty, které jsou alternativou NLA ke Kerberosu. Tentokrát ovšem trošku speciální certifikát pro RDP server. Zatímco certifikát pro RD Gateway jsme si mohli levně koupit, protože byl potřeba jen jeden, certifikáty pro RDP servery budeme potřebovat pro každý RDP server jiný. Ideálně si je tedy vydáme rovnou z naší vnitřní certifikační autority AD CS (Active Directory Certificate Services) zdarma. Následuje zrychlený návod.

V podstatě vytvoříme kopii výchozí šablony (certificate template) Web Server a změníme několik parametrů - zvláště se jedná o speciální EKU (Enhanced Key Usage, neboli Application Policy) s hodnotou OIDu Remote Desktop Authentication (1.3.6.1.4.1.311.54.1.2). Druhou věc, na kterou bych upozornil je jméno šablony. Šablona má vždy dvě jména. Windows 2008 mají chybu, že si ta jména pletou, takže je nastavte úplně stejná, bez mezer:

sev00

sev16sev17sev18sev19sev20sev21sev22sev23sev24sev25sev26sev27

V tuto chvíli máte šablonu certifikátu pro Remote Desktop Authentication vypublikovanou na AD CS a počítače si podle ní mohou vyžádat certifikáty. Musíme je k tomu ale nějak přinutit. To se dosáhne přes Group Policy object (GPO). Jméno vaší nové šablony (v mém případě GOPASRDPServer) potřeba nastavit do položky Computer Configuration - Policies - Administrative Templates - Windows Components - Remote Desktop Services - Remote Desktop Session Host - Security - Server authentication certificate template.

Můžete současně vynutit také TLS a NLA (Network Level Authentication), takže budete mít jistotu, že se starší klienti bez TLS a NLA ani vůbec nepřipojí. Jedná se o politiky Require use of specific security layer for remote RDP connections a Require user authentication for remote connections by using Network Level Authentication.

sev28sev29sev30

Mohli byste, třeba v tom samém GPO, ještě vynutit ověření i na straně RDP klienta - Configure server authentication for client = Do not connect if authentication failed.

Na RDP serverech už potom jenom zaktualizujte politiku a případně restartujte službu Remote Desktop Configuration (sessionenv), která si certifikát sama vyžádá a nastaví pro RDP. Ověřit výsledek je jednoduché na Windows 2008, kde to uvidíte rovnou v konzoli Remote Desktop Session Host Configuration. Od Windows 2012 tohle GUI zmizelo a jediná cesta je podívat se do registrů na thumbprint (fingerprint, otisk) certifikátu:

sev0000

sev31sev32

Pokud takové spojení zkusíte z vnitřní LAN sítě napřímo, mělo by vám to psát, že identita serveru byla ověřena současně jak Kerberos, tak i certifikátem (musíte jenom zadávat dlouhé jméno serveru - FQDN - v mém případě něco jako gps-rdp.gopas.virtual).

sev33

Z internetu Kerberos nejede, proto jsme dělali tyto certifikáty. Z internetu přes RD Gateway ale musíte vidět, že se to certifikátem skutečně ověřilo! Na Windows 7 musíme zadávat přihlašovací údaje pro doménové účty, pro lokální nikoliv. V následujícím obrázku je jak nastavení klienta, tak i výsledný zámeček na přípojení, které je v pořádku. Všimněte si, že i přes RD Gateway klient vidí přímo certifikát koncového RDP serveru a kompletně mu musí věřit:

sev34sev35sev36

Nějaké další informace k RDP certifikátům například zde a zde.

Teď ještě budete na Windows 7 ale i Windows 8 a Windows 10 klientech dostávat hlášku The credentials that were used to connect did not work - the logon attempt failed. To je způsobeno tím, že klient se snaží udělat credentials delegation za pomoci prvotního Kerberos ověření a to samozřejmě z internetu nejde (SPNEGO neumí ve skutečnosti NTLM fallback, ale rozhoduje se jenom jednorázově). Kdybyste použili lokální účet, tak by to fungovalo už teď, protože by stačil certifikát, který je důvěryhodný.

sev37

Povolení SSO pro RD Gateway

V tuto chvíli jsme tedy ve stavu, kdy máme ověřenu kvalitu certifikátů. Dále už stačí jen zapnout SSO pro RD Gateway a rozjedou se alespoň lokální účty na Windows 7.

Povolit SSO pro RD Gateway se dělá opět pomocí Group Policy - tentokrát je to klientská politika - User configuration - Policies - Administrative templates - Windows Components - Remote desktop services - RD gateway - Set RD gateway authentication method: Use locally logged-on credentials:

sev38sev39sev40

Výsledkem je automatické použití přihlášených údajů (SSO) i pro RD gateway spojení. Tam to bude fungovat ok. Problém je, že pořád se to nechce prorazit zadarmo až do cílového RDP serveru.

Windows 8 a Windows 2012 Kerberos KDC proxy

Právě proto, aby bylo možné z internetu používat Kerberos, přidal Microsoft do Windows 2012 novou Kerberos proxy. Je to zase normální HTTPS tunel, zkrz který prochází Kerberos z internetového klienta. Pokud uděláte RD Gateway na Windows 2012, rovnou vám to tam samo tu Kerberos proxy zapne. Je to služba KDC proxy service (kpssvc), která zneužívá přímo HTTP.SYS v jádře a poslouchá si na TCP 443 HTTPS na URI /kdcproxy.

Protože SSL/TLS certifikát je tam nastavený společný pro IIS, RD Gateway i pro Kerberos/KDC proxy, tak na serveru nemusíte už nic dalšího řešit. Jediné řešení leží na klientovi.

Musíte si RDP připojení nakonfigurované v předchozích krocích uložit do souboru .RDP. To je normální textový soubor ve skutečnosti, takže ho můžete otevřít například v notepadu, nebo v čemkoliv jiném. A stačí v něm zpanout použití KDC proxy. Najdete v něm nejspíš klíč rdgiskdcproxy:i:0. Pokud tam není, tak ho tam přidejte. Ale hlavně upravte jeho hodnotu na 1. Tedy výsledek musí být rdgiskdcproxy:i:1.

Pokud už jste vevnitř, můžete klidně upravit pro větší bezpečnost ještě další tři klíče - authentication level:i:1 a negotiate security layer:i:0 a gatewaycredentialssource:i:2, ale to jsou věci, které jsme už nastavili přes Group Policy.

sev41

A je to.

Poznámka na závěr

Podle toho pekelného návodu nahoře bych řekl, že se nejedná o single-sign-on, ale spíš o single-sajgon. Tak hodně štěstí.

- Ondřej Ševeček, MVP