Udostępnij za pośrednictwem


Samouczek: dodawanie punktu końcowego HTTPS dla aplikacji usługi Service Fabric przy użyciu biblioteki Kestrel

Ten samouczek jest trzecią częścią serii. Dowiedz się, jak dodać punkt końcowy HTTPS w usłudze ASP.NET Core uruchomionej w usłudze Azure Service Fabric. Po zakończeniu masz aplikację do głosowania z włączoną obsługą protokołu HTTPS ASP.NET Core frontonu internetowego, która nasłuchuje na porcie 443. Jeśli nie chcesz ręcznie tworzyć aplikacji do głosowania w części jednej z serii samouczków, możesz pobrać kod źródłowy, aby uzyskać ukończoną aplikację.

Z tego samouczka dowiesz się, jak wykonywać następujące czynności:

  • Definiowanie punktu końcowego HTTPS w usłudze
  • Konfigurowanie usługi Kestrel do korzystania z protokołu HTTPS
  • Instalowanie certyfikatu TLS/SSL w węzłach klastra zdalnego
  • Nadawanie usłudze sieciowej dostępu do klucza prywatnego certyfikatu
  • Otwieranie portu 443 w module równoważenia obciążenia platformy Azure
  • Wdrażanie aplikacji w klastrze zdalnym

W serii samouczków pokazano, jak wykonać następujące działania:

Uwaga

Do interakcji z platformą Azure zalecamy używanie modułu Azure Az w programie PowerShell. Aby rozpocząć, zobacz Instalowanie programu Azure PowerShell. Aby dowiedzieć się, jak przeprowadzić migrację do modułu Az PowerShell, zobacz Migracja programu Azure PowerShell z modułu AzureRM do modułu Az.

Wymagania wstępne

Przed rozpoczęciem tego samouczka:

Uzyskiwanie certyfikatu lub tworzenie certyfikatu programowania z podpisem własnym

W przypadku aplikacji produkcyjnych należy używać certyfikatu z urzędu certyfikacji. Dla celów projektowania i testowania możesz utworzyć i używać certyfikatu z podpisem własnym. Zestaw SDK usługi Service Fabric zawiera skrypt CertSetup.ps1 . Skrypt tworzy certyfikat z podpisem własnym i importuje go do magazynu certyfikatów Cert:\LocalMachine\My . Otwórz okno wiersza polecenia jako administrator i uruchom następujące polecenie, aby utworzyć certyfikat zawierający podmiot "CN=mytestcert":

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

Jeśli masz już plik wymiany informacji osobistych certyfikatu (PFX), uruchom następujące polecenie, aby zaimportować certyfikat do magazynu certyfikatów 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

Definiowanie punktu końcowego HTTPS w manifeście usługi

Otwórz program Visual Studio przy użyciu opcji Uruchom jako administrator , a następnie otwórz rozwiązanie do głosowania. W Eksploratorze rozwiązań otwórz plik VotingWeb/PackageRoot/ServiceManifest.xml. Manifest usługi definiuje punkty końcowe usługi. Znajdź sekcję i zmodyfikuj Endpoints wartość punktu ServiceEndpoint końcowego. Zmień nazwę na EndpointHttps, ustaw protokół na https, typ na Input, a port na 443. Zapisz zmiany.

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

Konfigurowanie usługi Kestrel do używania protokołu HTTPS

W Eksploratorze rozwiązań otwórz plik VotingWeb/VotingWeb.cs. Skonfiguruj usługę Kestrel, aby używać protokołu HTTPS i wyszukać certyfikat w magazynie Cert:\LocalMachine\My Store. Dodaj następujące instrukcje using:

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

Zaktualizuj wartość , ServiceInstanceListener aby użyć nowego EndpointHttps punktu końcowego i nasłuchiwać na porcie 443. Podczas konfigurowania hosta internetowego do używania serwera Kestrel należy skonfigurować usługę Kestrel tak, aby nasłuchiwać adresów IPv6 we wszystkich interfejsach sieciowych: 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();
        }))

Następnie dodaj następującą metodę, aby usługa Kestrel mogła znaleźć certyfikat w magazynie Cert:\LocalMachine\My store przy użyciu tematu.

