Automatizar a rotação de um segredo para recursos que usam um conjunto de credenciais de autenticação
A melhor maneira de se autenticar nos serviços do Azure é usando uma identidade gerenciada, mas há alguns cenários em que essa não é uma opção. Nesses casos, são usadas chaves de acesso ou segredos. Você deve realizar periodicamente a rotação de chaves de acesso ou segredos.
Este tutorial mostra como automatizar a rotação periódica de segredos para bancos de dados e serviços que usam um conjunto de credenciais de autenticação. Especificamente, este tutorial realiza a rotação das senhas do SQL Server armazenadas no Azure Key Vault usando uma função disparada pela notificação da Grade de Eventos do Azure:
- Trinta dias antes da data de validade de um segredo, o Key Vault publica o evento de "expiração próxima" na Grade de Eventos.
- A Grade de Eventos verifica as assinaturas de eventos e usa HTTP POST para chamar o ponto de extremidade do aplicativo de funções assinado para o evento.
- O aplicativo de funções recebe as informações secretas, gera uma nova senha aleatória e cria uma versão para o segredo com a nova senha no Key Vault.
- O aplicativo de funções atualiza o SQL Server com uma nova senha.
Observação
Pode haver um atraso entre as etapas 3 e 4. Durante esse tempo, o segredo no Key Vault não poderá se autenticar no SQL Server. Em caso de uma falha em qualquer uma das etapas, a Grade de Eventos realiza novas tentativas por duas horas.
Pré-requisitos
- Uma assinatura do Azure – crie uma gratuitamente.
- Cofre de Chave do Azure
- SQL Server
Se você não tiver um Key Vault nem um SQL Server existente, poderá usar este link de implantação:
- Em Grupo de recursos, selecione Criar. Dê um nome ao grupo, neste tutorial usamos akvrotation.
- Em Logon do Administrador do SQL, digite a ID de logon do administrador do SQL.
- Selecione Examinar + criar.
- Escolha Criar
Agora você terá um Key Vault e uma instância do SQL Server. Você pode verificar essa configuração na CLI do Azure executando o seguinte comando:
az resource list -o table -g akvrotation
O resultado terá uma aparência semelhante à da seguinte saída:
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 implantar função de rotação de senha do SQL Server
Importante
Este modelo exige que o Key Vault, o SQL Server e a Função do Azure estejam no mesmo grupo de recursos
Em seguida, crie um aplicativo de funções com uma identidade gerenciada pelo sistema, juntamente com os outros componentes necessários e implante as funções de rotação de senha do SQL Server
O aplicativo de funções requer estes componentes:
- Um plano do Serviço de Aplicativo do Azure
- Um Aplicativo de Funções com funções de rotação de senha do SQL com gatilho de evento e gatilho http
- Uma conta de armazenamento necessária para o gerenciamento de gatilho do aplicativo de funções
- Uma política de acesso para usar a identidade do Aplicativo de Funções para acessar segredos no Key Vault
- Assinatura de evento da Grade de Eventos para o evento SecretNearExpiry
Selecione o link de implantação de modelo do Azure:
Na lista Grupo de recursos, selecione akvrotation.
No Nome do SQL Server, digite o nome do SQL Server com a senha para rotação
No Nome do Cofre de Chaves, digite o nome do cofre de chaves
No Nome do Aplicativo de Funções, digite o nome do aplicativo de funções
No Nome do Segredo, digite o nome do segredo em que a senha será armazenada
Na URL do Repositório, digite a localização do GitHub do código de função (https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp.git)
Selecione Examinar + criar.
Selecione Criar.
Depois de concluir as etapas anteriores, você terá uma conta de armazenamento, um farm de servidores e um aplicativo de funções. Você pode verificar essa configuração na CLI do Azure executando o seguinte comando:
az resource list -o table -g akvrotation
O resultado terá uma aparência semelhante à da seguinte saída:
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 um aplicativo de funções e usar a identidade gerenciada para acessar o Key Vault, confira Criar um aplicativo de funções no portal do Azure, Como usar identidades gerenciadas para o Serviço de Aplicativo e o Azure Functions e Atribuir uma política de acesso do Key Vault usando o portal do Azure.
Função de rotação
A função implantada na etapa anterior usa um evento para disparar a rotação de um segredo atualizando o Key Vault e o Banco de Dados SQL.
Evento de gatilho de função
Essa função lê dados de eventos 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 do segredo
Esse método de rotação lê as informações do banco de dados do segredo, cria uma versão do segredo e atualiza o banco de dados com um 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");
}
}
É possível encontrar o código de exemplo no GitHub.
Adicionar o segredo ao Key Vault
Defina sua política de acesso para conceder as permissões para gerenciar segredos a usuários:
az keyvault set-policy --upn <email-address-of-user> --name akvrotation-kv --secret-permissions set delete get list
Crie um segredo com marcas que contenham a ID de recurso do SQL Server, o nome de logon do SQL Server e o período de validade do segredo em dias. Forneça o nome do segredo, a senha inicial do Banco de Dados SQL (em nosso exemplo "Simple123") e inclua uma data de validade 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 validade curta publicará um evento SecretNearExpiry
em 15 minutos, o que, por sua vez, disparará a função para realizar a rotação do segredo.
Testar e verificar
Para verificar se a rotação do segredo foi realizada, acesse Key Vault>Segredos:
Abra o segredo sqlPassword e veja as versões originais e com rotação:
Criar um aplicativo Web
Para verificar as credenciais do SQL, crie um aplicativo Web. Esse aplicativo Web obterá o segredo do Key Vault, extrairá as informações e as credenciais do Banco de Dados SQL do segredo e testará a conexão com o SQL Server.
O aplicativo Web requer estes componentes:
- Um aplicativo Web com identidade gerenciada pelo sistema
- Uma política de acesso para acessar segredos no Key Vault usando a identidade gerenciada do aplicativo Web
Selecione o link de implantação de modelo do Azure:
Selecione o grupo de recursos akvrotation.
No Nome do SQL Server, digite o nome do SQL Server com a senha para rotação
No Nome do Cofre de Chaves, digite o nome do cofre de chaves
No Nome do Segredo, digite o nome do segredo no qual a senha está armazenada
Na URL do Repositório, digite a localização do GitHub do código do aplicativo Web (https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp-WebApp.git)
Selecione Examinar + criar.
Selecione Criar.
Abra o aplicativo Web
Acesse a URL de aplicativo implantado:
'https://akvrotation-app.azurewebsites.net/'
Quando o aplicativo for aberto no navegador, você verá o Valor Secreto Gerado e um valor de Banco de Dados Conectado igual a verdadeiro.