Project

General

Profile

Actions

Milestone #78

open

install mailserver

Milestone #78: install mailserver

Added by Daniele Cruciani about 1 month ago. Updated about 1 month ago.

Status:
new
Priority:
wishlist
Assignee:
-
Start date:
Due date:
% Done:

0%

Estimated time:
Sprint:

Description

Setting up a mail server on Kubernetes that uses Gmail as a relay while maintaining good deliverability requires careful configuration. Here's a step-by-step guide:

1. Prerequisites

First, enable "Less Secure Apps" or better, create an App Password:

  1. Enable 2FA on your Google account
  2. Generate an App Password: Security > App passwords > Generate
  3. Note down the generated 16-character password

2. Kubernetes Deployment

Mail Server Configuration (Postfix)

# postfix-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postfix
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postfix
  template:
    metadata:
      labels:
        app: postfix
    spec:
      containers:
      - name: postfix
        image: catatnight/postfix:latest
        env:
        - name: maildomain
          value: "yourdomain.com"  # Your domain
        - name: smtp_user
          value: "your-email@gmail.com:your-app-password"
        - name: relayhost
          value: "[smtp.gmail.com]:587"
        ports:
        - containerPort: 25
        - containerPort: 587
        - containerPort: 465
        resources:
          limits:
            memory: "256Mi"
            cpu: "250m"
---
apiVersion: v1
kind: Service
metadata:
  name: postfix
spec:
  selector:
    app: postfix
  ports:
  - name: smtp
    port: 25
    targetPort: 25
  - name: submission
    port: 587
    targetPort: 587
  - name: smtps
    port: 465
    targetPort: 465

3. Postfix Configuration for Gmail Relay

Create a ConfigMap for additional Postfix settings:

# postfix-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: postfix-main-cf
data:
  main.cf: |
    # Basic configuration
    myhostname = mail.yourdomain.com
    myorigin = /etc/mailname
    mydestination = localhost
    
    # Gmail relay configuration
    relayhost = [smtp.gmail.com]:587
    smtp_use_tls = yes
    smtp_sasl_auth_enable = yes
    smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
    smtp_sasl_security_options = noanonymous
    smtp_sasl_tls_security_options = noanonymous
    smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
    
    # Important for sender rewriting
    sender_canonical_classes = envelope_sender, header_sender
    sender_canonical_maps = regexp:/etc/postfix/sender_canonical_maps
    smtp_header_checks = regexp:/etc/postfix/header_checks
    
    # Rate limiting to avoid Gmail limits
    smtp_destination_concurrency_limit = 2
    smtp_destination_rate_delay = 1s
    
    # Prevent being marked as open relay
    smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination

4. Authentication and Header Rewriting

SASL Password Secret:

kubectl create secret generic postfix-sasl \
  --from-literal=sasl_passwd="[smtp.gmail.com]:587 your-email@gmail.com:your-app-password"

Header Rewriting ConfigMap:

# header-rewrite.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: postfix-header-rewrite
data:
  header_checks: |
    /^From:.*@.*/ REPLACE From: "Your Name" <your-email@gmail.com>
    /^Reply-To:.*/ REPLACE Reply-To: "Your Name" <your-email@gmail.com>
    /^Sender:.*/ REPLACE Sender: "Your Name" <your-email@gmail.com>
  
  sender_canonical_maps: |
    /.*/ your-email@gmail.com

5. Updated Deployment with ConfigMaps

# updated-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postfix
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postfix
  template:
    metadata:
      labels:
        app: postfix
    spec:
      containers:
      - name: postfix
        image: catatnight/postfix:latest
        env:
        - name: maildomain
          value: "yourdomain.com"
        volumeMounts:
        - name: postfix-config
          mountPath: /etc/postfix/main.cf
          subPath: main.cf
        - name: header-rewrite
          mountPath: /etc/postfix/header_checks
          subPath: header_checks
        - name: sender-canonical
          mountPath: /etc/postfix/sender_canonical_maps
          subPath: sender_canonical_maps
        - name: sasl-secret
          mountPath: /etc/postfix/sasl_passwd
          subPath: sasl_passwd
        lifecycle:
          postStart:
            exec:
              command:
              - /bin/sh
              - -c
              - |
                postmap /etc/postfix/sasl_passwd
                postmap /etc/postfix/sender_canonical_maps
                postfix reload
      volumes:
      - name: postfix-config
        configMap:
          name: postfix-main-cf
      - name: header-rewrite
        configMap:
          name: postfix-header-rewrite
      - name: sender-canonical
        configMap:
          name: postfix-header-rewrite
      - name: sasl-secret
        secret:
          secretName: postfix-sasl

6. DNS Configuration for Better Deliverability

Add these DNS records for your domain:

TXT @ "v=spf1 include:_spf.google.com ~all"
TXT _dmarc "v=DMARC1; p=none; rua=mailto:dmarc-reports@yourdomain.com"
TXT google._domainkey "google-site-verification=..."

7. Test the Setup

# Test from inside the cluster
kubectl exec -it <postfix-pod> -- /bin/bash

# Send test email
echo "Test email" | mail -s "Test Subject" recipient@example.com \
  -a "From: Your Name <your-email@gmail.com>"

8. Additional Deliverability Tips

  1. Warm up the IP: Gradually increase email volume
  2. DKIM Signing: Consider using a DKIM signing service
  3. Consistent Headers: Ensure From, Reply-To, and Sender headers match
  4. Email Content: Avoid spam trigger words, use proper HTML/text alternatives
  5. Monitoring: Check Gmail's sending limits (500 recipients/day for free accounts)
  6. Bounce Handling: Implement proper bounce handling in your application

9. Alternative: Use Mailgun or SendGrid

For production, consider using a dedicated email service:

# Using Mailgun as example
relayhost = [smtp.mailgun.org]:587
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
# sasl_passwd contains: [smtp.mailgun.org]:587 postmaster@yourdomain.com:api-key

Important Notes:

  • Gmail Limits: Free accounts have daily sending limits
  • App Passwords: Required if 2FA is enabled
  • SPF/DKIM/DMARC: Configure these properly even when using Gmail as relay
  • Rate Limiting: Respect Gmail's rate limits (100 emails/hour)

This setup ensures your emails appear to come from your Gmail address properly authenticated, reducing spam filter issues.

Actions

Also available in: PDF Atom