Setting up mail accounts without real Linux users

19,492

Solution 1

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 .

Solution 2

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.

Share:
19,492

Related videos on Youtube

shavit
Author by

shavit

Updated on September 18, 2022

Comments

  • shavit
    shavit over 1 year

    I've setup Postfix and Dovecot on my Ubuntu Server. My aim is to create 27 mail accounts that can receive and send mail to everywhere. I've got emails to not show up as spam in Gmail, Yahoo and Outlook. I send emails with Rainloop and everything is just fine. Except;

    The system shouldn't have so many users. As I'm writing, I have 6 users on this system except for my personal sudo user and the root user. I give people access to receive and send emails by creating Linux users for them and giving them the credentials.

    I can't imagine big email services like Yahoo have over ten million system users, there must be a solution lets me connect Postfix/Dovecot to a database (probably MySQL?) that has all the email users stored in instead of creating so many Linux users.

    So basically, how would I setup what I wrote in the last paragraph without losing existing data? I don't have much received emails on the server, but losing data is bad practice and preventing it is always nice.

    Thanks!

    • Kondybas
      Kondybas almost 8 years
      Virtual users managed with postfixadmin is what you looking for.
    • HBruijn
      HBruijn almost 8 years
      The jargon for that are virtual users, which only exist for mail and not as full user accounts. See for instance wiki.dovecot.org/HowTo
    • shavit
      shavit almost 8 years
      @Kondybas will postfixadmin do what I want for both the IMAP and the SMTP server?
    • symcbean
      symcbean almost 8 years
      Since you have stated you only want to create 27 mail accounts, and not "over ten million" then just creating normal users is probably safer and less effort.
    • Kondybas
      Kondybas almost 8 years
      @shavit You have to setup postfix authentification via dovecot's auth-service then all your user's records will be located in the single place. In case of system users that is usually /etc/master.passwd For virtual users that can be file or some kind of DB. postfix should be configured for user lookup in the same source as dovecot. There is lot of howtos for chain postfix-dovecot-mysql-apache-php-postfixadmin
    • Johannes H.
      Johannes H. about 4 years
      @shavit despite my answer that shows that what you want to achieve is entirely possible, just for the records: just because big email providers can not reasonably work with local linux users doesn't man there has to be a way to connect postfix/dovecot to a DB - because most of these providers do likely not use postfix/dovecot.
  • Laryx Decidua
    Laryx Decidua over 4 years
    Tried on Ubuntu 18.04 LTS, worked. The only change is that the nologin program lives in /usr/sbin, not in sbin. I have added the new e-mail user with the slightly more convenient adduser command instead of useradd, like this: sudo adduser --shell /usr/sbin/nologin --ingroup mail <username>.
  • dortegaoh
    dortegaoh about 4 years
    Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference.