Postfix's Transport Encryption under Control of the User
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Gerrit 9c688fa1c5 use good english 7 years ago
posttls fixed timezone issue 8 years ago
.gitignore abstract username, harmonize quotes, extend gitignore 7 years ago
LICENSE import 8 years ago add 7 years ago abstract username, harmonize quotes, extend gitignore 7 years ago
requirements.txt import 8 years ago use good english 7 years ago

PostTLS - Postfix’s Transport Encryption under Control of the User

PostTLS is an addition to the excellent Postfix mail server. It allows to activate mandatory TLS for all domains in practice (e.g. to set smtp_tls_security_level = encrypt). PostTLS does this by enabling the sender of an email to delete or to send the email unencrypted if a secure connection cannot be established (e.g. because the recipients’ mail server does not support transport encryption) and thus the mail was deferred to the Postfix queue. More information can be found at


The code in this repository is licensed under version 3 of the GNU Affero General Public License (AGPLv3). Please see the LICENSE file for details.


Please be aware that PostTLS right now is in early stage and there are quite a few things to prepare on the server to use the software. You should be familiar with Linux system administration and you should know how to run a python program in production. In the following you will find a list of requirements - but this is not a step-by-step guide to meet these requirements! Of course, documentation and automation of the installation procedure will be enhanced in the future if there is demand.


Make sure to meet the following requirements:

  • Python 3
  • Virtualenv and virtualenvwrapper
  • Two Postfix instances. See Managing multiple Postfix instances on a single host to find out more about multiple instance support of Postfix.
    • First instance: Postfix option smtp_tls_security_level is set to encrypt and implements mandatory TLS for all domains.
    • Second instance: Postfix option smtp_tls_security_level is set to may and implements opportunistic TLS.
  • PostTLS calls some Postfix commands, which should be executable via sudo without password. So add something like this to /etc/sudoers using sudo visudo:
# User 'developer' can use apps needed for PostTLS
developer ALL = NOPASSWD: /usr/bin/mailq
developer ALL = NOPASSWD: /usr/sbin/postcat
developer ALL = NOPASSWD: /usr/sbin/postsuper


If the above mentioned requirements are met, you should be able to install and use PostTLS.

Create a virtual environment:

$ mkvirtualenv posttls

Clone the repository:

$ git clone

Install Python requirements:

$ pip install -r requirements.txt

Configuration of PostTLS is done via environment variables. You can use a bash script like this:

# Django configuration
export POSTTLS_SECRET_KEY="verysecretkey"
export POSTTLS_STATIC_ROOT_DIR="/home/developer/apps/posttls/static/"
export POSTTLS_MEDIA_ROOT_DIR="/home/developer/apps/posttls/media/"

# Set this to 'production' in production environment (see Django settings file)
export POSTTLS_ENVIRONMENT_TYPE="development"

# PostTLS settings

# Needed to generate the links in the notification mail:

PostTLS uses an SQLite database. But since Django supports a wide range of different databases, you can also choose a full-fledged database such as PostgreSQL. Create database tables:

$ ./ migrate

Check if the script to query the Postfix queue runs smoothly:

$ ./ process_queue

In the notification email sent by the Django management command process_queue you will find two buttons which link to the web server of our PostTLS installation. Make these features available by configuring a web server. For testing purposes you can use Django’s build-in development server by running:

$ ./ runserver

Now you should be able to access PostTLS via your web browser.

Please note, that you should not use Django’s development server in production. There are many different technology stacks to run a Django application in production. One option is to use Gunicorn behind Nginx as a reverse proxy.


You can configure a cron job to process the queue once every minute. To prevent overlapping of cron jobs, use the flock command:

*/1 * * * * . /home/developer/apps/posttls/ && /usr/bin/flock -w 0 /home/developer/apps/posttls/cron.lock /home/developer/.virtualenvs/posttls/bin/python3 /home/developer/apps/posttls/posttls/posttls/ process_queue >/dev/null 2>&1