SMTP server to relay emails via Amazon SES or Amazon Pinpoint using IAM roles.
Contents
Amazon SES and Amazon Pinpoint both provide an API and an SMTP interface to send emails:
The SMTP interface is useful for applications that must use SMTP to send emails, but it requires providing a set of SMTP credentials:
For security reasons, using IAM roles is preferable, but only possible with the Email API and not the SMTP interface.
This is where this project comes into play, as it provides an SMTP interface that relays emails via SES or Pinpoint API using IAM roles.
This repository provides a sample Dockerfile to build and run the project in a container environment.
A prebuilt Docker image is also available on Docker Hub:
docker run blueimp/aws-smtp-relay --helpThe aws-smtp-relay binary can be installed from source via
go get:
go get github.com/blueimp/aws-smtp-relayBy default, aws-smtp-relay listens on port 1025 on all interfaces as open
relay (without authentication) when started without arguments:
aws-smtp-relayAvailable options can be listed the following way:
aws-smtp-relay --helpUsage of aws-smtp-relay:
  -a string
        TCP listen address (default ":1025")
  -c string
        TLS cert file
  -d string
        Denied recipient emails regular expression
  -e string
        Amazon SES Configuration Set Name
  -h string
        Server hostname
  -i string
        Allowed client IPs (comma-separated)
  -k string
        TLS key file
  -l string
        Allowed sender emails regular expression
  -n string
        SMTP service name (default "AWS SMTP Relay")
  -r string
        Relay API to use (ses|pinpoint) (default "ses")
  -s    Require TLS via STARTTLS extension
  -t    Listen for incoming TLS connections only
  -u string
        Authentication username
The supported user-based SMTP authentication mechanisms and their required configuration settings (see also RFC 4954):
| Mechanism | TLS | User | Hash | Pass | 
|---|---|---|---|---|
| LOGIN | Yes | Yes | Yes | No | 
| PLAIN | Yes | Yes | Yes | No | 
| CRAM-MD5 | No | Yes | No | Yes | 
Authentication can be enabled for LOGIN and PLAIN mechanisms by configuring
TLS and a username and providing the
bcrypt encrypted password as
BCRYPT_HASH environment variable:
export BCRYPT_HASH=$(htpasswd -bnBC 10 '' password | tr -d ':\n')
export TLS_KEY_PASS="$PASSPHRASE"
aws-smtp-relay -c tls/default.crt -k tls/default.key -u usernameIf the password is provided as plain text PASSWORD environment variable, it
will also enable the CRAM-MD5 authentication mechanism:
export PASSWORD=password
export TLS_KEY_PASS="$PASSPHRASE"
aws-smtp-relay -c tls/default.crt -k tls/default.key -u usernameWithout TLS configuration, only CRAM-MD5 will be enabled:
export PASSWORD=password
aws-smtp-relay -u usernamePlease note:
It is not recommended to provide the password as plain text environment variable, nor to configure the SMTP server without TLS support.
To limit the allowed IP addresses, supply a comma-separated list via -i ips
option:
aws-smtp-relay -i 127.0.0.1,::1Please note:
To authorize their IP, clients must use a supported SMTP authentication mechanism, e.g.
LOGINorPLAINvia TLS orCRAM-MD5on unencrypted connections.
This is required even if no user authentication is configured on the server, although in this case the credentials can be chosen freely by the client.
Configure TLS with the following steps:
Edit the openssl config file and change localhost to your
server hostname.
Generate a self-signed certificate with a passphrase encrypted key:
openssl req -new -x509 -config tls/openssl.conf -days 24855 \
  -out tls/default.crt \
  -keyout /dev/stdout |
  openssl rsa -aes256 -out tls/default.keyPlease note:
Encrypted key files are only supported if they contain a
DEK-Infoheader, stating the encryption method used.
Theopenssl reqcommand does not create this header if encryption is enabled, which is why we pipe the unencrypted key output to theopenssl rsacommand, which outputs an encrypted key file with the requiredDEK-Infoheader.
Provide the key file passphrase as TLS_KEY_PASS environment variable and the
cert and key file as command-line arguments:
TLS_KEY_PASS="$PASSPHRASE" aws-smtp-relay -c tls/default.crt -k tls/default.keyPlease note:
It is recommended to require TLS via
STARTTLSextension (-soption flag) or to configure the server to listen for incoming TLS connections only (-toption flag).
To limit the allowed sender email addresses, provide an allow list as
regular expression via -l regexp
option:
aws-smtp-relay -l '@example\.org$'By default, all sender email addresses are allowed.
To deny certain recipient email addresses, provide a deny list as
regular expression via -d regexp
option:
aws-smtp-relay -d 'admin@example\.org$'By default, all recipient email addresses are allowed.
The AWS_REGION must be set to configure the AWS SDK, e.g. by executing the
following command before starting aws-smtp-relay:
export AWS_REGION=eu-west-1On EC2 or ECS, security credentials for the IAM role are automatically retrieved:
Requests are logged in JSON format to stdout with the Error property set
to null:
{
  "Time": "2018-04-18T15:08:42.4388893Z",
  "IP": "172.17.0.1",
  "From": "[email protected]",
  "To": ["[email protected]"],
  "Error": null
}Errors are logged in the same format to stderr, with the Error property set
to a string value:
{
  "Time": "2018-04-18T15:08:42.4388893Z",
  "IP": "172.17.0.1",
  "From": "[email protected]",
  "To": ["[email protected]"],
  "Error": "MissingRegion: could not find region configuration"
}First, clone the project and then switch into its source directory:
git clone https://github.com/blueimp/aws-smtp-relay.git
cd aws-smtp-relayPlease note:
This project relies on Go modules for automatic dependency resolution.
To build the project, run
Make in the repository
directory, which creates the aws-smtp-relay binary:
makeTo lint the source code, first install staticcheck:
go install honnef.co/go/tools/cmd/staticcheck@latestThen run the following command:
make lintAll components come with unit tests, which can be executed the following way:
make testSending mails can also be tested with the provided mail shell script:
echo TEXT | ./mail.sh -p 1025 -f [email protected] -t [email protected]Please note:
The provided shell script only supports the
LOGINauthentication mechanism.
See also Testing Amazon SES Email Sending.
The binary can also be built and installed in $GOPATH/bin/ with the following
command:
make installThe uninstall command removes the binary from $GOPATH/bin/:
make uninstallTo remove any build artifacts, run the following:
make cleanReleased under the MIT license.