Running email service on my own server!

If u want to follow the procedures below, be sure to replace informations like URL with ur own choice of configuration,

Update Hosts

Verify that the /etc/hosts file contains a line for the server's public IP address and is associated with the Fully Qualified Domain Name (FQDN). In the examples below, the public IP address of my VPS is and the FQDN is It's made for resolving the FQDN in the server locally and u needn't configure another A record for this. localhost mail

Software Installation

I'm using Debian Stretch on my Linode VPS, so I installed from stretch-backports. For backports to work, a line like the following one should be added to the /etc/apt/sources.list:

deb stretch-backports main

The address could be my choice of source containing the backports, what I added before installation is:

deb stretch-backports main

Then I installed the packages using the command:

$ sudo apt -t stretch-backports install postfix-pgsql sasl2-bin libsasl2-modules postgresql libpam-pgsql dovecot-pgsql dovecot-imapd dovecot-pop3d

Configuring PostgreSQL

  1. Edit /etc/postgresql/pg_hba.conf to accept password authentication for localhost:

    host    all         all   password
  2. Create the database:

    $ sudo su postgres
    $ createdb mails
    $ psql mails
  3. Create tables:

    CREATE TABLE transport (
      domain VARCHAR(128) NOT NULL,
      transport VARCHAR(128) NOT NULL,
      PRIMARY KEY (domain)
    CREATE TABLE users (
      userid VARCHAR(128) NOT NULL,
      password VARCHAR(128),
      realname VARCHAR(128),
      home VARCHAR(128),
      mail VARCHAR(255),
      PRIMARY KEY (userid)
    CREATE TABLE virtual (
      address VARCHAR(255) NOT NULL,
      userid VARCHAR(255) NOT NULL,
      PRIMARY KEY (address)
    create view postfix_mailboxes as
      select userid, home||'/' as mailbox from users
      union all
      select domain as userid, 'dummy' as mailbox from transport;
    create view postfix_virtual as
      select userid, userid as address from users
      union all
      select userid, address from virtual;
  4. Create separate users for read and write accesses. Postfix and Dovecot needs only read access. I may want to use the writer user for your own purposes.

    CREATE USER mailreader PASSWORD 'secret';
    grant select on transport, users, virtual, postfix_mailboxes, postfix_virtual to mailreader;
    create user mailwriter password 'secret';
    grant select, insert, update, delete on transport, users, virtual, postfix_mailboxes, postfix_virtual to mailwriter;
  5. Add domain, user to the database. The examples below add the domain and a user with the mail address

    insert into transport (domain, transport) values ('', 'virtual:');
    insert into users (userid, uid, gid, home) values ('', 5000, 5000, '');
    insert into users (userid, uid, gid, home) values ('', 5000, 5000, '');
    insert into virtual (address, userid) values ('', '');
  6. The password for a user can be generated using doveadm utility (do it as a user with permission to use sudo):

    $ sudo doveadm pw -s CRYPT

    It will prompt me to enter the password twice:

    Enter new password: 
    Retype new password:

    Then it will print a encrypted string like the one below for me to write into the database:


    To do something with the password, access the psql utility again:

    $ sudo su postgres
    $ psql mails

    To update an existing user with the password:

    UPDATE users SET password='{CRYPT}1cElWVzS3.EVg' WHERE userid='';

    To set the password when creating the user:

    insert into users (userid, password, uid, gid, home) values ('', '{CRYPT}1cElWVzS3.EVg', 5000, 5000, '');

Create the folder and user for mail

  1. Create /var/mail/vhosts/ and the folder named my domain:

    $ sudo mkdir /var/mail/vhosts
    $ sudo mkdir /var/mail/vhosts/
  2. Create the group and the user for it:

    $ sudo groupadd -g 5000 vmail
    $ sudo useradd -g vmail -u 5000 vmail -d /var/mail
  3. Change the owner of the /var/mail/ folder and its contents to belong to vmail:

    $ sudo chown -R vmail:vmail /var/mail

Configuring Postfix

  1. Edit /etc/postfix/ to include the following lines:

    transport_maps = pgsql:/etc/postfix/
    virtual_uid_maps = pgsql:/etc/postfix/
    virtual_gid_maps = pgsql:/etc/postfix/
    virtual_mailbox_base = /var/mail/vhosts
    virtual_mailbox_maps = pgsql:/etc/postfix/
    virtual_maps = pgsql:/etc/postfix/
    mydestination = $mydomain, $myhostname
    smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination
    smtpd_sasl_auth_enable = yes
    smtpd_sasl_security_options = noanonymous
    smtpd_sasl_local_domain =
    smtp_sasl_auth_enable = no
  2. Edit /etc/postfix/sasl/smtpd.conf to include the following lines:

    pwcheck_method: saslauthd
    saslauthd_path: /etc/mux
  3. /etc/postfix/

  4. /etc/postfix/

  5. /etc/postfix/

  6. /etc/postfix/

  7. /etc/postfix/


Configuring SASL2

  1. Edit /etc/default/saslauthd:

    PARAMS="-r -m /var/spool/postfix/etc"
  2. /etc/pam_pgsql.conf

    database = mails
    host = localhost
    user = mailreader
    password = secret
    table = users
    user_column = userid
    pwd_column = password
    #expired_column = acc_expired
    #newtok_column = acc_new_pwreq
    pw_type = crypt
  3. Create /etc/pam.d/smtp:

    auth        required
    account     required
    password    required
  4. Put the following line to /etc/postfix/sasl/smtpd.conf:

    mech_list: login plain

Configuring Dovecot

  1. Put the following lines in the /etc/dovecot/dovecot.conf:

    mail_location = maildir:~/
    auth default {
        passdb sql {
            args = /usr/local/etc/dovecot-sql.conf
        userdb sql {
            args = /usr/local/etc/dovecot-sql.conf
  2. /usr/local/etc/dovecot-sql.conf

    driver = pgsql
    connect = host=localhost dbname=mails user=mailreader password=secret
    default_pass_scheme = CRYPT
    password_query = SELECT userid as user, password FROM users WHERE userid = '%u'
    user_query = SELECT '/home/'||home AS home, uid, gid FROM users WHERE userid = '%u'
  3. Ensure the following line is included in /etc/dovecot/conf.d/10-auth.conf:

    disable_plaintext_auth = no

    `You probably want to switch this back to "yes" or other options afterward.

Configure DNS

When I'm ready to send and receive mails from my server, I should edit the domain's MX record so it points to the IP address of the server, similar to the examples below: A 10 MX 10

Then I can send and receive from Configuration varies. If I also want to send mails from, my record might look like the examples below: A 10 MX 10 MX 10

Testing Imap

  1. Restart the relevant services before testing:

    sudo systemctl restart saslauthd postgresql postfix dovecot
  2. Install the Mailutils package:

    sudo apt-get install mailutils
  3. Send a test email to an email address outside of my mail server, like a Gmail account.

    echo "Email body text" | sudo mail -s "Email subject line"
  4. Log into the test email account to check whether the mail is received, then send an email back to to check if there's any message:

    sudo mail -f /var/mail/vhosts/
  5. Now test imap using an Email Client like ThunderBird:

    • Username:, the full email address.
    • Password: The one I just set, not the encrypted string. The one before being encrypted.
    • Server name:, or the IP address of the server.
    • SSL: None
    • Port: 143

SMTP Relay

An email sent from a server IP can easily go to Spam Folder, so what I do for SMTP is use an email delivery service.
I'm now using Amazon SES for sending mails. Previously I've used Sendgrid to do it. Both of them perform perfectly. Amazon SES charges $0.10 for every 1,000 emails you send. Sendgrid charges at least $14.95 monthly if u exceed 100/day.
However u'll need request for a sending quota increase to get started with Amazon SES, while u can start with it as soon as u register on Sendgrid.
The documentations below r quite useful if u r using either of the email delivery services. They clarify how to configure the service and integrate it with Postfix and email client.

Some documentations useful for using Sendgrid:

Some documentations useful for using Amazon SES:


  1. HowTo/DovecotPostgresql - Dovecot Wiki
  2. Email with Postfix, Dovecot, and MySQL - Linode
  3. Debian Backports - Instructions
  4. centos - How do I change Dovecot virtual user passwords? - Server Fault
  5. BasicConfiguration - Dovecot Wiki