Script Azure DevOps Powershell Impossibile creare un canale protetto SSL / TLS

Sep 17 2020

Problema:
se chiamo il comando Get-AzureDeployment (anche Get-AzureService) dall'attività "Azure Powershell" nella pipeline DevOps, ricevo: " La richiesta è stata interrotta: impossibile creare il canale protetto SSL / TLS. '

Introduzione:

  • Uso Azure DevOps per distribuire il servizio Azure Cloud (classico) in Azure
  • L'attività "Azure Powershell" ha funzionato tutto il tempo, ma poi senza cambiare nulla ha smesso di funzionare
  • Ho anche importato il certificato (utilizzato da DevOps) nel mio PC (da Import-AzurePublishSettingsFile) e ho provato a eseguire lo stesso script PowerShell e ogni rete funziona bene, quindi mi aspetto un problema in DevOps

Connessione DevOps:

  • Ho creato la "connessione di servizio" in Azure DevOps per connettermi ad Azure
  • La connessione al servizio è di tipo "Azure classico" (perché "Azure Resource Manager" non è per "Servizio cloud classico")
  • Il metodo di autenticazione della "connessione al servizio classico di Azure" è "basato su certificato".
  • Ho usato il certificato generato da "File delle impostazioni di pubblicazione" per la mia sottoscrizione ad Azure. Il certificato è stato inserito da azure in Il mio abbonamento-> Certificati di gestione (la data di scadenza è a metà 2021)
  • Uso questa connessione di servizio per distribuire l'app (classica del servizio cloud) in Azure senza problemi (tramite l'attività DevOps "Distribuzione del servizio cloud di Azure") ma solo l'attività "Azure Powershell" inizia a fallire .

Tutto ha funzionato per 3 mesi e poi ha smesso di funzionare per qualsiasi motivo. La cosa strana è che quando stavo giocando con DevOps per scoprire cosa c'è che non va, l'attività è stata eseguita una volta con successo, ma quando ho provato di nuovo ho ricevuto nuovamente l'errore.

Ho entrambi i registri, dalla chiamata riuscita e dalla chiamata fallita. 2506 righe di log sono identiche e la modifica è dopo questa riga.

Posso inviarvi entrambi i registri completi ma non voglio inserire qui registri così lunghi.

Prova riuscita:

VERBOSE: 8:31:40 AM - Begin Operation: Get-AzureDeployment
VERBOSE: 8:31:42 AM - Completed Operation: Get-AzureDeployment
... some other info about the deployment in slot

Log dalla chiamata non riuscita:

VERBOSE: 9:53:39 AM - Begin Operation: Get-AzureDeployment
##[debug]Caught exception from task script.
##[debug]Error record:
##[debug]Get-AzureDeployment : An error occurred while sending the request.
##[debug]At D:\a\r1\a\_Tools\Powershell\cloud-service_swap-slot.ps1:14 char:15
##[debug]+ ... eployment = Get-AzureDeployment -Slot "Staging" -ServiceName $CloudSe ...
##[debug]+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
##[debug]    + CategoryInfo          : CloseError: (:) [Get-AzureDeployment], HttpRequestException
##[debug]    + FullyQualifiedErrorId : Microsoft.WindowsAzure.Commands.ServiceManagement.HostedServices.GetAzureDeploymentComma    nd
##[debug] 
##[debug]Script stack trace:
##[debug]at <ScriptBlock>, D:\a\r1\a\_Tools\Powershell\cloud-service_swap-slot.ps1: line 14
##[debug]at <ScriptBlock>, <No file>: line 1
##[debug]at <ScriptBlock>, D:\a\_tasks\AzurePowerShell_72a1931b-effb-4d2e-8fd8-f8472a07cb62\3.171.2\AzurePowerShell.ps1: line 145
##[debug]at <ScriptBlock>, D:\a\_tasks\AzurePowerShell_72a1931b-effb-4d2e-8fd8-f8472a07cb62\3.171.2\AzurePowerShell.ps1: line 141
##[debug]at <ScriptBlock>, <No file>: line 1
##[debug]at <ScriptBlock>, <No file>: line 22
##[debug]at <ScriptBlock>, <No file>: line 18
##[debug]at <ScriptBlock>, <No file>: line 1
##[debug]Exception:
##[debug]System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
##[debug]   at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
##[debug]   at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
##[debug]   --- End of inner exception stack trace ---
##[debug]   at Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
##[debug]   at Microsoft.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess(Task task)
##[debug]   at Microsoft.WindowsAzure.Management.Compute.DeploymentOperationsExtensions.GetBySlot(IDeploymentOperations operations, String serviceName, DeploymentSlot deploymentSlot)
##[debug]   at Microsoft.WindowsAzure.Commands.Utilities.Common.ServiceManagementBaseCmdlet.ExecuteClientActionNewSM[TResult](Object input, String operationDescription, Func`1 action, Func`3 contextFactory)
##[error]An error occurred while sending the request.
##[debug]Processed: ##vso[task.logissue type=error]An error occurred while sending the request.
##[debug]Processed: ##vso[task.complete result=Failed]

