Skip to content

Commit

Permalink
Deprecate some common properties and add auto-generation of DKIM keys
Browse files Browse the repository at this point in the history
  • Loading branch information
bokysan committed Jul 3, 2020
1 parent c460941 commit cfd1a13
Show file tree
Hide file tree
Showing 12 changed files with 352 additions and 162 deletions.
32 changes: 1 addition & 31 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,14 @@ ARG ALPINE_VERSION=latest
FROM alpine:${ALPINE_VERSION}
LABEL maintaner="Bojan Cekrlic - https://github.com/bokysan/docker-postfix/"

# See README.md for details

# Set the timezone for the container, if needed.
ENV TZ=
# Postfix myhostname
ENV HOSTNAME=
# Host that relays your msgs
ENV RELAYHOST=
# An (optional) username for the relay server
ENV RELAYHOST_USERNAME=
# An (optional) login password for the relay server
ENV RELAYHOST_PASSWORD=
# Define relay host TLS connection level. See http://www.postfix.org/postconf.5.html#smtp_tls_security_level for details.
# By default, the permissive level ("may") is used, if not defined.
ENV RELAYHOST_TLS_LEVEL=
# Allow domains from per Network ( default 127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 )
ENV MYNETWORKS=127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
# Allow any sender domains
ENV ALLOWED_SENDER_DOMAINS=
# Don't allow blank value for ALLOWED_SENDER_DOMAINS
ENV ALLOW_EMPTY_SENDER_DOMAINS=
# Attachments size. 0 means unlimited. Usually needs to be set if your relay host has an attachment size limit
ENV MESSAGE_SIZE_LIMIT=
# Enable additional debugging for connections to postfix
ENV INBOUND_DEBUGGING=
# DKIM domain selector. If not set, the default (mail) will be used
ENV DKIM_SELECTOR=
# Logformat. Defaults to "plain". Can be either "plain" or "json".
ENV LOG_FORMAT=

# Install supervisor, postfix
# Install postfix first to get the first account (101)
# Install opendkim second to get the second account (102)
RUN true && \
apk add --no-cache --upgrade cyrus-sasl cyrus-sasl-plain cyrus-sasl-login && \
apk add --no-cache postfix && \
apk add --no-cache opendkim && \
apk add --no-cache --upgrade ca-certificates tzdata supervisor rsyslog musl musl-utils bash && \
apk add --no-cache --upgrade ca-certificates tzdata supervisor rsyslog musl musl-utils bash opendkim-utils && \
(rm "/tmp/"* 2>/dev/null || true) && (rm -rf /var/cache/apk/* 2>/dev/null || true)

# Set up configuration
Expand Down
84 changes: 59 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ All standard caveats of configuring the SMTP server apply:
- Hosting centers also tend to block port 25, which can be unblocked per requirst (e.g. for AWS either [fill out a form](https://aws.amazon.com/premiumsupport/knowledge-center/ec2-port-25-throttle/) or forward mail to their [SES](https://aws.amazon.com/ses/) service, which is free for low volumes)
- You'll most likely need to at least [set up SPF records](https://en.wikipedia.org/wiki/Sender_Policy_Framework) or [DKIM](https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail)
- If using DKIM (below), make sure to add DKIM keys to your domain's DNS entries
- You'll most likely need to set up (PTR)[https://en.wikipedia.org/wiki/Reverse_DNS_lookup] records to prevent your mails going to spam
- You'll most likely need to set up [PTR](https://en.wikipedia.org/wiki/Reverse_DNS_lookup) records to prevent your mails going to spam

If you don't know what any of the above means, get some help. Google is your friend. It's also worth noting that as a consequence it's pretty difficult to host a SMTP server on a dynamic IP address.

Expand All @@ -38,26 +38,39 @@ exposed on purpose, as it's regularly blocked by ISP or already occupied by othe

## Configuration options

The following configuration options are available:

```Dockerfile
ENV vars
$TZ = The timezone for the image
$HOSTNAME = Postfix myhostname
$RELAYHOST = Host that relays your msgs
$RELAYHOST_USERNAME = An (optional) username for the relay server
$RELAYHOST_PASSWORD = An (optional) login password for the relay server
$RELAYHOST_TLS_LEVEL = Relay host TLS connection leve
$MYNETWORKS = allow domains from per Network ( default 127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 )
$ALLOWED_SENDER_DOMAINS = domains sender domains
$ALLOW_EMPTY_SENDER_DOMAINS = if value is set (i.e: "true"), $ALLOWED_SENDER_DOMAINS can be unset
$MESSAGE_SIZE_LIMIT = The size of the messsage, in bytes
$INBOUND_DEBUGGING = Set to 1 to enable detailed debugging in the logs
$MASQUERADED_DOMAINS = domains where you want to masquerade internal hosts
$DKIM_SELECTOR = override DKIM selector (by default "mail")
```
The following configuration options are available

### General options

- `TZ` = The timezone for the image
- `FORCE_COLOR` = Set to `1` to force color output (otherwise auto-detected)
- `INBOUND_DEBUGGING` = Set to `1` to enable detailed debugging in the logs
- `ALLOWED_SENDER_DOMAINS` = domains which are allowed to send email via this server
- `ALLOW_EMPTY_SENDER_DOMAINS` = if value is set (i.e: `true`), `ALLOWED_SENDER_DOMAINS` can be unset
- `LOG_FORMAT` = Set your log format (JSON or plain)

### Postfix-specific options

### `HOSTNAME`
- `RELAYHOST` = Host that relays your messages
- `RELAYHOST_USERNAME` = An (optional) username for the relay server
- `RELAYHOST_PASSWORD` = An (optional) login password for the relay server
- `RELAYHOST_TLS_LEVEL` = Relay host TLS connection leve
- `POSTFIX_message_size_limit` = The maximum size of the messsage, in bytes, by default it's unlimited
- `POSTFIX_mynetworks` = Allow sending mails only from specific networks ( default `127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16` )
- `POSTFIX_hostname` = Set tha name of this postfix server
- `MASQUERADED_DOMAINS` = domains where you want to masquerade internal hosts
- `POSTFIX_<any_postfix_setting>` = provide any additional postfix setting
- `SMTP_HEADER_CHECKS`= Set to `1` to enable header checks of to a location
of the file for header checks

### DKIM-specific options

- `DKIM_SELECTOR` = Override the default DKIM selector (by default "mail").
- `DKIM_AUTOGENERATE` = Set to non-empty value (e.g. `true` or `1`) to have
the server auto-generate domain keys.
- `OPENDKIM_<any_dkim_setting>` = Provide any additonal OpenDKIM setting.

### `POSTFIX_hostname`

You may configure a specific hostname that the SMTP server will use to identify itself. If you don't do it,
the default Docker host name will be used. A lot of times, this will be just the container id (e.g. `f73792d540a5`)
Expand Down Expand Up @@ -104,7 +117,7 @@ Define relay host TLS connection level. See [smtp_tls_security_level](http://www

This level defines how the postfix will connect to your upstream server.

### `MESSAGE_SIZE_LIMIT`
### `POSTFIX_message_size_limit`

Define the maximum size of the message, in bytes.
See more in [Postfix documentation](http://www.postfix.org/postconf.5.html#message_size_limit).
Expand All @@ -113,7 +126,7 @@ By default, this limit is set to 0 (zero), which means unlimited. Why would you
with `RELAYHOST` setting. If your relay host has a message limit (and usually it does), set it also here. This will help you "fail fast" --
your message will be rejected at the time of sending instead having it stuck in the outbound queue indefenetly.

### `MYNETWORKS`
### `POSTFIX_mynetworks`

This implementation is meant for private installations -- so that when you configure your services using _docker compose_
you can just plug it in. Precisely because of this reason and the prevent any issues with this postfix being inadvertently
Expand Down Expand Up @@ -174,7 +187,9 @@ Example:
docker run --rm --name postfix -e "SMTP_HEADER_CHECKS="regexp:/etc/postfix/smtp_header_checks" -e "ALLOWED_SENDER_DOMAINS=example.com example.org" -p 1587:587 boky/postfix
```
## `DKIM`
## DKIM / DomainKeys
### Supplying your own DKIM keys
**This image is equiped with support for DKIM.** If you want to use DKIM you will need to generate DKIM keys yourself.
You'll need to create a folder for every domain you want to send through Postfix and generate they key(s) with the following command, e.g.
Expand Down Expand Up @@ -203,7 +218,19 @@ will be used automatically, e.g.:
docker run --rm --name postfix -e "ALLOWED_SENDER_DOMAINS=example.com example.org" -v /host/keys:/etc/opendkim/keys -p 1587:587 boky/postfix
```
**NOTE:** `mail` is the *default DKIM selector* and should be sufficient for most usages. If you wish to override the selector,
### Auto-generating the DKIM selectors with
If you set the environment variable `DKIM_AUTOGENERATE` to a non-empty value
(e.g. `true` or `1`) the image will automatically generate the keys.
**Be careful when using this option**. If you don't bind `/etc/opendkim/keys`
to a persistent volume, you will get new keys every single time. You will need
to take the generated public part of the key (the one in the `.txt` file) and
copy it over to your DNS server manually.
### Changing the DKIM selector
`mail` is the *default DKIM selector* and should be sufficient for most usages. If you wish to override the selector,
set the environment variable `DKIM_SELECTOR`, e.g. `... -e DKIM_SELECTOR=postfix`. Note that the same DKIM selector will be
applied to all found domains. To override a selector for a specific domain use the syntax `[<domain>=<selector>,...]`, e.g.:
Expand All @@ -217,6 +244,11 @@ This means:
- use `blah` for `example.com` domain
- use `foo` if no domain matches
### Verifying your setup
I strongly suggest using a service such as [dkimvalidator](https://dkimvalidator.com/) to make sure your keys are set up properly
and your DNS server is serving them with the correct records.
## Extending the image
### Using custom init scripts
Expand Down Expand Up @@ -250,6 +282,8 @@ postconf -e "address_verify_negative_cache=yes"
Any Postfix [configuration option](http://www.postfix.org/postconf.5.html) can be overriden using `POSTFIX_<name>` environment variables, e.g.
`POSTFIX_allow_mail_to_commands=alias,forward,include`. Specifying no content (empty variable) will remove that variable from postfix config.
### Overriding specific OpenDKIM settings
Any OpenDKIM [configuration option](http://opendkim.org/opendkim.conf.5.html) can be overriden using `OPENDKIM_<name>` environment variables, e.g.
`OPENDKIM_RequireSafeKeys=yes`. Specifying no content (empty variable) will remove that variable from OpenDKIM config.
Expand All @@ -270,7 +304,7 @@ which will use `UID:GID` of `100:101`. `opendkim` will run under account `102:10
There are may other project offering similar functionality. The aim of this project, however, is:
- to make it as simple as possible to run the relay, without going too much into postfix configuration details
- to make as small image as possible (hence basing on Alpine linux)
- to make the image as small as possible (hence basing on Alpine linux)
- to make the image and the corresponding code testable
The other projects are, in completely random order:
Expand Down
34 changes: 25 additions & 9 deletions integration-test.sh
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
#!/bin/sh
#!/usr/bin/env bash
set -e
cd integration-tests
for i in `find -maxdepth 1 -type d`; do
i="$(basename "$i")"
if [ "$i" == "tester" ] || [ "$i" == "." ] || [ "$i" == ".." ]; then
continue
fi

run_test() {
echo
echo
echo "☆☆☆☆☆☆☆☆☆☆ $1 ☆☆☆☆☆☆☆☆☆☆"
echo
(
echo "$i"
cd "$i"
cd "$1"
docker-compose up --build --abort-on-container-exit --exit-code-from tests
docker-compose down
)
done
}

if [[ $# -gt 0 ]]; then
while [[ -n "$1" ]]; do
run_test "$1"
shift
done
else
for i in `find -maxdepth 1 -type d`; do
i="$(basename "$i")"
if [ "$i" == "tester" ] || [ "$i" == "." ] || [ "$i" == ".." ]; then
continue
fi
run_test $i
done
fi
1 change: 1 addition & 0 deletions integration-tests/basic-test/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ services:
- "./test-keys:/etc/opendkim/keys"
- "./docker-init.db:/docker-init.db/"
environment:
FORCE_COLOR: "1"
ALLOWED_SENDER_DOMAINS: "example.org"
tests:
image: "boky/postfix-integration-test"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

. /common.sh

echo -e "$notice Relaying all mails to blackhole.${reset}"
notice " Relaying all mails to blackhole.${reset}"
postconf -e "smtpd_end_of_data_restrictions=check_client_access static:discard"
32 changes: 32 additions & 0 deletions integration-tests/deprecated/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
version: '3.7'
services:
postfix_test_587:
hostname: "postfix"
image: "boky/postfix"
build:
context: ../..
restart: always
healthcheck:
test: [ "CMD", "sh", "-c", "netstat -an | fgrep 587 | fgrep -q LISTEN" ]
interval: 10s
timeout: 5s
start_period: 10s
retries: 2
environment:
FORCE_COLOR: "1"
MASQUERADED_DOMAINS: "postfix"
ALLOWED_SENDER_DOMAINS: "example.org"
POSTFIX_smtpd_end_of_data_restrictions: "check_client_access static:discard"
MYNETWORKS: "127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
HOSTNAME: "postfix"
tests:
image: "boky/postfix-integration-test"
restart: "no"
volumes:
- "../tester:/code"
build:
context: ../tester
command: "/"
environment:
FROM: "demo@example.org"
TO: "test@gmail.com"
30 changes: 30 additions & 0 deletions integration-tests/generate-dkim-keys/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
version: '3.7'
services:
postfix_test_587:
hostname: "postfix"
image: "boky/postfix"
build:
context: ../..
restart: always
healthcheck:
test: [ "CMD", "sh", "-c", "netstat -an | fgrep 587 | fgrep -q LISTEN" ]
interval: 10s
timeout: 5s
start_period: 10s
retries: 2
environment:
FORCE_COLOR: "1"
ALLOWED_SENDER_DOMAINS: "example.org"
DKIM_AUTOGENERATE: "true"
POSTFIX_smtpd_end_of_data_restrictions: "check_client_access static:discard"
tests:
image: "boky/postfix-integration-test"
restart: "no"
volumes:
- "../tester:/code"
build:
context: ../tester
command: "/"
environment:
FROM: "demo@example.org"
TO: "test@gmail.com"
1 change: 1 addition & 0 deletions integration-tests/no-dkim-test/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ services:
start_period: 10s
retries: 2
environment:
FORCE_COLOR: "1"
MASQUERADED_DOMAINS: "postfix"
ALLOWED_SENDER_DOMAINS: ""
ALLOW_EMPTY_SENDER_DOMAINS: "true"
Expand Down
4 changes: 2 additions & 2 deletions sample/docker-compose/sample.env
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
TZ=Europe/Amsterdam
HOSTNAME=smtp-relay
POSTFIX_myhostname=smtp-relay
RELAYHOST=smtp.gmail.com:587
RELAYHOST_USERNAME=you@gmail.com
RELAYHOST_PASSWORD=yourgmailapppassword
MESSAGE_SIZE_LIMIT=26214400
POSTFIX_message_size_limit=26214400
ALLOWED_SENDER_DOMAINS=example.org
Loading

0 comments on commit cfd1a13

Please sign in to comment.