SSL Security in Windows Azure

Een best practice bij webapplicaties is om SSL oftewel HTTPS te gebruiken om verkeer tussen een browser en de web server te versleutelen, zodat derde partijen dit verkeer niet kunnen lezen of onderscheppen. Om te kunnen versleutelen moet er op de webserver een server certificaat geïnstalleerd worden. Wat minder gebruikt wordt zijn SSL client certificaten om de gebruiker te identificeren. Hiertoe dient een client certificaat op de client met de web browser geinstalleerd te worden. Azure gebruikt dit bijvoorbeeld voor de remote desktop verbinding naar een instantie van een web role.

Dit artikel legt uit hoe een ASP.NET (MVC) webrol onder een HTTPS endpoint gebracht kan worden met gebruikmaking van SSL client certificaten voor authenticatie van de gebruiker.

Certificaten

Het belangrijkste bij HTTPS/SSL verbindingen zijn valide server- en clientcertificaten. Hierbij wordt het server certificaat door de web browser gevalideerd en wordt het client certificaat door de web server gevalideerd.

Validatie

Als het server certificaat niet door de web browser gevalideerd kan worden, dan geeft de web browser een melding aan de gebruiker. De gebruiker krijgt dan meestal wel de optie om deze certificaatmeldingen te negeren en de website toch te laten zien.
 
Als het client certificaat niet door de web server gevalideerd kan worden, dan geeft de server een ‘Access Denied’ foutmelding met een algemene HTTP code 403 terug, zelfs als alles verder goed is geconfigureerd. Standaard retourneert IIS namelijk geen gedetailleerde foutcodes bij SSL validaties. Dit kan opgelost worden door in de IIS configuratie van een website de HTTP Error codes aan te passen, zodat deze ook remote gedetailleerde fouten teruggeeft (zie figuur 1). Nu retourneert IIS gedetailleerde foutcodes met HTTP subcodes, bijvoorbeeld HTTP code 403.16 ‘Your client certificate is either not trusted or is invalid.’.
 
Een valide certificaat is het halve werk!
 
De belangrijkste validatie is of het certificaat wel van een zogenaamde vertrouwde certificaat autoriteit is uitgegeven. Er zijn maar een aantal van deze autoriteiten in de wereld. De enige mogelijkheid om zo’n valide certificaat te krijgen is om een certificaat aan te schaffen bij een autoriteit of bij een tussenpersoon. Een server certificaat wordt uitgegeven op een specifieke URL, een client certificaat is in pricipe URL onafhankelijk.
 
Figuur 1: Error Page Settings

Server Certificaat

Het eerste wat nodig is voor een SSL verbinding is een server certificaat. De gemakkelijkste manier is om deze aan te schaffen bijvoorbeeld bij VeriSigntm of Bingtm naar SSL Server Certificate. Er kan ook een self-signed certificaat gebruikt worden. Het nadeel van een self-signed certificaat is dat deze niet wordt vertrouwd door de browser en de browser dus waarschuwingen geeft als de site geopend wordt, het voordeel is natuurlijk dat deze gratis is. Als IIS Express is geïnstalleerd op je development machine, dan is er al een self-signed certificaat beschikbaar en kan deze gebruikt worden.
 
Een andere mogelijkheid is om deze aan te laten maken met behulp van de IIS Manager. Als in de IIS manager de focus op de machinenaam staat (dus niet op een website), dan is er rechts een icoon voor server certificaten. Hiermee kan een lijst met certificaten opgevraagd worden, die op de development machine aanwezig zijn en gebruikt kunnen worden als server certificaat. Hier is ook de mogelijkheid om een self-signed certificaat aan te maken d.m.v. ‘Create Self-Signed Certificate’.
 
