Automatisieren der Rotation eines Geheimnisses für Ressourcen mit einem Satz mit Anmeldeinformationen für die Authentifizierung

Die beste Möglichkeit zur Authentifizierung bei Azure-Diensten ist die Verwendung einer verwalteten Identität. Es gibt jedoch einige Szenarien, in denen dies nicht möglich ist. In diesen Fällen werden Zugriffsschlüssel oder Geheimnisse verwendet. Sie sollten Zugriffsschlüssel und Geheimnisse regelmäßig rotieren.

In diesem Tutorial wird gezeigt, wie Sie die regelmäßige Rotation von Geheimnissen für Datenbanken und Dienste automatisieren, bei denen ein Satz mit Anmeldeinformationen für die Authentifizierung verwendet wird. Genauer gesagt werden in diesem Tutorial in Azure Key Vault gespeicherte SQL Server-Kennwörter mithilfe einer Funktion rotiert, die durch eine Azure Event Grid-Benachrichtigung ausgelöst wird:

Diagramm der Rotationslösung

  1. 30 Tage vor dem Ablaufdatum eines Geheimnisses veröffentlicht Key Vault das Ereignis „Läuft demnächst ab“ in Event Grid.
  2. Event Grid überprüft die Ereignisabonnements und ruft mit HTTP POST den Funktions-App-Endpunkt auf, der dieses Ereignis abonniert hat.
  3. Die Funktions-App empfängt die Geheimnisinformationen, generiert ein neues zufälliges Kennwort und erstellt für das Geheimnis eine neue Version mit dem neuen Kennwort in Key Vault.
  4. Die Funktions-App aktualisiert SQL Server mit dem neuen Kennwort.

Hinweis

Zwischen den Schritten 3 und 4 kann es zu einer Verzögerung kommen. Während dieser Zeit kann das Geheimnis in Key Vault nicht bei SQL Server authentifiziert werden. Tritt in einem der Schritte ein Fehler auf, wiederholt Event Grid den Vorgang zwei Stunden lang.

Voraussetzungen

Wenn Sie keinen vorhandenen Key Vault und SQL Server haben, können Sie diesen Bereitstellungslink verwenden:

Abbildung einer Schaltfläche mit der Bezeichnung „Bereitstellung in Azure“

  1. Wählen Sie unter Ressourcengruppe die Option Neu erstellen aus. Geben Sie einen Namen für die Gruppe ein. In diesem Tutorial wird akvrotation verwendet.
  2. Geben Sie unter SQL-Administratoranmeldung den Anmeldenamen des SQL-Administrators ein.
  3. Klicken Sie auf Überprüfen + erstellen.
  4. Klicken Sie auf Erstellen

Erstellen einer Ressourcengruppe

Sie verfügen jetzt über eine Key Vault- und eine SQL Server-Instanz. Sie können dieses Setup in der Azure-Befehlszeilenschnittstelle überprüfen, indem Sie den folgenden Befehl ausführen:

az resource list -o table -g akvrotation

Das Ergebnis sieht in etwa wie die folgende Ausgabe aus:

Name                     ResourceGroup         Location    Type                               Status
-----------------------  --------------------  ----------  ---------------------------------  --------
akvrotation-kv           akvrotation      eastus      Microsoft.KeyVault/vaults
akvrotation-sql          akvrotation      eastus      Microsoft.Sql/servers
akvrotation-sql/master   akvrotation      eastus      Microsoft.Sql/servers/databases
akvrotation-sql2         akvrotation      eastus      Microsoft.Sql/servers
akvrotation-sql2/master  akvrotation      eastus      Microsoft.Sql/servers/databases

Erstellen und Bereitstellen einer Funktion für die SQL Server-Kennwortrotation

Wichtig

Für diese Vorlage müssen sich Key Vault, SQL Server und die Azure-Funktion in der selben Ressourcengruppe befinden.

Erstellen Sie als Nächstes zusätzlich zu den anderen erforderlichen Komponenten eine Funktions-App mit einer systemseitig verwalteten Identität, und stellen Sie Funktionen für die Rotation von SQL Server-Kennwörtern bereit.

