Autenticação com o IAM - Amazon ElastiCache (Redis OSS)

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Autenticação com o IAM

Visão geral

Com a autenticação do IAM, você pode autenticar uma conexão com ElastiCache (Redis OSS) usando identidades AWS do IAM, quando seu cache está configurado para usar o Redis OSS versão 7 ou superior. Isso possibilita que você fortaleça seu modelo de segurança e simplifique várias tarefas administrativas de segurança. Você também pode usar a autenticação do IAM para configurar um controle de acesso refinado para cada ElastiCache cache e ElastiCache usuário individual, seguindo os princípios de permissões de privilégio mínimo. A autenticação do IAM para ElastiCache (Redis OSS) funciona fornecendo um token de autenticação do IAM de curta duração em vez de uma senha de ElastiCache usuário de longa duração no OSS ou no comando do Redis. AUTH HELLO Para obter mais informações sobre o token de autenticação do IAM, consulte o processo de assinatura do Signature versão 4 no Guia de referência AWS geral e no exemplo de código abaixo.

Você pode usar identidades do IAM e suas políticas associadas para restringir ainda mais o acesso ao Redis OSS. Você também pode conceder acesso aos usuários de seus provedores de identidade federados diretamente aos caches do Redis OSS.

Para usar o AWS IAM com ElastiCache (Redis OSS), primeiro você precisa criar um ElastiCache usuário com o modo de autenticação definido como IAM. Em seguida, você pode criar ou reutilizar uma identidade do IAM. A identidade do IAM precisa de uma política associada para conceder a elasticache:Connect ação ao ElastiCache cache e ao ElastiCache usuário. Depois de configurado, você pode criar um token de autenticação do IAM usando AWS as credenciais do usuário ou da função do IAM. Finalmente, você precisa fornecer o token de autenticação IAM de curta duração como uma senha no seu cliente Redis OSS ao se conectar ao cache do Redis OSS. Um cliente Redis OSS com suporte para provedor de credenciais pode gerar automaticamente as credenciais temporárias para cada nova conexão. ElastiCache (Redis OSS) executará a autenticação do IAM para solicitações de conexão de ElastiCache usuários habilitados para IAM e validará as solicitações de conexão com o IAM.

Limitações

Ao usar a autenticação do IAM, as seguintes limitações se aplicam:

  • A autenticação do IAM está disponível ao usar ElastiCache (Redis OSS) versão 7.0 ou superior.

  • Para ElastiCache usuários habilitados para IAM, as propriedades de nome de usuário e ID de usuário devem ser idênticas.

  • O token de autenticação do IAM é válido por 15 minutos. Para conexões de longa duração, recomendamos usar um cliente Redis OSS que ofereça suporte a uma interface de provedor de credenciais.

  • Uma conexão autenticada pelo IAM com ElastiCache (Redis OSS) será automaticamente desconectada após 12 horas. A conexão pode ser prolongada por 12 horas enviando um comando AUTH ou HELLO com um novo token de autenticação do IAM.

  • A autenticação do IAM não tem suporte em comandos MULTI EXEC.

  • Atualmente, a autenticação do IAM não dá suporte às seguintes chaves de contexto de condição global:

    • Durante o uso da autenticação do IAM com caches sem servidor, aws:VpcSourceIp, aws:SourceVpc, aws:SourceVpce, aws:CurrentTime, aws:EpochTime e aws:ResourceTag/%s (de caches sem servidor associados e usuários) são compatíveis.

    • Durante o uso da autenticação do IAM com grupos de replicação, aws:SourceIp e aws:ResourceTag/%s (de grupos de replicação associados e usuários) são compatíveis.

    Para obter mais informações sobre chaves de contexto de condição global, consulte Chaves de contexto de condição global da AWS no Guia do usuário do IAM.

Configuração

Como configurar a autenticação do IAM

  1. Criar um cache

    aws elasticache create-serverless-cache \ --serverless-cache-name cache-01 \ --description "ElastiCache IAM auth application" \ --engine redis
  2. Crie um documento de política de confiança do IAM, conforme mostrado abaixo, para o perfil que permita que sua conta assuma o novo perfil. Salve a política em um arquivo chamado trust-policy.json.

    { "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:root" }, "Action": "sts:AssumeRole" } }
  3. Crie um documento de política do IAM, conforme mostrado abaixo. Salve a política em um arquivo chamado policy.json.

    { "Version": "2012-10-17", "Statement": [ { "Effect" : "Allow", "Action" : [ "elasticache:Connect" ], "Resource" : [ "arn:aws:elasticache:us-east-1:123456789012:serverlesscache:cache-01", "arn:aws:elasticache:us-east-1:123456789012:user:iam-user-01" ] } ] }
  4. Criar um perfil do IAM.

    aws iam create-role \ --role-name "elasticache-iam-auth-app" \ --assume-role-policy-document file://trust-policy.json
  5. Crie a política do IAM.

    aws iam create-policy \ --policy-name "elasticache-allow-all" \ --policy-document file://policy.json
  6. Anexe a política do IAM à função.

    aws iam attach-role-policy \ --role-name "elasticache-iam-auth-app" \ --policy-arn "arn:aws:iam::123456789012:policy/elasticache-allow-all"
  7. Crie um novo usuário habilitado para o IAM.

    aws elasticache create-user \ --user-name iam-user-01 \ --user-id iam-user-01 \ --authentication-mode Type=iam \ --engine redis \ --access-string "on ~* +@all"
  8. Crie um grupo de usuários e anexe o usuário.

    aws elasticache create-user-group \ --user-group-id iam-user-group-01 \ --engine redis \ --user-ids default iam-user-01 aws elasticache modify-serverless-cache \ --serverless-cache-name cache-01 \ --user-group-id iam-user-group-01

Conexão

Conectar com token como senha

Primeiro, é necessário gerar o token de autenticação do IAM de curta duração usando uma solicitação pré-assinada do AWS SigV4. Depois disso, você fornece o token de autenticação do IAM como senha ao se conectar a um cache do Redis OSS, conforme mostrado no exemplo abaixo.

String userId = "insert user id"; String cacheName = "insert cache name"; boolean isServerless = true; String region = "insert region"; // Create a default AWS Credentials provider. // This will look for AWS credentials defined in environment variables or system properties. AWSCredentialsProvider awsCredentialsProvider = new DefaultAWSCredentialsProviderChain(); // Create an IAM authentication token request and signed it using the AWS credentials. // The pre-signed request URL is used as an IAM authentication token for ElastiCache (Redis OSS). IAMAuthTokenRequest iamAuthTokenRequest = new IAMAuthTokenRequest(userId, cacheName, region, isServerless); String iamAuthToken = iamAuthTokenRequest.toSignedRequestUri(awsCredentialsProvider.getCredentials()); // Construct Redis OSS URL with IAM Auth credentials provider RedisURI redisURI = RedisURI.builder() .withHost(host) .withPort(port) .withSsl(ssl) .withAuthentication(userId, iamAuthToken) .build(); // Create a new Lettuce Redis OSS client RedisClient client = RedisClient.create(redisURI); client.connect();

Veja abaixo a definição de IAMAuthTokenRequest.

public class IAMAuthTokenRequest { private static final HttpMethodName REQUEST_METHOD = HttpMethodName.GET; private static final String REQUEST_PROTOCOL = "http://"; private static final String PARAM_ACTION = "Action"; private static final String PARAM_USER = "User"; private static final String PARAM_RESOURCE_TYPE = "ResourceType"; private static final String RESOURCE_TYPE_SERVERLESS_CACHE = "ServerlessCache"; private static final String ACTION_NAME = "connect"; private static final String SERVICE_NAME = "elasticache"; private static final long TOKEN_EXPIRY_SECONDS = 900; private final String userId; private final String cacheName; private final String region; private final boolean isServerless; public IAMAuthTokenRequest(String userId, String cacheName, String region, boolean isServerless) { this.userId = userId; this.cacheName = cacheName; this.region = region; this.isServerless = isServerless; } public String toSignedRequestUri(AWSCredentials credentials) throws URISyntaxException { Request<Void> request = getSignableRequest(); sign(request, credentials); return new URIBuilder(request.getEndpoint()) .addParameters(toNamedValuePair(request.getParameters())) .build() .toString() .replace(REQUEST_PROTOCOL, ""); } private <T> Request<T> getSignableRequest() { Request<T> request = new DefaultRequest<>(SERVICE_NAME); request.setHttpMethod(REQUEST_METHOD); request.setEndpoint(getRequestUri()); request.addParameters(PARAM_ACTION, Collections.singletonList(ACTION_NAME)); request.addParameters(PARAM_USER, Collections.singletonList(userId)); if (isServerless) { request.addParameters(PARAM_RESOURCE_TYPE, Collections.singletonList(RESOURCE_TYPE_SERVERLESS_CACHE)); } return request; } private URI getRequestUri() { return URI.create(String.format("%s%s/", REQUEST_PROTOCOL, cacheName)); } private <T> void sign(SignableRequest<T> request, AWSCredentials credentials) { AWS4Signer signer = new AWS4Signer(); signer.setRegionName(region); signer.setServiceName(SERVICE_NAME); DateTime dateTime = DateTime.now(); dateTime = dateTime.plus(Duration.standardSeconds(TOKEN_EXPIRY_SECONDS)); signer.presignRequest(request, credentials, dateTime.toDate()); } private static List<NameValuePair> toNamedValuePair(Map<String, List<String>> in) { return in.entrySet().stream() .map(e -> new BasicNameValuePair(e.getKey(), e.getValue().get(0))) .collect(Collectors.toList()); } }

Conectar com o provedor de credenciais

O código abaixo mostra como se autenticar com ElastiCache (Redis OSS) usando o provedor de credenciais de autenticação do IAM.

String userId = "insert user id"; String cacheName = "insert cache name"; boolean isServerless = true; String region = "insert region"; // Create a default AWS Credentials provider. // This will look for AWS credentials defined in environment variables or system properties. AWSCredentialsProvider awsCredentialsProvider = new DefaultAWSCredentialsProviderChain(); // Create an IAM authentication token request. Once this request is signed it can be used as an // IAM authentication token for ElastiCache (Redis OSS). IAMAuthTokenRequest iamAuthTokenRequest = new IAMAuthTokenRequest(userId, cacheName, region, isServerless); // Create a Redis OSS credentials provider using IAM credentials. RedisCredentialsProvider redisCredentialsProvider = new RedisIAMAuthCredentialsProvider( userId, iamAuthTokenRequest, awsCredentialsProvider); // Construct Redis OSS URL with IAM Auth credentials provider RedisURI redisURI = RedisURI.builder() .withHost(host) .withPort(port) .withSsl(ssl) .withAuthentication(redisCredentialsProvider) .build(); // Create a new Lettuce Redis OSS client RedisClient client = RedisClient.create(redisURI); client.connect();

Abaixo está um exemplo de um cliente Lettuce Redis OSS que envolve o IAM AuthTokenRequest em um provedor de credenciais para gerar automaticamente credenciais temporárias quando necessário.

public class RedisIAMAuthCredentialsProvider implements RedisCredentialsProvider { private static final long TOKEN_EXPIRY_SECONDS = 900; private final AWSCredentialsProvider awsCredentialsProvider; private final String userId; private final IAMAuthTokenRequest iamAuthTokenRequest; private final Supplier<String> iamAuthTokenSupplier; public RedisIAMAuthCredentialsProvider(String userId, IAMAuthTokenRequest iamAuthTokenRequest, AWSCredentialsProvider awsCredentialsProvider) { this.userName = userName; this.awsCredentialsProvider = awsCredentialsProvider; this.iamAuthTokenRequest = iamAuthTokenRequest; this.iamAuthTokenSupplier = Suppliers.memoizeWithExpiration(this::getIamAuthToken, TOKEN_EXPIRY_SECONDS, TimeUnit.SECONDS); } @Override public Mono<RedisCredentials> resolveCredentials() { return Mono.just(RedisCredentials.just(userId, iamAuthTokenSupplier.get())); } private String getIamAuthToken() { return iamAuthTokenRequest.toSignedRequestUri(awsCredentialsProvider.getCredentials()); } }