Zastąp <your_CN_value> ciągiem mytestcert , jeśli został utworzony certyfikat z podpisem własnym przy użyciu poprzedniego polecenia programu PowerShell lub użyj nazwy CN certyfikatu.

Jeśli używasz wdrożenia lokalnego do localhostprogramu , zalecamy CN=localhost , aby uniknąć wyjątków uwierzytelniania.

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


Udzielanie usłudze sieciowej dostępu do klucza prywatnego certyfikatu

W poprzednim kroku zaimportowaliśmy certyfikat do magazynu Cert:\LocalMachine\My na komputerze dewelopera.

Teraz jawnie nadaj konto, na którym jest uruchomiona usługa (usługa sieciowa, domyślnie) dostęp do klucza prywatnego certyfikatu. Ten krok można wykonać ręcznie (przy użyciu narzędzia certlm.msc ), ale lepiej uruchomić skrypt programu PowerShell, konfigurując skrypt uruchamiania w SetupEntryPoint manifeście usługi.

Uwaga

Usługa Service Fabric obsługuje deklarowanie certyfikatów punktów końcowych za pomocą odcisku palca lub nazwy pospolitej podmiotu. W takim przypadku środowisko uruchomieniowe konfiguruje powiązanie i alokację klucza prywatnego certyfikatu do tożsamości uruchomionej przez usługę jako. Środowisko uruchomieniowe monitoruje również certyfikat pod kątem zmian, odnawiania i aktualizacji alokacji odpowiedniego klucza prywatnego.

Konfigurowanie punktu wejścia usługi instalatora

W Eksploratorze rozwiązań otwórz plik VotingWeb/PackageRoot/ServiceManifest.xml. CodePackage W sekcji dodaj SetupEntryPoint węzeł, a następnie dodaj ExeHost węzeł. W ExeHostpliku ustaw wartość Setup.batProgram i ustaw wartość WorkingFolder CodePackage. Po uruchomieniu usługi VotingWeb skrypt Setup.bat jest wykonywany w folderze CodePackage przed rozpoczęciem 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>

Dodawanie partii i skryptów instalacji programu PowerShell

Aby uruchomić program PowerShell z wartości SetupEntryPoint, można uruchomić PowerShell.exe w pliku wsadowym wskazującym plik programu PowerShell.

Najpierw dodaj plik wsadowy do projektu usługi. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy pozycję VotingWeb, a następnie wybierz polecenie Dodaj>nowy element. Dodaj nowy plik o nazwie Setup.bat. Edytuj plik Setup.bat pliku i dodaj następujące polecenie:

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

Zmodyfikuj właściwości pliku Setup.bat, aby ustawić opcję Kopiuj do katalogu wyjściowego, aby skopiować, jeśli jest nowszy.

Zrzut ekranu przedstawiający konfigurowanie właściwości pliku.

W Eksplorator rozwiązań kliknij prawym przyciskiem myszy pozycję VotingWeb. Następnie wybierz pozycję Dodaj>nowy element i dodaj nowy plik o nazwie SetCertAccess.ps1. Edytuj plik SetCertAccess.ps1, aby dodać następujący skrypt:

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

Zmodyfikuj właściwości pliku SetCertAccess.ps1, aby ustawić opcję Kopiuj do katalogu wyjściowego, aby skopiować, jeśli jest nowszy.

Uruchamianie skryptu instalacji jako administrator

Domyślnie plik wykonywalny punktu wejścia konfiguracji usługi jest uruchamiany przy użyciu tych samych poświadczeń co usługa Service Fabric (zazwyczaj konto usługi sieciowej). SetCertAccess.ps1 wymaga uprawnień administratora. W manifeście aplikacji możesz zmienić uprawnienia zabezpieczeń do uruchamiania skryptu uruchamiania przy użyciu konta administratora lokalnego.

W Eksploratorze rozwiązań otwórz plik Voting/ApplicationPackageRoot/ApplicationManifest.xml. Najpierw utwórz sekcję Principals i dodaj nowego użytkownika (na przykład SetupAdminUser). Dodaj konto użytkownika SetupAdminUser do grupy systemowej Administratorzy.

