Öğretici: Kestrel kullanarak Service Fabric uygulaması için HTTPS uç noktası ekleme

Bu öğretici, serinin üçüncü bölümüdür. Azure Service Fabric'te çalışan bir ASP.NET Core hizmetine HTTPS uç noktası eklemeyi öğrenin. İşiniz bittiğinde, 443 numaralı bağlantı noktasını dinleyen HTTPS özellikli ASP.NET Core web ön ucuna sahip bir oylama uygulamanız olur. Öğretici serisinin birinci bölümünde oylama uygulamasını el ile oluşturmak istemiyorsanız, tamamlanmış uygulamayı almak için kaynak kodu indirebilirsiniz.

Bu öğreticide aşağıdakilerin nasıl yapılacağını öğreneceksiniz:

  • Hizmette bir HTTPS uç noktası tanımlama
  • Kestrel'i HTTPS kullanacak şekilde ayarlama
  • TlS/SSL sertifikasını uzak küme düğümlerine yükleme
  • Sertifikanın özel anahtarına NetworkService erişimi verme
  • Azure yük dengeleyicide 443 numaralı bağlantı noktasını açma
  • Uygulamayı uzak kümeye dağıtma

Öğretici serisi şunların nasıl yapılacağını gösterir:

Not

Azure ile etkileşim kurmak için Azure Az PowerShell modülünü kullanmanızı öneririz. Başlamak için bkz . Azure PowerShell'i yükleme. Az PowerShell modülüne nasıl geçeceğinizi öğrenmek için bkz. Azure PowerShell’i AzureRM’den Az’ye geçirme.

Önkoşullar

Bu öğreticiye başlamadan önce:

Sertifika alma veya otomatik olarak imzalanan geliştirme sertifikası oluşturma

Üretim uygulamaları için bir sertifika yetkilisinden (CA) alınan bir sertifikayı kullanın. Geliştirme ve test için otomatik olarak imzalanan bir sertifika oluşturup bunu kullanabilirsiniz. Service Fabric SDK'sı CertSetup.ps1 betiğini içerir. Betik otomatik olarak imzalanan bir sertifika oluşturur ve bunu Cert:\LocalMachine\My sertifika deposuna aktarır. Yönetici olarak bir Komut İstemi penceresi açın ve "CN=mytestcert" konusuna sahip bir sertifika oluşturmak için aşağıdaki komutu çalıştırın:

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

Zaten bir sertifika Kişisel Bilgi Değişimi (PFX) dosyanız varsa, sertifikayı Cert:\LocalMachine\My sertifika deposuna aktarmak için aşağıdakileri çalıştırın:


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

Hizmet bildiriminde bir HTTPS uç noktası tanımlama

Yönetici olarak çalıştır seçeneğini kullanarak Visual Studio'yu açın ve oylama çözümünü açın. Çözüm Gezgini'nde VotingWeb/PackageRoot/ServiceManifest.xml dosyasını açın. Hizmet bildirimi, hizmet uç noktalarını tanımlar. Endpoints bölümünü bulun ve uç nokta değerini ServiceEndpoint düzenleyin. adını EndpointHttpsolarak değiştirin, protokolü httpsolarak, türü Inputolarak, bağlantı noktasını 443olarak ayarlayın. Değişikliklerinizi kaydedin.

<?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’i HTTPS kullanacak şekilde yapılandırma

Çözüm Gezgini'nde VotingWeb/VotingWeb.cs dosyasını açın. Kestrel'i HTTPS kullanacak ve sertifikayı Cert:\LocalMachine\My store'da arayacak şekilde yapılandırın. Aşağıdaki using deyimlerini ekleyin:

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

yeni EndpointHttps uç noktayı kullanmak ve 443 numaralı bağlantı noktasını dinlemek için ServiceInstanceListener değerini güncelleştirin. Web konağını Kestrel sunucusunu kullanacak şekilde ayarlarken, Kestrel'i tüm ağ arabirimlerinde IPv6 adreslerini dinleyecek şekilde yapılandırmanız gerekir: 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();
        }))

Ardından, Kestrel'in sertifikayı Cert:\LocalMachine\My store'da konusunu kullanarak bulabilmesi için aşağıdaki yöntemi ekleyin.

