Setting Up Email Servers - Part 3
──────────────────────────────────────────────────────────────────────────────────
Introduction
Welcome to the third part of the Setting Up Email Servers series. In this part, we will go over setting up an email server on Linux.
We will be using Postfix as our Mail Transfer Agent (MTA), Dovecot as our Mail Delivery Agent (MDA), and Roundcube as our webmail client, with Apache as the web server and MariaDB as the backend database.
If you have been following along, you should have a basic understanding of how email servers work and be comfortable with making command-line configuration changes.
For now, we will stick to local authentication, but we will be exploring various configuration options and security considerations in future iterations of this series.
__
- Postfix is a free and open-source mail transfer agent (MTA) that routes and delivers electronic mail. It is Wietse Venema's mail server that started life at IBM research as an alternative to the widely-used Sendmail program. Now at Google, Wietse continues to support Postfix.
- Dovecot is an open-source IMAP and POP3 server for Unix-like operating systems, written primarily with security in mind. Dovecot is an excellent choice for both small and large installations. It's fast, simple to set up, requires no special administration, and it uses very little memory.
- Roundcube is a web-based IMAP email client. Roundcube's most prominent feature is the pervasive use of Ajax technology. It was one of the first webmail services to use the technology, and it was one of the first to offer a user interface that was more like a desktop application than a traditional web application.
- Apache is a free and open-source cross-platform web server software. Apache is developed and maintained by an open community of developers under the auspices of the Apache Software Foundation.
- MariaDB is a community-developed, commercially supported fork of the MySQL relational database management system (RDBMS), intended to remain free and open-source software under the GNU General Public License. Development is led by some of the original developers of MySQL, who forked it due to concerns over its acquisition by Oracle Corporation.
Below is a diagram illustration of how all of these different email components come together

