Delen via


Zelfstudie: Een HTTPS-eindpunt voor een Service Fabric-toepassing toevoegen met behulp van Kestrel

Deze zelfstudie is deel drie in een reeks. Meer informatie over het toevoegen van een HTTPS-eindpunt in een ASP.NET Core-service die wordt uitgevoerd in Azure Service Fabric. Wanneer u klaar bent, hebt u een stemtoepassing met een HTTPS-ingeschakelde ASP.NET Core-webfront-end die luistert op poort 443. Als u de stemtoepassing niet handmatig wilt maken in deel één van de reeks zelfstudies, kunt u de broncode downloaden om de voltooide toepassing op te halen.

In deze zelfstudie leert u het volgende:

  • Een HTTPS-eindpunt in de service definiëren
  • Kestrel instellen voor het gebruik van HTTPS
  • Het TLS/SSL-certificaat installeren op de externe clusterknooppunten
  • NetworkService toegang geven tot de persoonlijke sleutel van het certificaat
  • Poort 443 openen in de Azure-load balancer
  • De toepassing implementeren in een extern cluster

In de reeks zelfstudies ziet u hoe u het volgende kunt doen:

Notitie

Het wordt aanbevolen de Azure Az PowerShell-module te gebruiken om te communiceren met Azure. Zie Azure PowerShell installeren om aan de slag te gaan. Raadpleeg Azure PowerShell migreren van AzureRM naar Az om te leren hoe u naar de Azure PowerShell-module migreert.

Vereisten

Voor u met deze zelfstudie begint:

Een certificaat ophalen of een zelfondertekend ontwikkelingscertificaat maken

Gebruik voor productietoepassingen een certificaat van een certificeringsinstantie (CA). U kunt voor ontwikkelings- en testdoeleinden een zelfondertekend certificaat maken en gebruiken. De Service Fabric SDK bevat het script CertSetup.ps1 . Het script maakt een zelfondertekend certificaat en importeert het in het certificaatarchief Cert:\LocalMachine\My . Open een opdrachtpromptvenster als beheerder en voer de volgende opdracht uit om een certificaat te maken met het onderwerp CN=mytestcert:

PS C:\program files\microsoft sdks\service fabric\clustersetup\secure> .\CertSetup.ps1 -Install -CertSubjectName CN=mytestcert

Als u al een PFX-bestand (Personal Information Exchange) van een certificaat hebt, voert u het volgende uit om het certificaat te importeren in het certificaatarchief Cert:\LocalMachine\My :


PS C:\mycertificates> Import-PfxCertificate -FilePath .\mysslcertificate.pfx -CertStoreLocation Cert:\LocalMachine\My -Password (ConvertTo-SecureString "!Passw0rd321" -AsPlainText -Force)


   PSParentPath: Microsoft.PowerShell.Security\Certificate::LocalMachine\My

Thumbprint                                Subject
----------                                -------
3B138D84C077C292579BA35E4410634E164075CD  CN=zwin7fh14scd.westus.cloudapp.azure.com

Een HTTPS-eindpunt in het servicemanifest definiëren

Open Visual Studio met behulp van de optie Uitvoeren als administrator en open vervolgens de stemoplossing. Open VotingWeb/PackageRoot/ServiceManifest.xml vanuit Solution Explorer. Het servicemanifest definieert de service-eindpunten. Zoek de Endpoints sectie en bewerk de waarde voor ServiceEndpoint het eindpunt. Wijzig de naam in EndpointHttps, stel het protocol httpsin op , het type op Inputen de poort op 443. Sla uw wijzigingen op.

<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="VotingWebPkg"
                 Version="1.0.0"
                 xmlns="http://schemas.microsoft.com/2011/01/fabric"
                 xmlns:xsd="https://www.w3.org/2001/XMLSchema"
                 xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">
  <ServiceTypes>
    <StatelessServiceType ServiceTypeName="VotingWebType" />
  </ServiceTypes>

  <CodePackage Name="Code" Version="1.0.0">
    <EntryPoint>
      <ExeHost>
        <Program>VotingWeb.exe</Program>
        <WorkingFolder>CodePackage</WorkingFolder>
      </ExeHost>
    </EntryPoint>
  </CodePackage>

  <ConfigPackage Name="Config" Version="1.0.0" />

  <Resources>
    <Endpoints>
      <Endpoint Protocol="https" Name="EndpointHttps" Type="Input" Port="443" />
    </Endpoints>
  </Resources>
