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:
- 30 Tage vor dem Ablaufdatum eines Geheimnisses veröffentlicht Key Vault das Ereignis „Läuft demnächst ab“ in Event Grid.
- Event Grid überprüft die Ereignisabonnements und ruft mit HTTP POST den Funktions-App-Endpunkt auf, der dieses Ereignis abonniert hat.
- 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.
- 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
- Azure-Abonnement (kostenloses Abonnement erstellen)
- Azure-Schlüsseltresor
- SQL Server
Wenn Sie keinen vorhandenen Key Vault und SQL Server haben, können Sie diesen Bereitstellungslink verwenden:
- 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.
- Geben Sie unter SQL-Administratoranmeldung den Anmeldenamen des SQL-Administrators ein.
- Klicken Sie auf Überprüfen + erstellen.
- Klicken Sie auf Erstellen
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
Wählen Sie den Link zur Bereitstellung der Vorlage in Azure aus:
Wählen Sie in der Liste Ressourcengruppe die Option akvrotation aus.
Geben Sie unter SQL Server-Name den Namen des SQL Server mit dem zu rotierenden Kennwort ein.
Geben Sie unter Schlüsseltresorname den Namen des Schlüsseltresors ein.
Geben Sie unter Name der Funktions-App den Namen der Funktions-App ein.
Geben Sie unter Name des Geheimnisses den Namen des Geheimnisses an, unter dem das Kennwort gespeichert wird.
Geben Sie unter Repository-URL den GitHub-Speicherort des Funktionscodes an (https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp.git).
Klicken Sie auf Überprüfen + erstellen.
Klicken Sie auf 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:
Öffnen Sie das Geheimnis sqlPassword, und überprüfen Sie die ursprüngliche sowie die rotierte Version:
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
Wählen Sie den Link zur Bereitstellung der Vorlage in Azure aus:
Wählen Sie die Ressourcengruppe akvrotation aus.
Geben Sie unter SQL Server-Name den Namen des SQL Server mit dem zu rotierenden Kennwort ein.
Geben Sie unter Schlüsseltresorname den Namen des Schlüsseltresors ein.
Geben Sie unter Name des Geheimnisses den Namen des Geheimnisses an, unter dem das Kennwort gespeichert ist.
Geben Sie unter Repository-URL den GitHub-Speicherort des Web-App-Codes an (https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp-WebApp.git).
Klicken Sie auf Überprüfen + erstellen.
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
- Tutorial: Automatisieren der Rotation eines Geheimnisses für Ressourcen mit zwei Sätzen mit Anmeldeinformationen für die Authentifizierung
- Übersicht: Überwachen von Key Vault mit Azure Event Grid
- Gewusst wie: Verwenden von Logic Apps zum Empfangen einer E-Mail bei Statusänderungen von Key Vault-Geheimnissen
- Azure Event Grid-Ereignisschema für Azure Key Vault