Sdílet prostřednictvím


Kurz: Přidání koncového bodu HTTPS pro aplikaci Service Fabric pomocí Kestrel

Tento kurz je třetí částí série. Zjistěte, jak přidat koncový bod HTTPS do služby ASP.NET Core spuštěné v Azure Service Fabric. Až budete hotovi, máte hlasovací aplikaci, která má webový front-end s povoleným protokolem HTTPS ASP.NET Core, který naslouchá na portu 443. Pokud nechcete hlasovací aplikaci vytvořit ručně v první části série kurzů, můžete si stáhnout zdrojový kód , abyste získali dokončenou aplikaci.

V tomto kurzu se naučíte:

  • Definovat ve službě koncový bod HTTPS
  • Nastavení Kestrel pro použití HTTPS
  • Instalace certifikátu TLS/SSL na vzdálené uzly clusteru
  • Udělení přístupu k privátnímu klíči certifikátu službě NetworkService
  • Otevřít port 443 v nástroji pro vyrovnávání zatížení Azure
  • Nasadit aplikaci do vzdáleného clusteru

V této sérii kurzů se dozvíte, jak:

Poznámka:

Při práci s Azure doporučujeme používat modul Azure Az PowerShellu. Pokud chcete začít, přečtěte si téma Instalace Azure PowerShellu. Informace o tom, jak migrovat na modul Az PowerShell, najdete v tématu Migrace Azure PowerShellu z AzureRM na Az.

Požadavky

Než začnete s tímto kurzem:

Získání certifikátu nebo vytvoření vývojového certifikátu podepsaného svým držitelem

Pro produkční aplikace používejte certifikát od certifikační autority (CA). Pro účely vývoje a testování můžete vytvořit a používat certifikát podepsaný svým držitelem. Sada Service Fabric SDK obsahuje skript CertSetup.ps1 . Skript vytvoří certifikát podepsaný svým držitelem a importuje ho do úložiště certifikátů Cert:\LocalMachine\My . Otevřete okno příkazového řádku jako správce a spuštěním následujícího příkazu vytvořte certifikát s předmětem CN=mytestcert:

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

Pokud už máte soubor PFX (Personal Information Exchange), spusťte následující příkaz, který certifikát naimportuje do úložiště certifikátů Cert:\LocalMachine\My certificate Store:


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

Definice koncového bodu HTTPS v manifestu služby

Otevřete Visual Studio pomocí možnosti Spustit jako správce a otevřete řešení Voting. V Průzkumníku řešení otevřete soubor VotingWeb/PackageRoot/ServiceManifest.xml. Manifest služby definuje koncové body služby. Endpoints Vyhledejte oddíl a upravte hodnotu koncového ServiceEndpoint bodu. Změňte název na EndpointHttps, nastavte protokol na https, typ na Inputa port na 443. Uložte provedené změny.

<?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>

Nakonfigurovat Kestrel k používání HTTPS

V Průzkumníku řešení otevřete soubor VotingWeb/VotingWeb.cs. Nakonfigurujte Kestrel tak, aby používal protokol HTTPS a vyhledá certifikát v úložišti Cert:\LocalMachine\My . Přidejte následující příkazy using:

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

Aktualizujte hodnotu pro ServiceInstanceListener použití nového EndpointHttps koncového bodu a naslouchejte na portu 443. Když nastavíte webového hostitele tak, aby používal server Kestrel, musíte nakonfigurovat Kestrel, aby naslouchal adresám IPv6 ve všech síťových rozhraních: 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();
        }))

Dále přidejte následující metodu, aby Kestrel mohl najít certifikát v Cert:\LocalMachine\My store pomocí předmětu.

Nahraďte <your_CN_value> certifikát podepsaný mytestcert svým držitelem pomocí předchozího příkazu PowerShellu nebo použijte CN vašeho certifikátu.

Pokud používáte místní nasazení localhost, doporučujeme, CN=localhost abyste se vyhnuli výjimkám ověřování.

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];
    }
}


Udělení přístupu k privátnímu klíči certifikátu službě Network Service

V předchozím kroku jste certifikát naimportovali do úložiště Cert:\LocalMachine\My na vývojovém počítači.

Teď explicitně udělte účtu, na kterém je služba spuštěná (ve výchozím nastavení síťová služba), přístup k privátnímu klíči certifikátu. Tento krok můžete provést ručně (pomocí nástroje certlm.msc), ale lepší je spustit skript PowerShellu tak, že v SetupEntryPoint manifestu služby nakonfigurujete spouštěcí skript.

Poznámka:

Service Fabric podporuje deklarování certifikátů koncových bodů kryptografickým otiskem nebo běžným názvem subjektu. V takovém případě modul runtime nastaví vazbu a přidělení privátního klíče certifikátu k identitě, ve které služba běží. Modul runtime také monitoruje certifikát pro změny, obnovení a aktualizace přidělení odpovídajícího privátního klíče.

Konfigurace vstupního bodu nastavení služby

V Průzkumníku řešení otevřete soubor VotingWeb/PackageRoot/ServiceManifest.xml. CodePackage V části přidejte SetupEntryPoint uzel a pak přidejte ExeHost uzel. In ExeHost, set to Setup.batProgram , and set to CodePackageWorkingFolder . Při spuštění služby VotingWeb se skript Setup.bat spustí ve složce CodePackage před spuštěním VotingWeb.exe .

<?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>

Přidání dávkových skriptů a instalačních skriptů PowerShellu