──────────────────────────────────────────────────────────────────────────────────
Prerequisites
Before we begin, you will need to have a server running a Linux distribution. This guide follows both RHEL-based and Debian-based OSes, any other type, youll have to figure out on your own. You will also need to have a domain name and a server with a static IP address. For the purposes of this tutorial, the domain can be whatever you wish. You will also need to have a basic understanding of how to use the command line and be comfortable with making configuration changes.
Note, there are a few things on a freshly installed machine that may pose a bit of an issue later down the line:
SELinux should be disabled or, figure out those exceptions manually (vi /etc/selinux/config) prior to starting.
Also, sendmail (another MTA) is likely to be installed by default on your OS (and will take precedence over Postfix), so make sure it is disabled (systemctl disable sendmail).
Downloads
RHEL-type OS
yum install postfix dovecot
yum install roundcubemail httpd php php-common php-json php-xml php-mbstring php-imap php-pear-DB php-mysql mysql mysql-server (mod_nss or mod_ssl for HTTPS)
dnf -y install mariadb-server php-mysqlnd
Debian type OS
apt-get install postfix dovecot-pop3d dovecot-imapd php5 mysql-server php5-mysql
#This is intended for Debian 8/ Ubuntu 15, if you are using a newer OS go w that and use php7
wget github.com/roundcube/roundcubemail/releases/download/1.3.14/roundcubemail-1.3.14-complete.tar.gz
tar -zxvf roundcubemail-1.3.14-complete.tar.gz
#may have to apt-get install -f
mv roundcubemail-1.3.13-complete /var/www/html/roundcube
──────────────────────────────────────────────────────────────────────────────────
Postfix MTA
Postfix is a type of MTA that supports the transport of messages across servers. Reference
Supporting Command Reference
mailq/postqueue #views the contents of the Postfix queue (size | time of arrival | sender addr | rcpt addr )
newaliases/postalias #rebuilds local alias/email mapping files (ones stored on the pc)
postconf #shows Postfix’s configuration values(can also be used to modify it & check for errors)
postfix #the service name to start/stop/restart Postfix
postmap #rebuilds an indexed database file used for table lookups/queries any lookup table. Used for debugging purposes.
postqueue #also used to flush the queue (immediately deliver all messages)
postsuper #delete or requeue already sent items, and can perform structural checks on queue directions
Security-Related Information
- in most cases, mail delivery does not require a shell
- most processes are executed by a master daemon
- and do not run as a user child process
- does not used fixed-size buffers
- can chroot postfix**
Defaults
#Directories
/etc/postfix #Configuration files and lookup tables
/usr/libexec/postfix #Postfix daemons
/var/spool/postfix #Queue files
/usr/sbin #Postfix commands
#Users
postfix = user
postdrop = group
Local Authentication
Configure
vi /etc/postfix/main.cf
myhostname = .
mydomain =
myorigin = $mydomain
inet_interfaces = all
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
mynetworks = /,127.0.0.0/8
home_mailbox = Maildir/ or Mail
#relayhost = if you have to go through an ISP >> don’t actually worry eh
#Mailbox Creation* (only in older versions)
mkdir /home//Mail
chown : /home//Mail
chmod -R 700 /home//Mail
postalias /etc/aliases
Start/Restart Postfix
systemctl start postfix #you cant reload, b/c inet_interfaces was likely changed from default of loopback
systemctl restart postfix
Test Connectivity
telnet localhost 25
ehlo localhost
mail from: @
rcpt to: @
data
.
quit
See if the mail was actually sent
mail
──────────────────────────────────────────────────────────────────────────────────
Dovecot MDA - IMAP/POP3
Local Authentication
Configure
vi /etc/dovecot/dovecot.conf
protocols = imap pop3 (lmtp for local mail transfer)
vi /etc/dovecot/conf.d/10-mail.conf
mail_location = maildir:~/Mail
vi /etc/dovecot/conf.d/10-auth.conf
disable_plaintext_auth = no #ref ssl
auth_mechanisms = plain login
vi /etc/dovecot/conf.d/10-master.conf
unix_listener auth-userdb {
#mode
user = postfix
group = postfix
}
Start/Restart Dovecot
systemctl start dovecot
systemctl status dovecot
Test Connection
#TEST POP3
telnet localhost 110
user
pass
list
retr <#>
quit
#TEST IMAP
telnet localhost 143
a1 LOGIN
a2 LOGOUT
OPTIONAL >> Aliases
vi /etc/aliases
test1: test #mail sent to test1 will go to test
test66: test
vi /etc/postfix/main.cf
virtual_alias_domains = domain1.example.com, domain2.example.com
──────────────────────────────────────────────────────────────────────────────────
PHP
Test if install works
vi /var/www/html/index.php
navigate to localhost and see if this works:
http://localhost/index.php
then remove the test file
rm -f /var/www/html/index.php
Configure PHP Settings
RHEL type OS:
vi /etc/php.ini
date.timezone = America/Chicago #or UTC
extension=mysql.so
systemctl start httpd
systemctl status httpd #make sure its running
systemctl enable httpd
chown -R apache:apache /var/www/html
Debian type OS
vi /etc/php5/apache2/php.ini
date.timezone = America/Chicago #or UTC
extension=mysql.so
systemctl start apache2
systemctl status apache2 #make sure its running
chown -R www-data:www-data /var/www/html
──────────────────────────────────────────────────────────────────────────────────
MySQL
systemctl start mysql/d #or mariadb
Debian type OS
#create database
mysql --defaults-file=/etc/mysql/debian.cnf
create database roundcubemail;
create user roundcube;
grant all privileges on roundcubemail.* to roundcube@localhost identified by 'your password';
flush privileges;
use roundcubemail;
quit #or exit;
#if the above doesnt work, use this method to set the password:
FOR 'roundcubemail'@'localhost' = PASSWORD('newpassword');
RHEL type OS
mysql -u root -p
create database roundcubemail;
create user roundcube;
grant all privileges on roundcubemail.* to roundcube@localhost identified by 'your password';
flush privileges;
use roundcubemail;
quit #or exit;
#inititalize database
mysql -u root -p roundcubemail < /usr/share/roundcubemail/SQL/mysql.initial.sql
──────────────────────────────────────────────────────────────────────────────────
Roundcube (WebApp)
Install (With A GUI)
Navigate tohttp://localhost/roundcubemail/installer
Step 1 - Check preqs
Step 2 - Configure
make sure you add the password to the database conf. that’s all you have to do but you should probably specify a hostname and domain instead of localhost
download the conf file in step 2 and move it to /var/www/html/roundcube/config/config.inc.phpStep 3
Test your configuration if you are unsure, but you don’t actually have to do this.Step 4 - Edit Configuration Files
vi /etc/roundcubemail/db.inc.php
$rcmail_config['db_dsnw'] = 'mysql://
roundcube:password@localhost/roundcubemail';
OR
vi /var/www/html/roundcube/config.inc.php
$config[‘db_dsnw’] = 'mysql://roundcube:password@localhost/roundcubemail';
Step 5 - Acquire Mail
http://localhost/roundcubemail
*If you cant login >>
vi /var/www/html/roundcube/config/config.inc.php
[type] /username_domain
and comment that line out
──────────────────────────────────────────────────────────────────────────────────
Troubleshooting
Postfix
postconf -n # to see current settings
postconf -d # to see default values
#what errors?
systemctl status postfix
tail /var/log/maillog
#resolve config errors
postfix check
postfconf 1> /dev/null
#check directory permissions
chattr -R -i /var/log/
chattr -R -i /etc/postfix/
ls -l /var/log && ls -l /etc/postfix
#check the firewall logs for dropped SMTP traffic
vi /var/log/messages | grep ‘:drop_log:’
#monitor smtp traffic
tcpdump -w /file/name -s 0 host example.com and port 25
tcpdump -i -vv -x -X -s 1500 -i ‘port 25’ #Verbose Output for SMTP
#get very verbose log output
vi /etc/postfix/master.cf:
smtp inet n - n - - smtpd -v
postfix reload
#if connected to ldap -
postmap -q user@domain.com ldap:/path/to/ldap/conf
#find networks
cat /etc/postfix/main.cf | grep “mynetworks”
cat /etc/postfix/main.cf | grep “mydomain”
Dovecot
dovecot -n #to see current settings
dovecot -n -c /etc/dovecot/dovecot.conf #to see current settings
dovecot -n -c /etc/dovecot/dovecot.conf | grep -i ‘ssl’ #to see current settings
dovecot -n -c /etc/dovecot/dovecot.conf | grep -i ‘auth’ #to see current settings
# what errors?
cat /var/log/maillog >> maillog
#check the firewall logs for dropped IMAP/POP traffic
vi /var/log/messages | grep ‘:drop_log:’ #if you have logging set up for iptables
Roundcube/Apache
#check the logs
tail /var/log/httpd/access_log
tail /var/log/httpd/error_log
#monitor traffic
tcpdump -i eth2 ‘port 80’
#normal httpd.conf
https://github.com/assistanz247/APACHE/blob/master/httpd.conf
MySQL
#check the logs
tail /var/log/mysqld.log
tail /var/log/mysql/error.log
#monitor traffic
tcpdump -i eth2 ‘port 3306’
#if it doesn’t start: my.cnf
#check user permissions
#check password configs for the webserver
#**make sure your fw rules allow for external SQL/ loopback
#check the firewall logs for dropped External SQL connections (if applicable)
vi /var/log/messages | grep ‘:drop_log:’
──────────────────────────────────────────────────────────────────────────────────
Hardening
Firewall
#NOTE: *SASL is for 587, smart host relays (starttls encryption)
#Core Services
iptables -A INPUT -p tcp -m multiport --dports 25,80,110,143 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp -m multiport --sports 25,80,110,143 -m state --state ESTABLISHED -j ACCEPT
#SQL Database connection
iptables -A INPUT -s 172.20.240.20 -p tcp --sport 3306 -j ACCEPT
iptables -A OUTPUT -d 172.20.240.20 -p tcp --dport 3306 -j ACCEPT
#AD connection
iptables -A INPUT -s 172.20.242.200 -p tcp --sport 389 -j ACCEPT
iptables -A OUTPUT -d 172.20.242.200 -p tcp --dport 389 -j ACCEPT
Logging
Roundcube/Apache
#In the roundcube config file -- config.inc.php
$config['debug_level'] = 1; #System Error Reporting
$config['sql_debug'] = true; # Log SQL queries
$config['imap_debug'] = true; #Log IMAP4 conversation
$config[pop_debug’]=true; #Log POP3 converstation
$config['ldap_debug'] = true; #Log LDAP conversation
$config['smtp_debug'] = true; #Log SMTP conversation
Postfix
postconf -e smtp_tls_loglevel=1
notify_classes = resource, software, protocol
Dovecot
#located: /var/log/maillog or /var/log/mail.info or something similar
#the postfix mail queue is located in the directory tree /var/spool/postfix and below
Apache
#located in /var/log/httpd or /apache2
Backup
Postfix
tar czf /root/postfix-$(date “+%F”).tar.gz /etc/postfix
postconf > /root/postconf-$)date “+%F)
Dovecot
tar czf /root/dovecot-$(date “+%F”).tar.gz /etc/dovecot
Postfix Hardening – Hella ExtraTM
Chroot Jail
mkdir -p /var/spool/postfix/dev
syslogd -a /var/spool/postfix/dev/log
vi main.cf
Domain Restrictions
*can combine w/ a comma
smtpd_client_restrictions =reject_non_fqdn_sender, reject_non_fqdn_recipient
smtpd_client_restrictions = warn_if_reject reject_unknown_client
smtpd_client_restrictions = check_client_access hash:/etc/postfix/client_access
#vi /etc/postfix/client_access file:
10 REJECT RFC 1918 address not allowed here
192.168 REJECT RFC 1918 address not allowed here
# Known spammers
12.34.56.78 REJECT
spammer.example.com REJECT
Message Content Checks
mime_header_checks = /^Content-(Disposition|Type).*name\s*=\s*"?(.*\.( ade|adp|bas|bat|
chm|cmd|com|cpl|crt|dll|exe|hlp|hta|inf|ins|isp|js|jse|lnk|mdb|mde|mdt|
mdw|ms[cipt]|nws|ops|pcd|pif|prf|reg|sc[frt]|sh[bsm]|swf|vb[esx]?|vxd|
ws[cfh]))(\?=)?"?\s*(;|$)/x
REJECT Attachment not allowed. Filename "$2" may not end with ".$3".
Initial Scan of Postfix
#check config & resolve any errors
postfconf 1> /dev/null
#find version
dpkg -l postfix OR postconf mail_version | awk -F” = “ ‘{print $2}’
#check networks
cat /etc/postfix/conf.php | grep “mynetworks”
──────────────────────────────────────────────────────────────────────────────────
Conclusion
With that, your email server should be up and running. If you are an engineer, I cannot and will never reccomend using plaintext authentication. What we did in the lab is not secure, and will not scale very well with many many users. In the next post, we will go over some more secure options, as well as using directories via LDAP and Kerberos authentication.
Happy testing!