In entrambi i log posso anche trovare questo per l'aggiunta di un account Azure in Powershell:

##[debug]Added certificate to the certificate store.
##[command]Set-AzureSubscription -SubscriptionName PXX -SubscriptionId XXXXXX01-09f5-4703-bcc9-6ff914XXXXXX -Certificate ******** -Environment AzureCloud 
##[command]Select-AzureSubscription -SubscriptionId XXXXXX01-09f5-4703-bcc9-6ff914XXXXXX
##[debug]Leaving Initialize-Azure.
## Initializing Azure Complete 

(Ho sostituito alcune stringhe con X)

C'è l'attività Powershell in YAML:

steps:
- task: AzurePowerShell@3
  displayName: 'Swap slots'
  inputs:
    azureConnectionType: ConnectedServiceName
    azureClassicSubscription: 'PXX subscription'
    ScriptPath: '$(System.DefaultWorkingDirectory)/_Tools/Powershell/cloud-service_swap-slot.ps1'
    ScriptArguments: '-CloudServiceName $(CloudServiceName)'
    FailOnStandardError: true
    azurePowerShellVersion: LatestVersion

E lo script Powershell per lo scambio di slot che funziona dal PC locale (con lo stesso certificato) ma non funziona in DevOps:

[CmdletBinding(PositionalBinding=$True)]
Param(
    [Parameter(Mandatory = $true)] [String]$CloudServiceName              # required
)

# Check if Windows Azure Powershell is avaiable 
if ((Get-Module -ListAvailable Azure) -eq $null) { throw "Windows Azure Powershell not found! Please install from http://www.windowsazure.com/en-us/downloads/#cmd-line-tools" } # VIP Swap $Deployment = Get-AzureDeployment -Slot "Staging" -ServiceName $CloudServiceName #It's failing here if ($Deployment -ne $null -AND $Deployment.DeploymentId  -ne $null) { Write-Output ("Current Status of staging in {0}" -f $CloudServiceName); 
     Write-Host ($Deployment | Select-Object -Property * -ExcludeProperty Configuration,RolesConfiguration | Format-List | Out-String); $MoveStatus = Move-AzureDeployment -ServiceName $CloudServiceName Write-Output ("Vip swap of {0} status: {1}" -f $CloudServiceName, $MoveStatus.OperationStatus) }else { Write-Output ("There is no deployment in staging slot of {0} to swap." -f $CloudServiceName) 
} 

Qualcuno ha la stessa esperienza come me? Dove potrebbe essere il problema?

# Aggiornare

Ho provato ad aggiungere questa impostazione del protocollo di sicurezza all'inizio dello script ma con lo stesso errore.

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

Risposte

1 keyset Sep 29 2020 at 05:30

Questo sembra essere un problema con gli agenti di build Microsoft, ma l'aggiunta del codice seguente all'inizio di ogni attività di Azure Powershell sembra aver risolto il problema fino a quando non riescono a capirlo.

$pcert = (Get-Variable Endpoint -ValueOnly).Auth.Parameters.certificate $bytes = [convert]::FromBase64String($pcert) [IO.File]::WriteAllBytes("C:\cert.pfx",$bytes) 
$null = Import-PfxCertificate -FilePath C:\cert.pfx -CertStoreLocation cert:\CurrentUser\My
2 AmrutaKawade Oct 02 2020 at 20:37