Eine Funktions-App benötigt folgende Komponenten:

  • Einen Azure App Service-Plan
  • Eine Funktions-App mit Funktionen für die SQL-Kennwortrotation mit Ereignistrigger und HTTP-Trigger
  • Ein Speicherkonto, das für die Triggerverwaltung der Funktions-App benötigt wird
  • Eine Zugriffsrichtlinie für die Identität der Funktions-App für den Zugriff auf Geheimnisse in Key Vault
  • Ein Event Grid-Ereignisabonnement für das Ereignis SecretNearExpiry
  1. Wählen Sie den Link zur Bereitstellung der Vorlage in Azure aus:

    Abbildung einer Schaltfläche mit der Bezeichnung „Bereitstellung in Azure“

  2. Wählen Sie in der Liste Ressourcengruppe die Option akvrotation aus.

  3. Geben Sie unter SQL Server-Name den Namen des SQL Server mit dem zu rotierenden Kennwort ein.

  4. Geben Sie unter Schlüsseltresorname den Namen des Schlüsseltresors ein.

  5. Geben Sie unter Name der Funktions-App den Namen der Funktions-App ein.

  6. Geben Sie unter Name des Geheimnisses den Namen des Geheimnisses an, unter dem das Kennwort gespeichert wird.

  7. Geben Sie unter Repository-URL den GitHub-Speicherort des Funktionscodes an (https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp.git).

  8. Klicken Sie auf Überprüfen + erstellen.

  9. Klicken Sie auf Erstellen.

Auswählen von „Überprüfen + erstellen“

Nachdem Sie die obigen Schritte ausgeführt haben, verfügen Sie über ein Speicherkonto, eine Serverfarm und eine Funktions-App. Sie können dieses Setup in der Azure-Befehlszeilenschnittstelle überprüfen, indem Sie den folgenden Befehl ausführen:

az resource list -o table -g akvrotation

Das Ergebnis sieht in etwa wie die folgende Ausgabe aus:

Name                     ResourceGroup         Location    Type                               Status
-----------------------  --------------------  ----------  ---------------------------------  --------
akvrotation-kv           akvrotation       eastus      Microsoft.KeyVault/vaults
akvrotation-sql          akvrotation       eastus      Microsoft.Sql/servers
akvrotation-sql/master   akvrotation       eastus      Microsoft.Sql/servers/databases
cfogyydrufs5wazfunctions akvrotation       eastus      Microsoft.Storage/storageAccounts
akvrotation-fnapp        akvrotation       eastus      Microsoft.Web/serverFarms
akvrotation-fnapp        akvrotation       eastus      Microsoft.Web/sites
akvrotation-fnapp        akvrotation       eastus      Microsoft.insights/components

Informationen zum Erstellen einer Funktions-App sowie zum Zugreifen auf Key Vault mit einer verwalteten Identität finden Sie unter Erstellen einer Funktions-App im Azure-Portal, Verwenden verwalteter Identitäten für App Service und Azure Functions und Zuweisen einer Key Vault-Zugriffsrichtlinie im Azure-Portal.

Rotationsfunktion

Die im vorherigen Schritt bereitgestellte Funktion verwendet ein Ereignis, um die Rotation eines Geheimnisses durch Aktualisieren von Key Vault und SQL-Datenbank zu initiieren.

Funktionstriggerereignis

Diese Funktion liest Ereignisdaten und führt die Rotationslogik aus:

public static class SimpleRotationEventHandler
{
   [FunctionName("AKVSQLRotation")]
   public static void Run([EventGridTrigger]EventGridEvent eventGridEvent, ILogger log)
   {
      log.LogInformation("C# Event trigger function processed a request.");
      var secretName = eventGridEvent.Subject;
      var secretVersion = Regex.Match(eventGridEvent.Data.ToString(), "Version\":\"([a-z0-9]*)").Groups[1].ToString();
      var keyVaultName = Regex.Match(eventGridEvent.Topic, ".vaults.(.*)").Groups[1].ToString();
      log.LogInformation($"Key Vault Name: {keyVaultName}");
      log.LogInformation($"Secret Name: {secretName}");
      log.LogInformation($"Secret Version: {secretVersion}");

      SecretRotator.RotateSecret(log, secretName, keyVaultName);
   }
}

Logik für die Geheimnisrotation

Diese Rotationsmethode liest Datenbankinformationen aus dem Geheimnis, erstellt eine neue Version des Geheimnisses und aktualisiert die Datenbank mit dem neuen Geheimnis:

    public class SecretRotator
    {
		private const string CredentialIdTag = "CredentialId";
		private const string ProviderAddressTag = "ProviderAddress";
		private const string ValidityPeriodDaysTag = "ValidityPeriodDays";

		public static void RotateSecret(ILogger log, string secretName, string keyVaultName)
        {
            //Retrieve Current Secret
            var kvUri = "https://" + keyVaultName + ".vault.azure.net";
            var client = new SecretClient(new Uri(kvUri), new DefaultAzureCredential());
            KeyVaultSecret secret = client.GetSecret(secretName);
            log.LogInformation("Secret Info Retrieved");

            //Retrieve Secret Info
            var credentialId = secret.Properties.Tags.ContainsKey(CredentialIdTag) ? secret.Properties.Tags[CredentialIdTag] : "";
            var providerAddress = secret.Properties.Tags.ContainsKey(ProviderAddressTag) ? secret.Properties.Tags[ProviderAddressTag] : "";
            var validityPeriodDays = secret.Properties.Tags.ContainsKey(ValidityPeriodDaysTag) ? secret.Properties.Tags[ValidityPeriodDaysTag] : "";
            log.LogInformation($"Provider Address: {providerAddress}");
            log.LogInformation($"Credential Id: {credentialId}");

            //Check Service Provider connection
            CheckServiceConnection(secret);
            log.LogInformation("Service  Connection Validated");
            
            //Create new password
            var randomPassword = CreateRandomPassword();
            log.LogInformation("New Password Generated");

            //Add secret version with new password to Key Vault
            CreateNewSecretVersion(client, secret, randomPassword);
            log.LogInformation("New Secret Version Generated");

            //Update Service Provider with new password
            UpdateServicePassword(secret, randomPassword);
            log.LogInformation("Password Changed");
            log.LogInformation($"Secret Rotated Successfully");
        }
}