</ServiceManifest>

Kestrel configureren voor gebruik van HTTPS

Open in Solution Explorer het bestand VotingWeb/VotingWeb.cs. Configureer Kestrel voor het gebruik van HTTPS en zoek het certificaat op in het Cert:\LocalMachine\Mijn archief. Voeg de volgende using instructies toe:

using System.Net;
using Microsoft.Extensions.Configuration;
using System.Security.Cryptography.X509Certificates;

Werk de waarde voor ServiceInstanceListener het gebruik van het nieuwe EndpointHttps eindpunt bij en luister naar poort 443. Wanneer u de webhost instelt voor het gebruik van de Kestrel-server, moet u Kestrel configureren om te luisteren naar IPv6-adressen op alle netwerkinterfaces: opt.Listen(IPAddress.IPv6Any, port, listenOptions => {...}.

new ServiceInstanceListener(
serviceContext =>
    new KestrelCommunicationListener(
        serviceContext,
        "EndpointHttps",
        (url, listener) =>
        {
            ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");

            return new WebHostBuilder()
                .UseKestrel(opt =>
                {
                    int port = serviceContext.CodePackageActivationContext.GetEndpoint("EndpointHttps").Port;
                    opt.Listen(IPAddress.IPv6Any, port, listenOptions =>
                    {
                        listenOptions.UseHttps(FindMatchingCertificateBySubject());
                        listenOptions.NoDelay = true;
                    });
                })
                .ConfigureAppConfiguration((builderContext, config) =>
                {
                    config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
                })

                .ConfigureServices(
                    services => services
                        .AddSingleton<HttpClient>(new HttpClient())
                        .AddSingleton<FabricClient>(new FabricClient())
                        .AddSingleton<StatelessServiceContext>(serviceContext))
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseStartup<Startup>()
                .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
                .UseUrls(url)
                .Build();
        }))

Voeg vervolgens de volgende methode toe, zodat Kestrel het certificaat in het certificaat Cert:\LocalMachine\My Store kan vinden met behulp van het onderwerp.

Vervang <your_CN_value> door mytestcert als u een zelfondertekend certificaat hebt gemaakt met behulp van de vorige PowerShell-opdracht of gebruik de CN van uw certificaat.

Als u een lokale implementatie gebruikt localhost, raden we u CN=localhost aan om verificatie-uitzonderingen te voorkomen.

private X509Certificate2 FindMatchingCertificateBySubject(string subjectCommonName)
{
    using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
    {
        store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
        var certCollection = store.Certificates;
        var matchingCerts = new X509Certificate2Collection();
    
    foreach (var enumeratedCert in certCollection)
    {
      if (StringComparer.OrdinalIgnoreCase.Equals(subjectCommonName, enumeratedCert.GetNameInfo(X509NameType.SimpleName, forIssuer: false))
        && DateTime.Now < enumeratedCert.NotAfter
        && DateTime.Now >= enumeratedCert.NotBefore)
        {
          matchingCerts.Add(enumeratedCert);
        }
    }

        if (matchingCerts.Count == 0)
    {
        throw new Exception($"Could not find a match for a certificate with subject 'CN={subjectCommonName}'.");
    }
        
        return matchingCerts[0];
    }
}


Netwerkservice toegang verlenen tot de persoonlijke sleutel van het certificaat

In een eerdere stap hebt u het certificaat geïmporteerd in het certificaat:\LocalMachine\Mijn archief op de ontwikkelcomputer.

Geef nu expliciet het account waarop de service wordt uitgevoerd (netwerkservice, standaard) toegang tot de persoonlijke sleutel van het certificaat. U kunt deze stap handmatig uitvoeren (met behulp van het hulpprogramma certlm.msc ), maar het is beter om een PowerShell-script uit te voeren door een opstartscript te configureren in het SetupEntryPoint servicemanifest.

Notitie

Service Fabric biedt ondersteuning voor het declareren van eindpuntcertificaten op vingerafdruk of op algemene onderwerpnaam. In dat geval stelt de runtime de binding en toewijzing voor de persoonlijke sleutel van het certificaat in op de identiteit waarop de service wordt uitgevoerd. De runtime controleert ook het certificaat op wijzigingen, vernieuwingen en toewijzingsupdates voor de bijbehorende persoonlijke sleutel.

Het toegangspunt voor service-instellingen configureren

Open VotingWeb/PackageRoot/ServiceManifest.xml vanuit Solution Explorer. Voeg in de CodePackage sectie het SetupEntryPoint knooppunt toe en voeg vervolgens een ExeHost knooppunt toe. In ExeHost, ingesteld Program op Setup.baten ingesteld op WorkingFolder CodePackage. Wanneer de VotingWeb-service wordt gestart, wordt het Setup.bat script uitgevoerd in de map CodePackage voordat VotingWeb.exe wordt gestart.

<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="VotingWebPkg"
                 Version="1.0.0"
                 xmlns="http://schemas.microsoft.com/2011/01/fabric"
                 xmlns:xsd="https://www.w3.org/2001/XMLSchema"
                 xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">
  <ServiceTypes>
    <StatelessServiceType ServiceTypeName="VotingWebType" />
  </ServiceTypes>

  <CodePackage Name="Code" Version="1.0.0">
    <SetupEntryPoint>
      <ExeHost>
        <Program>Setup.bat</Program>
        <WorkingFolder>CodePackage</WorkingFolder>
      </ExeHost>
    </SetupEntryPoint>

    <EntryPoint>
      <ExeHost>
        <Program>VotingWeb.exe</Program>
        <WorkingFolder>CodePackage</WorkingFolder>
      </ExeHost>
    </EntryPoint>
  </CodePackage>

  <ConfigPackage Name="Config" Version="1.0.0" />

  <Resources>
    <Endpoints>
      <Endpoint Protocol="https" Name="EndpointHttps" Type="Input" Port="443" />
    </Endpoints>
  </Resources>
</ServiceManifest>

De batch- en PowerShell-installatiescripts toevoegen

Als u PowerShell vanaf waarde wilt SetupEntryPointuitvoeren, kunt u PowerShell.exe uitvoeren in een batchbestand dat verwijst naar een PowerShell-bestand.

Voeg eerst het batchbestand aan het serviceproject toe. Klik in Solution Explorer met de rechtermuisknop op VotingWeb en selecteer Nieuw item toevoegen>. Voeg een nieuw bestand toe met de naam Setup.bat. Bewerk het Setup.bat-bestand en voeg de volgende opdracht toe:

powershell.exe -ExecutionPolicy Bypass -Command ".\SetCertAccess.ps1"

Wijzig de eigenschappen voor het Setup.bat bestand om Kopiëren in te stellen op Uitvoermap om te kopiëren als nieuwer.

Schermopname van het instellen van de bestandseigenschappen.

Klik in Solution Explorer met de rechtermuisknop op VotingWeb. Selecteer Vervolgens Nieuw item toevoegen>en voeg een nieuw bestand toe met de naam SetCertAccess.ps1. Bewerk het bestand SetCertAccess.ps1 om het volgende script toe te voegen:

$subject="mytestcert"
$userGroup="Network Service"

Write-Host "Checking permissions to certificate $subject.." -ForegroundColor DarkCyan

$cert = (gci Cert:\LocalMachine\My\ | where { $_.Subject.Contains($subject) })[-1]

if ($cert -eq $null)
{
    $message="Certificate with subject:"+$subject+" does not exist at Cert:\LocalMachine\My\"
    Write-Host $message -ForegroundColor Red
    exit 1;
}elseif($cert.HasPrivateKey -eq $false){
    $message="Certificate with subject:"+$subject+" does not have a private key"
    Write-Host $message -ForegroundColor Red
    exit 1;
}else
{
    $keyName=$cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName

    $keyPath = "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\"

    if ($keyName -eq $null){
      $privateKey = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($cert)      
      $keyName = $privateKey.Key.UniqueName
      $keyPath = "C:\ProgramData\Microsoft\Crypto\Keys"
    }

    $fullPath=$keyPath+$keyName
    $acl=(Get-Item $fullPath).GetAccessControl('Access')


    $hasPermissionsAlready = ($acl.Access | where {$_.IdentityReference.Value.Contains($userGroup.ToUpperInvariant()) -and $_.FileSystemRights -eq [System.Security.AccessControl.FileSystemRights]::FullControl}).Count -eq 1

    if ($hasPermissionsAlready){
        Write-Host "Account $userGroup already has permissions to certificate '$subject'." -ForegroundColor Green
        return $false;
    } else {
        Write-Host "Need add permissions to '$subject' certificate..." -ForegroundColor DarkYellow

        $permission=$userGroup,"Full","Allow"
        $accessRule=new-object System.Security.AccessControl.FileSystemAccessRule $permission
        $acl.AddAccessRule($accessRule)
        Set-Acl $fullPath $acl

        Write-Output "Permissions were added"

        return $true;
    }
}

Wijzig eigenschappen voor het bestand SetCertAccess.ps1 om Kopiëren in te stellen op Uitvoermap om te kopiëren als nieuwer.

Voer het installatiescript uit als beheerder

Standaard wordt het uitvoerbare invoerpunt voor de service-installatie uitgevoerd met dezelfde referenties als Service Fabric (meestal het netwerkserviceaccount). Voor SetCertAccess.ps1 zijn beheerdersmachtigingen vereist. In het toepassingsmanifest kunt u de beveiligingsmachtigingen voor het uitvoeren van het opstartscript onder een lokaal beheerdersaccount wijzigen.

Open Voting/ApplicationPackageRoot/ApplicationManifest.xml vanuit Solution Explorer. Maak eerst een Principals sectie en voeg een nieuwe gebruiker toe (bijvoorbeeld SetupAdminUser). Voeg het gebruikersaccount SetupAdminUser toe aan de systeemgroep Administrators.

Configureer vervolgens in VotingWebPkg in de ServiceManifestImport sectie een RunAsPolicy om de Principal SetupAdminUser toe te passen op het beginpunt van de installatie. Dit beleid vertelt Service Fabric dat het Setup.bat-bestand wordt uitgevoerd als SetupAdminUser (met beheerdersmachtigingen).

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="VotingType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
  <Parameters>
    <Parameter Name="VotingData_MinReplicaSetSize" DefaultValue="3" />
    <Parameter Name="VotingData_PartitionCount" DefaultValue="1" />
    <Parameter Name="VotingData_TargetReplicaSetSize" DefaultValue="3" />
    <Parameter Name="VotingWeb_InstanceCount" DefaultValue="-1" />
  </Parameters>
  <ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="VotingDataPkg" ServiceManifestVersion="1.0.0" />
    <ConfigOverrides />
  </ServiceManifestImport>
  <ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="VotingWebPkg" ServiceManifestVersion="1.0.0" />
    <ConfigOverrides />
    <Policies>
      <RunAsPolicy CodePackageRef="Code" UserRef="SetupAdminUser" EntryPointType="Setup" />
    </Policies>
  </ServiceManifestImport>
  <DefaultServices>
    <Service Name="VotingData">
      <StatefulService ServiceTypeName="VotingDataType" TargetReplicaSetSize="[VotingData_TargetReplicaSetSize]" MinReplicaSetSize="[VotingData_MinReplicaSetSize]">
        <UniformInt64Partition PartitionCount="[VotingData_PartitionCount]" LowKey="0" HighKey="25" />
      </StatefulService>
    </Service>
    <Service Name="VotingWeb" ServicePackageActivationMode="ExclusiveProcess">
      <StatelessService ServiceTypeName="VotingWebType" InstanceCount="[VotingWeb_InstanceCount]">
        <SingletonPartition />
      </StatelessService>
    </Service>
  </DefaultServices>
  <Principals>
    <Users>
      <User Name="SetupAdminUser">
        <MemberOf>
          <SystemGroup Name="Administrators" />
        </MemberOf>
      </User>
    </Users>
  </Principals>
</ApplicationManifest>

De toepassing lokaal uitvoeren

Selecteer in Solution Explorer de stemtoepassing en stel de eigenschap Toepassings-URL in op https://localhost:443.

Sla alle bestanden op en selecteer vervolgens F5 om de toepassing lokaal uit te voeren. Nadat de toepassing is geïmplementeerd, wordt er een browser geopend.https://localhost:443 Als u een zelfondertekend certificaat gebruikt, ziet u een waarschuwing dat uw pc de beveiliging van deze website niet vertrouwt. Ga door naar de webpagina.

Schermopname van de Service Fabric Voting Sample-app die wordt uitgevoerd in een browser en de localhost-URL.

Het certificaat installeren op clusterknooppunten

Voordat u de toepassing in Azure implementeert, installeert u het certificaat in het certificaat Cert:\LocalMachine\My Store van alle externe clusterknooppunten. Services kunnen worden verplaatst naar andere knooppunten van het cluster. Wanneer de front-endwebservice wordt gestart op een clusterknooppunt, zoekt het opstartscript het certificaat op en configureert het toegangsmachtigingen.

Als u het certificaat op clusterknooppunten wilt installeren, moet u het certificaat eerst exporteren als een PFX-bestand. Open het toepassingsbestand certlm.msc en ga naar Persoonlijke>certificaten. Klik met de rechtermuisknop op het mytestcert-certificaat en selecteer vervolgens Alle taken>exporteren.

Schermopname van het exporteren van het certificaat.

Selecteer ja in de wizard Exporteren, exporteer de persoonlijke sleutel en selecteer vervolgens de PFX-indeling. Exporteer het bestand naar C:\Users\sfuser\votingappcert.pfx.

Installeer vervolgens het certificaat op het externe cluster met behulp van PowerShell-scripts.

Waarschuwing

Een zelfondertekend certificaat volstaat voor ontwikkel- en testtoepassingen. Gebruik voor productietoepassingen een certificaat van een certificeringsinstantie (CA) in plaats van een zelfondertekend certificaat.

Poort 443 openen in de Azure-load balancer en het virtuele netwerk

Open poort 443 in de load balancer als deze niet is geopend:

$probename = "AppPortProbe6"
$rulename="AppPortLBRule6"
$RGname="voting_RG"
$port=443

# Get the load balancer resource
$resource = Get-AzResource | Where {$_.ResourceGroupName –eq $RGname -and $_.ResourceType -eq "Microsoft.Network/loadBalancers"}
$slb = Get-AzLoadBalancer -Name $resource.Name -ResourceGroupName $RGname

# Add a new probe configuration to the load balancer
$slb | Add-AzLoadBalancerProbeConfig -Name $probename -Protocol Tcp -Port $port -IntervalInSeconds 15 -ProbeCount 2

# Add rule configuration to the load balancer
$probe = Get-AzLoadBalancerProbeConfig -Name $probename -LoadBalancer $slb
$slb | Add-AzLoadBalancerRuleConfig -Name $rulename -BackendAddressPool $slb.BackendAddressPools[0] -FrontendIpConfiguration $slb.FrontendIpConfigurations[0] -Probe $probe -Protocol Tcp -FrontendPort $port -BackendPort $port

# Set the goal state for the load balancer
$slb | Set-AzLoadBalancer

Doe hetzelfde voor het gekoppelde virtuele netwerk:

$rulename="allowAppPort$port"
$nsgname="voting-vnet-security"
$RGname="voting_RG"
$port=443

# Get the network security group resource
$nsg = Get-AzNetworkSecurityGroup -Name $nsgname -ResourceGroupName $RGname

# Add the inbound security rule.
$nsg | Add-AzNetworkSecurityRuleConfig -Name $rulename -Description "Allow app port" -Access Allow `
    -Protocol * -Direction Inbound -Priority 3891 -SourceAddressPrefix "*" -SourcePortRange * `
    -DestinationAddressPrefix * -DestinationPortRange $port

# Update the network security group
$nsg | Set-AzNetworkSecurityGroup

De app implementeren in Azure

Sla alle bestanden op, schakel over van Foutopsporing naar Release en selecteer F6 om opnieuw te bouwen. Klik in Solution Explorer met de rechtermuisknop op Stemmen en selecteer Publiceren. Selecteer het verbindingseindpunt van het cluster dat is gemaakt in Een toepassing implementeren op een cluster of selecteer een ander cluster. Selecteer Publiceren om de toepassing naar het externe cluster te publiceren.

Wanneer de toepassing wordt geïmplementeerd, opent u een webbrowser en gaat u naar https://mycluster.region.cloudapp.azure.com:443 (werk de URL bij met het verbindingseindpunt voor uw cluster). Als u een zelfondertekend certificaat gebruikt, ziet u een waarschuwing dat uw pc de beveiliging van deze website niet vertrouwt. Ga door naar de webpagina.

Schermopname van de Service Fabric Voting Sample-app die wordt uitgevoerd in een browservenster.

Volgende stap

Ga door naar de volgende zelfstudie: