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.
__

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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

Email Server Diagram
──────────────────────────────────────────────────────────────────────────────────

            

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

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 to
http://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.php

Step 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!