Simple yet functional dovecot+postfix

master
Pierre Jaury 9 years ago
parent 508c741ffa
commit 47272df96b

@ -3,12 +3,18 @@ FROM debian:jessie
RUN export DEBIAN_FRONTEND=noninteractive \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
postfix dovecot-imapd dovecot-sqlite \
postfix dovecot-imapd dovecot-sqlite dovecot-lmtpd \
dovecot-sieve dovecot-managesieved \
dovecot-antispam spamassassin clamav \
supervisor \
supervisor rsyslog \
&& apt-get clean
# When installed non-interactively, the file does not get copied to the
# postfix chroot, thus causing smtpd to fail.
RUN cp /etc/services /var/spool/postfix/etc/
ADD config /etc/
# Explicitely specify the configuration file to avoid problems when
# the default configuration path changes.
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]

@ -21,22 +21,15 @@ Architecture
The mail infrastructure is based on a standard MTA-LDA :
* Postfix with an SQL database for transport ;
* Dovecot with an SQL database for delivery and access ;
* Postfix with an SQLite database for transport ;
* Dovecot with an SQLite database for delivery and access ;
* Spamassassin for spam filtering ;
* ClamAV for malware filtering.
Additional Web UI :
* Roundcube Webmail (can easily be replaced) ;
* Administration UI based on Flask an VMM.
The administration UI does not interact with the database directly but with
VMM instead, which has a great API and already implements most features while
providing solid configuration files for Postfix and Dovecot.
Only authentication and authorization is managed directly by the Web
administration UI.
* Administration UI based on Flask.
All components are monitored by supervisord.
@ -47,10 +40,10 @@ The project is still at a very (very !) early stage.
This is more of a roadmap than a proper TODO list. Please poke me or pull
request if you would like to join the effort.
- [ ] Import vmm configuration files and tune them to support spamassassin and clamav.
- [ ] Run a mail container with a simple vmm command line.
- [x] Import vmm configuration files and get a simple postfix/dovecot running with SQLite.
- [ ] Add support for spamassassin.
- [ ] Add support for clamav.
- [ ] Draft a Web administration UI.
- [ ] Implement basic features from the free (as in beer) poste.io.
- [ ] Start using on a couple production mail servers.
- [ ] Find a proper way to maintain vmm without forking.
- [ ] Implement some fancy features.

@ -1,13 +0,0 @@
auth_mechanisms = plain login cram-md5
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
#!include auth-system.conf.ext

@ -1,6 +0,0 @@
# mailbox configuration
first_valid_gid = 70000
first_valid_uid = 70000
mail_access_groups = mail
mail_location = maildir:~/Maildir

@ -1,43 +0,0 @@
service imap-login {
inet_listener imap {
port = 143
}
inet_listener imaps {
port = 993
}
}
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
user = postfix
group = postfix
mode = 0600
}
}
service auth {
user = doveauth
unix_listener auth-userdb {
}
unix_listener /var/spool/postfix/private/dovecot-auth {
user = postfix
group = postfix
mode = 0600
}
}
service auth-worker {
unix_listener auth-worker {
user = mail
group = $default_internal_user
mode = 0660
}
user = mail
}
service dict {
unix_listener dict {
group = mail
mode = 0660
}
}

@ -1,4 +0,0 @@
# SSL/TLS support
ssl = yes
ssl_cert = </etc/ssl/cert.pem
ssl_key = </etc/ssl/key.pem

@ -1,6 +0,0 @@
# delivery configuration
postmaster_address = admin@domain.tld
recipient_delimiter = +
protocol lda {
}

@ -1,3 +0,0 @@
# mail browsing
protocol imap {
}

@ -1,3 +0,0 @@
# mail delivery
protocol lmtp {
}

@ -1,18 +1,10 @@
driver = pgsql
connect = host=localhost dbname=mailsys user=dovecot password=$Dovecot_PASS
driver = sqlite
connect = /data/freeposte.db
# Return the user hashed password
password_query = \
SELECT userid AS "user", password FROM dovecotpassword('%Ln', '%Ld') WHERE %Ls
SELECT password FROM users, domains WHERE username = '%n' AND domain = '%d'
# uncomment this user_query if you want to use the quota plugin
#user_query = \
# SELECT home, uid, gid, mail, quota_rule FROM dovecotquotauser('%Ln', '%Ld')
# otherwise uncomment the following user_query
#user_query = SELECT home, uid, gid, mail FROM dovecotuser('%Ln', '%Ld')
iterate_query = \
SELECT local_part AS username, domain_name.domainname AS domain \
FROM users \
LEFT JOIN domain_data USING (gid) \
LEFT JOIN domain_name USING (gid)
# Mostly get the user quota
user_query = \
SELECT '*:bytes=' || quota_bytes AS quota_rule FROM users WHERE username = '%n' AND domain = '%d'

