Kai Ole Hartwig
s3mail · Dokumentation

Einrichtung

Auf dem Rechner, der s3mail startet: nichts. Kein Webserver, keine Datenbank, kein Docker, keine Laufzeitumgebung. s3mail ist ein einzelnes Programm, bringt seinen eigenen Server mit und bindet ihn an 127.0.0.1. Nach außen gehen nur HTTPS-Verbindungen zu s3.<region>.amazonaws.com, email.<region>.amazonaws.com und, falls verschlüsselt, kms.<region>.amazonaws.com.

  • Paket: macOS (Apple Silicon und Intel, signiert und notarisiert), Linux und Windows, jeweils amd64/arm64, aus den Releases
  • Start:unzip s3mail-macos-arm64.zip && open s3mail.app, unter Linux und Windows ./s3mail oder Doppelklick
  • Selbst bauen: Go 1.27 oder neuer, CGO aus

Im AWS-Konto

WasWofürFehlt es, dann …
In SES verifizierte DomainEmpfang überhauptkommt keine Mail an
MX-Record auf SESleitet die Mail zu AWSMail geht an den alten Server
S3-Bucket in derselben Regiondie Mails liegen dort–
Bucket-Policy für SESSES darf hineinschreibenMails werden verworfen
Aktives Receipt-Rule-Set mit S3-Aktionschreibt die Mail in den BucketMail wird angenommen und weggeworfen
IAM-Identität mit der Policy untens3mail liest und sortierts3mail kommt nicht an den Bucket
Verifizierte AbsenderadresseSchreiben, Antworten, WeiterleitenLesen geht, Senden nicht (--no-send)
KMS-Schlüssel (optional)nur bei Verschlüsselungsiehe Verschlüsselte Buckets

Nicht gebraucht werden Lambda, EC2, VPC oder eine WorkMail-Organisation.

Der kurze Weg: CloudFormation

Bucket, Bucket-Policy, IAM-Benutzer samt Policy, die Geräte-Boundary und die SES-Empfangsregel legt eine Vorlage an (deploy/README.md im Repository sagt, wofür jede Ressource da ist):

 

aws cloudformation create-stack \
  --stack-name s3mail \
  --template-body file://deploy/s3mail.json \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameters \
      ParameterKey=MailDomain,ParameterValue=firma.de \
      ParameterKey=MailboxLocalPart,ParameterValue=info \
      ParameterKey=MailBucket,ParameterValue=mein-eindeutiger-bucket

 

Die Domain muss vorher in SES verifiziert sein; dafür braucht es DNS-Einträge, die nur du setzen kannst. Zwei Schritte kann die Vorlage nicht abschließen, und beide sind ein Befehl: das Rule-Set aktivieren (dafür gibt es keine CloudFormation-Ressource) und einen Zugangsschlüssel erzeugen. Die Vorlage legt bewusst keinen an: ein Schlüssel in einem Stack-Output ist für jeden lesbar, der den Stack lesen kann, und bleibt es.

 

aws ses set-active-receipt-rule-set --rule-set-name s3mail-info
aws iam create-access-key --user-name s3mail-info

Von Hand, der Reihe nach

1

Region wählen

SES nimmt Mail nur in bestimmten Regionen entgegen; Bucket und SES gehören in dieselbe.

2

Domain in SES verifizieren

Und die DKIM-CNAMEs im DNS setzen.

3

MX-Record

Der Domain auf inbound-smtp.<region>.amazonaws.com, Priorität 10.

4

S3-Bucket anlegen

Darin ein Prefix als Wurzel, üblicherweise mail/.

5

Bucket-Policy

Damit SES schreiben darf; die SES-Konsole bietet sie beim Anlegen der Regel an.

6

Receipt-Rule-Set anlegen und aktivieren

Darin eine Regel mit der Aktion S3 → Bucket und Prefix mail/. Danach das Rule-Set aktivieren. Ein angelegtes, aber inaktives Rule-Set ist der häufigste Grund dafür, dass nichts ankommt.

7

Zugang für s3mail

Ein IAM-Benutzer mit Access Key (empfohlen), ein vorhandenes Profil mit Schlüsseln, oder AWS SSO / IAM Identity Center nach aws sso login. Der Assistent schreibt eingetippte Schlüssel als eigenes, zusätzliches Profil nach ~/.aws/credentials (chmod 600); vorhandene Profile bleiben unangetastet.

8

Absenderadresse verifizieren

Wenn gesendet werden soll. Solange das SES-Konto in der Sandbox steckt, kann es nur an verifizierte Adressen senden; Empfang funktioniert dort uneingeschränkt.

9

Testmail schicken

Dann in s3mail „Neu laden“. Ob alles sitzt, musst du nicht raten: Schritt 3 des Assistenten prüft der Reihe nach Bucket lesen, Mail lesen, Schreiben, Löschen, Zustand von mehreren Rechnern, Verschlüsselung und SES-Absender, und schreibt zu jedem fehlenden Punkt die IAM-Aktion dazu, die dafür nötig wäre.