Ci sono alcune soluzioni alternative che funzionano.

  1. Soluzione 1

    1. Usa attività Azure Powershell versione 5
    2. Seleziona "Connessione ad Azure Resource Manager"
    3. Cambiare i comandi ASM Module per comandi Az
  2. Soluzione 2

    1. Usa attività Azure Powershell versione 3
    2. Connessione classica
    3. Eseguire il downgrade della versione di Azure Powershell a 4.2.1
  3. Soluzione 3 (per agenti privati)

    1. Crea un certificato autofirmato nel tuo CurrentUser \ Il mio negozio. puoi trovare i dettagli sulla creazione di un certificato autofirmato qui:https://docs.microsoft.com/en-us/azure/cloud-services/cloud-services-certs-create
    2. Esporta la chiave pubblica per il certificato come file CER con codifica DER (puoi utilizzare mmc o qualsiasi altro strumento di certificazione per questo)
    3. Carica il file .Cer come certificato di gestione tramite il portale: https://docs.microsoft.com/en-us/previous-versions/azure/azure-api-management-certs
    4. Autenticare utilizzando Set-AzureSubscription:
     PS C: \> Clear-AzureProfile
     PS C: \> $cert = Get-Item Cert:\CurrentUser\My\
     PS C:\ > Set-AzureSubscription -SubscriptionName "" -SubscriptionId  -Certificate $cert
     PS C: \> Select-AzureSubscription -SubscriptionId 
     
  4. Soluzione 4

    1. Aggiungi lo script seguente a ogni attività di Azure Powershell

        $p = (Get-Variable Endpoint -ValueOnly).Auth.Parameters.certificate
        $bytes = [convert] :: FromBase64String ($p)
        [IO.File]::WriteAllBytes("C:\cert.pfx",$byte)
        Import-PfxCertificate -FilePath C: \ cert.pfx -CertStoreLocation cert: \ CurrentUser \ My
        .
        .
        copione vero e proprio
        .
        .
        #remove certificate from store
        $thumb = (Get-PfxData -FilePath "C:\cert.pfx").EndEntityCertificates.Thumbprint
        Remove-Item -Path cert:\CurrentUser\My\$pollice -recurse -Force
      
1 Neil Sep 18 2020 at 16:27

Abbiamo avuto lo stesso problema. Si è manifestato solo sugli windows-2019agenti, no vs2017-win2016. Quindi puoi risolverlo cambiando il tipo di agente, ma una soluzione migliore è usare una versione specifica di Powershell 5.1.1invece di latest. Sembra che latestrecentemente sia aumentato a 5.3.0che causa questo errore.

1 BallaGyőző Sep 22 2020 at 13:58

Ho lo stesso problema e ho provato tutti questi, per me ha funzionato solo se ho aggiunto questo dopo la parte Initialize-Azure: "Set-AzureSubscription -SubscriptionId [my subscription id] -CurrentStorageAccountName [storage name]"

1 DamienCaro Oct 07 2020 at 01:17

Questo problema è causato da una modifica del comportamento introdotta con l'aggiornamento .NET di settembre. Il codice seguente ripristinerà l'archiviazione implicita delle chiavi (il comportamento precedente di .Net 4.x) tramite una variabile di ambiente:

Set-Item env:\COMPLUS_CngImplicitPersistKeySet 1

NOTA : sarà quindi necessario creare un nuovo file di impostazioni di pubblicazione, poiché il vecchio certificato e le chiavi non verranno sovrascritti da un'importazione successiva.

SourabhKrishna Sep 24 2020 at 16:28

Il downgrade della versione Az Powershell alla 4.2.1 funziona usando l'attività AzurePowerShell @ 3.

FrankvanEykelen Nov 11 2020 at 18:13

Nel mio caso ho Get-AzureServiceRemoteDesktopExtensionriscontrato questo problema con il comando in un'attività "Esegui Azure Powershell in linea" nel nostro Team Foundation Server 2017 locale.

Ho provato ad aggiungere la riga suggerita qui da @ damien-caro ...

Set-Item env:\COMPLUS_CngImplicitPersistKeySet 1

... al mio script, ma questo ha risolto il problema solo per una singola versione. Tutti i successivi rilasci / distribuzioni non sono riusciti con Could not create SSL/TLS secure channelancora una volta.

Il problema è stato risolto semplicemente aggiungendolo come variabile alla definizione del rilascio. (Per testarlo ho distribuito con successo la stessa versione a due ambienti, tre volte di seguito.)

Ho trovato questa soluzione qui: https://github.com/Azure/azure-powershell/issues/13117#issuecomment-706665722