Simplest and Smallest Email Forward Service for Docker.
View on GitHub | View on Docker
@Brian Christner : After testing a ton of different mail projects I finally discovered Simple Mail Forwarder (SMF) by Huan. This image is based on Alpine which is already a positive. It is super tiny and as the name suggests, easy to use. link
@kachkaev : really happy to discover it! link
@kiani: have a working mail server, seriously, it was that easy. link
@counterbeing: great image. Wonderfully easy interface, with all that i need. :+1: link
@nelfer: Guess what? Your image already supports this! link
@Czocher: It's at least a timesaver if not a lifesaver. link
@StrangePeanut: I am so glad to have found SMF. Many thanks for this brilliant solution to email forwarding. link
If you have a domain name, only want to have one (or a few) email address(es) on this domain, and you want to forward all the emails to another email account - Simple Mail Forwarder (SMF) is exactly what you need. (with Docker)
Because of the above, this docker image was built for ultimate simplicity. I've owned many domains and needed email addresses for them (for fun and/or work). I hated configuring email servers. Some DNS providers provide free email forwarding services for their own domains, some do not. And almost all email forwarding services are NOT free. So I decided to make one myself (thanks docker).
I was willing to pay $10/year, but the cheapest plan I could find was $9 per month. Having a $10 USD machine with unlimited e-mail & domains per month is an amazing idea! And of course you could also put other dockers on this machine. :-D
Just set SMF_CONFIG
and run:
export SMF_CONFIG='testi@testo.com:test@test.com:test'
docker run -e SMF_CONFIG -p 25:25 zixia/simple-mail-forwarder
Don't forget to modify the DNS MX record of your domain. (in this example, it's testo.com)
This will forward all emails received by testi@testo.com to test@test.com.
If you want to forward all emails sent to domain testo.com to all@test.com, set it like so:
export SMF_CONFIG='@testo.com:all@test.com'
See? There is nothing easier.
If you want to run it constanly in the background add
-t -d --restart=always
afterrun
:
docker run -t -d --restart=always -e SMF_CONFIG -p 25:25 zixia/simple-mail-forwarder
-t
: Allocate a pseudo-tty-d
: Detached Mode--restart=always
: Restart this container automaticallyOtherwise, docker thinks that your applications stops and shutdown the container.
Tested by BATS(Bash Automated Testing System), a bash implementation of TAP(Test Anything Protol).
How to run:
$ docker run zixia/simple-mail-forwarder test
>> exec bats test
1..20
ok 1 confirm hostname pretend to work.
ok 2 confirm hwclock pretend to work.
ok 3 service postfix could start/stop right.
ok 4 SMF_CONFIG exist
ok 5 SMF_DOMAIN exist
ok 6 virtual maping source is set
ok 7 virtual maping data is set
ok 8 virtual maping db is set
ok 9 system hostname FQDN resolvable
ok 10 postfix myhostname FQDN & resolvable
ok 11 check other hostname setting
ok 12 confirm postfix is running
ok 13 confirm port 25 is open
ok 14 crond is running
ok 15 ESMTP STATTLS supported
ok 16 ESMTP AUTH supported
ok 17 ESMTP STARTTLS supported
ok 18 create user testi@testo.com by password test
ok 19 ESMTP AUTH by testi@testo.com/test
ok 20 ESMTP TLS AUTH by testi@testo.com/test
You are all set! :-]
SMF_CONFIG
: MUST be defined. there's no default setting. (set me! I'm the only parameter you need to set~)
TZ
: (Optional) set the timezone , IE EST5EDT
or Europe/Rome
SMF_CONFIG
ExamplesHere's how to config the only required SMF_CONFIG
environment parameter of SMF Docker:
Forward all emails received by testi@testo.com to test@test.com:
export SMF_CONFIG='testi@testo.com:test@test.com'
Forward all emails received by any email address in domain testo.com to all@test.com:
export SMF_CONFIG='@testo.com:all@test.com'
You could get the ESMTP AUTH password for you on your docker log. It's randomly generated if you do not provide one.
Add ESMTP AUTH password:
export SMF_CONFIG='from@testi.com:to@testo.com:ThisIsPassword'
Password will be printed on the docker log.
Add as many email accounts as you want, with or without password. Seperated by semicolon or a new line:
export SMF_CONFIG='testi@testo.com:test@test.com:ThisIsPassword;testo@testi.com:test@test.com:AnotherPassword'
Tips: if you only provide the first password and leave the rest blank, then the passwords for all the rest accounts will be the same as the last password value you set. This is by design.
You can also forward all emails received by testi@testo.com to multiple destination addresses:
export SMF_CONFIG='testi@testo.com:test1@test.com|test2@test.com|test3@test.com'
SMF_RELAYHOST
ExamplesHere's how to configure a relayhost/smarthost to use for forwarding mail.
Send all outgoing mail trough a smarthost on 192.168.1.2
export SMF_RELAYHOST='192.168.1.2'
SMF_RELAYAUTH
ExamplesIf the SMF_RELAYHOST
require authentication,
export SMF_RELAYAUTH='username@relayhost.com:RelayHostPassword'
SMF creates its own certificate and private key when it starts. This certificate is self signed, so some systems might give you a warning about the server not being trusted. If you have valid certificates for the domain name of the host, then you can use them and avoid the warning about not being trusted.
First you need to prepare the certificate files. Copy your full chain certificate to a file named smtp.cert
(or smtp.ec.cert
if it contains a EC certificate). Then copy the private key to a file named smtp.key
(or smtp.ec.key
if it contains a EC key)
Copy these files to a folder. For example: /data/certs/
. This folder will be mounted as a volume in SMF
When creating the container, add the -v
(volume) parameter to mount it to the folder /etc/postfix/cert/
like so:
docker run -e SMF_CONFIG -p 25:25 -v /data/certs/:/etc/postfix/cert/ zixia/simple-mail-forwarder
Your emails should now be forwarded with trusted encryption. You can use this tool to test it: http://checktls.com/
If you do not have a certificate and don't have the budget to afford one, you can use https://letsencrypt.org if you have shell access to the server (Note, SMF does not provide this service, yet). Letsencrypt allows you to create valid trusted certificates for a server, if the server responds to the domain you specify. In order to do this, you need to run the program from within the server and have administrator rights.
First install letsencrypt. This might vary by distribution, but in Ubuntu it is like this:
sudo apt-get install letsencrypt
Stop any web server that might be using port 80 (Apache, nginx, etc)
Determine all of the domains and subdomains that you want the certificate to cover, for example mydomain.com
, www.mydomain.com
, smtp.mydomain.com
, etc. Remember to include the domain that SMF will respond to (as per MX record in DNS configuration of the domain)
Execute the following command (you can add as many domains as you wish with the -d
option. But remember, their DNS resolution must resolve to the server where letsencrypt
is being executed)
letsencrypt certonly --standalone -d yourdomain.com -d www.yourdomain.com -d mail.yourdomain.com
Follow the prompts and if everything is successful you will get your certificates in a folder like /etc/letsencrypt/live/mydomain.com
You can now use those certificates to make SMF TLS trusted.
This was a quick way of how to use letsencrypt. For a full tutorial based on your OS see: https://certbot.eff.org/
SMF will generate private/public keypairs for $SMF_DOMAIN
and for all source domains contained in SMF_CONFIG
. All keys will be stored in /var/db/dkim/<domain.tld>/
.
This will enable DKIM for multiple domains and test for their validity on SMF startup.
Public key must be set as TXT record in DNS under default._domainkey
name. default._domainkey
can be found in /var/db/dkim/<domain.tld>/default.txt
.
It is highly advised to mount /var/db/dkim/
folder to host, so generated keypair would not get lost/regenerated:
docker run -e SMF_CONFIG -p 25:25 -v $(pwd)/dkim:/var/db/dkim/ zixia/simple-mail-forwarder
SMF allows using environment variables to change the size of the DKIM key:
SMF_DKIM_KEYSIZE
will set the keysize of the generated DKIM key (setting opendkim-genkey -b $SMF_DKIM_KEYSIZE
). Defaults to 2048
.SMF will strip the sender's IP, client, and user agent headers when the SMF_SENDERPRIVACY
environment variable is defined.
SMF allows using environment variables to add or change lines to postfix main.cf
and master.cf
configuration files.
SMF_POSTFIXMAIN_*
variables will edit postfix main.cf
entries.
SMF_POSTFIXMAIN_option_name=value
SMF_POSTFIXMAIN_soft_bounce=yes
will call postconf -e soft_bounce=yes
and add the option.SMF_POSTFIXMASTER_*
variables will edit postfix master.cf
.
SMF_POSTFIXMASTER_service__name__type__parameter_name=value
Please note the double underscore __
to differentiate service and type (which require a /
as separation symbol) and the single underscore _
used only by parameter names.SMF_POSTFIXMASTER_submission__inet__smtpd__recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
will call postconf -P submission/inet/smtpd/recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
and add the option.The default log configuration of postfix is sending all log entries to /dev/stdout
. Because file logs are important in some cases, SMF allows overriding the default log configuration of postfix.
SMF_POSTFIXLOG
will edit postfix logging configuration
SMF_POSTFIXLOG=value
SMF_POSTFIXLOG=/var/log/postfix.log
will call postconf maillog_file="/var/log/postfix.log"
Attention: The logfile path must start with "/var".
When you wish to rotate logs, look at the postfix logrotate
command in the official documentation.
SRS is required if the sender uses SPF for verification. If SRS is not enabled, SPF verification will fail. (Additional Informations to SRS)
You can enable SRS by setting the environment variable SMF_SRS=true
. This will start PostSRSd inside the container. The secret is automatically created and the domain is set to SMF_DOMAIN
. Now you just need to set the following environment variables for Postfix:
SMF_POSTFIXMAIN_sender_canonical_maps=tcp:localhost:10001
SMF_POSTFIXMAIN_sender_canonical_classes=envelope_sender
SMF_POSTFIXMAIN_recipient_canonical_maps=tcp:localhost:10002
SMF_POSTFIXMAIN_recipient_canonical_classes=envelope_recipient,header_recipient
Build from source.
./script/build.sh latest
Run a self-test for SMF docker.
./script/run.sh latest test
Get a shell inside SMF docker.
./script/devshell.sh latest
$ telnet 127.0.0.1 25
> 220 testo.com ESMTP
ehlo test.com
> 250-testo.com
> 250-STARTTLS
> 250-AUTH PLAIN LOGIN
auth plain
> 334
dGVzdGlAdGVzdG8uY29tAHRlc3RpQHRlc3RvLmNvbQB0ZXN0
> 235 2.7.0 Authentication successful
quit
> 221 2.0.0 Bye
> Connection closed by foreign host
P.S. The magic string dGVzdGlAdGVzdG8uY29tAHRlc3RpQHRlc3RvLmNvbQB0ZXN0
stands for testi@testo.com\0test@testo.com\0test
in base64 encoding, required by AUTH PLAIN.
Useful article about SMTP Authentication: http://www.fehcom.de/qmail/smtpauth.html
Github Issue - https://github.com/huan/docker-simple-mail-forwarder/issues
timeout
args breaking changesetc
and libexec
path change for postfixA Cloud Service that could host docker is required.
A Docker management platform is recommanded.
Docker is required.