@ -1,2 +1,123 @@
# handled protocols
protocols = imap lmtp
###############
# General
###############
protocols = imap lmtp sieve
postmaster_address = %{env:POSTMASTER_ADDRESS}
hostname = %{env:MAIL_HOSTNAME}
###############
# Mailboxes
###############
first_valid_gid = 8
first_valid_uid = 8
mail_location = maildir:/data/mail/%u
mail_home = /data/mail/%u
mail_uid = mail
mail_gid = mail
mail_privileged_group = mail
mail_access_groups = mail
###############
# TLS
###############
ssl = yes
ssl_cert = </data/ssl/cert.pem
ssl_key = </data/ssl/key.pem
###############
# Authentication
###############
auth_mechanisms = plain login cram-md5
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
service auth {
user = dovecot
unix_listener auth-userdb {
}
unix_listener /var/spool/postfix/private/dovecot-auth {
user = postfix
group = postfix
mode = 0600
}
}
service auth-worker {
unix_listener auth-worker {
user = mail
group = $default_internal_user
mode = 0660
}
user = mail
}
###############
# IMAP
###############
protocol imap {
}
service imap-login {
inet_listener imap {
port = 143
}
inet_listener imaps {
port = 993
}
}
###############
# Delivery
###############
protocol lmtp {
}
protocol lda {
recipient_delimiter = +
}
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
user = postfix
group = postfix
mode = 0600
}
}
service dict {
unix_listener dict {
group = mail
mode = 0660
}
}
###############
# Filtering
###############
service managesieve-login {
inet_listener sieve {
port = 4190
}
inet_listener sieve_deprecated {
port = 2000
}
}
plugin {
sieve = ~/.sieve
sieve_dir = ~/sieve
sieve_before = /var/lib/dovecot/sieve/before.sieve
sieve_default = /var/lib/dovecot/sieve/default.sieve
sieve_after = /var/lib/dovecot/sieve/after.sieve
}

@ -1,33 +1,43 @@
# aliases
sql = pgsql:${config_directory}/
proxysql = proxy:${sql}
###############
# General
###############
# relocated users from the database
relocated_maps = ${proxysql}pgsql-relocated_maps.cf
# The list of relayed networks is still loaded from a configuration file
mynetworks = /data/relaynets
# Empty alias list to override the configuration variable and disable NIS
alias_maps = hash:/etc/aliases
# SQLite configuration
sql = sqlite:${config_directory}/
# transport settings from our database
transport_maps = ${proxysql}pgsql-transport_maps.cf
###############
# TLS
###############
smtpd_use_tls = yes
smtpd_tls_cert_file=/data/ssl/cert.pem
smtpd_tls_key_file=/data/ssl/key.pem
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
# virtual domains, mailboxes and aliases
virtual_mailbox_domains = ${proxysql}pgsql-virtual_mailbox_domains.cf
virtual_alias_maps = ${proxysql}pgsql-virtual_alias_maps.cf
virtual_minimum_uid = 70000
virtual_uid_maps = ${sql}pgsql-virtual_uid_maps.cf
virtual_gid_maps = ${sql}pgsql-virtual_gid_maps.cf
virtual_mailbox_base = /
virtual_mailbox_maps = ${proxysql}pgsql-virtual_mailbox_maps.cf
# delivery transport
virtual_transport = lmtp:unix:private/dovecot-lmtp
# dovecot SASL
###############
# SASL
###############
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/dovecot-auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noplaintext, noanonymous
smtpd_sasl_security_options = noanonymous
# submission restrictions
smtpd_recipient_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unauth_destination
###############
# Virtual
###############
virtual_mailbox_domains = ${sql}sqlite-virtual_mailbox_domains.cf
virtual_alias_maps = ${sql}sqlite-virtual_alias_maps.cf
virtual_transport = lmtp:unix:private/dovecot-lmtp
###############
# Milter
###############
milter_default_action = tempfail
milter_protocol = 6
smtpd_milters =
non_smtpd_milters =

@ -1,33 +1,18 @@
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (yes) (never) (100)
# main SMTP services
# Exposed SMTP services
smtp inet n - - - - smtpd
submission inet n - - - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_enforce_tls=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_reject_unlisted_recipient=no
-o smtpd_client_restrictions=$mua_client_restrictions
-o smtpd_helo_restrictions=$mua_helo_restrictions
-o smtpd_sender_restrictions=$mua_sender_restrictions
-o smtpd_recipient_restrictions=
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
smtps inet n - - - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_enforce_tls=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_reject_unlisted_recipient=no
-o smtpd_client_restrictions=$mua_client_restrictions
-o smtpd_helo_restrictions=$mua_helo_restrictions
-o smtpd_sender_restrictions=$mua_sender_restrictions
-o smtpd_recipient_restrictions=
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
# internal postfix services
pickup unix n - - 60 1 pickup
# Internal postfix services
cleanup unix n - - - 0 cleanup
qmgr unix n - n 300 1 qmgr
tlsmgr unix - - - 1000? 1 tlsmgr
@ -35,18 +20,14 @@ rewrite unix - - - - - trivial-rewrite
bounce unix - - - - 0 bounce
defer unix - - - - 0 bounce
trace unix - - - - 0 bounce
proxymap unix - - - - - proxymap
verify unix - - - - 1 verify
flush unix n - - 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
smtp unix - - - - - smtp
relay unix - - - - - smtp
showq unix n - - - - showq
error unix - - - - - error
retry unix - - - - - error
discard unix - - - - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - - - - lmtp
anvil unix - - - - 1 anvil
scache unix - - - - 1 scache

@ -1,14 +0,0 @@
# All parameters are described in pgsql_table(5) / PGSQL PARAMETERS
#
# The hosts that Postfix will try to connect to and query from.
hosts = localhost
# The user name and password to log into the pgsql server.
user = postfix
password = some_password
# The database name on the servers.
dbname = mailsys
# The SQL query template used to search the database
query = SELECT destination FROM postfix_relocated_map('%u', '%d')

@ -1,18 +0,0 @@
# All parameters are described in pgsql_table(5) / PGSQL PARAMETERS
#
# The hosts that Postfix will try to connect to and query from.
hosts = localhost
# The user name and password to log into the pgsql server.
user = postfix
password = some_password
# The database name on the servers.
dbname = mailsys
# XXX see create_optional_types_and_functions.pgsql
# * line 9: type sender_login
# * line 26: function postfix_smtpd_sender_login_map + comment above
#
# The SQL query template used to search the database
query = SELECT login FROM postfix_smtpd_sender_login_map('%u', '%d')

@ -1,14 +0,0 @@
# All parameters are described in pgsql_table(5) / PGSQL PARAMETERS
#
# The hosts that Postfix will try to connect to and query from.
hosts = localhost
# The user name and password to log into the pgsql server.
user = postfix
password = some_password
# The database name on the servers.
dbname = mailsys
# The SQL query template used to search the database
query = SELECT transport FROM postfix_transport_map('%u', '%d')

@ -1,14 +0,0 @@
# All parameters are described in pgsql_table(5) / PGSQL PARAMETERS
#
# The hosts that Postfix will try to connect to and query from.
hosts = localhost
# The user name and password to log into the pgsql server.
user = postfix
password = some_password
# The database name on the servers.
dbname = mailsys
# The SQL query template used to search the database
query = SELECT destination FROM postfix_virtual_alias_map('%u', '%d')

@ -1,14 +0,0 @@
# All parameters are described in pgsql_table(5) / PGSQL PARAMETERS
#
# The hosts that Postfix will try to connect to and query from.
hosts = localhost
# The user name and password to log into the pgsql server.
user = postfix
password = some_password
# The database name on the servers.
dbname = mailsys
# The SQL query template used to search the database
query = SELECT gid FROM postfix_gid WHERE domainname='%d'

@ -1,14 +0,0 @@
# All parameters are described in pgsql_table(5) / PGSQL PARAMETERS
#
# The hosts that Postfix will try to connect to and query from.
hosts = localhost
# The user name and password to log into the pgsql server.
user = postfix
password = some_password
# The database name on the servers.
dbname = mailsys
# The SQL query template used to search the database
query = SELECT gid FROM postfix_gid WHERE domainname='%s'

@ -1,14 +0,0 @@
# All parameters are described in pgsql_table(5) / PGSQL PARAMETERS
#
# The hosts that Postfix will try to connect to and query from.
hosts = localhost
# The user name and password to log into the pgsql server.
user = postfix
password = some_password
# The database name on the servers.
dbname = mailsys
# The SQL query template used to search the database
query = SELECT maildir FROM postfix_virtual_mailbox_map('%u', '%d')

@ -1,14 +0,0 @@
# All parameters are described in pgsql_table(5) / PGSQL PARAMETERS
#
# The hosts that Postfix will try to connect to and query from.
hosts = localhost
# The user name and password to log into the pgsql server.
user = postfix
password = some_password
# The database name on the servers.
dbname = mailsys
# The SQL query template used to search the database
query = SELECT uid FROM postfix_virtual_uid_map('%u', '%d')

@ -0,0 +1,2 @@
dbpath = /data/freeposte.db
query = SELECT destination FROM aliases WHERE localpart = '%u' AND domain = '%d'

@ -0,0 +1,2 @@
dbpath = /data/freeposte.db
query = SELECT domain FROM domains WHERE domain='%s'

@ -1,8 +1,12 @@
[supervisord]
nodaemon = true
loglevel=debug
[program:postfix]
command = /usr/lib/postfix/master -d
[program:dovecot]
command = /usr/sbin/dovecot -c /etc/dovecot/dovecot.conf -F
[program:rsyslog]
command = rsyslogd -n

Loading…
Cancel
Save