Następnie w pliku VotingWebPkg w ServiceManifestImport sekcji skonfiguruj element RunAsPolicy, aby zastosować podmiot zabezpieczeń SetupAdminUser do punktu wejścia konfiguracji. Te zasady informują usługę Service Fabric, że plik Setup.bat jest uruchamiany jako SetupAdminUser (z uprawnieniami administratora).

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

Lokalne uruchamianie aplikacji

W Eksplorator rozwiązań wybierz aplikację do głosowania i ustaw właściwość Adres URL aplikacji na https://localhost:443.

Zapisz wszystkie pliki, a następnie wybierz F5, aby uruchomić aplikację lokalnie. Po wdrożeniu aplikacji zostanie otwarta przeglądarka .https://localhost:443 Jeśli używasz certyfikatu z podpisem własnym, zostanie wyświetlone ostrzeżenie, że komputer nie ufa bezpieczeństwu tej witryny internetowej. Przejdź do strony internetowej.

Zrzut ekranu przedstawiający przykładową aplikację usługi Service Fabric Voting działającą w przeglądarce i adres URL hosta lokalnego.

Instalowanie certyfikatu w węzłach klastra

Przed wdrożeniem aplikacji na platformie Azure zainstaluj certyfikat w magazynie Cert:\LocalMachine\My store wszystkich węzłów klastra zdalnego. Usługi można przenosić do różnych węzłów klastra. Po uruchomieniu usługi internetowej frontonu w węźle klastra skrypt uruchamiania wyszukuje certyfikat i konfiguruje uprawnienia dostępu.

Aby zainstalować certyfikat w węzłach klastra, najpierw wyeksportuj certyfikat jako plik PFX. Otwórz plik aplikacji certlm.msc i przejdź do pozycji Certyfikaty osobiste>. Kliknij prawym przyciskiem myszy certyfikat mytestcert , a następnie wybierz pozycję Wszystkie zadania>Eksportuj.

Zrzut ekranu przedstawiający eksportowanie certyfikatu.

W kreatorze eksportu wybierz pozycję Tak, wyeksportuj klucz prywatny, a następnie wybierz format PFX. Wyeksportuj plik do pliku C:\Users\sfuser\votingappcert.pfx.

Następnie zainstaluj certyfikat w klastrze zdalnym przy użyciu skryptów programu PowerShell.

Ostrzeżenie

Certyfikat z podpisem własnym jest wystarczający w przypadku programowania i testowania aplikacji. W przypadku aplikacji produkcyjnych należy użyć certyfikatu z urzędu certyfikacji zamiast certyfikatu z podpisem własnym.

Otwieranie portu 443 w usłudze Azure Load Balancer i sieci wirtualnej

Otwórz port 443 w module równoważenia obciążenia, jeśli nie jest otwarty:

$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

Wykonaj to samo w przypadku skojarzonej sieci wirtualnej:

$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

Wdrożenie aplikacji na platformie Azure

Zapisz wszystkie pliki, przełącz się z debugowania do wydania i wybierz F6, aby ponownie skompilować. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy pozycję Voting (Głosowanie) i wybierz polecenie Publish (Publikuj). Wybierz punkt końcowy połączenia klastra utworzonego w sekcji Wdrażanie aplikacji w klastrze lub wybierz inny klaster. Wybierz pozycję Publikuj, aby opublikować aplikację w klastrze zdalnym.

Po wdrożeniu aplikacji otwórz przeglądarkę internetową i przejdź do https://mycluster.region.cloudapp.azure.com:443 strony (zaktualizuj adres URL przy użyciu punktu końcowego połączenia dla klastra). Jeśli używasz certyfikatu z podpisem własnym, zostanie wyświetlone ostrzeżenie, że komputer nie ufa bezpieczeństwu tej witryny internetowej. Przejdź do strony internetowej.

Zrzut ekranu przedstawiający aplikację Service Fabric Voting Sample działającą w oknie przeglądarki.

Następny krok

Przejdź do następnego samouczka: