Automatizar a rotação de um segredo para recursos que utilizam um conjunto de credenciais de autenticação
A melhor forma de autenticar nos serviços do Azure é através de uma identidade gerida, mas existem alguns cenários em que isso não é uma opção. Nesses casos, são utilizadas chaves de acesso ou segredos. Deve rodar periodicamente chaves de acesso ou segredos.
Este tutorial mostra como automatizar a rotação periódica de segredos para bases de dados e serviços que utilizam um conjunto de credenciais de autenticação. Especificamente, este tutorial roda SQL Server palavras-passe armazenadas no Azure Key Vault através de uma função acionada por Azure Event Grid notificação:
- Trinta dias antes da data de expiração de um segredo, Key Vault publica o evento "quase expiração" no Event Grid.
- O Event Grid verifica as subscrições de eventos e utiliza HTTP POST para chamar o ponto final da aplicação de funções subscrito ao evento.
- A aplicação de funções recebe as informações secretas, gera uma nova palavra-passe aleatória e cria uma nova versão para o segredo com a nova palavra-passe no Key Vault.
- A aplicação de funções atualiza SQL Server com a nova palavra-passe.
Nota
Pode haver um atraso entre os passos 3 e 4. Durante esse período, o segredo no Key Vault não poderá autenticar-se no SQL Server. Em caso de falha de qualquer um dos passos, o Event Grid volta a tentar durante duas horas.
Pré-requisitos
- Uma subscrição do Azure - crie uma gratuitamente.
- Azure Key Vault
- SQL Server
Se não tiver Key Vault e SQL Server existentes, pode utilizar esta ligação de implementação:
- Em Grupo de recursos, selecione Criar novo. Atribua um nome ao grupo, utilizamos akvrotation neste tutorial.
- Em Início de Sessão do SQL Administração, escreva nome de início de sessão do administrador do SQL.
- Selecione Rever + criar.
- Selecione Criar
Terá agora uma Key Vault e uma instância de SQL Server. Pode verificar esta configuração na CLI do Azure ao executar o seguinte comando:
az resource list -o table -g akvrotation
O resultado irá procurar algo no seguinte resultado:
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
Criar e implementar a função de rotação de palavras-passe do SQL Server
Importante
Este modelo requer que o cofre de chaves, o SQL Server e a Função do Azure estejam no mesmo grupo de recursos.
Em seguida, crie uma aplicação de funções com uma identidade gerida pelo sistema, para além dos outros componentes necessários, e implemente funções de rotação de palavras-passe do SQL Server
A aplicação de funções requer estes componentes:
- Um plano de Serviço de Aplicações do Azure
- Uma Aplicação de Funções com funções de rotação de palavras-passe SQL com acionador de eventos e acionador http
- Uma conta de armazenamento necessária para a gestão de acionadores da aplicação de funções
- Uma política de acesso para a identidade da Aplicação de Funções aceder a segredos no Key Vault
- Uma subscrição de evento do Event Grid para o evento SecretNearExpiry
Selecione a ligação de implementação de modelos do Azure:
Na lista Grupo de recursos, selecione akvrotation.
No Nome do SQL Server, escreva o nome do SQL Server com a palavra-passe para rodar
No nome do Key Vault, escreva o nome do cofre de chaves
No Nome da Aplicação de Funções, escreva o nome da aplicação de funções
No Nome do Segredo, escreva o nome do segredo onde a palavra-passe será armazenada
No Url do Repositório, escreva código de função Localização do GitHub (https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp.git)
Selecione Rever + criar.
Selecione Criar.
Depois de concluir os passos anteriores, terá uma conta de armazenamento, um farm de servidores e uma aplicação de funções. Pode verificar esta configuração na CLI do Azure ao executar o seguinte comando:
az resource list -o table -g akvrotation
O resultado terá um aspeto semelhante ao seguinte resultado:
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
Para obter informações sobre como criar uma aplicação de funções e utilizar a identidade gerida para aceder a Key Vault, consulte Criar uma aplicação de funções a partir do portal do Azure, Como utilizar a identidade gerida para Serviço de Aplicações e Funções do Azure e Atribuir uma Key Vault política de acesso com o portal do Azure.
Função rotação
Implementado na função passo anterior utiliza um evento para acionar a rotação de um segredo ao atualizar Key Vault e a base de dados SQL.
Evento do acionador de funções
Esta função lê os dados do evento e executa a lógica de rotação:
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);
}
}
Lógica de rotação secreta
Este método de rotação lê as informações da base de dados do segredo, cria uma nova versão do segredo e atualiza a base de dados com o novo segredo:
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");
}
}
Pode encontrar o código completo no GitHub.
Adicionar o segredo ao Key Vault
Defina a sua política de acesso para conceder permissões de gestão de segredos aos utilizadores:
az keyvault set-policy --upn <email-address-of-user> --name akvrotation-kv --secret-permissions set delete get list
Crie um novo segredo com etiquetas que contenham o ID de recurso SQL Server, o nome de início de sessão SQL Server e o período de validade do segredo em dias. Indique o nome do segredo, palavra-passe inicial da base de dados SQL (no nosso exemplo "Simple123") e inclua uma data de expiração definida para amanhã.
$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
A criação de um segredo com uma data de expiração curta irá publicar um SecretNearExpiry
evento dentro de 15 minutos, o que, por sua vez, irá acionar a função para rodar o segredo.
Testar e verificar
Para verificar se o segredo rodou, aceda a Key Vault>Secrets:
Abra o segredo sqlPassword e veja as versões originais e rotativas:
Criar uma aplicação Web
Para verificar as credenciais do SQL, crie uma aplicação Web. Esta aplicação Web obterá o segredo de Key Vault, extrairá as informações e credenciais da base de dados SQL do segredo e testará a ligação ao SQL Server.
A aplicação Web requer estes componentes:
- Uma aplicação Web com identidade gerida pelo sistema
- Uma política de acesso para aceder a segredos no Key Vault através da identidade gerida da aplicação Web
Selecione a ligação de implementação de modelos do Azure:
Selecione o grupo de recursos akvrotation .
No Nome do SQL Server, escreva o nome do SQL Server com a palavra-passe para rodar
No nome do Key Vault, escreva o nome do cofre de chaves
No Nome do Segredo, escreva o nome do segredo onde a palavra-passe está armazenada
No Url do Repositório, escreva a localização do GitHub do código da aplicação Web (https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp-WebApp.git)
Selecione Rever + criar.
Selecione Criar.
Abrir a aplicação Web
Aceda ao URL da aplicação implementada:
'https://akvrotation-app.azurewebsites.net/'
Quando a aplicação abrir no browser, verá o Valor do Segredo Gerado e um valor Ligado à Base de Dados verdadeiro.