Blog de Amazon Web Services (AWS)

Configuración Automática de TLS Mutuo (mTLS) en Amazon API Gateway

Por Pankaj Agrawal, Arquitecto de Soluciones en AWS Noruega

 

En septiembre de 2020, Amazon API Gateway anunció la compatibilidad de autenticación mediante TLS mutuo (mTLS). Este es un nuevo método para autenticación cliente-servidor que se puede utilizar con las opciones de autenticación actuales de Amazon API Gateway. Mutual TLS (mTLS) es una extensión de la capa de seguridad de transporte (en inglés, Transport Layer Security – TLS), que requiere que tanto el servidor como el cliente verifiquen sus certificados.

TLS mutuo se utiliza comúnmente para aplicaciones Business-to-Business (B2B). También se utiliza en estándares como Open Banking que permite la integración segura de API abiertas para instituciones financieras. También es común ver que se utiliza para aplicaciones de Internet de las cosas (IoT) para autenticar dispositivos a través de certificados digitales.

En este artículo se explica cómo automatizar la configuración de mTLS en Amazon API Gateway para API HTTP, pero se pueden utilizar los mismos pasos para las API REST. El código fuente de este paso a paso se puede obtener de este repositorio de GitHub.

 

Resumen de la solución

Para habilitar TLS mutuo, debe crear una API con un nombre de dominio personalizado válido. TLS mutuo está disponible tanto para API REST regionales como para las nuevas API HTTP. Para configurar TLS Mutuo con Amazon API Gateway, debe cargar la llave pública del certificado de la entidad emisora de certificados (CA) en Amazon S3. Esto se denomina almacén de confianza (trust store) y se utiliza para validar certificados de cliente.

 

 

AWS Certificate Manager Private Certificate Authority (CA Privada con ACM) es un servicio de CA privada de alta disponibilidad. En este ejemplo estoy usando ACM Private CA como entidad emisora de certificados para configurar API HTTP y distribuir los certificados a los clientes.

 

Implementación de la solución

Para implementar la aplicación usaremos AWS Serverless Application Model (AWS SAM). AWS SAM proporciona una sintaxis corta para definir funciones, APIs, bases de datos y mapeo de eventos. Como requisito previo, debe tener instalados la CLI de AWS SAM y Java 8 . También debe tener la CLI de AWS configurada correctamente.

Para implementar la solución:

  1. Debe clonar el repositorio de GitHub y crear la aplicación con la AWS SAM CLI. Ejecute los siguientes comandos en un terminal:
git clone https://github.com/aws-samples/api-gateway-auth.git

cd api-gateway-auth

sam build

 

 

  1. Implementar la aplicación:
sam deploy --guided

 

Proporcione el stack name y región de preferencia para el proceso de despliegue. El modelo requiere tres parámetros:

  1. HostedZoneID: la plantilla utiliza la Hosted Zone pública de Amazon Route 53 para configurar un nombre de dominio personalizado. Proporcione el hosted Zone ID donde el record set se debe crear.
  2. DomainName: Nombre de dominio personalizado para la API HTTP de Amazon API Gateway.
  3. TrustStoreKey: nombre del archivo de almacén de confianza (trust store) que se almacenará en Amazon S3 y que utilizará API Gateway para mTLS (TLS Mutuo). De forma predeterminada, este archivo es pem.

 

 

Después del despliegue, el stack proporciona la información del ARN de un certificado de prueba para el cliente (ClientOneCertArn). Esto se usará para validar la configuración más adelante. El endpoint de la API HTTP de API Gateay también se proporciona como resultado de la creación del modelo.

 

 

Usted ahora ha creado un endpoint para API Gateway HTTP API con mTLS.

 

Configuración de la CA privada de ACM

La plantilla de AWS SAM inicia con la configuración de la CA privada de ACM. Esto le permite crear una jerarquía de entidades de certificación (CA) con hasta cinco (5) niveles. Una jerarquía bien definida de CA proporciona ventajas como la granularidad de los controles de seguridad y la división de tareas administrativas. Para obtener más información sobre la jerarquía de CA, visite la página Diseñar una jerarquía de CA. La CA privada de ACM se utiliza para configurar API HTTP y para distribuir certificados a los clientes.

Primero, la CA raíz es creada y actividada, seguida de la creación de una CA subordinada de acuerdo con las prácticas recomendadas. La CA secundaria se utiliza para configurar el mTLS para las API y distribuir certificados de clientes.

 

PrivateCA:

    Type: AWS::ACMPCA::CertificateAuthority

    Properties:

      KeyAlgorithm: RSA_2048

      SigningAlgorithm: SHA256WITHRSA

      Subject:

        CommonName: !Sub "${AWS::StackName}-rootca"

      Type: ROOT




  PrivateCACertificate:

    Type: AWS::ACMPCA::Certificate

    Properties:

      CertificateAuthorityArn: !Ref PrivateCA

      CertificateSigningRequest: !GetAtt PrivateCA.CertificateSigningRequest

      SigningAlgorithm: SHA256WITHRSA

      TemplateArn: 'arn:aws:acm-pca:::template/RootCACertificate/V1'

      Validity:

        Type: YEARS

        Value: 10




  PrivateCAActivation:

    Type: AWS::ACMPCA::CertificateAuthorityActivation

    Properties:

      Certificate: !GetAtt

        - PrivateCACertificate

        - Certificate

      CertificateAuthorityArn: !Ref PrivateCA

      Status: ACTIVE




  MtlsCA:

    Type: AWS::ACMPCA::CertificateAuthority

    Properties:

      Type: SUBORDINATE

      KeyAlgorithm: RSA_2048

      SigningAlgorithm: SHA256WITHRSA

      Subject:

        CommonName: !Sub "${AWS::StackName}-mtlsca"




  MtlsCertificate:

    DependsOn: PrivateCAActivation

    Type: AWS::ACMPCA::Certificate

    Properties:

      CertificateAuthorityArn: !Ref PrivateCA

      CertificateSigningRequest: !GetAtt

        - MtlsCA

        - CertificateSigningRequest

      SigningAlgorithm: SHA256WITHRSA

      TemplateArn: 'arn:aws:acm-pca:::template/SubordinateCACertificate_PathLen3/V1'

      Validity:

        Type: YEARS

        Value: 3




  MtlsActivation:

    Type: AWS::ACMPCA::CertificateAuthorityActivation

    Properties:

      CertificateAuthorityArn: !Ref MtlsCA

      Certificate: !GetAtt

        - MtlsCertificate

        - Certificate

      CertificateChain: !GetAtt

        - PrivateCAActivation

        - CompleteCertificateChain

      Status: ACTIVE

 

Emisión de un certificado de cliente desde CA privada ACM

Cree un certificado de cliente, que se utilizará como certificado de prueba para validar la configuración de MTL:

 

ClientOneCert:

    DependsOn: MtlsActivation

    Type: AWS::CertificateManager::Certificate

    Properties:

      CertificateAuthorityArn: !Ref MtlsCA

      CertificateTransparencyLoggingPreference: ENABLED

      DomainName: !Ref DomainName

      Tags:

        - Key: Name

 

Value: ClientOneCert

 

Configurar un almacén de confianza en Amazon S3

ACM Private CA está lista para configurar mTLS en la API. La configuración utiliza un objeto Amazon S3 como almacén de confianza (truststore) para validar certificados de cliente. Para automatizar esto, un recurso personalizado de backend AWS Lambda copia la cadena de certificados públicos de la CA privada ACM en el bucket de S3:

 

TrustStoreBucket:

    Type: AWS::S3::Bucket

    Properties:

      VersioningConfiguration:

        Status: Enabled




  TrustedStoreCustomResourceFunction:

    Type: AWS::Serverless::Function

    Properties:

      FunctionName: TrustedStoreCustomResourceFunction

      Handler: com.auth.TrustedStoreCustomResourceHandler::handleRequest

      Timeout: 120

      Policies:

        - S3CrudPolicy:

            BucketName: !Ref TrustStoreBucket

 

La recurso de ejemplo custom está escrita en Java, pero puede escribirse en cualquier otro lenguaje de programación compatible con AWS Lambda. El recurso personalizado se invoca con los detalles del certificado público de CA root privada, la CA subordinada y la ubicación del buket de Amazon S3. A continuación, la función Lambda concatena la cadena de certificados y almacena el objeto en el bucket de S3.

 

TrustedStoreCustomResource:

    Type: Custom::TrustedStore

    Properties:

      ServiceToken: !GetAtt TrustedStoreCustomResourceFunction.Arn

      TrustStoreBucket: !Ref TrustStoreBucket

      TrustStoreKey: !Ref TruststoreKey

      Certs:

        - !GetAtt MtlsCertificate.Certificate

        - !GetAtt PrivateCACertificate.Certificate

 

Puede ver y descargar el código de ejecución del recurso personalizado (custom resource) que utiliza AWS Lambda en el repositorio de este proyecto.

 

Configuración de las API HTTP de Amazon API Gateway con mTLS

Con un objeto de almacén de confianza (truststore) guardado correctamente en Amazon S3, ahora puede configurar las API. Debe configurarse un nombre de dominio personalizado para que Amazon API Gateway pueda habilitar el mTLS. El siguiente código crea y configura un dominio personalizado para la API HTTP. Consulte el archivo template.yaml para ver el ejemplo completo.

 

