Setting up mail accounts without real Linux users
Honest advice, use normal user accounts and let your Linux system authenticate the users. This is easy to manage and very secure. I don't want to say that other systems are insecure but I trust my Linux system when it comes to storing and authenticating passwords. I use these commands to create users manually. This way they can do no harm on my system.
useradd -d /home/username -g 515 -u 603 -s /sbin/nologin username
echo 12345678 | passwd user --stdin
-g 515 is your groupid for mail users
-u 603 needs to be incremeted by one for each user you create
This deletes the user
userdel -f username
Then append to the file /etc/postfix/virtual your users as
[email protected] username
This is the part I use in master.cf
submission inet n - n - - smtpd
-o smtpd_helo_required=no
-o smtpd_tls_wrappermode=no
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o smtpd_recipient_restrictions=reject_non_fqdn_recipient,permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
-o smtpd_sasl_type=dovecot
-o smtpd_sasl_path=private/auth
-o smtpd_sasl_security_options=noanonymous
Run the following commands after adding or removing a user
postmap /etc/postfix/virtual
service postfix restart
(The last command may be different on not RHEL clones, e.g. Ubuntu. Not sure, don't use it.). And have in your /etc/postfix/main.cf the following settings
virtual_alias_maps = hash:/etc/postfix/virtual
Don't forget to increase in dovecot the mail_max_userip_connections variable, see Dovecot ignoring maximum number of IMAP connections .
There is several ways to do this. The easiest one however is to have only one software do the authentication - in your case this would be Dovecot as postfix can be configured to use Dovecot SASL for authentication. It is also convenient to only have one software managing directories for emails, so I recommend to use Dovecot as LDA (local delivery agent aka "the software that puts files in directories") instead of letting postfix do this itself.
Below I will show you the relevant parts from my config, keep in mind thogh that those are in no way complete, working configurations. There is no point in posting my complete mail stack config though as your exact needs will likely differ from mine.
I use PostgreSQL as database, however MySQL should work just as well - just make sure to change the driver and also install an matching driver if your dovecot does not ship with one.
From postfix/main.cf
virtual_mailbox_domains = $mydomain, pgsql:/etc/postfix/pgsql_domains.cf
virtual_alias_maps = pgsql:/etc/postfix/pgsql_aliases.cf
virtual_mailbox_maps = pgsql:/etc/postfix/pgsql_mailboxes.cf
######################
### Authentication ###
######################
# Basic
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/dovecot-auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $mydomain
# Allowed Methods
smtpd_tls_auth_only = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_tls_security_options = noanonymous
########################
### Mailbox Settings ###
########################
mail_spool_directory = /srv/mail/localhost/
virtual_mailbox_base = /srv/mail/
mailbox_command = /usr/lib/dovecot/dovecot-lda -f "$SENDER" -a
"$RECIPIENT" -d "$USER"
virtual_transport = dovecot
Make sure to also set your client restrictions to include permit_sasl_authenticated
but exclude other senders for outgoing email to not create an open relay.
content of /etc/postfix/pgsql_domains.cf
hosts = /var/run/postgresql
user = mail
dbname = mail
query = SELECT DISTINCT 1 FROM users WHERE domain='%s';
contents of /etc/postfix/pgsql_aliases.cf
hosts = /var/run/postgresql
user = mail
dbname = mail
query = SELECT email||'@'||domain AS alias FROM users WHERE '%u'='users' AND domain='%d';
contents of /etc/postfix/pgsql_mailboxes.cf
hosts = /var/run/postgresql
user = mail
dbname = mail
query = SELECT 1 FROM email WHERE email='%u' AND domain='%d';
from postfix/master.cf
dovecot unix - n n - - pipe
flags=DRhu user=mail:mail argv=/usr/lib/dovecot/dovecot-lda -f ${sender} -a ${recipient} -d ${user}@${nexthop}
From dovecot config (doesn't matter if you put it in a file that gets included somewhere or directly in the main config):
service auth {
#-- Default Socket
unix_listener auth-userdb {
mode = 0666
user = mail
group = mail
}
#-- Socket for Postfix
unix_listener /var/spool/postfix/private/dovecot-auth {
mode = 0660
user = postfix
group = postfix
}
}
######################
### Authentication ###
######################
passdb {
driver = sql
args = /etc/dovecot/conf.d/sql-login.conf.ext
}
userdb {
driver = sql
args = /etc/dovecot/conf.d/sql-login.conf.ext
}
#########################
### Location Settings ###
#########################
# %u - username
# %n - user part in user@domain, same as %u if there's no domain
# %d - domain part in user@domain, empty if there's no domain
# %h - home directory
mail_home = /srv/mail/%d/%n
mail_location = maildir:~/mai
Adjust /var/spool/postfix to wherever your postfix is chrooted to (if it is, but it should be)
Contents of /etc/dovecot/conf.d/sql-login.conf.ext referenced above:
driver = pgsql
connect = host=/var/run/postgresql/ dbname=mail user=mail
default_pass_scheme = SHA512
password_query = SELECT email as username, domain, password FROM users WHERE email = '%n' AND domain = '%d';
user_query = SELECT email as username, domain FROM users WHERE email = '%n' AND domain = '%d';
iterate_query = SELECT email as username, domain FROM users;
(Make sure to adjust the connection string according to your database host, db name, user and possibly also password)
My database layout:
Table "mail.users"
Column | Type | Modifiers
---------------+---------+---------------
email | text | not null
domain | text | not null
password | text |
Indexes:
"users_pkey" PRIMARY KEY, btree (email, domain)
Keep in mind that those are taken literally from my mail config and might need adjustments and need to be integrated in your current config. This is especially true for dovecot, where your distribution might or might not already have some of the settings in files scattered around your config directory - it is common for dovecot distributions to use a lot of includes.
ALso make sure that inbox folders for users /the config above puts them in /srv/mail) get created and dovecot-lda can write and access all folders. The config above also delivers email of local email users to /srv/mail/localhost for consistency, this is fully optional though and you can deliver them wherever you already have them.
You can do a lot more once you have that setup - configure master users who can login as anybody, configure blocklists for temporarily disabled accounts, configure alias emails, and so on. But what is above should be sufficient to authenticate against a DB and deliver email to virtual user accounts.
[Edit]: I just realized that Postfix DOES need some lookups for email-relaying, specifically for virtual_domain, virtual_alias and virtual_mailbox configurations. I added the relevant parts.