05 FÉVRIER 2025
Résoudre le problème du second saut avec CredSSP : installation de SQL Server via PowerShell Remoting
Cet article est consacré à un problème courant rencontré lors de l'automatisation d'infrastructure avec Azure DevOps, connu sous le nom de "second hop". Nous verrons pourquoi ce problème survient et comment le résoudre efficacement pour garantir une intégration fluide et une automatisation complète.
L'approche DevOps consiste à fournir des changements et une infrastructure aux environnements de production aussi rapidement et automatiquement que possible. Dans le cadre du pipeline Azure DevOps, il est souvent nécessaire d'automatiser le déploiement de machines virtuelles, d'y installer des applications complexes et d'effectuer la configuration à distance à l'aide de scripts PowerShell.

L'objectif de cette automatisation est d'accélérer considérablement le déploiement de l'infrastructure, de réduire les erreurs en éliminant les opérations manuelles et d'améliorer la stabilité et la prévisibilité globales du processus.

Définition du problème

Lorsque vous essayez de mettre en œuvre l'automatisation décrite ci-dessus, vous pouvez souvent rencontrer un problème connu sous le nom d'erreur de second saut. Qu'est-ce que cela signifie en pratique ?

Le deuxième problème de saut se réfère à la situation suivante :

  1. Vous vous êtes connecté au serveur A.
  2. Ensuite, à partir du serveurA, vous établissez une connexion à distance via PowerShell avec le serveurB.
  3. Lorsque vous exécutez un cmdlet sur le serveur B via cette session à distance, il tente d'accéder à une ressource située sur le serveur C.
  4. Cependant, ce dernier rejette la demande car les informations d'identification passées pour se connecter de ServeurA à ServeurB ne sont pas transmises de ServeurB à ServeurC.

Ce problème se produit dans les pipelines Azure DevOps, l'agent sur lequel les pipelines sont exécutés est connecté à distance à la machine virtuelle via PowerShell Remote. Ainsi, l'agent est ServerB et la machine virtuelle est ServerC. En effet, le mécanisme d'authentification Kerberos standard ne permet pas de transférer les informations d'identification au-delà d'une étape.

Ce problème est particulièrement critique dans le cadre de DevOps, car il rompt le concept d'automatisation et de continuité des processus. Il entraîne souvent la nécessité de recourir à des « solutions de contournement manuelles » temporaires, ce qui a un impact négatif sur la productivité et augmente la probabilité d'erreurs.

Quels sont les moyens de résoudre ce problème ?

Le problème du deuxième saut peut être résolu de plusieurs façons :

  • Utilisation de CredSSP (Credential Security Support Provider).
  • Utilisation de la délégation restreinte Kerberos.
  • En pré-copiant toutes les ressources nécessaires localement sur la machine virtuelle avant d'exécuter le déploiement.

Dans le cadre de DevOps, l'utilisation de la technologie CredSSP est devenue très populaire car il s'agit de la solution la plus abordable malgré certains risques de sécurité.

Résoudre ce problème avec CredSSP

Pour résoudre le problème du second wadding dans le pipeline Azure DevOps, nous devons suivre deux étapes.

La première consiste à activer CredSSP sur l'agent Azure DevOps.

         - task: PowerShell@2
          displayName: Enable CredSSP authentication on Client
          inputs:
            targetType: 'inline'
            script: |
              $vmdnsname = <VmDnsName>
              $vmusername = <VmUsername>
              $vmpassword = <VmPassword>
              # Enable CredSSP
              $allowedHost = "$vmdnsname".Replace("$vmdnsname".Split('.')[0],'*')
              $allowedHost
              $allowed = @("WSMAN/$allowedHost")         
              Write-Host Allowed hosts: $allowed
              Enable-WSManCredSSP -Role Client -DelegateComputer $allowed -Force
              # Following is equivalent to modifying gpedit.msc > Computer > Admin > System > Credentials > AllowFreshCredentialsWhenNTLMOnly
              $key = 'hklm:\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation'
              if (!(Test-Path $key)) {
                  md $key -Force
              }
              New-ItemProperty -Path $key -Name AllowFreshCredentialsWhenNTLMOnly -Value 1 -PropertyType Dword -Force
              $key = Join-Path $key 'AllowFreshCredentialsWhenNTLMOnly'
              if (!(Test-Path $key)) {
                  md $key -Force
              }
              $istr = Get-Item -Path $key | Select-Object -ExpandProperty Property | Select-Object -Last 1
              $i = [convert]::ToInt32($istr)
              $i++
              $allowed |% {
                  New-ItemProperty -Path $key -Name $i -Value $_ -PropertyType String -Force
                  $i++
              }
              # Following is equivalent to modifying gpedit.msc > Computer > Admin > System > Credentials > AllowFreshCredentials
              $key = 'hklm:\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation'
              if (!(Test-Path $key)) {
                  md $key -Force
              }
              New-ItemProperty -Path $key -Name AllowFreshCredentialsWhenNTLMOnly -Value 1 -PropertyType Dword -Force
              $key = Join-Path $key 'AllowFreshCredentials'
              if (!(Test-Path $key)) {
                  md $key -Force
              }
              $istr = Get-Item -Path $key | Select-Object -ExpandProperty Property | Select-Object -Last 1
              $i = [convert]::ToInt32($istr)
              $i++
              $allowed |% {
                  New-ItemProperty -Path $key -Name $i -Value $_ -PropertyType String -Force
                  $i++
              }
Le script ci-dessus comporte des étapes qui modifient les paramètres de la stratégie de l'hôte afin d'autoriser la connectivité CredSSP.

Deuxièmement - Activer l'authentification CredSSP sur la machine virtuelle.

Nous supposerons ici que l'option powershell remote sur la machine virtuelle est déjà activée. Vous pouvez voir comment le faire dans mon autre article.

         - task: PowerShell@2
          displayName: Enable CredSSP authentication on Server
          inputs:
            targetType: 'inline'
            script: |

              $vmdnsname = <VmDnsName>
              $vmusername = <VmUsername>
              $vmpassword = <VmPassword>
              # Convert Password
              $securePassword = ConvertTo-SecureString $vmpassword -AsPlainText -Force
              $cred = New-Object System.Management.Automation.PSCredential($vmusername, $securePassword)
              # Connect to the machine
              $soptions = New-PSSessionOption -SkipCACheck
              $session =  New-PSSession -ComputerName $vmdnsname -Port 5986 -Credential $cred -SessionOption $soptions -UseSSL
              Invoke-Command -Session $session -ScriptBlock {
                Enable-WSManCredSSP -Role "Server" -Force
              }
Vous pouvez alors vous connecter à l'aide de CredSSP et exécuter des commandes sur la machine virtuelle.
         - task: PowerShell@2
          inputs:
            targetType: 'inline'
            script: |
              $vmdnsname = <VmDnsName>
              $vmusername = <VmUsername>
              $vmpassword = <VmPassword>
              # Convert Password
              $securePassword = ConvertTo-SecureString $vmpassword -AsPlainText -Force
              $cred = New-Object System.Management.Automation.PSCredential($vmusername, $securePassword)
              # Connect to the machine
              $soptions = New-PSSessionOption -SkipCACheck
              $session =  New-PSSession -ComputerName $vmdnsname -Port 5986 -Credential $cred -SessionOption $soptions -UseSSL –Authentication CredSSP
              Invoke-Command -Session $session -ScriptBlock {
                echo "Hello from Azure DevOps!
              }
Ainsi, l'utilisation de CredSSP résout le problème du second saut et permet une automatisation et une efficacité maximales dans les processus CI/CD, en éliminant le besoin d'interventions manuelles et en accélérant considérablement le processus de déploiement de l'infrastructure dans Azure DevOps.