AWS WorkMail é um poderoso serviço de e-mail e calendário que combina segurança, confiabilidade e facilidade de uso. Sua integração com os serviços da AWS e a compatibilidade com clientes de e-mail existentes tornam-no uma escolha atraente para empresas que buscam agilizar o gerenciamento de e-mail e calendário, garantindo segurança e conformidade. Ao aproveitar o AWS WorkMail, as organizações podem se concentrar em suas atividades principais sem se preocupar com as complexidades do gerenciamento da infraestrutura de e-mail. Configurar um sistema de backup confiável para seu AWS WorkMail é crucial para garantir que seus e-mails sejam seguros e facilmente recuperáveis. Neste tutorial, orientarei você no processo de automatização de backups do AWS WorkMail para vários usuários, gerenciando até 10 trabalhos simultâneos de exportação de caixa de correio. Usaremos serviços AWS e Python para criar uma solução de backup robusta.
Ah! Lembro-me de quando estava usando o servidor de e-mail CPANEL e depois me intrometendo em meu próprio servidor de e-mail. Esses servidores de e-mail de instância única com acesso limitado a endereços IP no início de 2010 funcionavam bem, mas à medida que mais e mais pessoas em todo o mundo começaram a explorar esses servidores, comon, ainda recebemos muito spam e marketing. As coisas foram difíceis para garantir que seu e-mail não caísse na caixa de spam.
A escolha entre o AWS WorkMail, um servidor de e-mail auto-hospedado, e um servidor de e-mail cPanel depende de vários fatores, incluindo orçamento, conhecimento técnico, necessidades de escalabilidade e requisitos de segurança.
Minhas principais preocupações sempre foram as seguintes;
Então veio a AWS para o resgate e, desde que usei a AWS em 2015, as coisas têm sido muito fáceis, exceto quando houve um caso de backup da minha conta da AWS para mudar para uma nova conta. Bem, tenho pesquisado na Internet para encontrar uma solução confiável porque, pelo que falamos até agora, o AWS WorkMail não fornece uma maneira direta de fazer backup do seu e-mail para o seu computador local ou para o S3, e é compreensível com base na conformidade de segurança, mas ainda assim, ainda espero que a AWS forneça alguma GUI ou ferramenta para isso. Bom, enquanto navegava, me deparei com ferramentas definitivamente PAGAS, então decidi seguir o caminho de desenvolver minha própria ferramenta. Após testes rigorosos, com base em minha experiência com a AWS, sempre ocorrem problemas 9/10 quando um serviço não consegue se comunicar com outro serviço devido a problemas de política ou de função do IAM.
Esta é minha contribuição para todas aquelas pessoas que estão tendo dificuldade em fazer backups de contas de e-mail de trabalho da AWS.
Criamos uma função IAM em sua conta, dando à função acesso para exportar do AWS WorkMail e, em seguida, anexamos uma política à mesma função para permitir que ela acesse o S3. Em seguida, criamos uma chave KMS, que dá acesso à função IAM. O bucket S3 também precisa de acesso à função IAM para funcionar corretamente.
Primeiro, certifique-se de que a AWS CLI esteja instalada e configurada com as credenciais apropriadas. Abra seu terminal e execute:
aws configure
Siga as instruções para definir o ID da chave de acesso da AWS, a chave de acesso secreta, a região padrão e o formato de saída.
Precisamos criar uma função IAM, políticas, um bucket S3 e uma chave KMS. Salve o seguinte 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
Torne o script executável e execute-o:
chmod +x setup_workmail_export.sh ./setup_workmail_export.sh
Agora, vamos escrever o script Python para exportar caixas de correio em lotes de 10. Salve o script a seguir 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()
Substitua os espaços reservados pelo ID real da organização do AWS WorkMail, ID do usuário para mapeamentos de e-mail, nome do bucket S3, região, ARN da chave KMS, nome da função e ID da conta da AWS.
Certifique-se de ter o Boto3 instalado:
pip install boto3
Em seguida, execute o script 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()
Seguindo essas etapas, você configurou um sistema automatizado para fazer backup de suas caixas de correio do AWS WorkMail, lidando com até 10 trabalhos de exportação simultâneos. Esta solução garante que seus e-mails sejam armazenados com segurança em um bucket S3, organizados por e-mail e data do usuário e criptografados com uma chave KMS. Esta configuração fornece uma estratégia de backup robusta e escalonável para os dados de email da sua organização.
Repositório Github: https://github.com/th3n00bc0d3r/AWS-WorkMail-Backup
Sinta-se à vontade para entrar em contato no meu LinkedIn . Além disso, você sempre pode me comprar um café