diff --git a/examples/docker/mail-station/docker-compose.yml b/examples/docker/mail-station/docker-compose.yml new file mode 100644 index 0000000..448828c --- /dev/null +++ b/examples/docker/mail-station/docker-compose.yml @@ -0,0 +1,181 @@ + +# vim: noai:ts=2:sw=2:expandtab +# +# This example shows how this image can be used as a MTA in combination with Dovecot. Dovecot +# is used for authentication here. The example is not complete, but should give you a general +# overview of how flexible the image is. +# +version: "3.8" +services: + solr: # solr is used by Dovecot for full-text search and indexing + image: solr:7.7 + container_name: solr + deploy: + resources: + limits: + cpus: '0.5' + memory: '512M' + reservations: + cpus: '0.02' + memory: '32M' + ports: + - 8983:8983 + restart: unless-stopped + volumes: + - ./solr/data:/opt/solr/server/solr + - ./solr/logs:/opt/solr/server/logs + + tika: # Tika is used by Dovecot for extracing text from DOC, DOCX, PDF and other files + image: apache/tika + container_name: tika + build: + context: ./tika/docker + deploy: + resources: + limits: + cpus: '0.2' + memory: '512M' + reservations: + cpus: '0.02' + memory: '64M' + restart: unless-stopped + ports: + - 9998:9998 + + dovecot: # Main Dovecot container + image: dovecot/dovecot + container_name: dovecot + build: + context: ./dovecot/docker + deploy: + resources: + limits: + cpus: '0.5' + memory: '128M' + reservations: + cpus: '0.02' + memory: '32M' + restart: unless-stopped + network_mode: host + entrypoint: /usr/sbin/dovecot + command: + - -F + - -c + - /etc/dovecot/dovecot.conf + volumes: + - ./mail:/store/mail # All mail will be stored here + - ./dovecot/run:/var/run/dovecot + - ./dovecot/conf:/etc/dovecot # Dovecot configuration files + - ./dovecot/auth:/var/spool/postfix/private/dovecot # Dovecot authentication socket + - ./certs:/etc/letsencrypt # Certificates used by dovecot + + postfix: # The MTA + image: boky/postfix + container_name: postfix + deploy: + resources: + limits: + cpus: '0.2' + memory: '128M' + reservations: + cpus: '0.02' + memory: '32M' + restart: unless-stopped + network_mode: host + environment: + ALLOW_EMPTY_SENDER_DOMAINS: "1" # Allow any recipient + FORCE_COLOR: "1" # Force color + POSTFIX_smtp_sender_dependent_authentication: "yes" # Clients should authenticate + POSTFIX_sender_dependent_relayhost_maps: "lmdb:/etc/postfix/sender_dependent_relayhost" # Different relay MTAs for different domains + POSTFIX_smtp_sasl_auth_enable: "yes" # Enable SASL + POSTFIX_smtp_sasl_password_maps: "lmdb:/etc/postfix/sasl_password" # List of passwords (for outgoing MTAs) + POSTFIX_smtp_sasl_security_options: "noanonymous" # Always authenticate towards relay hosts + POSTFIX_smtp_sasl_mechanism_filter: "login, plain, digest-md5" # Login with these credentials + POSTFIX_smtpd_tls_cert_file: "/etc/letsencrypt/live/mail.example.com/fullchain.pem" # Public part of key, updated by Letsencrypt + POSTFIX_smtpd_tls_key_file: "/etc/letsencrypt/live/mail.example.com/privkey.pem" # Private part of key, updated by Letsencrypt + POSTFIX_smtpd_use_tls: "yes" # Enable TLS + POSTFIX_smtpd_tls_session_cache_database: "lmdb:${data_directory}/smtpd_scache" + POSTFIX_smtp_tls_session_cache_database: "lmdb:${data_directory}/smtp_scache" + POSTFIX_smtp_tls_loglevel: "1" + POSTFIX_smtpd_tls_security_level: "may" + POSTFIX_smtpd_tls_protocols: "TLSv1.2, TLSv1.1, TLSv1, !SSLv2" + POSTFIX_smtpd_relay_restrictions: "permit_sasl_authenticated, reject_unauth_destination" + POSTFIX_smtpd_sasl_auth_enable: "yes" + POSTFIX_smtpd_sasl_type: "dovecot" # Authenticate using Dovecot + POSTFIX_smtpd_sasl_path: "private/dovecot/auth" # Path to Dovecot socket + POSTFIX_smtpd_sasl_authenticated_header: "yes" + POSTFIX_smtpd_sasl_security_options: "noanonymous" # Don't allow non-authenticated connections + POSTFIX_smtpd_sasl_local_domain: "$myhostname" + POSTFIX_broken_sasl_auth_clients: "yes" + POSTFIX_smtpd_recipient_restrictions: "reject_non_fqdn_recipient, reject_non_fqdn_sender, reject_unlisted_recipient, reject_unknown_sender_domain, reject_unknown_recipient_domain, reject_unauth_pipelining, permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination" + POSTFIX_smtpd_sender_restrictions: "reject_unknown_sender_domain" + POSTFIX_smtpd_client_restrictions: "" + POSTFIX_virtual_transport: "lmtp:unix:/var/run/dovecot/lmtp" # Deliver (send) mail to Dovecot + POSTFIX_smtp_use_tls: "yes" + POSTFIX_smtpd_tls_received_header: "yes" + POSTFIX_smtpd_tls_mandatory_protocols: "!SSLv2, !SSLv3, !TLSv1.0, !TLSv1.1" + POSTFIX_smtpd_tls_mandatory_ciphers: "high" + POSTFIX_smtpd_tls_mandatory_exclude_ciphers: "aNULL, MD5, DSS, SSLv2 EXPORT LOW 3DES" + POSTFIX_smtpd_tls_exclude_ciphers: "aNULL, MD5, DSS, SSLv2 EXPORT LOW 3DES" + POSTFIX_smtpd_tls_auth_only: "yes" + POSTFIX_tls_random_source: "dev:/dev/urandom" + POSTFIX_message_size_limit: "40960000" + volumes: + - /dev/urandom:/dev/urandom + - ./postfix/sasl_password:/etc/postfix/sasl_password # List of passwords for upstream MTAs + - ./postfix/sender_dependent_relayhost:/etc/postfix/sender_dependent_relayhost # List of domains for upstream MTAs + - ./postfix/smtp_tls_policy:/etc/postfix/smtp_tls_policy # Different upstreams MTAs have different encryption connection policy + - ./postfix/init:/docker-init.db # Run 3rd-party init scripts at startup + - ./dovecot/run:/var/run/dovecot # Map Dovecot run directory + - ./dovecot/auth:/var/spool/postfix/private/dovecot # Map Dovecot auth socket + - ./certs:/etc/letsencrypt # Inject certificates + + rainloop: # Build webmail client + image: bokysan/rainloop + container_name: rainloop + build: + context: ./rainloop/rainloop + deploy: + resources: + limits: + cpus: '0.2' + memory: '512M' + reservations: + cpus: '0.02' + memory: '32M' + restart: unless-stopped + environment: + - UPLOAD_MAX_SIZE=200M + volumes: + - ./rainloop/data:/rainloop/data + - ./certs:/etc/letsencrypt + labels: + - "traefik.enable=true" + - "traefik.http.services.rainloop.loadbalancer.server.port=8888" + - "traefik.http.routers.rainloop.rule=Host(`mail.example.com`) && PathPrefix(`/`)" + - "traefik.http.routers.rainloop.entrypoints=websecure" + - "traefik.http.routers.rainloop.tls.certresolver=le" + + zpush: # Build activesync client, to pass through those pesky firewalls + image: bokysan/activesync + container_name: activesync + build: + context: ./zpush/docker + deploy: + resources: + limits: + cpus: '0.2' + memory: '512M' + reservations: + cpus: '0.02' + memory: '32M' + restart: unless-stopped + volumes: + - ./zpush/log:/var/log/z-push + - ./zpush/data:/var/lib/z-push + labels: + - "traefik.enable=true" + - "traefik.http.services.activesync.loadbalancer.server.port=80" + - "traefik.http.routers.activesync.rule=Host(`mail.example.com`) && PathPrefix(`/Microsoft-Server-ActiveSync`)" + - "traefik.http.routers.activesync.entrypoints=websecure" + - "traefik.http.routers.activesync.tls.certresolver=le" diff --git a/examples/docker/mail-station/postfix/init/postmap.sh b/examples/docker/mail-station/postfix/init/postmap.sh new file mode 100755 index 0000000..51dc3c8 --- /dev/null +++ b/examples/docker/mail-station/postfix/init/postmap.sh @@ -0,0 +1,9 @@ +#!/bin/sh +chown root:root /etc/postfix/sender_dependent_relayhost +postmap /etc/postfix/sender_dependent_relayhost + +chown root:root /etc/postfix/sasl_password +postmap /etc/postfix/sasl_password + +chown root:root /etc/postfix/smtp_tls_policy +postmap /etc/postfix/smtp_tls_policy diff --git a/examples/docker/mail-station/postfix/sasl_password b/examples/docker/mail-station/postfix/sasl_password new file mode 100644 index 0000000..08dfbcc --- /dev/null +++ b/examples/docker/mail-station/postfix/sasl_password @@ -0,0 +1,2 @@ +demo@example.org demo:aabbccddeeff +demo@example.net demo:ffeeddccbbaa diff --git a/examples/docker/mail-station/postfix/sender_dependent_relayhost b/examples/docker/mail-station/postfix/sender_dependent_relayhost new file mode 100644 index 0000000..87d3fb7 --- /dev/null +++ b/examples/docker/mail-station/postfix/sender_dependent_relayhost @@ -0,0 +1 @@ +demo@example.org [mail.example.org]:10025 diff --git a/examples/docker/mail-station/postfix/smtp_tls_policy b/examples/docker/mail-station/postfix/smtp_tls_policy new file mode 100644 index 0000000..83a2889 --- /dev/null +++ b/examples/docker/mail-station/postfix/smtp_tls_policy @@ -0,0 +1,3 @@ +[mail.example.org]:10025 encrypt +[smtp.gmail.com]:587 secure +[127.0.0.1]:20025 none diff --git a/examples/kubernetes/aws-ses-with-google-values.yml b/examples/kubernetes/aws-ses-with-google-values.yml new file mode 100644 index 0000000..74945f6 --- /dev/null +++ b/examples/kubernetes/aws-ses-with-google-values.yml @@ -0,0 +1,70 @@ +replicaCount: 1 +resources: + limits: + cpu: 200m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + +# priorityClassName: mail +extraVolumes: + - name: config + configMap: + name: postfix-mail +extraVolumeMounts: + - mountPath: /docker-init.db/startup.sh + subPath: startup.sh + name: config + +persistence: + enabled: true + storageClass: "gp3" + +secret: + AWS_SMTP_SERVER: email-smtp.eu-central-1.amazonaws.com + AWS_IAM_USER: smtp-user + AWS_ACCESS_KEY: XXXXXXXXXXXXXXXXXXXX + AWS_SECRET_KEY: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY + AWS_SMTP_PASSWORD: ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ + +config: + general: + TZ: "Europe/London" + + # Default relay with go to Google, but for example.com and example.org it will go to AWS + # No password provided for Google as it will be authenticated via IP + RELAYHOST: "smtp-relay.gmail.com:587" + ALLOWED_SENDER_DOMAINS: "example.com example.org example.net" + LOG_FORMAT: "json" + + startup.sh: | + #!/bin/sh + set -e + + RELAY_MAPS=/etc/postfix/relay_maps + SASL_PASSWD=/etc/postfix/sasl_passwd + + : > $RELAY_MAPS + cat > $RELAY_MAPS < $SASL_PASSWD + cat > $SASL_PASSWD < $SASL_PASSWD + cat > $SASL_PASSWD <