Pokud chcete spustit PowerShell z hodnoty pro SetupEntryPoint, můžete spustit PowerShell.exe v dávkovém souboru, který odkazuje na soubor PowerShellu.

Nejprve do projektu služby přidejte dávkový soubor. V Průzkumník řešení klepněte pravým tlačítkem myši VotingWeb a pak vyberte Přidat>novou položku. Přidejte nový soubor s názvem Setup.bat. Upravte soubor Setup.bat a přidejte následující příkaz:

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

Upravte vlastnosti souboru Setup.bat a nastavte kopírovat do výstupního adresáře , pokud je novější.

Snímek obrazovky znázorňující nastavení vlastností souboru

V Průzkumník řešení klikněte pravým tlačítkem na VotingWeb. Pak vyberte Přidat>novou položku a přidejte nový soubor s názvem SetCertAccess.ps1. Upravte soubor SetCertAccess.ps1 a přidejte následující skript:

$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;
    }
}

Upravte vlastnosti pro soubor SetCertAccess.ps1 a nastavte kopírovat do výstupního adresáře, pokud je novější.

Spuštění instalačního skriptu jako správce

Ve výchozím nastavení se spustitelný soubor vstupního bodu služby spouští pomocí stejných přihlašovacích údajů jako Service Fabric (obvykle účet síťové služby). SetCertAccess.ps1 vyžaduje oprávnění správce. V manifestu aplikace můžete změnit oprávnění zabezpečení tak, aby se spouštěcí skript spouštěl pod účtem místního správce.

V Průzkumníku řešení otevřete soubor Voting/ApplicationPackageRoot/ApplicationManifest.xml. Nejprve vytvořte Principals oddíl a přidejte nového uživatele (například SetupAdminUser). Přidejte uživatelský účet SetupAdminUser do systémové skupiny Správci.

Dále v VotingWebPkg v ServiceManifestImport části nakonfigurujte RunAsPolicy, aby použil objekt zabezpečení SetupAdminUser na vstupní bod nastavení. Tato zásada říká Service Fabric, že soubor Setup.bat běží jako SetupAdminUser (s oprávněními správce).

<?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>

Aplikaci spustíte místně.

V Průzkumník řešení vyberte hlasovací aplikaci a nastavte vlastnost Adresa URL aplikace na https://localhost:443.

Uložte všechny soubory a pak výběrem klávesy F5 spusťte aplikaci místně. Po nasazení aplikace se otevře https://localhost:443prohlížeč . Pokud používáte certifikát podepsaný svým držitelem, zobrazí se upozornění, že váš počítač nedůvěřuje zabezpečení tohoto webu. Pokračujte na webovou stránku.

Snímek obrazovky znázorňující ukázkovou aplikaci Service Fabric Voting spuštěnou v prohlížeči a adresu URL místního hostitele

Instalace certifikátu na uzly clusteru

Před nasazením aplikace do Azure nainstalujte certifikát do úložiště Cert:\LocalMachine\My store všech uzlů vzdáleného clusteru. Služby se můžou přesunout na různé uzly clusteru. Když se front-endová webová služba spustí na uzlu clusteru, spouštěcí skript vyhledá certifikát a nakonfiguruje přístupová oprávnění.

Pokud chcete certifikát nainstalovat na uzly clusteru, nejprve certifikát vyexportujte jako soubor PFX. Otevřete soubor aplikace certlm.msc a přejděte na Osobní>certifikáty. Klikněte pravým tlačítkem myši na certifikát mytestcert a pak vyberte Všechny úlohy>exportu.

Snímek obrazovky znázorňující export certifikátu

V průvodci exportem vyberte Ano, exportujte privátní klíč a pak vyberte formát PFX. Exportujte soubor do umístění C:\Users\sfuser\votingappcert.pfx.

Dále nainstalujte certifikát do vzdáleného clusteru pomocí skriptů PowerShellu.

Upozorňující

Certifikát podepsaný svým držitelem je dostačující pro vývoj a testování aplikací. Pro produkční aplikace místo použití certifikátu podepsaného svým držitelem použijte certifikát od certifikační autority (CA ).

Otevření portu 443 v nástroji pro vyrovnávání zatížení Azure a virtuální síti

Pokud není otevřený, otevřete port 443 v nástroji pro vyrovnávání zatížení:

$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

Totéž udělejte pro přidruženou virtuální síť:

$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

Nasazení aplikace do Azure

Uložte všechny soubory, přepněte z ladění na release a vyberte F6 k opětovnému sestavení. V Průzkumník řešení klikněte pravým tlačítkem myši na Hlasování a vyberte Publikovat. Vyberte koncový bod připojení clusteru vytvořeného v tématu Nasazení aplikace do clusteru nebo vyberte jiný cluster. Výběrem možnosti Publikovat publikujte aplikaci do vzdáleného clusteru.

Když se aplikace nasadí, otevřete webový prohlížeč a přejděte na https://mycluster.region.cloudapp.azure.com:443 adresu URL (aktualizujte adresu URL koncovým bodem připojení pro váš cluster). Pokud používáte certifikát podepsaný svým držitelem, zobrazí se upozornění, že váš počítač nedůvěřuje zabezpečení tohoto webu. Pokračujte na webovou stránku.

Snímek obrazovky znázorňující ukázkovou aplikaci Service Fabric Voting spuštěnou v okně prohlížeče

Další krok

Přejděte k dalšímu kurzu: