Blog de Amazon Web Services (AWS)
Automatización del cifrado por defecto en sus Buckets Amazon S3 usando AWS KMS y AWS Config
Por Dario Goldfarb, Security Solutions Architect LATAM de AWS
En este Blog conocerás como crear una automatización para que todos tus Buckets usen cifrado por defecto usando llaves particulares que tu gestionas con AWS Key Management Service (KMS).
Introducción y ventajas del AWS Key Management Service (KMS)
AWS Key Management Service (KMS) es un servicio para el almacenamiento de claves (llaves) de cifrado, que utiliza Hardware Security Modules (HSMs) para brindar un alto grado de seguridad. El uso de este servicio provee muchas ventajas:
- Permite al usuario gestionar la clave (ej.: rotarla anualmente, deshabilitarla, borrarla)
- Actualmente está integrado a todos los otros servicios de AWS que proveen cifrado del lado del servidor (Server Side Encrytion – SSE)
- Es resistente a manipulaciones físicas (tamper-resistant).
- Es un servicio gestionado (es decir, el cliente no tiene que administrar un cluster de HSMs, ni su replicación), y se ocupa automáticamente de rotar las claves si así lo decidiera el usuario
- No tiene API de extracción de claves: es decir, ni siquiera un administrador de AWS tiene forma de extraer una clave del KMS
- Soporta múltiples mecanismos de cifrado simétricos y asimétricos, tanto para encriptar como para firma digital
- Disminuye la latencia hasta sus aplicaciones en la nube, ya que reside en la nube
- Si se requiere que el HSM sea dedicado, KMS cuenta con integración con AWS CloudHSM para que se almacenen sus claves en un HSM dedicado (single-tenant)
- Permite aplicar control de acceso a la llave (y por ende a cualquier dato que se encuentre encriptado usando la misma). Por ejemplo:
- Sólo se puede utilizar para cifrado y descifrado por <estos usuarios y roles> en <estas cuentas>
- Puede ser utilizado por la aplicación A para cifrar y sólo utilizado por la aplicación B para descifrar
- Sólo se puede administrar mediante este conjunto de usuarios de IAM de administrador o roles de IAM
- Puede ser utilizado por <estas cuentas externas>, pero sólo para el cifrado/descifrado, no para tareas administrativas
Pueden encontrar mas detalles sobre las características de KMS en el whitepaper KMS Cryptographic Details.
Amazon Simple Storage Service (S3) es un servicio de almacenamiento de objetos que ofrece gran escalabilidad, performance, seguridad, disponibilidad, y durabilidad de los datos. Con Amazon S3, tu puedes elegir entre tres tipos de configuraciones de cifrado del lado del servidor para tus archivos:
- SSE-S3 – usa claves de cifrado gestionadas por Amazon S3
- SSE-KMS – usa claves de cifrado particulares a cada cliente (Customer Master Keys – CMKs) almacenadas en el servicio AWS Key Management Service (KMS)
- SSE-C – usa claves de cifrado provistas por el cliente en cada pedido PUT, GET, HEAD, POST o en subida de archivos (multipart upload)
Estas opciones permiten elegir el método de cifrado adecuado para cada caso, pero en algunas organizaciones es requerido el uso de claves de cifrado particulares (dedicadas) para cada cliente en todos sus Buckets, por ejemplo, para aquellas organizaciones que deben cumplir con PCI-DSS y que usan los servicios de AWS para procesar números de cuenta primario (Primary Account Number – PAN), existe un requerimiento que cualquier dato de PAN sea almacenado de modo que sea ilegible para terceros.
Entonces, surge la pregunta: ¿Cómo puedo hacer que todos los datos que subo a Buckets de Amazon S3 cuenten por defecto con el cifrado con llaves particulares (CMKs) gestionadas por AWS KMS?
Opción 1: Denegar operaciones no cifradas:
Una opción podría ser usar políticas de IAM para denegar operaciones s3:PutObject donde no esté en uso el cifrado requerido:
{ "Version":"2012-10-17", "Id":"PutObjectPolicy", "Statement":[{ "Sid":"DenyUnEncryptedObjectUploads", "Effect":"Deny", "Principal":"*", "Action":"s3:PutObject", "Resource":"arn:aws:s3:::awsexamplebucket1/*", "Condition":{ "StringNotEquals":{ "s3:x-amz-server-side-encryption":"aws:kms" } } } ] }
De modo que cualquier operación de subida de archivos que no utilice KMS será denegada, como por ejemplo la siguiente operación que utiliza SSE-S3 sería rechazada (al igual que una que no especifique cifrado):
PUT /example-object HTTP/1.1 Host: myBucket.s3.amazonaws.com Date: Wed, 8 Jun 2016 17:50:00 GMT Authorization: authorization string Content-Type: text/plain Content-Length: 11434 x-amz-meta-author: Janet Expect: 100-continue x-amz-server-side-encryption: AES256 [11434 bytes of object data]
Pero esta opción puede ser disruptiva para las aplicaciones actuales.
Opción 2: Automatización del cifrado de los objetos en un Bucket
Amazon S3 ofrece un parámetro de configuración para especificar un cifrado por defecto:
De este modo, si subimos un nuevo archivo sin indicar el tipo de cifrado, lo mismo será automáticamente encriptado con la clave de especificada.
La llave puede estar en otra cuenta, por ejemplo, la cuenta de seguridad de la organización. Lo que se resuelve indicando Custom KMS ARN y especificando el ARN completo:
Automatización del cifrado en múltiples Buckets
Ahora bien, tal vez en tu organización hay cientos de Buckets…
A. ¿Cómo puedes hacer para detectar los Buckets que no estén cifrados con KMS?
B. ¿Cómo puedes hacer para que todos los Buckets sean configurados para cifrar con llaves de KMS?
C. ¿Cómo puedes hacer para asegurar que si alguien por error o con mala intención quita el cifrado por defecto, que se vuelva a aplicar automáticamente?
A. ¿Cómo puedes hacer para detectar los Buckets que no estén cifrados con KMS?
Para la detección de Buckets no cifrados con KMS, puedes utilizar AWS Config, que cuenta con un chequeo nativo llamado s3-default-encryption-kms que recibe como parámetro el ARN o ID de la clave de cifrado que se desea verificar si los Buckets están utilizándola o no.
B. ¿Cómo puedes hacer para que todos los Buckets sean configurados para cifrar con llaves de KMS?
Para lograr que todos los Buckets que AWS Config detecta como Non-Compliant tengan la configuración deseada, configuraremos una acción de remediación.
Las acciones de remediación que ejecuta AWS Config son documentos de automatización de AWS Systems Manager. La arquitectura de la solución es la siguiente:
Ante todo, debes crear un rol con una política que permita al AWS Systems Manager cambiar la configuración del Amazon S3 permitiendo la operación s3:PutEncryptionConfiguration en todos los Buckets, así como una relación de confianza con el servicio de AWS System Manager para poder ejecutar la remediación.
Relaciones de Confianza (Trust relationships JSON):
{ "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Principal": { "Service": "ssm.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
Política de IAM:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "s3:PutEncryptionConfiguration", "Resource": "arn:aws:s3:::*" } ] }
Al momento de la escritura de este blog no existen una acción de remediación nativa en el servicio que permita configurar cifrado por defecto usando KMS (solo existe AWS-EnableS3BucketEncryption para encriptar con SSE-S3). Por consiguiente, crearemos un nuevo documento de automatización a medida (custom): EnableS3BucketEncryptionWithKMS.
Especificamos la automatización usando JSON:
Y utilizamos el siguiente texto para el documento de automatización:
description: Enables Encryption on S3 Bucket using KMS CMK schemaVersion: '0.3' assumeRole: '{{ AutomationAssumeRole }}' parameters: BucketName: type: String description: (Required) The name of the S3 Bucket whose content will be encrypted. KMSMasterKeyID: type: String description: (Required) KMS CMK to use for Server-side encryption for the encryption. AutomationAssumeRole: type: String description: (Optional) The ARN of the role that allows actions on your behalf. default: '' mainSteps: - name: PutBucketEncryption action: 'aws:executeAwsApi' inputs: Service: s3 Api: PutBucketEncryption Bucket: '{{BucketName}}' ServerSideEncryptionConfiguration: Rules: - ApplyServerSideEncryptionByDefault: SSEAlgorithm: 'aws:kms' KMSMasterKeyID: '{{KMSMasterKeyID}}' isEnd: true
Finalmente especificamos en AWS Config la acción de Remediación:
Seleccionamos la acción de remediación que acabamos de crear en AWS Systems Manager EnableS3BucketEncryptionWithKMS con remediación automática, enviando como parámetros:
- BucketName: desde AWS Config, que nos indicará el nombre del bucket que encontró non-compliant con la política que exige el cifrado por defecto a una clave especifica de KMS.
- KMSMasterKeyID: ARN o ID de la llave de KMS a utilizar (la misma configurada en la detección en AWS Config). En escenarios multi-cuenta es necesario especificar el ARN.
- AutomationAssumeRole: el ARN del rol que creamos para permitir al AWS Systems Manager modificar la configuración de Amazon S3.
Luego de estas acciones todos los Buckets pasarán a ser cifrados con la llave de KMS especificada en KMSMasterKeyID, y cualquier nuevo archivo que suban, donde en la llamada a la API no se especifique un cifrado, será automáticamente cifrado por defecto (con llave de KMS).
Opcionalmente pueden utilizar Amazon Macie que les brinda una vista general del estado de seguridad de sus Buckets, para comprobar que efectivamente todos los Buckets están encriptando por defecto con SSE-KMS. Como se ve en las siguiente imágenes, la activación del servicio es muy sencilla y cuenta con un período de pueba de 30 días:
C. ¿Cómo puedes hacer para asegurar que si alguien por error o con mala intención quita el cifrado por defecto, que se vuelva a aplicar automáticamente?
AWS Config hace chequeos continuos, cada vez que cambie la configuración del Bucket, la regla será evaluada, y si lo encuentra non-compliant, será corregido automáticamente, por lo que no se requiere ninguna acción adicional para que cuando la configuración de Amazon S3 tenga un desvío, la misma sea corregida automáticamente.
Como vemos en la figura anterior, si un usuario con los permisos suficientes cambia la configuración de un Bucket quitando el cifrado por defecto, en minutos AWS Config revertirá la configuración de cifrado al valor deseado.
Cifrado retroactivo
Datos anteriores que estén encriptados con claves distintas pueden ser re-encriptados manualmente (sobre cada dato), o pueden referirse al siguiente AWS Blog sobre como hacerlo para múltiples objetos en múltiples Buckets.
Conclusiones
AWS KMS es un servicio que permite fácilmente encriptar con claves propias distintos datos, con muchos beneficios en seguridad y facilidad de implementación. Amazon S3 nos ofrece distintas opciones para encriptar, entre ellas el uso de AWS KMS para la gestión de las llaves, permitiendo también encriptar por defecto.
Usando AWS Config se puede detectar Buckets configurados para guardar los datos sin cifrado por defecto, o usando otro tipo de cifrado y podemos remediar automáticamente esos Buckets para que utilicen una llave de AWS KMS siguiendo los pasos en el presente Blog.
Recomendaciones:
Si necesita que los datos a almacenar en Amazon S3 cuenten con cifrado, siguiendo los pasos explicados en el presente Blog podrán rápidamente cambiar la configuración de cifrado por defecto, y controlar periódicamente que la configuración persista en el tiempo.
Sobre el autor
Dario Goldfarb, Security Solutions Architect, LATAM.
Me dedico a ayudar a los clientes en su camino de madurez en la seguridad de las cargas en la nube. Disfruto crear materiales de aprendizaje y webinars y participa en eventos. Tengo 15+ años de experiencia en ciberseguridad, y conseguí múltiples certificaciones, tales como CISSP, AWS Security Specialty, The Open Group Master IT Architect. Me gusta estudiar textos bíblicos en su idioma original (arameo), hacer ciclismo y bucear.
Revisores
Omner Barajas, Security Specialist Solutions Architect, Mexico.
Julio Carvalho, Principal Security Architect for Financial Services, LATAM.