AWS WorkMail es un potente servicio de correo electrónico y calendario que combina seguridad, confiabilidad y facilidad de uso. Su integración con los servicios de AWS y su compatibilidad con los clientes de correo electrónico existentes lo convierten en una opción atractiva para las empresas que buscan optimizar su administración de correo electrónico y calendario, garantizando al mismo tiempo la seguridad y el cumplimiento. Al aprovechar AWS WorkMail, las organizaciones pueden centrarse en sus actividades principales sin preocuparse por las complejidades de administrar la infraestructura de correo electrónico. Configurar un sistema de respaldo confiable para su AWS WorkMail es crucial para garantizar que sus correos electrónicos sean seguros y fácilmente recuperables. En este tutorial, lo guiaré a través del proceso de automatización de copias de seguridad de AWS WorkMail para múltiples usuarios, manejando hasta 10 trabajos de exportación de buzones simultáneos. Utilizaremos los servicios de AWS y Python para crear una solución de respaldo sólida.
¡Ah! Recuerdo la vez que estaba usando el servidor de correo CPANEL y luego me entrometía con mi propio servidor de correo. Esos servidores de correo de instancia única con acceso limitado a direcciones IP a principios de la década de 2010 funcionaban sin problemas, pero a medida que más y más personas en todo el mundo comenzaron a explotar estos servidores, Comon, todavía recibimos mucho spam y marketing. Las cosas fueron difíciles para asegurarse de que su correo electrónico no terminara en la casilla de spam.
La elección entre AWS WorkMail, un servidor de correo autohospedado, y un servidor de correo cPanel depende de varios factores, incluido el presupuesto, la experiencia técnica, las necesidades de escalabilidad y los requisitos de seguridad.
Mis principales preocupaciones siempre fueron las siguientes;
Luego vino AWS al rescate y, desde que utilicé AWS en 2015, las cosas han sido muy sencillas, excepto cuando tuve que hacer una copia de seguridad de mi cuenta de AWS para pasar a una nueva cuenta. Bueno, he estado buscando en Internet para encontrar una solución confiable porque, hasta donde hablamos hasta ahora, AWS WorkMail no proporciona una forma sencilla de realizar una copia de seguridad de su correo electrónico en su computadora local o en S3, y es Es comprensible en función del cumplimiento de la seguridad, pero aún así, sigo esperando que AWS proporcione alguna GUI o una herramienta para eso. Bueno, mientras navegaba, encontré herramientas definitivamente PAGADAS, así que decidí emprender el camino de desarrollar mi propia herramienta. Después de pruebas rigurosas, según mi experiencia con AWS, 9/10 siempre ocurren problemas cuando un servicio no puede comunicarse con el otro debido a problemas de política o función de IAM.
Este es mi aporte para todas aquellas personas que están teniendo dificultades para realizar copias de seguridad de las cuentas de correo de trabajo de AWS.
Creamos un rol de IAM en su cuenta, dándole acceso para exportar desde AWS WorkMail, y luego adjuntamos una política al mismo rol para permitirle acceder a S3. Luego creamos una CMK, a la que se le otorga acceso al rol de IAM. El depósito de S3 también necesita acceso a la función de IAM para funcionar correctamente.
Primero, asegúrese de que AWS CLI esté instalada y configurada con las credenciales adecuadas. Abre tu terminal y ejecuta:
aws configure
Siga las instrucciones para configurar su ID de clave de acceso de AWS, su clave de acceso secreta, su región predeterminada y su formato de salida.
Necesitamos crear una función de IAM, políticas, un depósito S3 y una clave KMS. Guarde el siguiente script bash como setup_workmail_export.sh
.
#!/bin/bash # Configuration ROLE_NAME="WorkMailExportRole" POLICY_NAME="workmail-export" S3_BUCKET_NAME="s3.bucket.name" AWS_REGION="your-region" ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) # Create Trust Policy cat <<EOF > trust-policy.json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "export.workmail.amazonaws.com" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId": "$ACCOUNT_ID" } } } ] } EOF # Create IAM Role aws iam create-role --role-name $ROLE_NAME --assume-role-policy-document file://trust-policy.json # Create IAM Policy cat <<EOF > role-policy.json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:*", "Resource": [ "arn:aws:s3:::$S3_BUCKET_NAME", "arn:aws:s3:::$S3_BUCKET_NAME/*" ] }, { "Effect": "Allow", "Action": [ "kms:Decrypt", "kms:GenerateDataKey" ], "Resource": "*" } ] } EOF # Attach the Policy to the Role aws iam put-role-policy --role-name $ROLE_NAME --policy-name $POLICY_NAME --policy-document file://role-policy.json # Create S3 Bucket aws s3api create-bucket --bucket $S3_BUCKET_NAME --region $AWS_REGION --create-bucket-configuration LocationConstraint=$AWS_REGION # Create Key Policy cat <<EOF > key-policy.json { "Version": "2012-10-17", "Id": "workmail-export-key", "Statement": [ { "Sid": "Enable IAM User Permissions", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::$ACCOUNT_ID:root" }, "Action": "kms:*", "Resource": "*" }, { "Sid": "Allow administration of the key", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::$ACCOUNT_ID:role/$ROLE_NAME" }, "Action": [ "kms:Create*", "kms:Describe*", "kms:Enable*", "kms:List*", "kms:Put*", "kms:Update*", "kms:Revoke*", "kms:Disable*", "kms:Get*", "kms:Delete*", "kms:ScheduleKeyDeletion", "kms:CancelKeyDeletion" ], "Resource": "*" } ] } EOF # Create the KMS Key and get the Key ID and ARN using Python for JSON parsing KEY_METADATA=$(aws kms create-key --policy file://key-policy.json) KEY_ID=$(python3 -c "import sys, json; print(json.load(sys.stdin)['KeyMetadata']['KeyId'])" <<< "$KEY_METADATA") KEY_ARN=$(python3 -c "import sys, json; print(json.load(sys.stdin)['KeyMetadata']['Arn'])" <<< "$KEY_METADATA") # Update S3 Bucket Policy cat <<EOF > s3_bucket_policy.json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::$ACCOUNT_ID:role/$ROLE_NAME" }, "Action": "s3:*" "Resource": [ "arn:aws:s3:::$S3_BUCKET_NAME", "arn:aws:s3:::$S3_BUCKET_NAME/*" ] } ] } EOF # Apply the Bucket Policy aws s3api put-bucket-policy --bucket $S3_BUCKET_NAME --policy file://s3_bucket_policy.json # Clean up temporary files rm trust-policy.json role-policy.json key-policy.json s3_bucket_policy.json # Display the variables required for the backup script cat <<EOF Setup complete. Here are the variables required for the backup script: # Print out the Variables organization_id = 'your-organization-id' user_id = 'your-user-id' s3_bucket_name = '$S3_BUCKET_NAME' s3_prefix = 'workmail-backup/' region = '$AWS_REGION' kms_key_arn = '$KEY_ARN' role_name = '$ROLE_NAME' account_id = '$ACCOUNT_ID' EOF
Haga el script ejecutable y ejecútelo:
chmod +x setup_workmail_export.sh ./setup_workmail_export.sh
Ahora, escribamos el script de Python para exportar buzones de correo en lotes de 10. Guarde el siguiente script como workmail_export.py
.
import boto3 import json import time from datetime import datetime # Configuration organization_id = 'your-organization-id' user_emails = { 'user-id-1': '[email protected]', 'user-id-2': '[email protected]', 'user-id-3': '[email protected]', 'user-id-4': '[email protected]', 'user-id-5': '[email protected]', 'user-id-6': '[email protected]', 'user-id-7': '[email protected]', 'user-id-8': '[email protected]', 'user-id-9': '[email protected]', 'user-id-10': '[email protected]', 'user-id-11': '[email protected]', 'user-id-12': '[email protected]' # Add more user ID to email mappings as needed } s3_bucket_name = 's3.bucket.name' region = 'your-region' kms_key_arn = 'arn:aws:kms:your-region:your-account-id:key/your-key-id' role_name = 'WorkMailExportRole' account_id = 'your-account-id' # Get the current date current_date = datetime.now().strftime('%Y-%m-%d') # Set the S3 prefix with the date included s3_prefix_base = f'workmail-backup/{current_date}/' # Initialize AWS clients workmail = boto3.client('workmail', region_name=region) sts = boto3.client('sts', region_name=region) def start_export_job(entity_id, user_email): client_token = str(time.time()) # Unique client token role_arn = f"arn:aws:iam::{account_id}:role/{role_name}" s3_prefix = f"{s3_prefix_base}{user_email}/" try: response = workmail.start_mailbox_export_job( ClientToken=client_token, OrganizationId=organization_id, EntityId=entity_id, Description='Backup job', RoleArn=role_arn, KmsKeyArn=kms_key_arn, S3BucketName=s3_bucket_name, S3Prefix=s3_prefix ) return response['JobId'] except Exception as e: print(f"Failed to start export job for {entity_id}: {e}") return None def check_job_status(job_id): while True: try: response = workmail.describe_mailbox_export_job( OrganizationId=organization_id, JobId=job_id ) print(f"Full Response: {response}") # Log full response for debugging state = response.get('State', 'UNKNOWN') print(f"Job State: {state}") if state in ['COMPLETED', 'FAILED']: break except Exception as e : print(f"Error checking job status for {job_id}: {e}") time.sleep(30) # Wait for 30 seconds before checking again return state def export_mailboxes_in_batches(user_emails, batch_size=10): user_ids = list(user_emails.keys()) for i in range(0, len(user_ids), batch_size): batch = user_ids[i:i+batch_size] job_ids = [] for user_id in batch: user_email = user_emails[user_id] job_id = start_export_job(user_id, user_email) if job_id: print(f"Started export job for {user_email} with Job ID: {job_id}") job_ids.append((user_email, job_id)) for user_email, job_id in job_ids: state = check_job_status(job_id) if state == 'COMPLETED': print(f"Export job for {user_email} completed successfully") else: print(f"Export job for {user_email} failed with state: {state}") def main(): export_mailboxes_in_batches(user_emails) if __name__ == "__main__": main()
Reemplace los marcadores de posición con su ID de organización de AWS WorkMail real, ID de usuario para asignaciones de correo electrónico, nombre del depósito S3, región, ARN de clave KMS, nombre de función e ID de cuenta de AWS.
Asegúrese de tener Boto3 instalado:
pip install boto3
Luego, ejecute el script de Python:
python workmail_export.py
import boto3 import json import time # Configuration organization_id = 'your-organization-id' user_import_data = { 'user-id-1': '[email protected]', 'user-id-2': '[email protected]', 'user-id-3': '[email protected]', 'user-id-4': '[email protected]', 'user-id-5': '[email protected]', 'user-id-6': '[email protected]', 'user-id-7': '[email protected]', 'user-id-8': '[email protected]', 'user-id-9': '[email protected]', 'user-id-10': '[email protected]', 'user-id-11': '[email protected]', 'user-id-12': '[email protected]' # Add more user ID to email mappings as needed } s3_bucket_name = 's3.bucket.name' s3_object_prefix = 'workmail-backup/' # Prefix for S3 objects (folders) region = 'your-region' role_name = 'WorkMailImportRole' account_id = 'your-account-id' # Initialize AWS clients workmail = boto3.client('workmail', region_name=region) sts = boto3.client('sts', region_name=region) def start_import_job(entity_id, user_email): client_token = str(time.time()) # Unique client token role_arn = f"arn:aws:iam::{account_id}:role/{role_name}" s3_object_key = f"{s3_object_prefix}{user_email}/export.zip" try: response = workmail.start_mailbox_import_job( ClientToken=client_token, OrganizationId=organization_id, EntityId=entity_id, Description='Import job', RoleArn=role_arn, S3BucketName=s3_bucket_name, S3ObjectKey=s3_object_key ) return response['JobId'] except Exception as e: print(f"Failed to start import job for {entity_id}: {e}") return None def check_job_status(job_id): while True: try: response = workmail.describe_mailbox_import_job( OrganizationId=organization_id, JobId=job_id ) state = response.get('State', 'UNKNOWN') print(f"Job State: {state}") if state in ['COMPLETED', 'FAILED']: break except Exception as e: print(f"Error checking job status for {job_id}: {e}") time.sleep(30) # Wait for 30 seconds before checking again return state def import_mailboxes_in_batches(user_import_data, batch_size=10): user_ids = list(user_import_data.keys()) for i in range(0, len(user_ids), batch_size): batch = user_ids[i:i+batch_size] job_ids = [] for user_id in batch: user_email = user_import_data[user_id] job_id = start_import_job(user_id, user_email) if job_id: print(f"Started import job for {user_email} with Job ID: {job_id}") job_ids.append((user_email, job_id)) for user_email, job_id in job_ids: state = check_job_status(job_id) if state == 'COMPLETED': print(f"Import job for {user_email} completed successfully") else: print(f"Import job for {user_email} failed with state: {state}") def main(): import_mailboxes_in_batches(user_import_data) if __name__ == "__main__": main()
Si sigue estos pasos, habrá configurado un sistema automatizado para realizar una copia de seguridad de sus buzones de correo de AWS WorkMail y manejar hasta 10 trabajos de exportación simultáneos. Esta solución garantiza que sus correos electrónicos se almacenen de forma segura en un depósito S3, organizados por correo electrónico y fecha del usuario, y cifrados con una clave KMS. Esta configuración proporciona una estrategia de respaldo sólida y escalable para los datos de correo electrónico de su organización.
Repositorio de Github: https://github.com/th3n00bc0d3r/AWS-WorkMail-Backup
No dudes en ponerte en contacto en mi LinkedIn . También siempre puedes invitarme a un café.