Het probleem met de meeste self-signed certificaten is, dat deze uitgegeven zijn op de naam van de development machine (https://machinenaam) en niet op de URL waarop straks in Windows Azure de webrol beschikbaar is (https://webrol.cloudapp.net).
 
Een alternatief is het gebruik van Active Directory Certificate Services. Dit is beschikbaar in Windows Server 2003 of 2008 en in tegenstelling tot wat de naam aangeeft hoeft er geen Active Directory geïnstalleerd te zijn. Hoe met Active Directory Certificate Services een certificaat aangemaakt kan worden valt buiten de scope van dit artikel.

Client Certificaat

Ook voor het client certificaat geldt dat je deze het beste kan aanschaffen. Deze is namelijk niet gelinkt aan een specifieke URL en deze kan dus hergebruikt worden in de gehele OTAP omgeving.
 
Indien je wel zelf een client certificaat aanmaakt, dan is het certificaat niet uitgegeven door een vertrouwde instantie en retourneert de server een HTTP 403 Access Denied melding. Dit kan opgelost worden door het self-signed certificaat te installeren op de web server. Deze moet dan geplaatst worden in de certificate store van de locale machine onder de trusted root (zie figuur 2).
 
Figuur 2: Certificaten
 
In Windows Azure is dit mogelijk door middel van een remote desktop naar de virtuele machine. Het probleem hierbij is echter, dat als de Windows Azure een nieuwe VM aanmaakt, deze instelling kwijt raakt. Het kan ook via code gedaan worden, dit wordt verderop in het artikel uitgelegd.

Webapplicatie

In dit artikel ga ik uit van een nieuw aangemaakte ASP.NET MVC 2 web role. Hier wordt default een AccountController gegenereerd. Deze kan verwijderd worden, omdat de gebruiker niet inlogt met een gebruikersnaam en wachtwoord, maar alleen met een HTTPS client certificaat (de combinatie is echter wel mogelijk). De website bevat verder geen functionaliteit.
 
De authentication mode in web.config moet ook op None staan. Er wordt namelijk geen HTTP of Windows authenticatie gebruikt, maar SSL authenticatie.  
 
Ook moet er in de Windows Azure service configuration de osFamily op 2 staan, zodat Windows Azure een Windows Server 2008R2 virtuele machine aanmaakt met IIS 7.5.

Installeren Server Certificaat

Nadat de webrol is aangemaakt, moet het server certificaat geconfigureerd worden in de webrol. In de properties van de webrol bevindt zich een tab certificates. Hier kan een server certificaat toegevoegd worden met als friendly naam de url van de uiteindelijke website. Door te klikken op de ... naast de  thumbprint kan het certificaat geconfigureerd worden.
 
Figuur 3: Certificaat instellen
 
Hierna moet het server certificaat ge-upload worden in de Azure portal. Hiervoor moet het certificaat wel beschikbaar zijn als bestand. Het eenvoudigste is om dit via de webrol properties te doen. Bij het selecteren van het server certificaat is er een mogelijkheid om het certificaat te bekijken via de link ‘Click here to view certificate properties’. Op de details tab is er dan een button ‘Copy to File’ beschikbaar. Nu wordt er een wizard gestart. Kies eerst Next. Kies dan voor ‘Yes, export the private key’ en druk op Next. Kies nu de defaults en druk op Next. Kies een wachtwoord en druk op Next. Kies een bestandsnaam en folder en druk op next. Druk nu op Finish (zie figuur 4).
 
Figuur 4: Certificaat exporteren
 
In de Azure management portal bevindt zich onder de hosted service een folder Certificates. Hier kan het certificaat toegevoegd worden via Add Certificate. Kies nu het bestand dat net is aangemaakt met het bijbehorende wachtwoord en druk op Create.
Het server certificaat is nu klaar om gebruikt te worden.
 
Er moet echter nog wel een HTTPS endpoint aangemaakt worden. Default wordt er namelijk alleen een HTTP endpoint aangemaakt. Wijzig hiervoor het protocol naar HTTPS , wijzig de poort naar 443 en selecteer het server certificaat (zie figuur 5).
 
Figuur 5: HTTPS endpoint instellen
 
Nu kan het project worden gebouwd en gepubliceerd worden naar Windows Azure. Bij een self-signed certificaat geeft de web browser meldingen, dat het certificaat niet is uitgegeven door een vertrouwde instantie en meestal dat het certificaat uitgegeven is voor een andere URL. In de meeste browsers kun je dit negeren.

Configureren Client Certificaat

Indien je gebruik wilt maken van authenticatie met client certificaten dan moet er in IIS de role feature IISCertificateMappingAuthentication geïnstalleerd zijn. Dit is standaard in een webrol van Windows Azure echter niet het geval. Om deze feature te kunnen installeren in Windows Azure moet er gebruik gemaakt worden van een startup task. Deze startup task is een batch bestand, die uitgevoerd wordt voordat de webrol wordt opgestart. Voor het installeren van een feature moet deze startup task ook in elevated mode draaien.
 
Voeg een bestand Startup.cmd toe aan het project en zet ‘Copy to Output Directory’ op Always. Zie listing 1 voor de inhoud van het batch bestand.
 
Opgelet: Visual Studio maakt standaard een textbestand met een UTF-8 encoding, deze kan echter niet uitgevoerd worden als batch bestand. Dit bestand moet opgeslagen worden als bestand met ANSI formaat.
 
start /w pkgmgr /iu:IIS-IISCertificateMappingAuthentication
Listing 1: Startup batch bestand
 
Hierna moet in de service definition de startup task worden toegevoegd (zie listing 2).
 
<ServiceDefinition>
 <WebRole>
    <Startup>
      <Task commandLine="Startup.cmd" executionContext="elevated" />
    </Startup>
 
Listing 2: Configuratie Startup batch bestand
 
Nu IIS kan omgaan met authenticatie via client certificaten moet de website zelf geconfigureerd worden. Dit kan normaal gesproken via de IIS manager. Met Windows Azure kan dit niet, omdat Windows Azure de virtuele machine weer opnieuw kan opbouwen en deze wijzigingen dan kwijt raken. Een betere manier is om dit via code te doen. Deze code moet echter wel in elevated mode gedraaid worden en dus niet in de webapplicatie zelf.
 
Sinds de Windows Azure SDK 1.3 draait de OnStart methode van de webrol niet meer binnen IIS, maar wordt hier een apart proces voor opgestart. Dit proces kan in elevated mode draaien, dus kan de configuratie code in de WebRole.OnStart worden geïmplementeerd. Om dit proces in elevated mode te laten draaien moet de service definition worden aangepast (zie listing 3).
 
<ServiceDefinition>
 <WebRole>
    <Startup>
      <Runtime executionContext="elevated" />
    </Startup>
Listing 3: Configuratie elevated mode
 
Om de client certificate mapping te configureren maken we gebruik van de class Microsoft.Web.Administration.ServerManager. Zie listing 4.

 

public override bool OnStart()
{
  // Get SiteName of WebRole
  string siteName = RoleEnvironment.CurrentRoleInstance.Id + "_Web";
 
  // Instantieer de server manager
  using (ServerManager serverManager = new ServerManager())
  {
    // haal de configuratie op
    Configuration config = serverManager.GetApplicationHostConfiguration();
 
    // enable de client certificate mapping 
    // en gebruik een one-to-one mapping
    ConfigurationSection mappingSection = config.GetSection(
        "system.webServer/security/authentication/" + 
        "iisClientCertificateMappingAuthentication", siteName);
    mappingSection["enabled"] = true;
    mappingSection["oneToOneCertificateMappingsEnabled"] = true;
 
    // voeg een gebruiker toe
    ConfigurationElementCollection oneToOneMappingsCollection = 
      clientCertificateMappingSection.GetCollection("oneToOneMappings");
    ConfigurationElement addElement = 
      oneToOneMappingsCollection.CreateElement("add");
    addElement["enabled"] = true;
    addElement["userName"] = userName;
    addElement["password"] = password;
    addElement["certificate"] = publicKey;
    oneToOneMappingsCollection.Add(addElement);
 
    // alleen HTTPS met  client certificaten is toegestaan
    ConfigurationSection accessSection = config.GetSection(
      "system.webServer/security/access", siteName);
    accessSection["sslFlags"] = 
      @"Ssl, SslNegotiateCert, SslRequireCert, Ssl128";
 
    serverManager.CommitChanges();
  }
 
  return base.OnStart();
}

 

Listing 4: Configuratie code
 
In listing 4 moet userName en password van een bestaande gebruiker zijn. Als remote desktop wordt gebruikt, dan kan de userName en wachtwoord van deze gebruiker gebruikt worden.
 
De publicKey moet de public key van het client certificaat bevatten. Hiervoor moet het client certificaat ge-exporteerd worden naar een base64 CER bestand. Dit bestand moet dan geopend worden in notepad. Hierbij dient de eerste en laatste regel weggehaald worden en wat overblijft op 1 regel gezet worden.
 
In dit voorbeeld wordt 1 mapping aangemaakt, maar er moet uiteindelijk voor elke gebruiker een mapping aangemaakt worden.
Gebruikergegevens
De webapplicatie maakt nu gebruik van HTTPS client authenticatie en IIS mapt deze naar een Windows gebruiker. Voor de webapplicatie lijkt het nu dus of de gebruiker via Windows authenticatie heeft ingelogd.
 
Om te weten wie de gebruiker is, kan de Request.LogonUserIdentity opgevraagd worden, bijvoorbeeld Request.LogonUserIdentity.Name geeft de naam van de Windows gebruiker die gekoppeld is.
Installeren certificaat als trusted root
Als je geen client certificaat hebt, dan uitgegeven is door een vertrouwde instantie, dan kan de code in listing 5 toegevoegd worden in de WebRole.OnStart om het het client certificaat in de trusted root van de local machine te installeren. filePath is het pad naar het certificaat en password het wachtwoord.
 
var pfx = new X509Certificate2();
pfx.Import(filePath, password,X509KeyStorageFlags.PersistKeySet);
 
var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store.Open(OpenFlags.MaxAllowed);
store.Add(pfx);
store.Close();
Listing 5: Code installeren certificaat als trusted root

Conclusie

Met gebruikmaking van HTTPS verbindingen in combinatie met SSL client certificaten kan een webapplicatie in de cloud behoorlijk veilig gemaakt worden. Zeker als je websites, die normaal on-premise draaien voor een beperkte set mensen, naar de cloud wil brengen is een beveiliging met client certificaten een goede oplossing.
 
Het opzetten van een SSL verbinding met client certificaten onder Windows Azure is de eerste keer lastig. Je moet met veel randzaken rekening houden. Maar als je het eenmaal voor elkaar hebt dan is het duidelijk en behoorlijk veilig. 
 
De meeste problemen zijn te verwachten als certificaten worden gebruikt, die niet zijn uitgegeven door een zogenaamde trusted root certificate authority, bijvoorbeeld een self-signed certificaat. In dit artikel heb ik proberen uit te leggen hoe deze problemen voorkomen kunnen worden. Uiteindelijk moeten in een productieomgeving natuurlijk wel valide (lees gekochte) certificaten gebruikt worden.

 

Geef feedback:

CAPTCHA image
Vul de bovenstaande code hieronder in
Verzend Commentaar