AWS WorkMail ist ein leistungsstarker E-Mail- und Kalenderdienst, der Sicherheit, Zuverlässigkeit und Benutzerfreundlichkeit vereint. Seine Integration mit AWS-Diensten und die Kompatibilität mit vorhandenen E-Mail-Clients machen ihn zu einer attraktiven Wahl für Unternehmen, die ihre E-Mail- und Kalenderverwaltung optimieren und gleichzeitig Sicherheit und Compliance gewährleisten möchten. Durch die Nutzung von AWS WorkMail können sich Unternehmen auf ihre Kernaktivitäten konzentrieren, ohne sich um die Komplexität der Verwaltung der E-Mail-Infrastruktur kümmern zu müssen. Das Einrichten eines zuverlässigen Backup-Systems für Ihr AWS WorkMail ist entscheidend, um sicherzustellen, dass Ihre E-Mails sicher und leicht wiederherstellbar sind. In diesem Tutorial führe ich Sie durch den Prozess der Automatisierung von AWS WorkMail-Backups für mehrere Benutzer und verarbeite bis zu 10 gleichzeitige Postfach-Exportaufträge. Wir werden AWS-Dienste und Python verwenden, um eine robuste Backup-Lösung zu erstellen.
Ach! Ich erinnere mich noch an die Zeit, als ich den CPANEL-Mailserver benutzte und dann meinen eigenen Mailserver bastelte. Diese Single-Instance-Mailserver mit eingeschränktem Zugriff auf IP-Adressen liefen Anfang der 2010er Jahre reibungslos, aber als immer mehr Menschen weltweit begannen, diese Server auszunutzen, bekamen wir immer noch jede Menge Spam und Werbung. Es war schwierig, sicherzustellen, dass Ihre E-Mail nicht im Spam-Ordner landete.
Die Wahl zwischen AWS WorkMail, einem selbst gehosteten Mailserver und einem cPanel-Mailserver hängt von mehreren Faktoren ab, darunter Budget, technisches Fachwissen, Skalierbarkeitsanforderungen und Sicherheitsanforderungen.
Meine Hauptanliegen waren immer die folgenden:
Dann kam AWS zur Rettung und seitdem ich AWS seit 2015 verwende, ist alles ein Kinderspiel, außer als ich mein AWS-Konto sichern musste, um es auf ein neues Konto zu übertragen. Ich habe im Internet nach einer zuverlässigen Lösung gesucht, denn soweit wir wissen, bietet AWS WorkMail derzeit keine direkte Möglichkeit, Ihre E-Mails auf Ihrem lokalen Computer oder in S3 zu sichern. Angesichts der Sicherheitskonformität ist das auch verständlich, aber ich erwarte dennoch, dass AWS eine GUI oder ein Tool dafür bereitstellt. Beim Suchen bin ich auf definitiv KOSTENPFLICHTIGE Tools gestoßen und habe mich daher entschlossen, mein eigenes Tool dafür zu entwickeln. Nach rigorosen Tests treten meiner Erfahrung mit AWS zufolge 90 % der Probleme immer dann auf, wenn ein Dienst aufgrund von Richtlinien oder IAM-Rollenproblemen nicht mit dem anderen Dienst kommunizieren kann.
Dies ist mein Beitrag für alle, die Schwierigkeiten beim Erstellen von Backups ihrer AWS Work Mail-Konten haben.
Wir haben in Ihrem Konto eine IAM-Rolle erstellt, die der Rolle Zugriff auf den Export aus AWS WorkMail gewährt, und dann haben wir derselben Rolle eine Richtlinie zugeordnet, die ihr den Zugriff auf S3 ermöglicht. Anschließend erstellen wir einen KMS-Schlüssel, der Zugriff auf die IAM-Rolle erhält. Der S3-Bucket benötigt auch Zugriff auf die IAM-Rolle, um ordnungsgemäß zu funktionieren.
Stellen Sie zunächst sicher, dass die AWS CLI installiert und mit den entsprechenden Anmeldeinformationen konfiguriert ist. Öffnen Sie Ihr Terminal und führen Sie Folgendes aus:
aws configure
Folgen Sie den Anweisungen, um Ihre AWS-Zugriffsschlüssel-ID, Ihren geheimen Zugriffsschlüssel, die Standardregion und das Ausgabeformat festzulegen.
Wir müssen eine IAM-Rolle, Richtlinien, einen S3-Bucket und einen KMS-Schlüssel erstellen. Speichern Sie das folgende Bash-Skript als 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
Machen Sie das Skript ausführbar und führen Sie es aus:
chmod +x setup_workmail_export.sh ./setup_workmail_export.sh
Schreiben wir nun das Python-Skript zum Exportieren von Postfächern in Stapeln zu je 10 Stück. Speichern Sie das folgende Skript als 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()
Ersetzen Sie die Platzhalter durch Ihre tatsächliche AWS WorkMail-Organisations-ID, Benutzer-ID für E-Mail-Zuordnungen, S3-Bucket-Namen, Region, KMS-Schlüssel-ARN, Rollennamen und AWS-Konto-ID.
Stellen Sie sicher, dass Sie Boto3 installiert haben:
pip install boto3
Führen Sie dann das Python-Skript aus:
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()
Indem Sie diese Schritte befolgen, haben Sie ein automatisiertes System zum Sichern Ihrer AWS WorkMail-Postfächer eingerichtet, das bis zu 10 gleichzeitige Exportaufträge verarbeiten kann. Diese Lösung stellt sicher, dass Ihre E-Mails sicher in einem S3-Bucket gespeichert, nach Benutzer-E-Mail und Datum organisiert und mit einem KMS-Schlüssel verschlüsselt werden. Dieses Setup bietet eine robuste und skalierbare Sicherungsstrategie für die E-Mail-Daten Ihres Unternehmens.
Github-Repo: https://github.com/th3n00bc0d3r/AWS-WorkMail-Backup
Nehmen Sie gerne über LinkedIn Kontakt mit mir auf. Sie können mir auch jederzeit einen Kaffee spendieren.