mytestcert değerini, önceki PowerShell komutunu kullanarak otomatik olarak imzalanan bir sertifika oluşturduysanız veya sertifikanızın CN'sini kullanarak ile değiştirin<your_CN_value>.

için localhostyerel bir dağıtım kullanıyorsanız, kimlik doğrulaması özel durumlarını önlemek için kullanmanızı CN=localhost öneririz.

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


Sertifikanın özel anahtarına Ağ Hizmeti erişimi verme

Önceki bir adımda, sertifikayı geliştirme bilgisayarındaki Cert:\LocalMachine\My deposuna aktarmıştınız.

Şimdi, hizmeti çalıştıran hesaba (varsayılan olarak Ağ Hizmeti) sertifikanın özel anahtarına açıkça erişim verin. Bu adımı el ile (certlm.msc aracını kullanarak) yapabilirsiniz, ancak hizmet bildiriminde SetupEntryPoint bir başlangıç betiği yapılandırarak PowerShell betiğini çalıştırmak daha iyidir.

Not

Service Fabric, uç nokta sertifikalarını parmak izi veya konu ortak adına göre bildirmeyi destekler. Bu durumda, çalışma zamanı sertifikanın özel anahtarı için bağlamayı ve ayırmayı hizmetin çalıştığı kimliğe ayarlar. Çalışma zamanı ayrıca sertifikayı ilgili özel anahtar için değişiklikler, yenilemeler ve ayırma güncelleştirmeleri için izler.

Hizmet kurulumu giriş noktasını yapılandırma

Çözüm Gezgini'nde VotingWeb/PackageRoot/ServiceManifest.xml dosyasını açın. CodePackage bölümünde düğümü ekleyin SetupEntryPoint ve ardından bir ExeHost düğüm ekleyin. içindeExeHost, olarak Setup.batayarlayın Program ve olarak CodePackageayarlayınWorkingFolder. VotingWeb hizmeti başlatıldığında, Setup.bat betiği VotingWeb.exe başlamadan önce CodePackage klasöründe yürütülür.

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

Toplu işi ve PowerShell kurulum betiklerini ekleme

PowerShell'i değerinden çalıştırmak içinSetupEntryPoint, PowerShell.exe bir PowerShell dosyasına işaret eden bir toplu iş dosyasında çalıştırabilirsiniz.

İlk olarak, toplu iş dosyasını hizmet projesine ekleyin. Çözüm Gezgini'de VotingWeb'e sağ tıklayın ve ardından Yeni Öğe Ekle'yi>seçin. Setup.bat adlı yeni bir dosya ekleyin. Setup.bat dosyasını düzenleyin ve aşağıdaki komutu ekleyin:

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

Setup.bat dosyasının özelliklerini değiştirerek Çıktı Dizinine Kopyala'yı daha yeniyse Kopyala olarak ayarlayın.

Dosya özelliklerini ayarlamayı gösteren ekran görüntüsü.

Çözüm Gezgini'da VotingWeb'e sağ tıklayın. Ardından Yeni Öğe Ekle'yi>seçin ve SetCertAccess.ps1 adlı yeni bir dosya ekleyin. Aşağıdaki betiği eklemek için SetCertAccess.ps1 dosyasını düzenleyin:

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

SetCertAccess.ps1 dosyasının özelliklerini değiştirerek Çıktı Dizinine Kopyala'yı daha yeniyse Kopyala olarak ayarlayın.

Kurulum betiğini yönetici olarak çalıştırma

Varsayılan olarak, hizmet kurulum giriş noktası yürütülebilir dosyası Service Fabric ile aynı kimlik bilgilerini (genellikle Ağ Hizmeti hesabı) kullanarak çalışır. SetCertAccess.ps1 için yönetici izinleri gerekir. Uygulama bildiriminde güvenlik izinlerini bir yerel yönetici hesabı altındaki başlangıç betiğini çalıştıracak şekilde değiştirebilirsiniz.