IAM-Policy

{
  "Version": "2012-10-17",
  "Statement": [
    { "Effect": "Allow", "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::MEIN-BUCKET",
      "Condition": {"StringLike": {"s3:prefix": ["mail/*"]}} },
    { "Effect": "Allow", "Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
      "Resource": "arn:aws:s3:::MEIN-BUCKET/mail/*" },
    { "Effect": "Allow", "Action": "ses:SendRawEmail", "Resource": "*" },
    { "Effect": "Allow", "Action": ["sqs:ReceiveMessage", "sqs:DeleteMessage"],
      "Resource": "arn:aws:sqs:REGION:KONTO:MEINE-QUEUE" },
    { "Effect": "Allow", "Action": ["kms:Decrypt", "kms:GenerateDataKey"],
      "Resource": "arn:aws:kms:REGION:KONTO:key/DEIN-SCHLUESSEL" }
  ]
}

 

Der KMS-Teil entfällt, wenn weder der Bucket noch die SES-Regel verschlüsselt. Der SQS-Teil entfällt, wenn es keine Klingel gibt; dann läuft der Abgleich im Takt. sqs:GetQueueUrl steht bewusst nicht dabei: s3mail baut die URL aus dem ARN, den es ohnehin in der Policy liest.

Bucket, Ordner, Absenderadresse und Queue stehen bereits in der Policy, als genau die Angabe, an der AWS den Zugriff später misst. Darf der Zugang seine eigene Policy lesen (iam:ListUserPolicies, iam:GetUserPolicy auf user/${aws:username}), holt s3mail sie sich von dort, statt danach zu fragen: eintragen musst du dann nur noch Access Key und Secret. Gelesen werden nur eingebettete Policies. Die Region nennt S3 selbst im Kopf seiner Antwort.

Optional, nur für die Bequemlichkeit des Assistenten: s3:ListAllMyBuckets (Bucket-Auswahlliste; bewusst nicht in der Policy oben, weil es jeden Bucket des Kontos zeigt), ses:ListIdentities und ses:GetIdentityVerificationAttributes (Absender-Auswahl), s3:GetLifecycleConfiguration und s3:PutLifecycleConfiguration (Papierkorb-Automatik).

Erster Start

./s3mail

 

Beim Start schreibt s3mail eine Adresse ins Terminal, die ein Token enthält: s3mail laeuft auf 127.0.0.1.. Der Browser öffnet sich damit von selbst. Ohne dieses Token antwortet der Server nicht.

Beim ersten Mal öffnet sich der Einrichtungs-Assistent statt des Postfachs, in drei Schritten: AWS-Zugang (Profil wählen oder Access Key ID + Secret eintragen, dazu die Region), Postfach (Bucket, Prefix aus der SES-Regel, Absenderadresse für Antworten, optional Signatur und ein Name für den Umschalter), Prüfen (legt kurz ein Testobjekt an und löscht es wieder; Ergebnis ist eine Checkliste, und was fehlt, steht im Klartext dabei). Danach lässt sich optional eine Lifecycle-Regel setzen, die den Papierkorb nach 7/30/90 Tagen leert.

„Speichern und starten“ schreibt ~/.config/s3mail/config.json (chmod 600) und lädt direkt das Postfach. Ab dann genügt ./s3mail. Über Einstellungen oben rechts kommst du jederzeit zurück in den Assistenten, auch für ein zweites Postfach.

Optionen

OptionBedeutung
--setupAssistent öffnen, auch wenn schon konfiguriert
--bucket, --prefix, --region, --profile, --fromBucket, Wurzel-Prefix, Region, Profil, Absender; bei mehreren Postfächern wirken sie auf das erste
--no-sendSES-Versand deaktivieren (reiner Lesemodus)
--no-deleteEndgültiges Löschen sperren; dann geht nur Papierkorb
--port / --hostStandard 127.0.0.1:8765
--no-browserBrowser nicht automatisch öffnen
--no-cacheNichts auf Platte zwischenspeichern
--cache-plaintextCache unverschlüsselt schreiben, wenn kein Schlüsselbund da ist
--debugAufrufe an S3 und SES protokollieren: Schlüssel, Größen, Dauer, keine Mailinhalte
--refreshSekunden zwischen automatischen Abgleichen, 0 schaltet ab (Standard 60)
--mcp, --mcp-readonlyals MCP-Server über stdin/stdout laufen; readonly ohne Verschieben, Verschlagworten, Entwerfen
--versionVersion ausgeben und beenden

Weiter

Zurück zu s3mail

Die Übersicht: was s3mail ausmacht, Loslegen, alle Kapitel.

s3mail →
Zurück zu s3mail

Funktionen

Ordner als S3-Prefixe, Lesen, Schreiben, Regeln, Suche, mehrere Postfächer.

Lesen →
Funktionen