Skip to content

Refactoring the docker. #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
debug.sh
sftp-config.json
assets/domainkeys/mail.*
.DS_Store
.env.prod
data/opendkim/*
data/.users.prod
18 changes: 0 additions & 18 deletions Dockerfile

This file was deleted.

4 changes: 2 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2014 Minghou Ye
Copyright (c) 2014

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand All @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
114 changes: 78 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,51 +1,93 @@
docker-postfix
==============

run postfix with smtp authentication (sasldb) in a docker container.
TLS and OpenDKIM support are optional.

## Requirement
+ Docker 1.0
Postfix with SMTP authentication (SASLdb) in a Docker container.
TLS and OpenDKIM are also supported.
With a simple environment and configuration file, you can set up multiple domains and email addresses.
The settings allow you to forward incoming emails to other addresses, such as Gmail.
This option can be useful if you want to use Google Gmail with your own email domain.

## Installation
1. Build image

```bash
$ sudo docker pull catatnight/postfix
$ docker compose build
```

## Usage
1. Create postfix container with smtp authentication
## Configure the service:
There are two important files:
1. One for the environment, which should contain two variables:
```
maindomain=example01.com
maildomains=example01.com,example02.com
```
The `maindomain`, as its name indicates, should be the main domain of your server and will be used to set the Postfix variable `myhostname`.
The second variable, `maildomains`, is the list of domains that you want Postfix to support. This value will be used to set the Postfix `virtual_alias_domains`.
It will also be used by OpenDKIM to generate the required keys for each domain.
Please check the example file `docker/.env.example`.

```bash
$ sudo docker run -p 25:25 \
-e maildomain=mail.example.com -e smtp_user=user:pwd \
--name postfix -d catatnight/postfix
# Set multiple user credentials: -e smtp_user=user1:pwd1,user2:pwd2,...,userN:pwdN
```
2. Enable OpenDKIM: save your domain key ```.private``` in ```/path/to/domainkeys```
2. The second file is the list of users/emails that need to be created. We use a Docker volume to sync this file into the container path /tmp/passwd.
The file follows this format:
```
_domain:_user:_password:_cannonical
example01.com:[email protected]:somepassword:[email protected]
```
The content of this file is used to set up the SASL DB (`/etc/sasldb2`).
Additionally, it sets the Postfix `sender_canonical` and `header_checks` variables, which replace outgoing emails `_canonical` `From` values with the email address for our domain `_user`.
Please check the example file `data/.users.example`.

```bash
$ sudo docker run -p 25:25 \
-e maildomain=mail.example.com -e smtp_user=user:pwd \
-v /path/to/domainkeys:/etc/opendkim/domainkeys \
--name postfix -d catatnight/postfix
```
3. Enable TLS(587): save your SSL certificates ```.key``` and ```.crt``` to ```/path/to/certs```

```bash
$ sudo docker run -p 587:587 \
-e maildomain=mail.example.com -e smtp_user=user:pwd \
-v /path/to/certs:/etc/postfix/certs \
--name postfix -d catatnight/postfix
```
## Start the service
All the service configurations will be performed by simply running the `setup.sh` script inside the container. This script will read the environment variables and the user list file to generate the required Postfix and OpenDKIM configuration files.
The steps to follow are:
```BASH
# login to the container
docker exec -it postfix sh

# when you get the container prompt then you run the setup script:
./setup.sh

# After the setup we launch the service in this order
syslogd # optional to capture opemdkim logs
opendkim # start the opmkdim service
postfix start # to start postfix
```

You can check if the services started properly by tailing the logs:
```BASH
tail -f /var/log/messages # sys log where you can find details about openkdim service
tail -f /var/log/postfix.log
```

## Setting up your DNS records:
You can find plenty documentation about this on internet but basically to have a valid smtp server running you need 3 things:
### SPF: It specifies a list of IP addresses where email messages are allowed to sent on behalf of that domain.
For instance, if you want to be able to use your SMTP server to send email from a google gmail account, then you can do something like this:
```
Type: txt
Name: @
Data/Value: v=spf1 mx a include:_spf.google.com -all
```
You can use this generator: https://dmarcly.com/tools/spf-record-generator

### DKIM: DKIM detects forged header fields and content in emails. DKIM enables the receiver to check if email headers and content have been altered in transit.
The content of this records will be automatically generated by the `setup.sh` script and it will place it in the docker volume `data/opendkim/domainkey` with the name convention `{domain}.txt`.
```
Type: txt
Name: mail._domainkey
Data/Value: v=DKIM1; k=rsa; p={your_pub_key_generated_by_opendkim}
```
You can use this generator: https://dmarcly.com/tools/dkim-record-generator

## Note
+ Login credential should be set to (`[email protected]`, `password`) in Smtp Client
+ You can assign the port of MTA on the host machine to one other than 25 ([postfix how-to](http://www.postfix.org/MULTI_INSTANCE_README.html))
+ Read the reference below to find out how to generate domain keys and add public key to the domain's DNS records
### DMARC: Domain-based Message Authentication Reporting & Conformance (DMARC) is an email security protocol.
You can learn more about this here (https://www.fortinet.com/resources/cyberglossary/dmarc)
Example:
```
Type: txt
Name: _dmarc
Data/Value: v=DMARC1; p=reject; rua=mailto:[email protected]; adkim=s; aspf=s;
```
You can use this generator: https://dmarcly.com/tools/dmarc-generator

## Reference
+ [Postfix SASL Howto](http://www.postfix.org/SASL_README.html)
+ [How To Install and Configure DKIM with Postfix on Debian Wheezy](https://www.digitalocean.com/community/articles/how-to-install-and-configure-dkim-with-postfix-on-debian-wheezy)
+ TBD
### My favorite validator:
I use this exceptional validator https://www.learndmarc.com/ to see if everything is working as expected.
1 change: 0 additions & 1 deletion assets/certs/readme

This file was deleted.

1 change: 0 additions & 1 deletion assets/domainkeys/readme

This file was deleted.

130 changes: 0 additions & 130 deletions assets/install.sh

This file was deleted.

3 changes: 0 additions & 3 deletions build.sh

This file was deleted.

2 changes: 2 additions & 0 deletions data/.users.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
example01.com:[email protected]:somepassword:[email protected]
example02.com:[email protected]:somepassword:[email protected]
21 changes: 21 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
services:
smtp:
build:
context: .
dockerfile: ./hub/alpine/Dockerfile
# we push the log out so we can capture it by other service like fail2band
command: 'tail -f /var/log/postfix.log'
container_name: postfix
env_file:
# for production I switch this to ./docker/.env.prod
- ./docker/.env.example
ports:
- "25:25"
- "465:465"
- '587:587'
volumes:
- ./data/.users.example:/tmp/passwd
- ./data/opendkim/domainkey:/etc/opendkim/domainkey
# this is for dev purpose only, the scripts are being copied by the dockerfile build
- ./docker/map_ssl.py:/root/map_ssl.py
- ./docker/setup.sh:/root/setup.sh
2 changes: 2 additions & 0 deletions docker/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
maindomain=example01.com
maildomains=example01.com,example02.com
18 changes: 18 additions & 0 deletions docker/map_ssl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env python3

import json
import os

# constants
DOMAINS = os.environ.get('maildomains').split(',')
DOMAIN_MAP = os.path.join(os.sep, 'etc', 'postfix', 'ssl_map')
PATH = os.path.join(os.sep, 'etc', 'letsencrypt', 'live')

# open a file to write the mapping
with open(DOMAIN_MAP, 'w+') as mapping:
# loop per domain
for domain in DOMAINS:
# write the domain, key and crt
privkey_pem = os.path.join(PATH, domain, 'privkey.pem')
fullchain_pem = os.path.join(PATH, domain, 'fullchain.pem')
mapping.write(f'{domain} {privkey_pem} {fullchain_pem}\n')
Loading