Självstudie: Lägga till en HTTPS-slutpunkt för ett Service Fabric-program med hjälp av Kestrel
Den här självstudien är del tre i en serie. Lär dig hur du lägger till en HTTPS-slutpunkt i en ASP.NET Core-tjänst som körs i Azure Service Fabric. När du är klar har du ett röstningsprogram som har en HTTPS-aktiverad ASP.NET Core-webbklientdel som lyssnar på port 443. Om du inte vill skapa röstningsprogrammet manuellt i del ett av självstudieserien kan du hämta källkoden för att hämta det färdiga programmet.
I den här självstudien lär du dig att:
- Definiera en HTTPS-slutpunkt i tjänsten
- Konfigurera Kestrel att använda HTTPS
- Installera TLS/SSL-certifikatet på fjärrklusternoderna
- Ge NetworkService åtkomst till certifikatets privata nyckel
- Öppna port 443 i Azure-lastbalanseraren
- Distribuera programmet till ett fjärrkluster
Självstudieserien visar hur du:
- Skapa ett .NET Service Fabric-program
- Distribuera programmet till ett fjärrkluster
- Lägga till en HTTPS-slutpunkt i en ASP.NET Core-klientdelstjänst (den här självstudien)
- Konfigurera CI/CD med hjälp av Azure Pipelines
- konfigurera övervakning och diagnostik för programmet
Kommentar
Vi rekommenderar att du använder Azure Az PowerShell-modulen för att interagera med Azure. Information om hur du kommer igång finns i Installera Azure PowerShell. Information om hur du migrerar till Az PowerShell-modulen finns i artikeln om att migrera Azure PowerShell från AzureRM till Az.
Förutsättningar
Innan du börjar den här självstudien:
- Om du inte har någon Azure-prenumeration kan du skapa ett kostnadsfritt konto.
- Installera Visual Studio 2019 version 16.5 eller senare, inklusive arbetsbelastningen för Azure-utveckling och arbetsbelastningen ASP.NET och webbutveckling.
- Installera Service Fabric SDK.
Hämta ett certifikat eller skapa ett självsignerat utvecklingscertifikat
För produktionsprogram ska du använda ett certifikat från en certifikatutfärdare (CA). För utveckling och testning kan du skapa och använda ett självsignerat certifikat. Service Fabric SDK innehåller skriptet CertSetup.ps1 . Skriptet skapar ett självsignerat certifikat och importerar det till certifikatarkivet Cert:\LocalMachine\My . Öppna kommandotolken som administratör och kör följande kommando för att skapa ett certifikat med ämnet "CN=mytestcert":
PS C:\program files\microsoft sdks\service fabric\clustersetup\secure> .\CertSetup.ps1 -Install -CertSubjectName CN=mytestcert
Om du redan har en PFX-fil (Personal Information Exchange) för certifikat kör du följande för att importera certifikatet till certifikatarkivet 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
Definiera en HTTPS-slutpunkt i tjänstmanifestet
Öppna Visual Studio med alternativet Kör som administratör och öppna sedan röstningslösningen. Öppna VotingWeb/PackageRoot/ServiceManifest.xml i Solution Explorer. Tjänstmanifestet definierar tjänstens slutpunkter. Leta upp avsnittet Endpoints
och redigera värdet för ServiceEndpoint
slutpunkten. Ändra namnet till EndpointHttps
, ange protokollet till https
, typen till Input
och porten till 443
. Spara dina ändringar.
<?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>
Konfigurera Kestrel för användning av HTTPS
Öppna filen VotingWeb/VotingWeb.cs i Solution Explorer. Konfigurera Kestrel att använda HTTPS och att söka efter certifikatet i Cert:\LocalMachine\My Store. Lägg till följande using
-uttryck:
using System.Net;
using Microsoft.Extensions.Configuration;
using System.Security.Cryptography.X509Certificates;
Uppdatera värdet för för ServiceInstanceListener
att använda den nya EndpointHttps
slutpunkten och lyssna på port 443. När du konfigurerar webbvärden för att använda Kestrel-servern måste du konfigurera Kestrel att lyssna efter IPv6-adresser i alla nätverksgränssnitt: 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();
}))
Lägg sedan till följande metod så att Kestrel kan hitta certifikatet i certifikatet :\LocalMachine\My store med hjälp av ämnet.
Ersätt <your_CN_value>
med mytestcert
om du skapade ett självsignerat certifikat med hjälp av det tidigare PowerShell-kommandot, eller använd certifikatets CN.
Om du använder en lokal distribution till localhost
rekommenderar vi att du använder CN=localhost
för att undvika autentiseringsfel.
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];
}
}
Bevilja nätverkstjänst åtkomst till certifikatets privata nyckel
I ett tidigare steg importerade du certifikatet till Cert:\LocalMachine\My Store på utvecklingsdatorn.
Ge nu uttryckligen det konto som kör tjänsten (nätverkstjänst, som standard) åtkomst till certifikatets privata nyckel. Du kan göra det här steget manuellt (med hjälp av verktyget certlm.msc ), men det är bättre att köra ett PowerShell-skript genom att konfigurera ett startskript i SetupEntryPoint
tjänstmanifestet.
Kommentar
Service Fabric stöder deklarering av slutpunktscertifikat med tumavtryck eller efter ämnesnamn. I så fall konfigurerar körningen bindningen och allokeringen för certifikatets privata nyckel till den identitet som tjänsten körs som. Körningen övervakar även certifikatet för ändringar, förnyelser och allokeringsuppdateringar för motsvarande privata nyckel.
Konfigurera tjänstens konfigurationsstartpunkt
Öppna VotingWeb/PackageRoot/ServiceManifest.xml i Solution Explorer. I avsnittet CodePackage
lägger du till SetupEntryPoint
noden och lägger sedan till en ExeHost
nod. I ExeHost
anger du Program
till Setup.bat
och anger WorkingFolder
till CodePackage
. När VotingWeb-tjänsten startar körs Setup.bat-skriptet i mappen CodePackage innan VotingWeb.exe startar.
<?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>
Lägga till konfigurationsskript för batch och PowerShell
Om du vill köra PowerShell från värdet för SetupEntryPoint
kan du köra PowerShell.exe i en batchfil som pekar på en PowerShell-fil.
Lägg först till batchfilen i tjänstens projekt. I Istraživač rešenja högerklickar du på VotingWeb och väljer sedan Lägg till>nytt objekt. Lägg till en ny fil med namnet Setup.bat. Redigera filen Setup.bat och lägg till följande kommando:
powershell.exe -ExecutionPolicy Bypass -Command ".\SetCertAccess.ps1"
Ändra egenskaperna för Setup.bat-filen för att ange Kopiera till Utdatakatalog till Kopiera om det är nyare.
Högerklicka på VotingWeb i Istraživač rešenja. Välj sedan Lägg till>nytt objekt och lägg till en ny fil med namnet SetCertAccess.ps1. Redigera filen SetCertAccess.ps1 för att lägga till följande 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;
}
}
Ändra egenskaper för filen SetCertAccess.ps1 för att ange Kopiera till Utdatakatalog till Kopiera om det är nyare.
Kör installationsskriptet som administratör
Som standard körs startpunkten för tjänstinstallationen med samma autentiseringsuppgifter som Service Fabric (vanligtvis nätverkstjänstkontot). SetCertAccess.ps1 kräver administratörsbehörighet. Du kan ändra säkerhetsbehörigheterna i manifestet så att startskriptet körs under ett lokalt administratörskonto.
Öppna Voting/ApplicationPackageRoot/ApplicationManifest.xml i Solution Explorer. Skapa först ett Principals
avsnitt och lägg till en ny användare (till exempel SetupAdminUser
). Lägg till användarkontot SetupAdminUser i systemgruppen Administrators.
I VotingWebPkg i ServiceManifestImport
avsnittet konfigurerar du sedan en RunAsPolicy för att tillämpa setupAdminUser-huvudnamnet på startpunkten för installationen. Den här principen anger för Service Fabric att Setup.bat-filen körs som SetupAdminUser (med administratörsbehörighet).
<?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>
Köra appen lokalt
I Istraživač rešenja väljer du programmet Röstning och anger egenskapen Application URL till https://localhost:443
.
Spara alla filer och välj sedan F5 för att köra programmet lokalt. När programmet har distribuerats öppnas en webbläsare till https://localhost:443
. Om du använder ett självsignerat certifikat visas en varning om att datorn inte litar på webbplatsens säkerhet. Fortsätt till webbsidan.
Installera certifikatet på klusternoder
Innan du distribuerar programmet till Azure installerar du certifikatet i certifikatet :\LocalMachine\My store för alla fjärrklusternoder. Tjänster kan flyttas till olika noder i klustret. När klientwebbtjänsten startar på en klusternod letar startskriptet upp certifikatet och konfigurerar åtkomstbehörigheter.
Om du vill installera certifikatet på klusternoder exporterar du först certifikatet som en PFX-fil. Öppna programfilen certlm.msc och gå till Personliga>certifikat. Högerklicka på mytestcert-certifikatet och välj sedan Exportera alla uppgifter>.
I exportguiden väljer du Ja, exporterar den privata nyckeln och väljer sedan PFX-format. Exportera filen till C:\Users\sfuser\votingappcert.pfx.
Installera sedan certifikatet på fjärrklustret med hjälp av PowerShell-skript.
Varning
Ett självsignerat certifikat räcker för utveckling och testning. För produktionsprogram använder du ett certifikat från en certifikatutfärdare (CA) i stället för att använda ett självsignerat certifikat.
Öppna port 443 i Azure-lastbalanseraren och det virtuella nätverket
Öppna port 443 i lastbalanseraren om den inte är öppen:
$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
Gör samma sak för det associerade virtuella nätverket:
$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
Distribuera appen till Azure
Spara alla filer, växla från Felsökning till Släpp och välj F6 för att återskapa. I Istraživač rešenja högerklickar du på Röstning och väljer Publicera. Välj klustrets slutpunkt för anslutning som du skapade i Distribuera ett program till ett kluster, eller välj ett annat kluster. Välj Publicera för att publicera programmet till fjärrklustret.
När programmet distribueras öppnar du en webbläsare och går till https://mycluster.region.cloudapp.azure.com:443
(uppdatera URL:en med anslutningsslutpunkten för klustret). Om du använder ett självsignerat certifikat visas en varning om att datorn inte litar på webbplatsens säkerhet. Fortsätt till webbsidan.
Gå vidare
Gå vidare till nästa kurs: