Setting up a mail server in your ArchLinux box

This is my second time writing these notes.  The first time I was about 90% done when I accidentally deleted my whole notes so I may have forgetten to include some key configuration or some detailed steps from my first attempt to write this blog plost.

As I attempted to write these posts, I first looked at three different archwiki tutorials and even though they did provide some insights on what packages I would need as well as how to edit the configuration files, I noticed that the tutorials were out of date and broken.
The best documentation I found on the web was from Ian Barton blog post
A lot of what I will describe here is similar to what you can find in his post but with smaller changes to work with my recent installation of newer packages.
What we will try to accomplish here is to install a virtual mail server that supports secure SMTP through port 465 and secure IMAP with sieve support through port 993.  
Virtual mail server means that we will use mysql server to store the virtual mail user accounts and postfixAdmin to administer the email domains as well as the virutal users associated to the domains in the mysql database.
I will also describe how to install spamassassin and postgrey to filter out incoming spam.
In this post I will assume that the user already has mysql, apache http, and php installed in his server.
The following software will be installed:
  • postfix - server that supports the smtp protocol that is used to send emails
  • dovecot - server that supports the imap protocol that is used by client email applications to connect to the server and retrieve incoming emails to an email account
  • postgrey - filter out incoming email that has been sent to the smtp server more than once in a small period of time
  • spamassassin - scam the contents of emails and filter it out if it is considered spam
  • saslauthd - used by postfix to authenticate user requests to send email
  • cyrus-sasl, cyrus-sasl-sql, pam_mysql - application packages that allows postfix to authenticate vim SASL+PAM
  • pigeonhole - sieve plugin that can be used in conjuction with dovecot to allow email client applications to subscribe to specific imap folders
It is important to run postgrey together with spamassasin because postgrey will filter out most of the spam in an efficient way and leave the rest for spamassassin to analyse. From the Postgrey website:
"When a request for delivery of a mail is received by Postfix via SMTP, the triplet CLIENTIP / SENDER / RECIPIENT is built. If it is the first time that this triplet is seen, or if the triplet was first seen, less than 5 minutes ago, then the mail gets rejected with a temporary error. Hopefully spammers or viruses will not try again later, as it is however required per RFC."


To install all the software needed run the following in the console:
pacman -S postfix doveot spamassassin pigeonhole postgrey cyrus-sasl cyrus-sasl-sql pam_mysql

User Creation

We will create two linux users and groups to support virtual user mailboxes managing in the filesystem and to run spamassassin service. Please run the following commands below as root to create these users:
Virtual mail user account used by dovecot and postfix to access emails in the filesystem
  groupadd -g 5000 vmail

  useradd -u 5000 -g vmail -s /sbin/nologin -d /home/vmail -m vmail

  chmod 750 /home/vmail
Spam assassin user account used to run/access the spamassassin service
  groupadd -g 5001 spamd

  useradd -u 5001 -g spamd -s /sbin/nologin -d /var/lib/spamassassin -m spamd

  chown spamd:spamd /var/lib/spamassassin


Secure Certificate

It is in any user best interest to connect to our server using secure connections to either send or receive emails in his account.  We will therefore create a secure certificate to allow users to authenticate securely.
As you run the commands below please pay attention to the passphrase and the FQDN Common Name question.  The passphrase can be any secure phrase that you do not need to remember after you are done.  The Common Name question needs to be your server name plus its domain (.i.e.
To create the ssl sertificates please run the following as root user:
  cd /etc/ssl/certs

  openssl req -new -x509 -newkey rsa:1024 -days 3650 -keyout mail.key -out mail.crt

  openssl rsa -in mail.key -out mail.key

  chown nobody:nobody mail.key

  chmod 600 mail.key

  mv mail.key /etc/ssl/private/



We will use yaourt to install postfixAdmin.  This will require you to install yaourt from AUR if you have not done so yet.
PostfixAdmin will allow use to setup automatically all the tables in the mysql database to store all the virtual email users/passwords that will have access to emails in the server.
Before we install postfixAdmin we will create a database in my sql with the following commands:
  mysqladmin -u root -p create postfix_db
  mysql -u root -p
In this case:
  'databasename' is the name of your database
  'username@localhost' is the username of your MySQL account
  'your_password' is the password required for that username  
After the database is created we can go ahead and install postfixAdmin with yaourt:
  yaourt --noconfirm -S postfixadmin
Before we can run postfixAdmin in our web browser we will have to change some settings in php.ini and httpd.conf so that the application can run without issues.
 1) In /etc/php/php.ini make sure that magic_quotes_gpc is set to On and is not commented out.
    magic_quotes_gpc = On  
  2) Make sure you have the following directories in open_basedir
    open_basedir = /srv/http/:/home/:/tmp/:/usr/share/pear/:/usr/share/webapps/postfixAdmin/:/etc/webapps/postfixadmin/
  3) And also check that the following mysql extensions are not commented out
  4) In /etc/httpd/conf/httpd.conf add the following directory tags:
    <Directory "/usr/share/webapps/postfixAdmin">
       AllowOverride All
       Options FollowSymlinks
       Order allow,deny
       Allow from all
  5) Add the following line in httpd.conf under the <IfModule alias_module> tag:
    Alias /postfixAdmin "/usr/share/webapps/postfixAdmin"
  6) Edit /usr/share/webapps/postfixAdmin/ as shown below:
    $CONF['configured'] = true;
    $CONF['setup_password'] = ''
    $CONF['database_user'] = 'postfix';
    $CONF['database_password'] = 'your_password';
    $CONF['database_name'] = 'postfix_db';
    $CONF['domain_path'] = 'YES';
    $CONF['domain_in_mailbox'] = 'NO';
    $CONF['maildir_name_hook'] = 'NO';
  7) Restart apache:
rc.d restart httpd
    8) Enter the following in a webbrowser
  9) Create a administrator password through the gui and once done save the encrypted version to /usr/share/webapps/postfixAdmin/ in the following config parameter:
      $CONF['setup_password'] = '<your encrypted password>'


Spamassasin will scan your incoming mails and filtered out any spam before it reaches your inbox. First we will configure the application and second we will update its matching patterns.
 1) Edit /etc/conf.d/spamd file to look something like this:
  SPAMD_OPTS="--create-prefs --max-children 5 --username spamd --helper-home-dir ${SAHOME} -s ${SAHOME}spamd.log --pidfile /var/run/"
 2) Update the matching pattern by running the following:


Postfix will be responsible to sending and receiving emails through smtp protocol on either port 25, 465, or 587.
  • port 25 is not the secure port
  • port 465 is ssl secure port
  • port 587 is used if you use a relay host to send emails through. This is handy if you are setting up postfix in a machne that has a dynamic ip.
Below we will configure postfix to work with spamassasin and postgrey for mail spam filtering and mysql to do user authentication.
Configure the following variables /etc/postfix/
  mail_owner = postfix
  myhostname =
  mydestination = $myhostname, localhost.$mydomain, localhost
  relay_domains = $mydestination
Add the following variables at the end of /etc/postfix/ for virtual user authentication and smtpd authentication:
  # Postfix with MySQL maps (Configure domain emails with Postfix Admin)
  # Virtual Mailbox Domain Settings
  virtual_alias_maps = mysql:/etc/postfix/
  virtual_mailbox_domains = mysql:/etc/postfix/
  virtual_mailbox_maps = mysql:/etc/postfix/
  virtual_mailbox_limit = 51200000
  virtual_minimum_uid = 5000
  virtual_uid_maps = static:5000
  virtual_gid_maps = static:5000
  virtual_mailbox_base = /home/vmail
  virtual_transport = virtual
  # Additional for quota support
  virtual_create_maildirsize = yes
  virtual_mailbox_extended = yes
  virtual_mailbox_limit_maps = mysql:/etc/postfix/
  virtual_mailbox_limit_override = yes
  virtual_maildir_limit_message = Sorry, your maildir has overdrawn your diskspace quota, please free up some space and try again.
  virtual_overquota_bounce = yes
  smtpd_sasl_auth_enable = yes
  #postgrey service listens on port 10030
  smtpd_recipient_restrictions =  permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, 
  reject_invalid_hostname, reject_unauth_pipelining, reject_unknown_sender_domain, reject_rbl_client,
  reject_rbl_client, reject_rbl_client, check_policy_service inet:
  smtpd_sasl_security_options = noanonymous
  smtpd_sasl_tls_security_options = $smtpd_sasl_security_options
  smtpd_tls_auth_only = yes
  smtpd_tls_cert_file = /etc/ssl/certs/mail.crt
  smtpd_tls_key_file = /etc/ssl/private/mail.key
  smtpd_sasl_local_domain = $mydomain
  broken_sasl_auth_clients = yes
  smtpd_tls_loglevel = 1
The following postfix maps needs to be created to allow postfix to interface with the postfix_db tables that we created via postfixAdmin.  These tables will contain domain, alias, domain_alias, mailbox, and quota information that are needed for postfix to administer its users email content, location to store the in/out emails, email quota, and where to send it.
1) Create a file called /etc/postfix/ with the following contents:
  user = postfix
  password = your_password
  hosts = localhost
  dbname = postfix_db
  table = alias
  select_field = goto
  where_field = address
2) Create a file called /etc/postfix/ with the following contents:  
  user = postfix
  password = your_password
  hosts = localhost
  dbname = postfix_db
  table = domain
  select_field = domain
  where_field = domain
  additional_conditions = and backupmx = '0' and active = '1'
3) Create a file called /etc/postfix/ with the following contents:    
  user = postfix
  password = your_password
  hosts = localhost
  dbname = postfix_db
  table = mailbox
  select_field = maildir
  where_field = username
  additional_conditions = and active = '1'
4) Create a file called /etc/postfix/ with the following contents:    
  user = postfix
  password = your_password
  hosts = localhost
  dbname = postfix_db
  table = mailbox
  select_field = quota
  where_field = username
  additional_conditions = and active = '1'
5) Give the right permissions for the map files:
  chgrp postfix /etc/postfix/mysql_*.cf
  chmod 640 /etc/postfix/mysql_*.cf
Configure to send and receive emails and to pipe mail through spamassasin by editing /etc/postfix/
  Replace this line
    smtp      inet  n       -       n       -       -       smtpd
  with this line
    smtp      inet  n       -       n       -       -       smtpd -o content_filter=spamassassin
  Add the following line before smtps inet n ... line:
    465 inet n - n - - smtpd -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes
  Add this at the end:
    dovecot   unix  -       n       n       -       -       pipe flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -d ${recipient}
    spamassassin unix -     n       n       -       -       pipe  user=spamd argv=/usr/bin/vendor_perl/spamc -f -e   /usr/sbin/sendmail -oi -f ${sender} ${recipient}


The setup described above to send email via postfix uses SMTPS(SSL on port 465) using SASL+PAM to authenticate with the mysql database.  Ideally, you should use postfix to relay email via your ISP provider if you have a dynamic ip on your server.  Most of the big mail hosts will not accept a connection from a dynamic ip smtp host and your outbound emails will bounce back.
If you do not use dynamic ip and you are using the postfix configuration described above then the following needs to be done to do the SMTP-AUTH via SASL+PAM.
Edit the /etc/pam.d/smpt to have the following contents:
  SASLAUTHD_OPTS="-m /var/run/saslauthd -r -a pam"
Edit/Create the following file /usr/lib/sasl2/smtpd.conf to have the following contents:
  pwcheck_method: saslauthd
  mech_list: plain login
  saslauthd_path: /var/run/saslauthd/mux
  log_level: 7

Configure Dovecot to serve email to your email client applications via secure IMAP and sieve

1) Edit /etc/dovecot/dovecont.conf with the following contents:
  protocols = imap sieve
  ssl = yes
  ssl_cert = </etc/ssl/certs/mail.crt
  ssl_key = </etc/ssl/private/mail.key
  first_valid_uid = 5000
  first_valid_gid = 5000
  auth_username_chars = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@
  namespace {
    separator = .
    type = private
    prefix = INBOX.
    inbox = yes
    #hidden = yes
    location = maildir:/home/vmail/%d/%n
  service auth {
      unix_listener auth-userdb {
 mode = 0600
 user = vmail # User running dovecot-lda
 #group = vmail # Or alternatively mode 0660 + dovecot-lda user in this group
  passdb  {
      args = /etc/dovecot/dovecot-sql.conf
  #userdb  {
  #    driver=static
  #    args = uid=5000 gid=5000 home=/home/vmail/%d/%n allow_all_users=yes
  protocol imap {
    imap_client_workarounds = delay-newmail tb-extra-mailbox-sep
  protocol lda {
  postmaster_address =
  hostname =
  sendmail_path = /usr/sbin/sendmail
  mail_plugins = $mail_plugins sieve
  log_path = /var/log/dovecot-lda-errors.log
  info_log_path = /var/log/dovecot-lda.log
  protocol sieve {
  # Defaults are OK, so nothing in this section.
  plugin {
    sieve = ~/.dovecot.sieve
    sieve_global_path = /home/vmail/globalsieverc
    sieve_dir = ~/
  #passdb {
  #   driver = sql
  #   args = /etc/dovecot/dovecot-sql.conf
  userdb {
    driver = sql
    args = /etc/dovecot/dovecot-sql.conf
2) Edit /etc/dovecot/dovecot-sql.conf
  driver = mysql
  connect = host=localhost dbname=postfix_db user=postfix password=your_password
  default_pass_scheme = CRYPT
  user_query = SELECT maildir AS mail, 5000 AS uid, 5000 AS gid, "/home/vmail/%d/%n" AS home FROM mailbox WHERE username = '%u' AND active = '1'
  password_query = SELECT password FROM mailbox WHERE username = '%u' AND active = '1'                                                                                   
Here is a definition of the special variables being used in the config file above for dovecot:
  • %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 
The following ports needs to be opened in your firewall or need to be forwarding traffic to your server:
  • 80  - HTTP
  • 443 - Secure HTTP (HTTPS)
  • 143 - IMAP
  • 585 - Secure IMAP (IMAP4-SSL)
  • 993 - IMAP over SSL (IMAPS)
  • 110 - POP3
  • 995 - Secure POP3 (SSL-POP)
  • 25  - SMTP
  • 465 - Secure SMTP (SSMTP)
  • 587 - Secure SMTP for Email submission

Run the services

  rc.d restart httpd

  rc.d start spamd

  rc.d start postgrey

  rc.d start saslauthd

  rc.d start postfix

  rc.d start dovecot


Go to and create a domain and add users to the domain
Test that postfix is working by telnet to your localhost on port 25.  If you do not have telnet installed then install i using the following command:
pacman -S inetutils
Test postfix with the following:
telnet localhost 25


mail from: root@localhost

rcpt to:


Subject: Test

This is a test email


Test Dovecot is working by using gnutls-cli command
gnutls-cli --starttls -p 4190 
It will print the following on the screen
  Processed 152 CA certificate(s).
  Resolving ''...
  Connecting to 'XXX.XX.XXX.XX:4190'...
  - Simple Client Mode:                                                                                                  
  "IMPLEMENTATION" "Dovecot Pigeonhole"                                                                                  
  "SIEVE" "fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date ihave"                                            
  "NOTIFY" "mailto"                                                                                                      
  "SASL" ""                                                                                                              
  "VERSION" "1.0"                                                                                                        
  OK "Dovecot ready."
Now type the following :
It will print the following
  OK "Begin TLS negotiation now."


Sending emails through a relay host on postfix

1) In your /etc/postfix/ configuration file for postfix, add the following smtp variables for sending out emails using a gmail as a relay host:
  # sets gmail or centurylink as relay  
  relayhost = []:587
  #relayhost = []:587
  #  use tls
  # use sasl when authenticating to foreign SMTP servers
  smtp_sasl_auth_enable = yes 
  # path to password map file
  smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
  # list of CAs to trust when verifying server certificate
  smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
  # eliminates default security options which are incompatible with gmail
  smtp_sasl_security_options =
2) Create a file /etc/postfix/sasl_passwd and add your gmail account
3) Run the foolowing command to create a postfix lookup table for your credentials
postmap /etc/postfix/sasl_passwd
4) Remove the plain password file for gmail and change the permissions for sasl_passwd.db
  rm /etc/postfix/sasl_passwd

  chmod 600 /etc/postfix/sasl_passwd.db
5) Restart postfix
rc.d restart postfix
6)Make sure you have an MX record in your DNS service provider pointing to an A record that points to your server. 
Domain name:
Record FQDN        Record Type      Record Value                     MX Pref  A                          XXX.XXX.XXX.XXX          MX                           10          A                           XXX.XXX.XXX.XXX


In your desktop when adding the account to connect to your mail server via IMAP you will have to enter the  username as the full account name including the domain. 
I would recommend using your ISP provider instead of gmail because google will overwrite the email from field with your gmail account whereas you ISP provider relay host may not do that.
If you can not receive email from external accounts it probably means that your ISP provider as the majority of the providers out there blocks port 25.  You will have to call your ISP provider and ask them to turn port 25 filtering off.  I had to call my ISP provider and I asked them to turn port 25 filtering off.  They said they were sorry that I was having problems with port 25 and they quickly in less than 15 minutes turn off filtering off on port 25.



No votes yet