Den vollständigen Beispielcode finden Sie auf GitHub.

Hinzufügen des Geheimnisses zu Key Vault

Erteilen Sie Benutzern in Ihrer Zugriffsrichtlinie Berechtigungen zum Verwalten von Geheimnissen:

az keyvault set-policy --upn <email-address-of-user> --name akvrotation-kv --secret-permissions set delete get list

Erstellen Sie ein neues Geheimnis mit Tags, das die SQL Server-Ressourcen-ID, den SQL Server-Anmeldenamen und die Gültigkeitsdauer für das Geheimnis in Tagen enthalten. Geben Sie den Namen des Geheimnisses und das erste Kennwort aus SQL-Datenbank (in unserem Beispiel „Simple123“) ein, und fügen Sie ein Ablaufdatum ein, das auf den morgigen Tag festgelegt ist

$tomorrowDate = (get-date).AddDays(+1).ToString("yyy-MM-ddThh:mm:ssZ")
az keyvault secret set --name sqlPassword --vault-name akvrotation-kv --value "Simple123" --tags "CredentialId=sqlAdmin" "ProviderAddress=<sql-database-resource-id>" "ValidityPeriodDays=90" --expires $tomorrowDate

Wenn Sie ein Geheimnis mit einem kurzen Ablaufdatum erstellen, wird innerhalb von 15 Minuten ein Ereignis vom Typ SecretNearExpiry veröffentlicht, wodurch wiederum die Funktion zum Rotieren des Geheimnisses ausgelöst wird.

Testen und Überprüfen

Vergewissern Sie sich unter Key Vault>Geheimnisse, dass das Geheimnis rotiert wurde:

Screenshot: Zugriff auf „Key Vault“ und „Geheimnisse“.

Öffnen Sie das Geheimnis sqlPassword, und überprüfen Sie die ursprüngliche sowie die rotierte Version:

Navigieren zu „Geheimnisse“

Erstellen einer Web-App

Erstellen Sie zum Überprüfen der SQL-Anmeldeinformationen eine Web-App. Diese Web-App ruft das Geheimnis aus Key Vault ab, extrahiert SQL-Datenbank- und Anmeldeinformationen aus dem Geheimnis und testet die Verbindung mit SQL Server.

Die Web-App benötigt folgende Komponenten:

  • Eine Web-App mit systemseitig verwalteter Identität
  • Eine Zugriffsrichtlinie für den Zugriff auf Geheimnisse in Key Vault mithilfe der verwalteten Identität der Web-App
  1. Wählen Sie den Link zur Bereitstellung der Vorlage in Azure aus:

    Abbildung einer Schaltfläche mit der Bezeichnung „Bereitstellung in Azure“

  2. Wählen Sie die Ressourcengruppe akvrotation aus.

  3. Geben Sie unter SQL Server-Name den Namen des SQL Server mit dem zu rotierenden Kennwort ein.

  4. Geben Sie unter Schlüsseltresorname den Namen des Schlüsseltresors ein.

  5. Geben Sie unter Name des Geheimnisses den Namen des Geheimnisses an, unter dem das Kennwort gespeichert ist.

  6. Geben Sie unter Repository-URL den GitHub-Speicherort des Web-App-Codes an (https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp-WebApp.git).

  7. Klicken Sie auf Überprüfen + erstellen.

  8. Klicken Sie auf Erstellen.

Öffnen der Web-App

Wechseln Sie zur URL der bereitgestellten Anwendung:

'https://akvrotation-app.azurewebsites.net/'

Wenn die Anwendung im Browser geöffnet wird, wird für den Wert Generated Secret Value (Geheimniswert generiert) und Database Connected (Datenbank verbunden) der Wert true angezeigt.

Weitere Informationen