CustomDomainCert:

    Type: AWS::CertificateManager::Certificate

    Properties:

      CertificateTransparencyLoggingPreference: ENABLED

      DomainName: !Ref DomainName

      DomainValidationOptions:

        - DomainName: !Ref DomainName

          HostedZoneId: !Ref HostedZoneId

      ValidationMethod: DNS




  SampleHttpApi:

    Type: AWS::Serverless::HttpApi

    DependsOn: TrustedStoreCustomResource

    Properties:

      CorsConfiguration:

        AllowMethods:

          - GET

        AllowOrigins:

          - http://localhost:8080

      Domain:

        CertificateArn: !Ref CustomDomainCert

        DomainName: !Ref DomainName

        EndpointConfiguration: REGIONAL

        SecurityPolicy: TLS_1_2

        MutualTlsAuthentication:

          TruststoreUri: !GetAtt TrustedStoreCustomResource.TrustStoreUri

          TruststoreVersion: !GetAtt TrustedStoreCustomResource.ObjectVersion

        Route53:

          EvaluateTargetHealth: False

          HostedZoneId: !Ref HostedZoneId

        DisableExecuteApiEndpoint: true

 

Se utiliza una hosted zone alojada en Amazon Route 53 para configurar el dominio personalizado. Esto debe configurarse previamente en su cuenta de AWS y debe proporcionar el ID del Hosted Zone como parámetro para la plantilla.

Como el endpoint por defecto de HTTP API no requiere el uso de TLS mutuo, debe deshabilitarse mediante la llamada a la API DisableExecuteApiendPoint. De esta manera, nos aseguramos de que la autenticación con mTLS sea obligatoria para todo el tráfico de API.

La API de ejemplo invoca una función Lambda y devuelve el payload de la respuesta.

 

Prueba y validación de la configuración

Para validar la configuración, primero exportamos el certificado de cliente creado anteriormente. Puede exportar el certificado mediante AWS Management Console o la AWS CLI. En este ejemplo, utilizaremos la AWS CLI para exportar el certificado. Para obtener información sobre cómo exportar a través de la consola de administración, consulte la documentación sobre cómo exportar un certificado privado mediante la consola.

  1. Exporte el certificado codificado en Base64-PEM a un archivo local, client.pem.
aws acm export-certificate --certificate-arn <<Certificat ARN from stack output>> 
--passphrase $(echo -n 'your paraphrase' | base64) --region us-east-2 | jq -r '"\(.Certificate)"' > client.pem
  1. Exporte la llave privada cifrada que esta asociada a la llave pública del certificado y guárdela en un archivo localcrypted.key . Debe proporcionar una frase clave para asociarla con la llave privada cifrada. Esto se usará para descifrar la clave privada exportada.
aws acm export-certificate --certificate-arn <<Certificat ARN from stack output>> 
--passphrase $(echo -n 'your paraphrase' | base64) --region us-east-2| jq -r '"\(.PrivateKey)"' > client.encrypted.key
  1. Descifrar la clave privada exportada utilizando la frase clave y la librería de OpenSSL.
openssl rsa -in client.encrypted.key -out client.decrypted.key
  1. Acceda a la API mediante TLS Mutuo (mTLS).
curl -v --cert client.pem  --key client.decrypted.key https://demo-api.example.com

 

Agregar una lista de revocación de certificados

AWS Certificate Manager Private Certificate Authority (CA Privada de ACM) se puede configurar de forma nativa con una lista de revocación de certificados (CRL).

CRL es una forma para que la entidad emisora de certificados (CA) reconozca que uno o más de sus certificados digitales ya no son de confianza. Cuando los clientes revocan certificados, los certificados se invalidan antes de su fecha de caducidad. La entidad emisora de certificados puede revocar un certificado emitido por numerosas razones, la más común es cuando la llave privada de un certificado está comprometida.

La configuración mTLS para API HTTP de Amazon API Gateway se puede utilizar con todas las opciones de autenticación de API Gateway. Incluso puede extender la validación a autorizadores personalizados de AWS Lambda que se pueden configurar para validar certificados de cliente mediante una lista de revocación de certificados (CRL). Por ejemplo:

 

Por un blueprint que utiliza Lambda Authorizer, consulte aws-apigateway-lambda-authorizer-blueprints.

 

Conclusión

TLS Mutuo (mTLS) para API Gateway está disponible sin costo adicional. Este artículo muestra cómo automatizar la configuración de mTLS en Amazon API Gateway para API HTTP utilizando AWS Certificate Manager Private Certificate Authority como CA privada. Usando Infrastructure as Code (IAC) le permite desarrollar, implementar y escalar aplicaciones en la nube a alta velocidad, menos riesgo y menor costo.

Para descargar el ejemplo funcional completo para implementar MTL con API Gateway use este repositorio de GitHub. Para obtener más información sobre Amazon API Gateway, visite la documentación de API Gateway Developer Guide.

Para obtener más información sobre las funciones serverless, visite el sitio web de Serverless Land.

 

Este artículo fue traducido del Blog da AWS en Inglés.

 


Sobre el autor

Pankaj Agrawal es Arquitecto de Soluciones en AWS Noruega.

 

 

 

 

Revisor

Javier Cristancho es Arquitecto de Soluciones Senior  en AWS Colombia. Ha trabajado en AWS para clientes en Sudamérica y Centroamérica. En su puesto actual, trabajó apoyando a las principales organizaciones de servicios financieros en su adopción de la nube. Es uno de los pioneros de la comunidad interna de LATAM AWS Serverless Advocate.