This project integrates parts of the code of eldada/postfix-relay-kubernetes and instrumentisto/opendkim-docker-image. Many thanks for their great work! It implements a postfix based mail relay, that can be run on Docker or Kubernetes with different common configurations.
The configuration can be done via environment variables or a .env file for Docker or Kubernetes and by an additional helm chart for Kubernetes.
Check the sections Build Docker images, Run locally with Docker and Deploy to Kubernetes with the Helm Chart to run the different configuration options locally or deploy them.
Use the test container to check your configuration. Please see the Test container section.
With these options you can configure the postfix basics:
- Hostname (hostname; default: my.local)
- Networks (string; default 10.0.0.0/8,127.0.0.0/8,172.17.0.0/16,192.0.0.0/8)
- Custom config (string of any valid postfix configuration directive)
Important: the custom config is executed as the last directive, so you are able to overwrite other defaults by that directive.
POSTFIX_RELAY_HOSTNAME=
POSTFIX_RELAY_NETWORKS=
POSTFIX_RELAY_CUSTOM_CONFIG=
postfixRelay:
hostname:
networks:
customConfig:
You can configure the following common configuration options and combine them:
- Simple mail relay
- Inbound mail transport via TLS
- Outbound mail transport via TLS
- Sender based routing
- DKIM
For each scenario a .env and values dist file is provided. The .env dist files are located in the projects root folder and the values dist files can be found in the helm folder.
This configuration option handles the local mail forwarding for one sender domain to their official outbound SMTP server. To achieve this you have to configure the following values:
- Default outbound relay host (ip address or hostname)
- Default outbound relay username (string)
- Default outbound relay password (string)
POSTFIX_RELAY_DEFAULT_OUTBOUND_RELAY_HOST=
POSTFIX_RELAY_DEFAULT_OUTBOUND_RELAY_USERNAME=
POSTFIX_RELAY_DEFAULT_OUTBOUND_RELAY_PASSWORD=
postfixRelay:
defaultOutboundRelay:
host:
username:
password:
To configure this scenario, please use the .env-01-simple-mailrelay.dist and the helm/values-01-simple-mailrelay.yaml dist files.
This configuration options handles inbound TLS encrypted mail transport.
You can create a certificate request with a new key without a passphrase by the following command:
openssl req -new -newkey rsa:2048 -nodes -keyout foo-key.pem -out foo-req.pem
You can self-sign the certificate by the following command:
openssl ca -out foo-cert.pem -days 365 -infiles foo-req.pem
And get the base64 encoded values of the certificate and the key by these commands:
cat foo-cert.pem | base64
cat foo-key.pem | base64
Please keep in mind, that the certificate has to be trusted!
- Inbound TLS (false, may or encrypt)
- Inbound TLS certificate (base64 encoded certificate string; append a trailing newline before encoding)
- Inbound TLS key (base64 encoded key string; append a trailing newline before encoding)
- Inbound TLS settings (string)
POSTFIX_RELAY_INBOUND_TLS=
POSTFIX_RELAY_INBOUND_TLS_CERTIFICATE=
POSTFIX_RELAY_INBOUND_TLS_KEY=
POSTFIX_RELAY_INBOUND_TLS_SETTINGS=
Important: the helm properties for certificate and key accept multiline values without base64 encoding
postfixRelay:
inboundTls:
inboundTlsCertificate:
inboundTlsKey:
inboundTlsSettings:
You can find additional information about inbound TLS at the postfix TLS readme.
To configure this scenario, please use the .env-02-simple-mailrelay-inbound-tls.dist and the helm/values-02-simple-mailrelay-inbound-tls.yaml.dist dist files.
This configuration option handles outbound TLS encrypted mail transport.
- Outbound TLS (false, may or encrypt)
- Outbound TLS settings (string)
POSTFIX_RELAY_OUTBOUND_TLS=
POSTFIX_RELAY_OUTBOUND_TLS_SETTINGS=
postfixRelay:
outboundTls:
outboundTlsSettings:
You can find additional information about outbound TLS at the postfix TLS readme.
To configure this scenario, you can use the .env-03-simple-mailrelay-inbound-outbound-tls.dist and the helm/values-03-simple-mailrelay-inbound-outbound-tls.yaml.dist dist files.
This configuration option handles the local mail forwarding for a default sender domain to their official outbound SMTP server and multiple additional sender domains. To achieve this you have to configure the following values:
- Multiple additional outbound senders (email address)
- Multiple additional outbound relay hosts (ip address or hostname)
- Multiple additional outbound relay usernames
- Multiple additional outbound relay passwords
POSTFIX_RELAY_ADDITIONAL_OUTBOUND_RELAY_0_SENDER=
POSTFIX_RELAY_ADDITIONAL_OUTBOUND_RELAY_0_HOST=
POSTFIX_RELAY_ADDITIONAL_OUTBOUND_RELAY_0_USERNAME=
POSTFIX_RELAY_ADDITIONAL_OUTBOUND_RELAY_0_PASSWORD=
postfixRelay:
additionalOutBoundRelay:
- sender:
host:
username:
password:
To configure this scenario, you can use the .env-04-simple-mailrelay-inbound-outbound-tls-sender-based-routing.dist and the helm/values-04-sender-based-routing-inbound-outbound-tls.yaml.dist dist files.
This configuration option handles the signing of forwarded mails via the DKIM pattern.
- Milter host (ip address or hostname; e.g. localhost)
- Trusted hosts (cldr string; e.g. 0.0.0.0/0)
- Default outbound relay dkim domain (string; e.g. test.de)
- Default outbound relay dkim selector (string; e.g. s1)
- Default outbound relay dkim key (base64 encoded key string; append a trailing newline before encoding)
- Default outbound relay dkim filter (string; e.g. *@test.de)
- Multiple additional outbound dkim domains (string; e.g. test.de)
- Multiple additional outbound dkim selectors (string; e.g. s1)
- Multiple additional outbound dkim keys (base64 encoded key string; append a trailing newline before encoding)
- Multiple additional outbound dkim filters (string; e.g. *@test.de)
POSTFIX_RELAY_DKIM_MILTER_HOST=
POSTFIX_RELAY_DKIM_TRUSTED_HOSTS=
POSTFIX_RELAY_DEFAULT_OUTBOUND_RELAY_DKIM_DOMAIN=
POSTFIX_RELAY_DEFAULT_OUTBOUND_RELAY_DKIM_SELECTOR=
POSTFIX_RELAY_DEFAULT_OUTBOUND_RELAY_DKIM_KEY=
POSTFIX_RELAY_DEFAULT_OUTBOUND_RELAY_DKIM_FILTER=
POSTFIX_RELAY_ADDITIONAL_OUTBOUND_RELAY_0_DKIM_DOMAIN=
POSTFIX_RELAY_ADDITIONAL_OUTBOUND_RELAY_0_DKIM_SELECTOR=
POSTFIX_RELAY_ADDITIONAL_OUTBOUND_RELAY_0_DKIM_KEY=
POSTFIX_RELAY_ADDITIONAL_OUTBOUND_RELAY_0_DKIM_FILTER=
postfixRelay:
relayDkim:
relayDkimMilterHost:
defaultOutboundRelay:
dkimDomain:
dkimSelector:
dkimKey:
dkimFilter:
additionalOutBoundRelay:
- dkimDomain:
dkimSelector:
dkimKey:
dkimFilter:
To configure this scenario, you can use the .env-05-simple-mailrelay-inbound-outbound-tls-sender-based-routing-dkim.dist and the helm/values-05-sender-based-routing-inbound-outbound-tls-dkim.yaml.dist dist files.
You can build the postfix Docker image locally by executing:
# For local build
cd docker/postfix
docker build .
You can build the opendkim Docker image locally by executing:
# For local build
cd docker/opendkim
docker build .
You can build the test Docker image locally by executing:
# For local build
cd docker/test
docker build .
There are dist env files for common scenarios in the projects root folder. The first block of variables in the dist files is used to define the test scenario. The other blocks are used to define the configuration of the services.
Copy the .env-.dist files to .env- and add your values
Add postfix-relay to /etc/hosts
Run the container with the variables defined in the env file by executing
docker run --env-file <env-file> -p 1025:25 chrb0/postfix:latest
To check out the examples with dkim you have to run the opendkim container additionally
docker run --env-file <env-file> -p <exposed port>:8891 chrb0/opendkim:latest
To test the configuration you can use the test container with the predefined environment variables in the environment file.
cd docker/test
docker build . -t postfix-relay-test:latest
docker run --rm -ti --env-file <env-file> postfix-relay-test:latest
The Helm Chart in helm/postfix directory can be used to deploy the postfix-relay into your Kubernetes cluster.
Create a custom-values.yaml
with the configuration details. There are dist files for common scenarios in the
helm folder. For all supported values see the values.yaml file in the chart
folder.
Deploy the relay to Kubernetes by executing
helm upgrade --install postfix-relay helm/postfix -f example-values-simple-mailrelay.yaml
or
cd helm
helm template postfix-relay postfix-relay -f custom-values.yaml | kubectl apply -f -
An optional postfix-exporter sidecar can be deployed for exposing postfix metrics. This is using the work from https://github.com/kumina/postfix_exporter.
To enable the exporter sidecar, update your custom-values.yaml
file and add
# Enable the postfix-exporter sidecar
exporter:
enabled: true
# Enable a ServiceMonitor object for Prometheus scraping
serviceMonitor:
enabled: true
To test the configuration you can use the test container with the predefined environment variables in the environment file.
cd docker/test
docker build . -t postfix-relay-test:latest
kubectl create secret generic test --from-env-file <env-file> && \
kubectl run test --attach --rm --overrides='{"spec":{"containers":[{"name":"test","image":"postfix-relay-test:latest","args":["bash","-c","sleep 5;test.sh"],"envFrom":[{"secretRef":{"name":"test"}}]}]}}' --image=postfix-relay-test:latest && \
kubectl delete secret test
The test container brings a test script, that can be configured by environment variables. All env dist files includes the environment variable for a complete test in the first block. It connects to a smtp server and sends emails.
- Host (ip address or hostname of the smtp server to connect to; e.g. localhost)
- Port (port of the smtp server to connect to; e.g. 1025)
- Multiple email senders (email address; e.g. [email protected])
- Multiple email recipients (email address; e.g. [email protected])
- Config option if the test script should ask for additional senders and recipients (max 3 additional; boolean; e.g. false)
- Config option if the test script should connect plain (unencrypted) to the smtp server (string; e.g. yes or no)
- Config option if the test script should connect encrypted to the smtp server (string; e.g. yes or no)
POSTFIX_RELAY_TEST_POSTFIX_HOST=
POSTFIX_RELAY_TEST_POSTFIX_PORT=
POSTFIX_RELAY_TEST_0_SENDER=
POSTFIX_RELAY_TEST_0_RECIPIENT=
POSTFIX_RELAY_TEST_1_SENDER=
POSTFIX_RELAY_TEST_1_RECIPIENT=
POSTFIX_RELAY_TEST_ASK_FOR_ADDITIONAL=
POSTFIX_RELAY_TEST_EXECUTE_PLAIN=
POSTFIX_RELAY_TEST_EXECUTE_TLS=
cd docker/test
docker build . -t postfix-relay-test:latest
On Docker:
docker run --rm -ti --env-file <env-file> postfix-relay-test:latest
On Kubernetes:
kubectl create secret generic test --from-env-file <env-file> && \
kubectl run test --attach --rm --overrides='{"spec":{"containers":[{"name":"test","image":"postfix-relay-test:latest","args":["bash","-c","sleep 5;test.sh"],"envFrom":[{"secretRef":{"name":"test"}}]}]}}' --image=postfix-relay-test:latest && \
kubectl delete secret test
The work in this repository is based on