Skip to content

Instantly share code, notes, and snippets.

@gabriel-curtino
Last active November 4, 2024 14:10
Show Gist options
  • Save gabriel-curtino/034aa4c9174ec21e37eb462f087c087c to your computer and use it in GitHub Desktop.
Save gabriel-curtino/034aa4c9174ec21e37eb462f087c087c to your computer and use it in GitHub Desktop.
Exim4 relay for Action Mailbox

1. Relay script

This bash script replaces the Rails task action_mailbox:ingress:exim then your rails app doesn't need to be running in the same location than the email server.

$ nano /usr/local/bin/action_mailbox_relay.sh

URL and INGRESS_PASSWORD are hardcoded as defaults but these can be removed if prefer work with ENV vars.

#!/bin/bash

# Check for required environment variables
URL="${URL:-https://<your-app-domain>/rails/action_mailbox/relay/inbound_emails}"
INGRESS_PASSWORD="${INGRESS_PASSWORD:-<your-ingress-password>}"

if [[ -z "$URL" || -z "$INGRESS_PASSWORD" ]]; then
  echo "URL and INGRESS_PASSWORD are required"
  exit 64 # EX_USAGE
fi

# Read email from stdin and write to a temporary file
EMAIL_FILE=$(mktemp)
cat > "$EMAIL_FILE"

# Base64 encode username and password for Basic Auth
USERNAME="actionmailbox"
AUTH_HEADER="Authorization: Basic $(echo -n "$USERNAME:$INGRESS_PASSWORD" | base64)"

# Send POST request to the Action Mailbox ingress
RESPONSE=$(curl -s -w "%{http_code}" -o /dev/null \
  -X POST "$URL" \
  -H "Content-Type: message/rfc822" \
  -H "User-Agent: Action Mailbox Bash Relayer v1.0" \
  -H "$AUTH_HEADER" \
  --data-binary @"$EMAIL_FILE")

# Handle response codes
case "$RESPONSE" in
  2*)
    echo "Successfully relayed message to ingress"
    exit 0
    ;;
  4*)
    if [[ "$RESPONSE" == "401" ]]; then
      echo "Invalid credentials for ingress"
      exit 75 # EX_TEMPFAIL
    else
      echo "HTTP $RESPONSE"
      exit 69 # EX_UNAVAILABLE
    fi
    ;;
  *)
    echo "Error relaying to ingress: HTTP $RESPONSE"
    exit 69 # EX_UNAVAILABLE
    ;;    
esac

# Clean up temporary file
rm "$EMAIL_FILE"
$ chown root:Debian-exim /usr/local/bin/action_mailbox_relay.sh
$ chmod 750 /usr/local/bin/action_mailbox_relay.sh

2. Configure exim

This setup works for exim with split config scheme in Ubuntu.

$ nano /etc/exim4/conf.d/transport/30_exim4-config_action_mailbox

action_mailbox_transport:
  driver = pipe
  command = /usr/local/bin/action_mailbox_relay.sh
  user = Debian-exim 
  group = Debian-exim
  delivery_date_add = true
  message_size_limit = 0
  temp_errors = 64 : 75 : 69  
  
$ nano /etc/exim4/conf.d/router/300_exim4-config_action_mailbox

action_mailbox_router:
  driver = manualroute
  route_list = +local_domains
  transport = action_mailbox_transport

$ update-exim4.conf && systemctl restart exim4

3. Troubleshooting

Test Action Mailbox

$ AUTH=$(echo -n "actionmailbox:<your-ingress-password>" | base64)

$ curl -s -w '%{http_code}' -o /dev/null -X POST "https://<your-domain>/rails/action_mailbox/relay/inbound_emails" \
-H "Content-Type: message/rfc822" \
-H "User-Agent: Action Mailbox Bash Relayer v1.0" \
-H "Authorization: Basic $AUTH" \
--data-binary $'From: [email protected]\nTo: [email protected]\nSubject: Test Email\nDate: Mon, 28 Oct 2024 12:34:56 +0000\nMIME-Version: 1.0\nContent-Type: multipart/alternative; boundary="boundary123"\nX-Forwarded-For: [email protected]\n\n--boundary123\nContent-Type: text/plain; charset=utf-8\nContent-Transfer-Encoding: base64\n\nSGVsbG8sIFRoaXMgaXMgdGVzdCBjb250ZW50IGZvc3RlciB0ZXN0aW5nIGVtYWlsLg==\n\n--boundary123\nContent-Type: text/html; charset=utf-8\nContent-Transfer-Encoding: base64\n\nPGRpdiBzdHlsZT0iZm9udC1mYW1pbHk6IEFyaWFsLCBzYW5zLXNlcmlmOyBmb250LXNpemU6IDE0cHg7Ij48c3Bhbj5IZWxsbyBXb3JsZDwvc3Bhbj48L2Rpdj4K\n\n--boundary123--'

Test the script

$ echo -e "From: [email protected]\nTo: [email protected]\nSubject: Test Email\nDate: Mon, 28 Oct 2024 12:34:56 +0000\nMIME-Version: 1.0\nContent-Type: multipart/alternative; boundary="boundary123"\nX-Forwarded-For: [email protected]\n\n--boundary123\nContent-Type: text/plain; charset=utf-8\nContent-Transfer-Encoding: base64\n\nSGVsbG8sIFRoaXMgaXMgdGVzdCBjb250ZW50IGZvc3RlciB0ZXN0aW5nIGVtYWlsLg==\n\n--boundary123\nContent-Type: text/html; charset=utf-8\nContent-Transfer-Encoding: base64\n\nPGRpdiBzdHlsZT0iZm9udC1mYW1pbHk6IEFyaWFsLCBzYW5zLXNlcmlmOyBmb250LXNpemU6IDE0cHg7Ij48c3Bhbj5IZWxsbyBXb3JsZDwvc3Bhbj48L2Rpdj4K\n\n--boundary123--" > test_email.txt
$ URL=https://<your-domain>/rails/action_mailbox/relay/inbound_emails INGRESS_PASSWORD=<your-ingress-password> /usr/local/bin/action_mailbox_relay.sh < test_email.txt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment