Table of Content
- Requirements
- Goal
- Mail-Server
- Vmail User
- Dovecot
- Configuration
- /etc/dovecot/dovecot.conf
- /etc/dovecot/conf.d/10-ssl.conf
- /etc/dovecot/conf.d/10-mail.conf
- /etc/dovecot/conf.d/10-master.conf
- /etc/dovecot/conf.d/20-managesieve.conf
- /etc/dovecot/conf.d/20-imap.conf
- /etc/dovecot/conf.d/20-lmtp.conf
- /etc/dovecot/conf.d/auth-sql.conf
- /etc/dovecot/conf.d/15-mailboxes.conf
- /etc/dovecot/conf.d/90-sieve.conf
- /etc/dovecot/dovecot-sql.conf
- Global Sieve Filter Script for Spam Detection
- Configuration
- Postfix - Installation and Configuration
- Mail-Queue Settings
- TLS Settings
- Local mail delivery using Dovecot
- Spam-filter and DKIM-Sig via Rspamd
- Server Restrictions for clients, receiver and relaying
- Settings, Postfix as Relay (for clients)
- Bedingungen, damit Postfix ankommende E-Mails als Empfängerserver entgegennimmt (zusätzlich zu relay-Bedingungen)
- check_recipient_access prüft, ob ein account sendonly ist
- Bedingungen, die SMTP-Clients erfüllen müssen (sendende Server)
- Wenn fremde Server eine Verbindung herstellen, müssen sie einen gültigen Hostnamen im HELO haben.
- Clients blockieren, wenn sie versuchen zu früh zu senden
- Verbindungen beenden, wenn der fremde Server es zu eilig hat
- {:.} DNS blocklists- MySQL Abfragen
- Sonstiges
- Maximale Größe der gesamten Mailbox (soll von Dovecot festgelegt werden, 0 = unbegrenzt)
- Maximale Größe eingehender E-Mails in Bytes (50 MB)
- Keine System-Benachrichtigung für Benutzer bei neuer E-Mail
- Nutzer müssen immer volle E-Mail Adresse angeben - nicht nur Hostname
- Trenn-Zeichen für “Address Tagging”
I use a very good and detailed guide created by Thomas Leister.
Since I have a Gentoo Linux running I want to explain within this article how you can use this guide for Gentoo Linux.
Therefore, please read this guide first to get an overview of all the stuff.
Requirements
You have to had a are running a Gentoo Linux with working internet connection and you must be root
.
Goal
At the end we will have a running Gentoo Server with:
- Dovecot
- Postfix
- MySQL
- Rspamd
- Postfix-Admin
Mail-Server
Certifications
emerge -av app-crypt/certbot
emerge -av app-crypt/certbot-nginx
Database
We will use MariaDB as Database (https://wiki.gentoo.org/wiki/MariaDB):
If you do not have mariadb installed already you have to configure it, therefore, we can use a predefined configuration helper:
emerge -av --config dev-db/mariadb
Start database and add them to your autostart:
rc-update add mysql default
rc-service mysql start
Open MySQL Root Shell to perform SQL commands:
mysql -u root -p -h localhost
The first step is to create a database for our mail-service, called vmail
:
create database vmail CHARACTER SET 'utf8';
Create a user who can access the database using vmaildbpass
as password (please use a secure one):
grant select on vmail.* to 'vmail'@'localhost' identified by 'vmaildbpass';
Next step we have to use our database vmail
:
use vmail;
** CHECK IF YOU NEED THIS … SINCE WE WILL USE POSTFIX-ADMIN **
Our Mail-setup will use 4 different tables. Therefore, we have to create them:
Domain Table
CREATE TABLE `domains` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`domain` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY (`domain`)
);
Account Table
CREATE TABLE `accounts` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(64) NOT NULL,
`domain` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`quota` int unsigned DEFAULT '0',
`enabled` boolean DEFAULT '0',
`sendonly` boolean DEFAULT '0',
PRIMARY KEY (id),
UNIQUE KEY (`username`, `domain`),
FOREIGN KEY (`domain`) REFERENCES `domains` (`domain`)
);
Alias Table
CREATE TABLE `aliases` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`source_username` varchar(64) NOT NULL,
`source_domain` varchar(255) NOT NULL,
`destination_username` varchar(64) NOT NULL,
`destination_domain` varchar(255) NOT NULL,
`enabled` boolean DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY (`source_username`, `source_domain`, `destination_username`, `destination_domain`),
FOREIGN KEY (`source_domain`) REFERENCES `domains` (`domain`)
);
TLS Policy-Tabelle
CREATE TABLE `tlspolicies` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`domain` varchar(255) NOT NULL,
`policy` enum('none', 'may', 'encrypt', 'dane', 'dane-only', 'fingerprint', 'verify', 'secure') NOT NULL,
`params` varchar(255),
PRIMARY KEY (`id`),
UNIQUE KEY (`domain`)
);
Vmail User
We will use /home/vmail
as mail-server file storage directory (mailboxes, filter-scripts, …):
mkdir /home/vmail
vmail-Systembenutzer erstellen:
useradd --shell /usr/sbin/nologin -d /home/vmail vmail
vmail Unterverzeichnisse erstellen:
mkdir /home/vmail/mailboxes
mkdir -p /home/vmail/sieve/global
/var/vmail an vmail-User übereignen und Verzeichnisrechte passend setzen:
chown -R vmail:vmail /home/vmail
chmod -R 770 /home/vmail
Dovecot
emerge -av net-mail/dovecot
Please ensure that at least the following USE-flags are enabled.
net-mail/dovecot USE="bzip2 ipv6 managesieve mysql pam sieve ssl tcpd zlib"
Configuration
All configuration files are located at /etc/dovecot/
.
/etc/dovecot/dovecot.conf
protocols = imap lmtp sieve
/etc/dovecot/conf.d/10-ssl.conf
# SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt>
ssl = required
# PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
# dropping root privileges, so keep the key file unreadable by anyone but
# root. Included doc/mkcert.sh can be used to easily generate self-signed
# certificate, just make sure to update the domains in dovecot-openssl.cnf
ssl_cert = /etc/letsencrypt/live/YOUR.MAIL.DOMAIN/fullchain.pem
ssl_key = /etc/letsencrypt/live/YOUR.MAIL.DOMAIN/privkey.pem
# SSL ciphers to use
# ###############
# Added by Gentoo
# You are encouraged to change the cipher list to
#ssl_cipher_list = DEFAULT:!EXPORT:!LOW:!MEDIUM:!MD5
# if you are not required to support legacy mail clients.
# ###############
ssl_cipher_list = ALL:!LOW:!SSLv2:!EXP:!aNULL
/etc/dovecot/conf.d/10-mail.conf
If you want maildirs to use hierarchical directories, such as:
- Maildir/folder/
- Maildir/folder/subfolder/
Therefore, we have to addLAYOUT=fs
:
mail_home = /home/vmail/%d/%n
mail_location = maildir:~/Maildir:LAYOUT=fs
/etc/dovecot/conf.d/10-master.conf
service imap-login {
inet_listener imap {
port = 143
}
inet_listener imaps {
#port = 993
#ssl = yes
}
# Number of connections to handle before starting a new process. Typically
# the only useful values are 0 (unlimited) or 1. 1 is more secure, but 0
# is faster. <doc/wiki/LoginProcess.txt>
#service_count = 1
# Number of processes to always keep waiting for more connections.
#process_min_avail = 0
# If you set service_count=0, you probably need to grow this.
#vsz_limit = $default_vsz_limit
}
/etc/dovecot/conf.d/20-managesieve.conf
service managesieve-login {
inet_listener sieve {
port = 4190
}
}
/etc/dovecot/conf.d/20-imap.conf
protocol imap {
# Space separated list of plugins to load (default is global mail_plugins).
mail_plugins = $mail_plugins quota imap_quota imap_sieve
# Maximum number of IMAP connections allowed for a user from each IP address.
# NOTE: The username is compared case-sensitively.
mail_max_userip_connections = 20
imap_idle_notify_interval = 29 mins
}
/etc/dovecot/conf.d/20-lmtp.conf
protocol lmtp {
# Space separated list of plugins to load (default is global mail_plugins).
postmaster_address = postmaster@YOUR.MAIL.DOMAIN
mail_plugins = $mail_plugins sieve
}
/etc/dovecot/conf.d/auth-sql.conf
# Authentication for SQL users. Included from 10-auth.conf.
#
# <doc/wiki/AuthDatabase.SQL.txt>
passdb {
driver = sql
# Path for SQL configuration file, see example-config/dovecot-sql.conf.ext
args = /etc/dovecot/dovecot-sql.conf
}
# "prefetch" user database means that the passdb already provided the
# needed information and there's no need to do a separate userdb lookup.
# <doc/wiki/UserDatabase.Prefetch.txt>
#userdb {
# driver = prefetch
#}
userdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf
}
/etc/dovecot/conf.d/15-mailboxes.conf
namespace inbox {
inbox = yes
# These mailboxes are widely used and could perhaps be created automatically:
mailbox Drafts {
auto = subscribe
special_use = \Drafts
}
mailbox Junk {
auto = subscribe
special_use = \Junk
}
mailbox Trash {
auto = subscribe
special_use = \Trash
}
# For \Sent mailboxes there are two widely used names. We'll mark both of
# them as \Sent. User typically deletes one of them if duplicates are created.
mailbox Sent {
auto = subscribe
special_use = \Sent
}
mailbox "Sent Messages" {
special_use = \Sent
}
}
/etc/dovecot/conf.d/90-sieve.conf
###
### Spam learning
###
# From elsewhere to Spam folder
imapsieve_mailbox1_name = Spam
imapsieve_mailbox1_causes = COPY
imapsieve_mailbox1_before = file:/var/vmail/sieve/global/learn-spam.sieve
# From Spam folder to elsewhere
imapsieve_mailbox2_name = *
imapsieve_mailbox2_from = Spam
imapsieve_mailbox2_causes = COPY
imapsieve_mailbox2_before = file:/var/vmail/sieve/global/learn-ham.sieve
sieve_pipe_bin_dir = /usr/bin
sieve_global_extensions = +vnd.dovecot.pipe
quota = maildir:User quota
quota_exceeded_message = Benutzer %u hat das Speichervolumen überschritten. / User %u has exhausted allowed storage space.
/etc/dovecot/dovecot-sql.conf
driver=mysql
connect = "host=127.0.0.1 dbname=vmail user=vmail password=vmaildbpass"
default_pass_scheme = SHA512-CRYPT
password_query = SELECT username AS user, domain, password FROM accounts WHERE username = '%n' AND domain = '%d' and enabled = true;
user_query = SELECT concat('*:storage=', quota, 'M') AS quota_rule FROM accounts WHERE username = '%n' AND domain = '%d' AND sendonly = false;
iterate_query = SELECT username, domain FROM accounts where sendonly = false;
Since dovecot-sql.conf
contains sensitive data we secure the file:
chmod 440 dovecot-sql.conf
Global Sieve Filter Script for Spam Detection
Create the file /home/vmail/sieve/global/spam-global.sieve
:
require "fileinto";
if header :contains "X-Spam-Flag" "YES" {
fileinto "Spam";
}
if header :is "X-Spam" "Yes" {
fileinto "Spam";
}
This script will move all emails taged with Spam-Flag header into Spam
the folder.
Scripts for Spam Improvement (Rspamd)
/home/vmail/sieve/global/learn-spam.sieve
require ["vnd.dovecot.pipe", "copy", "imapsieve"];
pipe :copy "rspamc" ["learn_spam"];
/home/vmail/sieve/global/learn-ham.sieve
require ["vnd.dovecot.pipe", "copy", "imapsieve"];
pipe :copy "rspamc" ["learn_ham"];
Compile Sieve files: will generate *.svbin files
sievec FILE.sieve
Postfix - Installation and Configuration
emerge -av mail-mta/postfix
Ensure you have the use flag mysql
enabled.
Mail-Queue Settings
maximal_queue_lifetime = 1h
bounce_queue_lifetime = 1h
maximal_backoff_time = 15m
minimal_backoff_time = 5m
queue_run_delay = 5m
TLS Settings
tls_preempt_cipherlist = yes
tls_ssl_options = NO_COMPRESSION
tls_high_cipherlist = EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES128-SHA
Outgoing SMTP-Connections (Postfix as sender)
smtp_tls_security_level = dane
smtp_dns_support_level = dnssec
smtp_tls_policy_maps = mysql:/etc/postfix/sql/tls-policy.cf
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_tls_protocols = !SSLv2, !SSLv3
smtp_tls_ciphers = high
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
Incoming SMTP-Connections
smtpd_tls_security_level = may
smtpd_tls_protocols = !SSLv2, !SSLv3
smtpd_tls_ciphers = high
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtpd_tls_cert_file=/etc/letsencrypt/live/mail.mysystems.tld/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/mail.mysystems.tld/privkey.pem
Local mail delivery using Dovecot
virtual_transport = lmtp:unix:private/dovecot-lmtp
Spam-filter and DKIM-Sig via Rspamd
smtpd_milters = inet:localhost:11332
non_smtpd_milters = inet:localhost:11332
milter_protocol = 6
milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}
milter_default_action = accept
Server Restrictions for clients, receiver and relaying
Settings, Postfix as Relay (for clients)
smtpd_relay_restrictions = reject_non_fqdn_recipient
reject_unknown_recipient_domain
permit_mynetworks
reject_unauth_destination
Bedingungen, damit Postfix ankommende E-Mails als Empfängerserver entgegennimmt (zusätzlich zu relay-Bedingungen)
check_recipient_access prüft, ob ein account sendonly ist
smtpd_recipient_restrictions = check_recipient_access mysql:/etc/postfix/sql/recipient-access.cf
Bedingungen, die SMTP-Clients erfüllen müssen (sendende Server)
smtpd_client_restrictions = permit_mynetworks
check_client_access hash:/etc/postfix/without_ptr
reject_unknown_client_hostname
Wenn fremde Server eine Verbindung herstellen, müssen sie einen gültigen Hostnamen im HELO haben.
smtpd_helo_required = yes
smtpd_helo_restrictions = permit_mynetworks
reject_invalid_helo_hostname
reject_non_fqdn_helo_hostname
reject_unknown_helo_hostname
Clients blockieren, wenn sie versuchen zu früh zu senden
smtpd_data_restrictions = reject_unauth_pipelining
Restrictions für MUAs (Mail user agents)
mua_relay_restrictions = reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_mynetworks,permit_sasl_authenticated,reject
mua_sender_restrictions = permit_mynetworks,reject_non_fqdn_sender,reject_sender_login_mismatch,permit_sasl_authenticated,reject
mua_client_restrictions = permit_mynetworks,permit_sasl_authenticated,reject
Postscreen Filter
Postscreen Whitelist / Blocklist
postscreen_access_list = permit_mynetworks
cidr:/etc/postfix/postscreen_access
postscreen_blacklist_action = drop
Verbindungen beenden, wenn der fremde Server es zu eilig hat
postscreen_greet_action = drop
DNS blocklists
postscreen_dnsbl_threshold = 2
postscreen_dnsbl_sites = ix.dnsbl.manitu.net*2
zen.spamhaus.org*2
postscreen_dnsbl_action = drop
MySQL Abfragen
virtual_alias_maps = mysql:/etc/postfix/sql/aliases.cf
virtual_mailbox_maps = mysql:/etc/postfix/sql/accounts.cf
virtual_mailbox_domains = mysql:/etc/postfix/sql/domains.cf
local_recipient_maps = $virtual_mailbox_maps
Sonstiges
Maximale Größe der gesamten Mailbox (soll von Dovecot festgelegt werden, 0 = unbegrenzt)
mailbox_size_limit = 0
Maximale Größe eingehender E-Mails in Bytes (50 MB)
message_size_limit = 52428800
Keine System-Benachrichtigung für Benutzer bei neuer E-Mail
biff = no
Nutzer müssen immer volle E-Mail Adresse angeben - nicht nur Hostname
append_dot_mydomain = no
Trenn-Zeichen für “Address Tagging”
recipient_delimiter = +