Çözüm Gezgini’nde Voting/ApplicationPackageRoot/ApplicationManifest.xml dosyasını açın. İlk olarak, bir Principals bölüm oluşturun ve yeni bir kullanıcı ekleyin (örneğin, SetupAdminUser). SetupAdminUser kullanıcı hesabını Administrators sistem grubuna ekleyin.

Ardından VotingWebPkg bölümünde, SetupAdminUser sorumlusunu ServiceManifestImport kurulum giriş noktasına uygulamak için bir RunAsPolicy yapılandırın. Bu ilke Service Fabric'e Setup.bat dosyasının SetupAdminUser (yönetici izinleriyle) olarak çalıştığını bildirir.

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

Uygulamayı yerel olarak çalıştırma

Çözüm Gezgini'de Voting uygulamasını seçin ve Uygulama URL'si özelliğini olarak https://localhost:443 ayarlayın.

Tüm dosyaları kaydedin ve ardından F5'i seçerek uygulamayı yerel olarak çalıştırın. Uygulama dağıtıldıktan sonra için bir tarayıcı açılır https://localhost:443. Otomatik olarak imzalanan bir sertifika kullanıyorsanız bilgisayarınızın bu web sitesinin güvenliğine güvenmediğini belirten bir uyarı görürsünüz. Web sayfasına geçin.

Tarayıcıda çalışan Service Fabric Voting Sample uygulamasını ve localhost URL'sini gösteren ekran görüntüsü.

Sertifikayı küme düğümlerine yükleme

Uygulamayı Azure'a dağıtmadan önce, sertifikayı tüm uzak küme düğümlerinin Cert:\LocalMachine\My deposuna yükleyin. Hizmetler kümenin farklı düğümlerine geçebilir. Ön uç web hizmeti bir küme düğümünde başlatıldığında, başlangıç betiği sertifikayı arar ve erişim izinlerini yapılandırılır.

Sertifikayı küme düğümlerine yüklemek için önce sertifikayı PFX dosyası olarak dışarı aktarın. certlm.msc uygulama dosyasını açın ve Kişisel>Sertifikalar'a gidin. mytestcert sertifikasına sağ tıklayın ve ardından Tüm Görevleri>Dışarı Aktar'ı seçin.

Sertifikanın dışarı aktarıldığını gösteren ekran görüntüsü.

Dışarı aktarma sihirbazında Evet, özel anahtarı dışarı aktar'ı ve ardından PFX biçimini seçin. Dosyayı C:\Users\sfuser\votingappcert.pfx konumuna aktarın.

Ardından, PowerShell betiklerini kullanarak sertifikayı uzak kümeye yükleyin.

Uyarı

Geliştirme ve test uygulamaları için otomatik olarak imzalanan bir sertifika yeterlidir. Üretim uygulamaları için, otomatik olarak imzalanan bir sertifika kullanmak yerine sertifika yetkilisinden (CA) bir sertifika kullanın.

Azure yük dengeleyicide ve sanal ağda 443 numaralı bağlantı noktasını açma

Açık değilse yük dengeleyicide 443 numaralı bağlantı noktasını açın:

$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

İlişkili sanal ağ için de aynısını yapın:

$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

Uygulamayı Azure'a dağıtma

Tüm dosyaları kaydedin, Hata Ayıkla'dan Yayın'a geçin ve yeniden derlemek için F6'yı seçin. Çözüm Gezgini'da Oylama'ya sağ tıklayın ve Yayımla'yı seçin. Bir kümeye uygulama dağıtma bölümünde oluşturulan kümenin bağlantı uç noktasını veya başka bir kümeyi seçin. Uygulamayı uzak kümede yayımlamak için Yayımla'yı seçin.

Uygulama dağıtıldığında bir web tarayıcısı açın ve adresine gidin (URL'yi https://mycluster.region.cloudapp.azure.com:443 kümenizin bağlantı uç noktasıyla güncelleştirin). Otomatik olarak imzalanan bir sertifika kullanıyorsanız bilgisayarınızın bu web sitesinin güvenliğine güvenmediğini belirten bir uyarı görürsünüz. Web sayfasına geçin.

Tarayıcı penceresinde çalışan Service Fabric Oylama Örneği uygulamasını gösteren ekran görüntüsü.

Sonraki adım

Sonraki öğreticiye ilerleyin: