commit
4bfdcee246
@ -0,0 +1,17 @@
|
||||
FROM registry.jochum.dev/library/debian:buster-slim
|
||||
|
||||
LABEL maintainer "René Jochum <rene@jochum.dev>"
|
||||
|
||||
RUN echo "postfix postfix/mailname string mail.example.com" | debconf-set-selections && \
|
||||
echo "postfix postfix/main_mailer_type string 'No configuration'" | debconf-set-selections && \
|
||||
apt-get update --allow-releaseinfo-change && \
|
||||
apt-get install -qy -o 'DPkg::Options::=--force-confold' -o 'DPkg::Options::=--force-confdef' postfix postfix-pgsql postfix-mysql postfix-pcre python3-minimal python3-jinja2
|
||||
|
||||
COPY conf /conf
|
||||
COPY start.py /start.py
|
||||
|
||||
EXPOSE 25/tcp 465/tcp 587/tcp
|
||||
|
||||
VOLUME ["/data", "/overrides", "/cert"]
|
||||
|
||||
CMD /start.py
|
@ -0,0 +1,28 @@
|
||||
# Postfix
|
||||
|
||||
## Create Readonly PostgreSQL user
|
||||
|
||||
```sql
|
||||
USE postfixadmin;
|
||||
GRANT CONNECT ON DATABASE postfixadmin TO postfix;
|
||||
GRANT USAGE ON SCHEMA public TO postfix;
|
||||
GRANT SELECT ON ALL TABLES IN SCHEMA public TO postfix;
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO postfix;
|
||||
```
|
||||
|
||||
## Environment variables
|
||||
|
||||
- MYDOMAIN
|
||||
- SUBNET
|
||||
- RELAYNETS
|
||||
- SQL_TYPE - either `pgsql` or `mysql`
|
||||
- SQL_USER - readonly Database user
|
||||
- SQL_PASSWORD
|
||||
- SQL_HOST
|
||||
- SQL_DATABASE
|
||||
- MESSAGE_SIZE_LIMIT - defaults to 52428800
|
||||
- REJECT_UNLISTED_RECIPIENT - "yes" or "no"
|
||||
|
||||
## Links
|
||||
|
||||
- [HOWTO this is based on](https://kuther.net/2011/11/15/soho-mailserver-with-postfix-postgresql-dovecot-spamassassin-roundcube/)
|
@ -0,0 +1,57 @@
|
||||
# basic domain settings
|
||||
myhostname = {{ HOSTNAME }}
|
||||
mydomain = {{ MYDOMAIN }}
|
||||
mydestination = $myhostname, localhost
|
||||
# mynetworks = 192.168.1.0/24, 127.0.0.0/8
|
||||
mynetworks = 127.0.0.1/32 [::1]/128 {{ SUBNET }} {{ RELAYNETS }}
|
||||
myorigin = $mydomain
|
||||
relay_domains = proxy:{{ SQL_TYPE }}:/etc/postfix/sql/relay_domains.cf
|
||||
|
||||
# In kube we don't often don't have a stable outgoing IP Address, use a relayhost for this.
|
||||
relayhost = {{ RELAYHOST }}
|
||||
|
||||
# enable auth via Dovecot
|
||||
smtpd_sasl_auth_enable = yes
|
||||
smtpd_sasl_path = inet:{{ DOVECOT_HOST }}:2525
|
||||
smtpd_sasl_type = dovecot
|
||||
|
||||
message_size_limit = 52428800
|
||||
|
||||
# virtual mail setup for Postgresql and Dovecot transport
|
||||
virtual_mailbox_limit = 0
|
||||
virtual_mailbox_domains = proxy:{{ SQL_TYPE }}:/etc/postfix/sql/virtual_domains_maps.cf
|
||||
virtual_mailbox_maps = proxy:{{ SQL_TYPE }}:/etc/postfix/sql/virtual_mailbox_maps.cf
|
||||
virtual_alias_maps = proxy:{{ SQL_TYPE }}:/etc/postfix/sql/virtual_alias_maps.cf
|
||||
virtual_uid_maps = static:8
|
||||
virtual_gid_maps = static:8
|
||||
virtual_minimum_uid = 8
|
||||
virtual_transport=lmtp:inet:{{ DOVECOT_HOST }}:2525
|
||||
dovecot_destination_recipient_limit = 1
|
||||
|
||||
# also local accounts are handled via virtual users, configure aliases for those in PostfixAdmin
|
||||
local_transport = virtual
|
||||
local_recipient_maps = $virtual_mailbox_maps
|
||||
|
||||
# TLS server (receiving)
|
||||
smtpd_tls_auth_only = yes
|
||||
smtpd_tls_security_level = encrypt
|
||||
smtpd_tls_key_file = /cert/tls.key
|
||||
smtpd_tls_cert_file = /cert/tls.crt
|
||||
smtpd_tls_CAfile = /cert/ca.crt
|
||||
|
||||
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
|
||||
|
||||
# TLS client (sending)
|
||||
smtp_tls_security_level = encrypt
|
||||
|
||||
# security and basic spam protection
|
||||
smtpd_recipient_restrictions =
|
||||
permit_sasl_authenticated
|
||||
permit_mynetworks
|
||||
reject_unauth_destination
|
||||
smtpd_relay_restrictions =
|
||||
permit_mynetworks
|
||||
permit_sasl_authenticated
|
||||
defer_unauth_destination
|
||||
smtpd_client_restrictions =
|
||||
permit_sasl_authenticated
|
@ -0,0 +1,40 @@
|
||||
# service type private unpriv chroot wakeup maxproc command + args
|
||||
# (yes) (yes) (yes) (never) (100)
|
||||
|
||||
# Exposed SMTP service
|
||||
smtp inet n - n - - smtpd
|
||||
|
||||
# Expose 587
|
||||
submission inet n - n - - smtpd
|
||||
-o smtpd_enforce_tls=yes
|
||||
-o smtpd_sasl_auth_enable=yes
|
||||
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
|
||||
|
||||
# Expose 465
|
||||
smtps inet n - y - - smtpd
|
||||
-o smtpd_tls_wrappermode=yes
|
||||
|
||||
outclean unix n - n - 0 cleanup
|
||||
-o header_checks=pcre:/etc/postfix/outclean_header_filter.cf
|
||||
|
||||
# Internal postfix services
|
||||
pickup unix n - n 60 1 pickup
|
||||
cleanup unix n - n - 0 cleanup
|
||||
qmgr unix n - n 300 1 qmgr
|
||||
tlsmgr unix - - n 1000? 1 tlsmgr
|
||||
rewrite unix - - n - - trivial-rewrite
|
||||
bounce unix - - n - 0 bounce
|
||||
defer unix - - n - 0 bounce
|
||||
trace unix - - n - 0 bounce
|
||||
verify unix - - n - 1 verify
|
||||
flush unix n - n 1000? 0 flush
|
||||
proxymap unix - - n - - proxymap
|
||||
smtp unix - - n - - smtp
|
||||
relay unix - - n - - smtp
|
||||
error unix - - n - - error
|
||||
retry unix - - n - - error
|
||||
discard unix - - n - - discard
|
||||
lmtp unix - - n - - lmtp
|
||||
anvil unix - - n - 1 anvil
|
||||
scache unix - - n - 1 scache
|
||||
postlog unix-dgram n - n - 1 postlogd
|
@ -0,0 +1,5 @@
|
||||
user = {{ SQL_USER }}
|
||||
password = {{ SQL_PASSWORD }}
|
||||
hosts = {{ SQL_HOST }}
|
||||
dbname = {{ SQL_DATABASE }}
|
||||
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = true
|
@ -0,0 +1,5 @@
|
||||
user = {{ SQL_USER }}
|
||||
password = {{ SQL_PASSWORD }}
|
||||
hosts = {{ SQL_HOST }}
|
||||
dbname = {{ SQL_DATABASE }}
|
||||
query = SELECT goto FROM alias WHERE address='%s' AND active = true
|
@ -0,0 +1,5 @@
|
||||
user = {{ SQL_USER }}
|
||||
password = {{ SQL_PASSWORD }}
|
||||
hosts = {{ SQL_HOST }}
|
||||
dbname = {{ SQL_DATABASE }}
|
||||
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = false and active = true
|
@ -0,0 +1,5 @@
|
||||
user = {{ SQL_USER }}
|
||||
password = {{ SQL_PASSWORD }}
|
||||
hosts = {{ SQL_HOST }}
|
||||
dbname = {{ SQL_DATABASE }}
|
||||
query = SELECT quota FROM mailbox WHERE username='%s'
|
@ -0,0 +1,5 @@
|
||||
user = {{ SQL_USER }}
|
||||
password = {{ SQL_PASSWORD }}
|
||||
hosts = {{ SQL_HOST }}
|
||||
dbname = {{ SQL_DATABASE }}
|
||||
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = true
|
@ -0,0 +1,58 @@
|
||||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import glob
|
||||
import jinja2
|
||||
|
||||
def jinja_render_file(in_path, data, out_path):
|
||||
render_environment = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.dirname(in_path)))
|
||||
output = render_environment.get_template(os.path.basename(in_path)).render(**data)
|
||||
|
||||
with open(out_path, 'w', encoding='utf-8') as rf:
|
||||
rf.write(output)
|
||||
|
||||
|
||||
def is_valid_postconf_line(line):
|
||||
return not line.startswith("#") \
|
||||
and not line == ''
|
||||
|
||||
if "MESSAGE_SIZE_LIMIT" not in os.environ:
|
||||
os.environ["MESSAGE_SIZE_LIMIT"] = 52428800
|
||||
|
||||
if "DOVECOT_HOST" not in os.environ:
|
||||
os.environ['DOVECOT_HOST'] = 'dovecot'
|
||||
|
||||
for postfix_file in glob.glob("/conf/*.cf"):
|
||||
destination = os.path.join("/etc/postfix", os.path.basename(postfix_file))
|
||||
shutil.copyfile(postfix_file, destination)
|
||||
os.chmod(destination, 600)
|
||||
|
||||
for postfix_file in glob.glob("/conf/*.cf.jinja"):
|
||||
out_path = os.path.join("/etc/postfix", os.path.basename(postfix_file))
|
||||
out_path = out_path[0:-6] # Remove .jinja from the output path
|
||||
jinja_render_file(postfix_file, os.environ, out_path)
|
||||
os.chmod(out_path, 600)
|
||||
|
||||
if os.path.exists("/overrides/postfix.cf"):
|
||||
for line in open("/overrides/postfix.cf").read().strip().split("\n"):
|
||||
if is_valid_postconf_line(line):
|
||||
os.system('postconf -e "{}"'.format(line))
|
||||
|
||||
if os.path.exists("/overrides/postfix.master"):
|
||||
for line in open("/overrides/postfix.master").read().strip().split("\n"):
|
||||
if is_valid_postconf_line(line):
|
||||
os.system('postconf -Me "{}"'.format(line))
|
||||
|
||||
os.system("/bin/mkdir -p /data/vmail")
|
||||
os.system("/bin/chmod u=rwX,g=rX,o=rX /data")
|
||||
os.system("/bin/chown -R mail: /data/vmail")
|
||||
os.system("/bin/chmod -R u=rwX,g=rX,o= /data/vmail")
|
||||
|
||||
os.system("/usr/libexec/postfix/post-install meta_directory=/etc/postfix create-missing")
|
||||
# Before starting postfix, we need to check permissions on /queue
|
||||
# in the event that postfix,postdrop id have changed
|
||||
os.system("postfix set-permissions")
|
||||
os.system("postfix start-fg")
|
Loading…
Reference in New Issue