Saturday, March 10, 2012

Implement Disk Quotas

Implement Disk Quotas in RHEL 6 and CentOS 6

Quotas are used to limit a user's or a group of users' ability to consume disk space. This prevents a small group of users from monopolising disk capacity and potentially interfering with other users or the entire system. This feature of Linux allows the system administrator to allocate a maximum amount of disk space a user or group may use. It can be flexible in its adherence to the rules assigned and is applied per filesystem. The default Linux Kernel which comes with Redhat and Fedora Core comes with quota support compiled in. In order to implement quotas you need to check whether the kernel supports them.

Check whether the quota support is built into the kernel

Terminal
[root@server1~] # grep CONFIG_QUOTA /boot/config-2.6.18-1.2798.fc6
CONFIG_QUOTA=y
CONFIG_QUOTACTL=y
Those two values should be 'y'. If its not you may need to install the quota rpm package or you may have to recompile your kernel.

Prerequisites

  • You should have a seperate unique partition to implement quotas and mount the partition.
  • Make necessary changes in /etc/fstab file and remount the partition and check that quotas are on.
  • Create files aquota.user and aquota.group in mounted partition folder. [ Note: this may not be required for RHEL5 ]  and make sure the owner of those files in root and he should be able to read and write to those files ( chmod 600 aquota.*).
  • Run the command quotacheck to check that quotas are implemented.

Create a seperate partitiion

Using your favorite partitiion tool like ( fdisk, parted, gnuparted or any other tool create a partition). Create a directory and mount that partition to that directory.

Terminal
[root@server1~] # mkdir -p /partmount
[root@server1~] # mount /dev/sda7 /partmount

Changes to /etc/fstab

In order to impletment quotas on the partition you need to make changes to /etc/fstab so that when you reboot the system, the quotas are still there on the filesystem. This step is required if you intend to make the quotas permenant. Change the last line as shown in the example.

Terminal
[root@server1~] # vim /etc/fstab
LABEL=/                 /                       ext3    defaults        1 1
LABEL=/boot             /boot                   ext3    defaults        1 2
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
tmpfs                   /dev/shm                tmpfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
sysfs                   /sys                    sysfs   defaults        0 0
LABEL=SWAP-hdb1         swap                    swap    defaults        0 0
/dev/sda7  /partmount  ext3 defaults,usrquota,grpquota  0 0

Now we need to remount the partition for the quotas to be implemented.

Terminal
[root@server1~] # mount -o remount /partmount

Creating quota related files

Terminal
[root@server1~] # cd /partmount
[root@server1 partmount] # touch aquota.user; touch aquota.group
[root@server1 partmount] # chown root:root aquota.*; chmod 600 aquota.*

Check that quotas are working

Terminal
[root@server1~] # quotacheck -vgum /partmount

Implementing Quotas for users and groups

edquota command

To specify disk quotas you need to run either edquota or setquota commands. In order to specify quota for the user henry you will use the command edquota as follows.

Terminal
[root@server1~] # edquota -u henry

You will be presented with the vi editor specifying the soft limit the hard limit and inodes ( the number of files ) soft limit and hard limit.

Soft Limit: This is the maximum amount of space a user can have on that partition. If you have set a grace period, this will act as an alarm, and you will also be required to set a hard limit.

Hard Limit: Hard limits are only neccessary when you are using grace periods. If grace periods are used this will be the absolute limit a user can use.

Grace periods are set by using the command edquota -t /partition

The edquota command can also be used to copy quota settings for one user as a template to any number of users in your system You will need to use -p switch of the edquota command to copy quota settings.

Terminal
[root@server1~] # edquota -up user1 user2 user3 user4

setquota command

Alternatively you can use the setquota command to set quotas on users and groups.

Terminal
[root@server1~] # setquota -u user1 0 0 0 0 /partmount

To set a quota of 4GB to user henry we would use the following command

Terminal
[root@server1~] # setquota -u henry 4194304 4194304 0 0  /partmount
Its important to remember to calcuate Megabytes in times 1024 X 1MB and Gigabytes as (1024)2 x 1GB

To set 240Msoft, 256M hard for user jerry

Terminal
[root@server1~] # setquota -u jerry 245760 262144 0 0 /partmount

Reporting quotas

Reports on quotas allocated to users and groups could be obtained by using the command repquota

Terminal
[root@server1~] # repquota -u /partmount

To obtain individual quota for users jerry and group payroll the commands would be as follows:

Terminal
[root@server1~] # repquota -uv jerry
[root@server1~] # repquota -gv payroll

Quota management

Quotas management can be done with the command quotacheck. This command is useful in the sense we can check that the quotas that are allocated are really in the pipeline for execution.

Terminal
[root@server1~] # quotacheck -vgum /partmount

Configure a Caching Only DNS Server

Caching-Only DNS Server

A caching-only name server is used for looking up zone data and caching (storing) the result which is returned. Then it can return the answers to subsequent queries by using the cached information.

A caching-only server is authoritative only for the local host i.e 0.0.127.in-addr.arpa, but it can automatically send requests to the Internet host handling name lookups for the domain in question.

In most situations, a caching-only name server sends queries directly to the name server that contains the answer. Because of its simplified nature, a DNS zone file is not created for a caching-only name server.

Running the Caching-only Name Server in an chroot environment is a secure approach. The chroot environment has more security compared to the normal environment.

To configure the /etc/named.conf file for a simple caching name server, use this configuration for all servers that don't act as a master or slave name server. Setting up a simple caching server for local client machines will reduce the load on the network's primary server. Many users on DSL connections may use this configuration along with bind for such a purpose. Ensure that the file /etc/named.conf highlights the entries below:

Terminal Window View
options {
directory "/var/named";
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
forwarders { 192.168.1.1; 192.168.1.100; };
forward only;
};
// a caching only nameserver config
controls {
inet 127.0.0.1 allow { localhost; } keys { rndckey; };
};
zone "." IN {
type hint;
file "named.ca";
};
zone "0.0.127.in-addr.arpa" IN {
type master;
file "named.local";
allow-update { none; };
};

With the forwarders option, 192.168.1.1 and 192.168.1.100 are the IP addresses of the Primary/Master and Secondary/Slave DNS server on the network in question. They can also be the IP addresses of the ISPs DNS server and another DNS server, respectively. With the forward only option set in the named.conf file, the name server doesn't try to contact other servers to find out information if the forwarders does not give it an answer.  To test this setup try the following commands

Terminal
[root@station1.example.com~] # chkconfig --levels 25 named on
[root@station1.example.com~] # service named restart

We have now turned on the named server for persistent reboots and started the service for the current session. Now to test whether the caching - named server is working or not lets see:

Terminal Window View
# nslookup
>Default
Server: localhost
Address: 127.0.0.1

> www.redhat.com
Server: localhost
Address: 127.0.0.1
Name: www.redhat.com
Address: 209.132.177.50

nslookup now asked the named to look for the machine www.redhat.com. It then contacted one of the name server machines named in the root.cache file, and asked it's way from there. It might take a while before the result is shown, as it searches all the domains the user entered in /etc/resolve.conf. When tried again, the result should be similar to this example:

Terminal Window View
> www.redhat.com
Server: localhost
Address: 127.0.0.1
Non-authoritative answer:
Name: www.redhat.com
Address: 209.132.177.50

Note the Non-authoritative answer in the result this time. This means that named did not go out on the network to ask this time, it instead looked up in its cache and found it there. But the cached information might be out of date. So the user is informed of this danger by it saying Non-authoritative answer. When nslookup says this the second time when a user ask for a host, it is a sign that it caches the information and that it's working. Now exit nslookup by giving the command exit.

Create your own private yum repository.

Create your own private yum repository

Sometimes, especially when you create your own RPMs, it is extremely useful to keep them in a local YUM repository . The advantage of this is that, when you install a package, YUM automatically resolves any dependencies, not only by downloading the necessary packages from the other repositories you might have in you list, but also by using your local repo as a resource for potential dependencies.

So, when installing a package (eg my_package.rpm ) with YUM, you are supposed to have already created RPM packages for all of the my_package.rpm 's dependencies and to have updated the repository's metadata, so that yum is able to resolve all the dependencies. If these dependencies do not exist in any of the repositories in your list, then, in short, you cannot install your package with yum.

So, in order to install an RPM package and all the other packages that it depends on, you only need to run:

# yum install my_package.rpm

How to create a local YUM repo ?

You will need an utility, named createrepo . Its RPM package exists in Fedora Extras. To install it, just run as root:

Terminal
# yum install createrepo 

Then, put all your custom RPM packages in a directory. Assuming that this directory is /path/to/repository , you can create all the necessary metadata for your local repository by running the following command as root or as the user that owns the directory:

Terminal
# createrepo -v /path/to/directory

That's it! Your local YUM repository is ready.

Keep in mind that every time you put any new RPMs in that directory or remove any old RPMs, you will need to run the above command again, so that the repository metadata gets updated.

Add your local repo to the list

The next thing you need to do is to add your local repository to your list of repos, so that yum knows where to find it. This info is kept in the /etc/yum.repos.d/ directory. As root, create a new text file in this directory, name it fedora-local.repo (you can use any name you like, but remember to add the extension .repo ), and add the following info in it:

Terminal
[root@station1.example.com~]# cat /etc/yum.repos.d/fedora-local.repo
[localrepo] 
name=[give any name you like without the square brackets ofcourse]
baseurl=[file:| ftp | http |<path to the repository>] 
enabled=1 
gpgcheck=0 
In Order to access the repository over ftp or http the urls should be modified as follows
baseurl=http://server1.example.com/path/to/repository
or
baseurl=ftp://server1.example.com/path/to/repository

As you can see, we used the protocol file:/// in the baseurl option. This assumes that the local repo exists in the local machine. If it exists in another machine of your internal network, feel free to use any other protocol in order to tell yum where to find your local repository, For example you can use http:// , ftp:// , smb:// etc.

In the above example, the GPG key check is disabled ( gpgcheck=0 ). If you sign your packages, you can set this to " 1 " and uncomment the following line ( gpgkey=... ). This contains the path to your public key, so that YUM can verify the package signatures.

You can have as many local YUM repositories as you like.

Other uses of a local repository

Using a local repository does not only serve as a place for your custom RPMs. You can perfectly save some bandwidth by downloading all the released fedora updates in that repo and use this to update all the systems of your internal network. This will save bandwidth and time.

The Procedure is the same for all RPM based systems, using YUM Package Manager. So this can be applied to Fedora, Redhat and CentOS systems

Understanding DNS ACL Directives

Understanding Bind DNS ACL Directives

An ACL or access control list can be used in DNS to restrict unwanted queries to the DNS server

  • In its simplest form, an ACL assigns a name to an address match list.
  • Can generally be used in place of a match list (nesting is allowd).
  • Best practice is to define ACL's at the top of /etc/named.conf.

Address Match List

A semicolon-seperated list of IP Addresses or subnets used with security directives for host based access control.

Format

  • IP Address : 192.168.1.1
  • Trailing dot: 192.168.0.
  • CIDR: 192.168.1/24 [Classless InterDomain Routing]
  • Use a bang (!) to denote inversion / negation.

Example Declaration

The following ACL defines a trusted host:
acl  "trusted"          { 192.168.1.21; };

The following ACL defines a trusted domain or network
acl  "classroom"   { 192.168.0.0/24; trusted; };

This ACL defines an untrusted network or domain
acl  "cracker"          { 192.168.1.0/24; };

This ACL defines the MASTER DNS SERVER
acl  "mymasters"     { 192.168.1.1; };

Usage as follows:

The above ACL's can be used with the following directives in the /etc/named.conf as:

Option:  listen-on port 53 { trusted; };
The option above states that the DNS is setup on "trusted" ACL and you are configuring Bind to listen to IP address of the same system.

Option:  allow-query { classroom; !cracker; };
The option above will allow queries from all hosts that are in the "classroom" ACL but not from "cracker" ACL.

Option:  allow-transfer { classroom; !cracker; };
The option above will allow zone transfer to Slave DNS servers in the "classroom" ACL but not to"cracker" ACL.

Option:  forwarders { classroom; !cracker; };
The option above will forward queries "classroom" ACL but not to"cracker" ACL.

Likewise you can form ACL's and fine tune and restrict you DNS server so as to deny unwanted domains and queries.

Basic PXE Install Server

Basic TFTP PXE DHCP Setup in Redhat 6 and CentOS 6

In order to prepare a Normal PXE Server we need the following Servers and Services to be set up prior to proceeding further.

  • Install NFS, FTP, HTTP and related packages.
  • Install TFTP Server and related Packages
  • Install DHCP Server and related Packages

Setting up the Network Server  [ NFS | FTP | HTTP ]

First, configure an NFS, FTP, or HTTP server to export the entire installation tree for the version and variant of Linux to be installed.

We are going to use NFS simply because there are fewer steps involved. You are free to use any server to your liking, infact I recommend to install all the Servers and see for your self.

Terminal
[root@station1.example.com~] # yum install nfs-utils*
//then 
[root@station1.example.com~] # chkconfig portmap on
[root@station1.example.com~] # chkconfig nfs on
[root@station1.example.com~] # service portmap restart
[root@station1.example.com~] # service nfs restart

Create a directory /Linix_Distros/Osdir and dump the contents of the Linux DVD / Linux CD’s in that directory. And export the directory of /Linux_Distros to your local Network

Your /etc/exports file should look like this.

Terminal Window View
[root@station1.example.com~] # cat /etc/exports
/Linux_Distros  *.example.com(ro,sync)

Setting up the TFTP Server and related packages

Install the TFTP server and the related packages with the following commands.

Terminal
[root@station1.example.com~] # yum install tftp*

Before we move on we need to configure the tftp-server so that it will be started when the the system boots. First of all we need to enable the tftp-server so that its running in the first place. To do this we need to go to /etc/xinetd.d/tftp file and change the disable=yes to disable=no and then restart the xinetd service. Just check the following to see how to do that.

Terminal Window View
[root@station1.example.com~] # cat /etc/xinetd.d/tftp
# default: off
# description: The tftp server serves files using the trivial file transfer \
# protocol.  The tftp protocol is often used to boot diskless \
# workstations, download configuration files to network-aware printers, \
# and to start the installation process for some operating systems.
service tftp
{
 socket_type  = dgram
 protocol  = udp
 wait   = yes
 user   = root
 server   = /usr/sbin/in.tftpd
 server_args  = -s /tftpboot
 #change the following to 'no'
 #disable  = yes
 disable          = no
 per_source  = 11
 cps   = 100 2
 flags   = IPv4
}

Then restart the xinetd service.

Terminal
[root@station1.example.com~] # chkconfig --levels 35 xinetd on
[root@station1.example.com~] # service xinetd restart

Create a directory /tftpboot and under it create another directory pxelinux.cfg so the path looks like this
/tftpboot/pxelinux.cfg for clarity look to the following.

Terminal
[root@station1.example.com~] # mkdir -p /tftpboot/pxelinux.cfg

You will need to find the vmlinuz and initrd.img files in the /Linux_Distros/Osdir directory and copy them into the /tftpboot directory. These files will be used to start the kickstart process after the PXE boot has taken place.

Suppose we have a Red Hat Enterprise Linux™ 5 installation then my path should be /Linux_Distros/RHEL5 and I would find the vmlinuz and initrd.img in the following locations /Linux_Distros/RHEL5/images/pxeboot

Please note that the vmlinuz kernel must match the version of OS you are going to build.
Terminal
[root@station1.example.com~] # cp /Linux_Distros/RHEL5/images/pxeboot/initrd.img\
      /tftpboot
[root@station1.example.com~] # cp /Linux_Distros/RHEL5/images/pxeboot/vmlinuz\
      /tftpboot

Booting a PC without a kernel written to a disk requires the use of PXE boot. And this can be achieved by installing the syslinux package. This package if not installed,  install it with the following command.

Terminal
[root@station1.example.com~] # yum install syslinux*

The component that is needed from this package to perform a PXE boot is pxelinux.0   Run a search for this file under the entire / directory. Once found copy the file to /tftpboot.

Terminal
[root@station1.example.com~] # cp /var/lib/syslinux/pxelinux.0 /tftpboot

Setting up the DHCP Server and related packages

Install a DHCP server that allows bootp onto the Linux Server. If a compatible DHCP package cannot be found on the installation disks, one can be downloaded at http://www.rpmfind.net

The installation of the DHCP server should create an example of /etc/dhcpd.conf. The dhcpd.conf file is configuration file for the DHCP server. Rename this file and create a new one with the same name.  For the sake of your convinience I have provided one below.

Terminal Window View
ddns-update-style none;
ignore client-updates;

option domain-name  "example.com";
option domain-name-servers 192.168.1.1;
default-lease-time 21600;
max-lease-time 43200;

########## IMPORTANT FOR PXE BOOTING ###############
allow booting;
allow bootp;

subnet 192.168.1.0 netmask 255.255.255.0 {

# --- default gateway
option routers   192.168.1.1;
option subnet-mask  255.255.255.0;
range  192.168.1.2 192.168.1.20;

########## VERY IMPORTANT FOR PXE BOOTING ##########
filename "pxelinux.0"; 
next-server 192.168.1.1;
########## IMPORTANT FOR PXE BOOTING ###############
}

Create a Kickstart File

You can create a Kickstart file from the system-config-kickstart if your are using Redhat or Fedora. Create a Kickstart file and name it ks.cfg or alternatively you can rename the anaconda-ks.cfg found in your root directory as a template for your ongoing installations.

Make the ks.cfg available though FTP,HTTP or NFS. For this we will use NFS and make it available through the /Linix_Distros directory since its exported already.

Once the client machine obtains the PXE environment specified in the dhcpd.conf file it begins to make tftp requests for a file named after its’ IP address in uppercase hexadecimal format. The hexadecimal file needs to be contained in the /tftpboot/pxelinux.cfg directory.

For example: The IP that was used for this document was 192.168.2.25. The file that the machine then requested was /tftpboot/pxelinux.cfg/C0A80219 .

Incase you have not configured dhcp entries for each station in your network the pxelinux environment looks for a default file located in the /tftpboot/pxelinux.cfg/default. Create one to avoid confusion.

It should contain the following

Terminal Window View
[root@station1.example.com~] # cat /tftpboot/pxelinux.cfg/default
default ks
prompt 0
timeout 600
label ks
kernel vmlinuz
append ks=nfs:192.168.1.1:/tftpboot/ks.cfg initrd=initrd.img

Once the kernel is loaded an nfs mount is performed and the kickstart information is pulled from the specified the location.

CONGRATULATIONS you have now configured a TFTP,DHCP,NFS PXE Server to distibute the OS to a wide range of clients simultaneously, for unattended installations.

VsFTPD Virtual Server

Mysql Virtual Hosting, Individual User Directories and SSL Authentication with Chmod facility in Redhat6 and CentOS 6

Step 1: Install the required packages

  • Vsftpd
  • pam_mysql (for supporting mysql backend through pam)
Terminal
[root@station1.example.com~]# yum install vsftpd* pam_mysql

Step 2: Create Mysql database for Vsftpd

Terminal
[root@station1.example.com~]# mysql -u root -p
Enter password: 
#after entering the password you will get a 'mysql>' prompt
# type the following here
mysql > create database vsftpd;
#database will be created.
mysql > GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON vsftpd.* \
        TO 'vsftpd'@'localhost' IDENTIFIED BY 'ftpdpass';
mysql > GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON vsftpd.* \
        TO 'vsftpd'@'localhost.localdomain' IDENTIFIED BY 'ftpdpass';
mysql > FLUSH PRIVILEGES;

Replace the string ftpdpass with whatever password you want to use for the MySQL user vsftpd. Still on the MySQL shell, we create the database table we need (yes, there is only one table!):

Terminal
mysql > USE vsftpd;
mysql > CREATE TABLE `accounts` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 30 ) NOT NULL ,
`pass` VARCHAR( 50 ) NOT NULL ,
UNIQUE (
`username`
)
) ENGINE = MYISAM ;
# table will be created
mysql > quit ; 

As you may have noticed, with the quit; command we have left the MySQL shell and are back on the Linux shell.

Step 3: Create a virtual user virtualftp

First we create a non-privileged user called virtualftp (with the homedir /home/virtualftp ) belonging to the group virtualftp. We will run vsftpd under this user, and the FTP directories of our virtual users will be in the /home/virtualftp directory (e.g. /home/virtualftp/user1 , /home/virtualftp/user2 , etc.).

Terminal
[root@station1.example.com~]# useradd -d /home/virtualftp -s /sbin/nologin virtualftp

Then we make a backup of the original /etc/vsftpd.conf file and create our own:

Terminal
[root@station1.example.com~]# cp /etc/vsftpd/vsftpd.conf \
                              /etc/vsftpd/vsftpd.conf_orig
[root@station1.example.com~]# cat /dev/null > /etc/vsftpd.conf
[root@station1.example.com~]# vi /etc/vsftpd.conf
# Enter the following in vsftpd.conf file.

listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
xferlog_file=/var/log/vsftpd.log
connect_from_port_20=NO
listen_port=990
#ftpd_banner=Welcome to server2.linux.com FTP SITE
banner_file=/etc/vsftpd/banner_file
nopriv_user=nobody
chroot_local_user=YES
secure_chroot_dir=/var/run/vsftpd
pam_service_name=vsftpd

ssl_enable=YES
force_local_logins_ssl=YES
rsa_cert_file=/etc/pki/tls/certs/vsftpd.pem
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO

guest_enable=YES
guest_username=virtualftp
user_sub_token=$USER
local_root=/home/virtualftp/$USER
virtual_use_local_privs=YES
chmod_enable=YES
#user_config_dir=/etc/vsftpd_user_conf

The configuration options are explained on http://vsftpd.beasts.org/vsftpd_conf.html. The important options for our virtual setup are chroot_local_user, guest_enable, guest_username, user_sub_token, local_root, and virtual_use_local_privs.

With the user_config_dir option you can specify a directory for per-user configuration files that override parts of the global settings. This is totally optional and up to you if you want to use this feature. I have not used this feature here so I put the # characher in front of the user_config_dir option.

Step 4: Configuring PAM to use Mysql

Now we must configure PAM so that it uses the MySQL database to authenticate our virtual FTP users instead of /etc/passwd and /etc/shadow. The PAM configuration for vsftpd is in /etc/pam.d/vsftpd. We make a backup of the original file and create a new one like this:

Terminal
[root@station1.example.com~]# cp /etc/pam.d/vsftpd /etc/pam.d/vsftpd_orig
[root@station1.example.com~]# cat /dev/null > /etc/pam.d/vsftpd
[root@station1.example.com~]# vi /etc/pam.d/vsftpd

# this sould have the following line
auth required /lib/security/pam_mysql.so user=virtualftp passwd=virtualftp \
     host=localhost db=vsftpd table=accounts usercolumn=username \
     passwdcolumn=pass crypt=2
account required /lib/security/pam_mysql.so user=virtualftp passwd=virtualftp \
     host=localhost db=vsftpd table=accounts usercolumn=username \
     passwdcolumn=pass crypt=2

Please make sure mysql password is the same as the one you used in mysql previously

Afterwards, we restart vsftpd:

Terminal
[root@station1.example.com~]# service vsftpd restart

Step 5: Creating the first virtual user

To populate the database we have to go back to the MySql shell again, login as before and follow the instructions below.

Terminal
mysql > use vsftpd;
database changed
mysql > INSERT INTO accounts (username, pass) VALUES('Jimi', PASSWORD('secret'));
query successful

Jimi's homedir is /home/virtualftp/Jimi; unfortunately vsftpd doesn't create that directory automatically. Therefore we create it manually now and make it owned by the virtualftp user and the virtualftp group:

Terminal
[root@station1.example.com~]# mkdir /home/virtualftp/Jimi
[root@station1.example.com~]# chown virtualftp:virtualftp /home/vsftpd/Jimi

For database administration you can use PhpMyAdmin web interface to manage your users more time efficiently.

Now open your FTP client program on your work station (something like WS_FTP or SmartFTP if you are on a Windows system or gFTP on a Linux desktop) and try to connect. As hostname you use ftp.example.com (or the IP address of the system), the username is Jimi , and the password is secret . And remember use the port 990 to connect and check whether Auth-SSL is selected to authenticate.

If you are able to connect - congratulations! If not, something went wrong.

SSL and CHMOD notes below

To create a rsa certificate you would have to go to the /etc/pki/tls/certs directory and give a make command over there to get a vsftpd.pem

Terminal
[root@station1.example.com~]# cd /etc/pki/tls/certs
[root@station1.example.com~]# make vsftpd.pem

Note from Step 3 the SSL section this settings will force local logins to use SSL

Users on this server can change the permissions of thier files through the client program
chmod_enable and virtual_use_local_privs are the directives needed to accomplish that.

Friday, February 24, 2012

Enterprise Class Mail Server

Enterprise Class Mail Server

Virtual Users and Virtual Domains Using Postfix, PostfixAdmin, Mysql, Dovecot, Dovecot Sieve, Dovecot Pigeonhole, Dovecot Antispam, DSPAM, DSPAM WebUI with Apache SuExec and ModIMAP, SqlGrey, ClamAV, DKIM, SSL/TLS and SASL on RHEL 6 and CentOS 6

When working with this set up keep in mind that you need to install a set of packages
that go by working together in the end. Sometimes the configuration may vary but you need to
realise that things cannot go smoothly unless the required know how is there with you. Training
yourself with the packages and knowing the capabilities of the packages go a long way
in easing up this type of setup.

That said, does not mean to discourage you, but to make you realise that it could also be a rewarding and
fulfilling experience

Before we go about this setup we need to know how to complete this job right from the start to the finish. Please bear in mind that this installation is specific to CentOs, Redhat and Fedora systems alone. I will not be responsible for your loss of data, and this installation may not be the only way that you can achieve results.

Our installation will provide the following features within this setup:

  • Postfix Server with full capability to support MySQL or PgSQL maps, support for perl regular expressions, built in quota support (via the VDA patch). I have built this rpm from source, so you might not get this rpm. And also SSL/TLS and SASL support via Dovecot with CRAM-MD5 authentication
  • Dovecot Server with full capability to support MySQL or PgSQL maps lookup, with Sieve(mail filter scripts) and ManageSieve(Sieve Server),full quota support and DSPAM antispam plugin with CRAM-MD5 authentication
  • Postfixadmin with vacation support and improved look and feel with CRAM-MD5 authentication. (I changed the default css file and image logo as I did not like the dull look)
  • Round Cube webmail with improved plugins like vacation, userinfo, configuration help, managesieve etc and CRAM-MD5 authentication.
  • Clam Antivirus
  • SQLGrey
  • DSPAM and DSPAM WebUI with apache suexec with mod_imap
  • Domain Keys Internet Mail(DKIM)
  • This installation is not specific to version 6 of RHEL or CentOS, the packages for an earlier version 5.x of RHEL or CentOs packages are available as a tarball file through this download link. [DOWNLOAD EARLIER PACKAGES]. Please note only Postfix and Dovecot packages are available here. You would need to install PHP 5.2 or later and MySQL 5.1.54 or later for this setup to work as expected.

    If your installation is based on RHEL6 or CentOS6 then you need this tar ball file to work on this setup. [DOWNLOAD HERE].

Our installation is based on the following steps :



STEP: 1 Install appropriate Operating System (CentOS(5.x), Redhat(5.x), Fedora(latest breed).

I assume that you have installed your operating system with the appropriate partitions and mount points.Get the system to be internet ready and configure your yum repositories. Although the packages have been supplied, you can very well install all the packages through yum, provided they are available. I have supplied these packages as they are custom built, and may not be available on your yum. Take extra care when installing packages and don't miss out on the dependencies.




STEP: 2 Install Postfix Packages

  • Postfix with (quota, mysql, pgsql support)
  • Postfix with perl support

Download the postfix packages in one location from the tar ball files offered at the beginning of the download and use yum to install the packages. This way if you have any dependency issues you can resolve them.

Also make sure you install RPMForge, ATRPMS, DAG and EPEL repositories and enable them in your yum.
Terminal Window
[root@mail1 ~]# cd /location-of-RPMS/
[root@mail1 ~]# yum localinstall postfix*



STEP: 3 Install Dovecot Packages

  • Dovecot
  • Dovecot-Devel
  • Dovecot-MySQL
  • Dovecot-PgSQL
  • Dovecot Sieve and Manage Sieve Server

Download the dovecot packages from the tar ball downloads offered earlier. Once you extract the tar ball
you will have the expanded structure of the download. Change to the directory where dovecot rpms are present
and issue the following commands there.

Terminal Window
[root@mail1 ~]# cd /location-of-RPMS/
[root@mail1 ~]# yum localinstall dovecot*



STEP: 4 Check whether postfix supports mysql

Now we seem to have installed both the major pieces together, to be doubly sure we need to check whether
our Postfix Server supports MySQL maps or not. We can also figure out whether it supports quotas, Perl
regular expressions etc. Just run the command as shown below to see what maps your postfix installation
supports. Observe that Perl regular expressions and MySQL maps are supported with this installation.

Terminal Window
[root@mail1 ~]# postconf -m
btree
cdb
cidr
environ
hash
internal
ldap
mysql
nis
pcre
pgsql
proxy
regexp
static
tcp
unix



STEP: 5 Create Virtual User and Group to administer Virtual Mail Store

Our whole mail server system needs to be run as an unprivileged user and group, this is because, we want to reduce the amount of damage any intruder might cause in the event the Server is hacked. At the very same time, administration
of the mail server becomes manageable if the Virtual mail system, has one user and group. The idea behind
this system is this, we create one virtual user and group, this virtual user will be sole owner of the whole
mailbox store, only this user will have the privileges to read, write and delete files from the mailbox store.

We want to create a new partition of say 20GB, mount it on /mailboxes. I will assume that you have
already created the partition and formatted it in ext3/ext4 fs. Use the mount command and mount the partition on
/mailboxes, and don't forget to make the necessary changes in /etc/fstab. We now have to create a virtual folder
under /mailboxes and change the owner ship of the whole mailbox store to the newly created virtual user. Follow
the commands shown below that do exactly the same.

Terminal Window
[root@mail1 ~]# mkdir -p /mailboxes/vmail
[root@mail1 ~]# groupadd -g 901 vmail
[root@mail1 ~]# useradd  -g 901 -u 901 -s/sbin/nologin -d /mailboxes/vmail vmail
[root@mail1 ~]# chown -R vmail:vmail /mailboxes
[root@mail1 ~]# chmod -R 700 /mailboxes 



STEP: 6 Install latest MYSQL


Terminal Window
[root@mail1 ~]# yum install mysql*

You might get to install a little bit more software in the way of dependencies, but do it as we want our MySQL server to
function properly.




STEP: 7 Configure Mysql Password

When MySQL is first installed, the root can access the mysql console without the password. And that could raise
concerns. So we need to secure the MySQL console, but assigning a passwd for the root user. This can be done as
follows:

Terminal Window
[root@mail1 ~]# mysqladmin -u root password NEWPASSWORD



STEP: 8 Configure all software to startup at boot time.

Setting up all software to start at boot time could be a handy thing to do at this time. So as to avoid confusion
as to why certain software is not working. This can be done as follows:

Terminal Window
[root@mail1 ~]# chkconfig --levels 345 postfix on
[root@mail1 ~]# chkconfig --levels 345 dovecot on
[root@mail1 ~]# chkconfig --levels 345 mysqld  on



STEP: 9 Uninstall Sendmail

This step is not required if you are running RHEL/CentOS 6 or newer. By default sendmail is not the default MTA in the newer
enterprise linux anymore. However this is required for RHEL/CentOS 5.x versions. So we need to remove sendmail software, as
it might lead to confusion and to be short it's not needed anymore for this setup. Sendmail can be removed as follows:

Terminal Window
[root@mail1 ~]# yum remove sendmail



STEP: 10 Install latest PHP for RoundCube Webmail and Postfixadmin

Follow these steps if you are running RHEL/CentOS 5.x, RHEL/CentOS come with php 5.1 which is not helpful so we
need to change and install a better version to make this setup running.

We need to install at least the latest PHP version 5.2 for RoundCube Webmail and Postfixadmin. The new RoundCube Webmail
has got many features which were not there before. The whole set of PHP 5.2 packages are setup as a tar file
and can be DOWNLOADED HERE. Before you can install these packages you might consider to remove your existing
PHP installation as this might conflict with newer packages.

Terminal Window
[root@mail1 ~]# yum remove php

If you feel that a lot of packages are being lost as a result of the above command, you might consider
"rpm -e php.1XXX --nodeps " as an alternative to remove php.

Once the above tar file is downloaded and extracted change to that directory and issue the following command:

Terminal Window
[root@mail1 ~]# yum localinstall php52-*

There is a chance that you might come across some dependency issues, but if you install the dependencies you are good
to go.

Check your PHP installation.

This should show you that your php installation is PHP 5.2, If you encounter any errors check your /var/log/messages file
to rectify the situation.

Terminal Window
[root@mail1 ~]# php -v
PHP 5.2.17 (cli) (built: Jan 11 2011 11:02:17)
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies
Follow these steps if you are running RHEL/CentOS 6.x, RHEL/CentOS 6.x comes with php 5.3 which is even better.
Terminal Window
[root@mail1 ~]# yum install php-*

You might encounter some issues during installation just make sure you install php properly and check the version.

Terminal Window
[root@mail ~]# php -v
PHP 5.3.2 (cli) (built: Nov 12 2010 08:16:13) 
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies



STEP: 11 Install and Configure Postfixadmin

  • Prepare MySQL for Postfixadmin
  • Access Postfixadmin via Localhost
  • Configure Postfixadmin to use CRAM-MD5 passwords
  • Complete Postfixadmin Configuration.
  • Enable Vacation script facility.

Download the latest stable version of Postfix Admin in .tar.gz format from here. Assuming you got the file postfixadmin-2.x.x.x.tar.gz and it is located on your Desktop, type in the commands below to extract and to put it into its proper directory.

Terminal Window
[root@mail1 ~]# tar -xvzf postfixadmin-2.x.x.x.tar.gz
[root@mail1 ~]# mv postfixadmin-2.x.x.x postfixadmin

Prepare MySQL for Postfixadmin

In order to install postfixadmin the very first prerequisite is to create a database or it, and a user in mysql who will have all privileges to do all operations on that database.

Terminal Window
[root@mail1 ~]# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 642
Server version: 5.1.54-ius Distributed by The IUS Community Project
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>CREATE DATABASE postfix;
mysql> CREATE USER postfix@localhost IDENTIFIED BY 'your_password';
mysql> GRANT ALL PRIVILEGES ON postfix.* TO postfix;

Access Postfixadmin via Localhost

We need to access postfixadmin from our apache localhost, so that we can administer
virtual domains and virtual users. To do that we need to move the postfixadmin folder that we downloaded earlier
to /var/www/html/ folder. We can do that as follows:

Terminal Window
[root@mail1 ~]# mv /root/Desktop/postfixadmin /var/www/html/
[root@mail1 ~]# chown -R apache:apache /var/www/html/postfixadmin
[root@mail1 ~]# chmod -R 755 /var/www/html/postfixadmin

Before we fireup the browser, there are certain steps that need to be taken care of. First we need to configure the file config.inc.php, and change the values presented there.

Terminal Window
[root@mail1 ~]# vim /var/www/html/postfixadmin/config.inc.php
........................................
........................................
........................................
........................................
//to connect to the database
$CONF['database_type'] = 'mysql';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfix';
$CONF['database_password'] = 'your_password';
$CONF['database_name'] = 'postfix';
$CONF['database_prefix'] = '';
........................................
........................................
// your administrator e-mail address
$CONF['admin_email'] = 'postmaster@yourmaindomain.tld';
// The default aliases that need to be created for all domains.
$CONF['default_aliases'] = array (
        'abuse' => 'abuse@yourmaindomain.tld',
        'hostmaster' => 'hostmaster@yourmaindomain.tld',
        'postmaster' => 'postmaster@yourmaindomain.tld',
        'webmaster' => 'webmaster@yourmaindomain.tld'
);
........................................
........................................
// to get a mailbox structure like /domain/user
$CONF['domain_path'] = 'YES';
$CONF['domain_in_mailbox'] = 'NO';
........................................
........................................
// Quota
// When you want to enforce quota for your mailbox users set this to 'YES'.
$CONF['quota'] = 'YES';
// You can either use '1024000' or '1048576'
$CONF['quota_multiplier'] = '1024000';
........................................
........................................
// Optional:
// Show used quotas from Dovecot dictionary backend in virtual
// mailbox listing.
// See: DOCUMENTATION/DOVECOT.txt
//      http://wiki.dovecot.org/Quota/Dict
//
$CONF['used_quotas'] = 'YES';
// if you use dovecot >= 1.2, set this to yes.
// Note about dovecot config: table "quota" is for 1.0 & 1.1, table "quota2" is for dovecot 1.2 and newer
$CONF['new_quota_table'] = 'YES';

Configure Postfixadmin to use CRAM-MD5 passwords

You can set up Postfix Admin to use Dovecot to encrypt the email passwords using the CRAM-MD5 scheme. This will allow you to offer CRAM-MD5 authentication, which is more secure in some situations. Do this to change the encrypt section as follows:

Terminal Window
[root@mail1 ~]# vim /var/www/html/postfixadmin/config.inc.php
........................................
........................................
// Encrypt
// In what way do you want the passwords to be crypted?
// md5crypt = internal postfix admin md5
// md5 = md5 sum of the password
// system = whatever you have set as your PHP system default
// cleartext = clear text passwords (ouch!)
// mysql_encrypt = useful for PAM integration
// authlib = support for courier-authlib style passwords
// dovecot:CRYPT-METHOD = use dovecotpw -s 'CRYPT-METHOD'. Example: dovecot:CRAM-MD5
   $CONF['encrypt'] = 'dovecot:CRAM-MD5';
// you might have to set the binary for dovecotpw.
// For Dovecot 1.2 and later the command to create cram-md5 passwords is different
// compared to Dovecot2
// FOR DOVECOT 1.1 - DOVECOT 1.2 AND LATER SET
   $conf['dovecotpw'] = "/usr/bin/dovecotpw"
// FOR DOVECOT 2.0 AND LATER
   $conf['dovecotpw'] = "/usr/bin/doveadm pw"
// By default doveadm pw creates cram-md5 passwords.

Complete Postfixadmin Configuration.

Save that file config.inc.php, and then go to http://localhost/postfixadmin/setup.php

It will run some tests to verify that requirements are met. Now Postfix Admin will create the database schema that Postfix and Dovecot are going to read.

Next, it prompts you to enter a 'setup password'. You enter a password twice, and it will give you a hash (a long string of gibberish) to enter in /var/www/html/postfixadmin/config.inc.php

Find this line,

Terminal Window
[root@mail1 ~]# $CONF['setup_password'] = 'changeme'

and replace 'changeme' with the hashed password. I believe this measure prevents anyone else from re-installing Postfix Admin and wiping out your configuration. You could open up the Apache configuration now.

Finally, it will ask you to create a super-administrator account. I named mine admin@example.com, but you can name it whatever you want. The name does have to be in the format of an email address, even though it's not an account that receives mail.

Enable Vacation script facility.

Before you can install all the vacation features install all these perl packages
as they are needed for the vacation script to work.
Terminal Window
[root@mail1 ~]# yum install perl-DBD-MySQL perl-DBD-SQLite perl-DBD-Pg perl-Mail-Sender
                            perl-Email-Valid perl-Log-Log4perl perl-Log-Dispatch 
			    perl-MIME-EncWords perl-Getopt-Std-Strict

When you install postfixadmin there will be a folder by the name of
VIRTUAL_VACATION. Inside that folder you will find a file called INSTALL.txt.
Follow the instructions of that file and you will have working vacation script
for all your users. Just make sure that all the permissions match
the instructions.

I have created a custom theme for postfixadmin server and changed the colors and
look and feel of the software which is quite good. I really did not like the default look
so I changed it a bit. You can find in my second download of mailserver.tar.gz there
would be a folder called postfixadmin, there you would find my installation folder as a
tar ball file use it as it is and change the config.inc.php



STEP: 12 Configuring Postfix Server

  • Initial Configuration
  • Configure Virtual Domains to use MySQL
  • Configure Quotas

Initial Configuration

Postfix keeps most of configurations in the two files, they are /etc/postfix/main.cf and /etc/postfix/master.cf.
In /etc/postfix/main.cf all configurations are kept, whereas /etc/postfix/master.cf all transport configurations
are kept. We will be dealing with /etc/postfix/main.cf first. You may need to change the following parameters in
/etc/postfix/main.cf like this:

Terminal Window
[root@mail1 ~]# vim /etc/postfix/main.cf
........................................
........................................
myhostname = host.domain.tld  ##change this to your FQDN name.
mydomain = domain.tld         ##change this to your domain name.
##Uncomment this line, but you can probably leave it set to $mydomain 
myorigin = $mydomain
## According to the Postfix documentation, this setting specifies, 
## "the domain name that locally-posted mail appears to come from, 
## and that locally posted mail is delivered to"
## Set Postfix to listen on all interfaces:
inet_interfaces = all
........................................
........................................
mydestination = localhost
## Because I intend to manage everything as virtual domains 
## and virtual users.You probably also want to uncomment 
## this line, 
mynetworks_style = host

This will make postfix consider only the localhost part of the trusted "mynetwork". By default, it considers all other machines on the same subnet as part of your network, but that's probably not the setup you want if your server is in a data center with many other servers belonging to different customers.

Configure Virtual Domains to use MySQL

In order for Postfix to communicate with the MySQL database, you have to create several special files that contain database queries to return the information about your email users. First, we need to tell Postfix to look for those files. Open main.cf to edit again and add the following at the very end of the file.

Terminal Window
[root@mail1 ~]# vim /etc/postfix/main.cf
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
####################################################################
##CUSTOM CONFIGURATION FOR POSTFIX AND MYSQL##
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_uid_maps = static:901
virtual_gid_maps = static:901
virtual_mailbox_base = /mailboxes/vmail
####################################################################

The virtual_alias_maps specifies a mysql lookup map file that alias specific mail addresses or domains to other local or remote address.This is an important file. The virtual_mailbox_domains map file shows postfix the final destination for the specified list of domains. The virtual_mailbox_maps file is the one that shows Optional lookup tables with all valid addresses in the domains that match $virtual_mailbox_domains. The contents of these files are as follows:

Terminal Window
[root@mail1 ~]# cat /etc/postfix/mysql_virtual_alias_maps.cf
user = postfix
password = your_password
hosts = localhost
dbname = postfix
query = SELECT goto from alias WHERE address = '%s' AND active = '1'
[root@mail1 ~]# cat /etc/postfix/mysql_virtual_domains_maps.cf
user = postfix
password = your_password
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain = '%s' AND backupmx = '0' AND active = '1'
[root@mail1 ~]# cat mysql_virtual_mailbox_maps.cf
user = postfix
password = your_password
hosts = localhost
dbname = postfix
query = SELECT maildir FROM mailbox WHERE username = '%s' AND active = '1'

virtual_uid_maps files is a lookup map user ID that the virtual delivery agent uses while writing to the recipient's mailbox. In our example we have a user vmail with uid 901 and gid 901. The same applies to the virtual_gid_maps lookip map.
The virtual_mailbox_base entry is the path that we have created at the beginning of this tutorial. This is where all the user mail boxes will be located.

Configure Quotas

Our Postfix server supports mailbox quotas. There are some special settings that we need to specify so that
postfix will enable those features that support quotas. We will have to further add the following to the
/etc/postfix/main.cf file.

Terminal Window
[root@mail1 ~]# vim /etc/postfix/main.cf
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
#######################################################
##CUSTOM CONFIGURATION FOR POSTFIX AND MYSQL##
........................................
........................................
#######################################################
#####QUOTA CONFIGURATION###############################
virtual_create_maildirsize = yes
virtual_mailbox_extended = yes
virtual_mailbox_limit_maps = mysql:/etc/postfix/mysql_virtual_mailbox_limit_maps.cf
virtual_mailbox_limit_override = yes
virtual_maildir_limit_message = Sorry, this user has exceeded their disk space quota, 
				  please try again later.
virtual_overquota_bounce = yes
#######################################################

We are enforcing quotas in this setup so there is a special lookup map file and that is
virtual_mailbox_limit_map that specifies the amount of disk space needed for each user
mailbox. The contents of that file are as follows:

Terminal Window
[root@mail1~]# cat /etc/postfix/mysql_virtual_mailbox_limit_maps.cf
user = postfix
password = your_password
hosts = localhost
dbname = postfix
query = select quota from mailbox where username='%s' and active='1'



STEP: 13 Configuring Dovecot2 IMAP Server

  • Initial Configuration
  • Configure Quotas
  • Dovecot Authentication using CRAM-MD5 passwords
  • Configure Dovecot to access user info from MySQL
  • Configure Transports

Initial Configuration

Configuring Dovecot2 IMAP server could be easy for some and daunting for others if you know how and where to place the
right configuration values. You need to be cautious when doing this. This server is not only used to access your IMAP folders it is also used for authentication (SASL) and mailbox delivery. Let us look how this can be achieved. Check your configuration and make the necessary changes as shown:

Terminal Window
[root@mail1 ~]# vim /etc/dovecot/dovecot.conf
........................................
........................................
# Protocols we want to be serving: imap imaps pop3 pop3s
# If you only want to use dovecot-auth, you can set this to "none".
protocols = imap pop3 lmtp sieve

And again we need to configure the authentication for dovecot
about how we want the authentication to made and what type of authentication
we want. We want to allow plain text authentication and we also want to have CRAM-MD5 authentication,
So in order to do that, we make the necessary configatration changes in /etc/dovecot/conf.d/10-auth.conf

In Dovecot Version 2 instead off all settings being in one file as in /etc/dovecot.conf
the team at Dovecot have put all configurations as seperate files in /etc/dovecot/conf.d
directory. This avoids confusion and we can also pin point the whereabouts of errors
caused.
Terminal Window
[root@mail1 ~]# vim /etc/dovecot/conf.d/10-auth.conf
........................................
........................................
........................................
........................................
# Disable LOGIN command and all other plaintext authentications unless
# SSL/TLS is used (LOGINDISABLED capability). Note that if the remote IP
# matches the local IP (ie. you're connecting from the same computer), the
# connection is considered secure and plaintext authentication is allowed.
disable_plaintext_auth = no
........................................
........................................

Next we need to set where our mail store is. This is the place where all users
email will be stored and accessed. This setting can be found in the file
/etc/dovecot/conf.d/10-mail.conf

Terminal Window
[root@mail1 ~]# vim /etc/dovecot/conf.d/10-mail.conf
##
## Mailbox Locations and namespaces
#
........................................
........................................
........................................
........................................
........................................
mail_location = Maildir:/mailboxes/vmail/%d/%n

The namespace feature of Dovecot lets you manually specify some parameters to help
IMAP clients find the Inbox and other folders.It's probably a good idea to include
this information, given that email software seems to do a pretty mediocre job
supporting IMAP. These settings should be backward-compatible with Courier-IMAP
which is another very popular IMAP server in use today.

Terminal Window
[root@mail1 ~]# vim /etc/dovecot/conf.d/10-mail.conf
........................................
........................................
mail_location = Maildir:/mailboxes/vmail/%d/%n
........................................
........................................
namespace private {
# Namespace type: private, shared or public
type = private
# Hierarchy separator to use. You should use the same separator for all
# namespaces or some clients get confused. '/' is usually a good one.
# The default however depends on the underlying mail storage format.
separator = .
# Prefix required to access this namespace. This needs to be different for
# all namespaces. For example "Public/".
prefix = INBOX.
# Physical location of the mailbox. This is in same format as
# mail_location, which is also the default for it.
#location =
# There can be only one INBOX, and this setting defines which namespace
# has it.
inbox = yes
# If namespace is hidden, it's not advertised to clients via NAMESPACE
# extension or shown in LIST replies. This is mostly useful when converting
# from another server with different namespaces which you want to depricate
# but still keep working. For example you can create hidden namespaces with
# prefixes "~/mail/", "~%u/mail/" and "mail/".
hidden = no
}

Configure Quotas

We are going to use IMAP and pop3 protocols and we need to specify some settings in the configuration file. We want quota support in our setup. There are two quota related plugins:

  • quota: Implements the actual quota handling and includes also all the quota backends.
  • imap_quota: For reporting quota information via IMAP.

There are two files in which you need to make the neccessary configuration changes.

  • /etc/dovecot/conf.d/10-mail.conf
  • /etc/dovecot/conf.d/20-imap.conf
Terminal Window
[root@mail1 ~]# vim /etc/dovecot/conf.d/10-mail.conf
##
## Mail Process
##
........................................
........................................
........................................
mail_plugins = $mail_plugins quota
........................................
........................................
//then again in 20-imap.conf
[root@mail1 ~]# vim /etc/dovecot/conf.d/20-imap.conf
........................................
protocol imap {
........................................
........................................
  # Space separated list of plugins to load (default is global mail_plugins).
  mail_plugins = $mail_plugins imap_quota
}
........................................
........................................

If you want to have quota support in pop3 protocol do the following in /etc/dovecot/conf.d/20-pop3.conf

Terminal Window
[root@mail1 ~]# vim /etc/dovecot/conf.d/20-pop3.conf
........................................
........................................
pop3_uidl_format = %08Xu%08Xv
........................................
........................................
........................................
mail_plugins = $mail_plugins quota

We also need to make changes to the local delivery agent (LDA). The stanza beginning with sets parameters relevant for Dovecot's LDA that will be delivering the messages. Here's what mine looks like, note that you may want to change the postmaster address and the hostname to suit your own preferences, and again, if you want quota enforcement, add the quota plugin.

Terminal Window
[root@mail1 ~]# vim /etc/dovecot/conf.d/15-lda.conf
# Address to use when sending rejection mails.
postmaster_address = postmaster@example.com
# Hostname to use in various parts of sent mails, eg. in Message-Id.
# Default is the system's real hostname.
#hostname =
# Support for dynamically loadable plugins. mail_plugins is a space separated
# list of plugins to load.
# Should saving a mail to a nonexistent mailbox automatically create it?
lda_mailbox_autocreate = yes
# Should automatically created mailboxes be also automatically subscribed?
lda_mailbox_autosubscribe = yes
protocol lda {
#space separated list of plugins to load (default is global mail_plugins).
mail_plugins = $mail_plugins quota sieve
}

So far you've told Dovecot how to check what the quota limits are supposed to be for a given user. We have also set autosubsribe and autocreate mailboxes to yes, as this feature is not set on by default. Now, you also need to tell Dovecot where to keep information about how much mail the user already has. Edit the /etc/dovecot/conf.d/90-quota.conf as follows:

Terminal Window
[root@mail1 ~]# vim /etc/dovecot/conf.d/90-quota.conf
........................................
........................................
........................................
........................................
##  Edit the following stanza in the file
dict {
quotadict = mysql:/etc/dovecot-dict-quota.conf
}
........................................
........................................
........................................
........................................
##  Next find the plugin stanza
plugin {
........................................
........................................
........................................
........................................
# Quota setting per /usr/share/postfixadmin/DOCUMENTS/DOVECOT.txt
# http://wiki.dovecot.org/Quota/Dict
quota = dict:user::proxy::quotadict
........................................
........................................
........................................
........................................
}

That would complete the quota configuration as far as dovecot is concerned. As the last file that needs to be created for quota lookups for users in the MySQL database, these are the details of the file "dovecot-dict-quota.conf" file. And you can create it as follows

Terminal Window
[root@mail1 ~]# vim /etc/dovecot/dovecot-dict-quota.conf
connect = host=localhost dbname=postfix user=postfix password=your_password
map {
pattern = priv/quota/storage
table = quota2
username_field = username
value_field = bytes
}
map {
pattern = priv/quota/messages
table = quota2
username_field = username
value_field = messages
}

Dovecot Authentication using CRAM-MD5 passwords

We want to use CRAM-MD5 passwords that ensure a certain level of security over the authentication
mechanism, even at a plain text login level. If you set up your server and email software to use TLS/SSL, as explained later in this guide, then it doesn't really matter which authentication mechanism you use. The entire session will be encrypted by TLS, so even plaintext authentication will be protected. The only time CRAM-MD5 would really matter is if you needed to authenticate securely in a non-TLS session.

To achieve that we need to make changes to the file /etc/dovecot/conf.d/10-auth.conf

Terminal Window
[root@mail1 ~]# vim /etc/dovecot/conf.d/10-auth.conf
auth default{
........................................
........................................
........................................
........................................
mechanisms = plain login cram-md5
........................................
........................................
........................................
........................................
}

Next, we need to tell Dovecot where it's going to look to check those passwords.

Terminal Window
[root@mail1 ~]# vim /etc/dovecot/conf.d/auth-sql.conf
........................................
........................................
### UNCOMMENT the  following block
# SQL database 
  passdb  {
    driver = sql
    # Path for SQL configuration file, see doc/dovecot-sql-example.conf
    args = /etc/dovecot/dovecot-mysql.conf 
  }
##  We are telling dovecot to get user name and password information
##  from MySQl.  The details of the file dovecot-mysql.conf we will
##  discuss shortly.
........................................
........................................
........................................
##  UNCOMMENT the whole prefetch block 
# "prefetch" user database means that the passdb already provided the
  # needed information and there's no need to do a separate userdb lookup.
  # This can be made to work with SQL and LDAP databases, see their example
  # configuration files for more information how to do it.
  # 
  userdb  {
	driver = prefetch
  }
........................................
........................................
........................................
##  Further down COMMENT OUT the whole userdb passwd block to disable it.
userdb  {
    driver = sql
    # Path for SQL configuration file, see doc/dovecot-sql-example.conf
    args = /etc/dovecot/dovecot-mysql.conf 
  }

Here's what's going on: The passdb and userdb settings tell Dovecot where to check to verify passwords and look up other user information, respectively. In our case, that information is all stored in the same place--the 'mailbox' table in our MySQL database. So, rather than having Dovecot make two separate MySQL queries any time a user connects with POP or IMAP, you can have it 'prefetch' the user's information at the same time it validates the password. That's what the 'prefetch' is about. However, because we want Dovecot's LDA to be responsible for delivering mail to user's folders, it has to have a way of looking up that user information even when there isn't anyone logging in with a password to validate. That's why we still need the 'userdb sql' stanza AFTER the prefetch stanza.

Set the user account that's Dovecot's authentication process will run as. I'm using the 'vmail' user we created earlier.

Terminal Window
[root@mail1 ~]# vim /etc/dovecot/conf.d/10-master.conf
........................................
........................................
........................................
service auth {
  # auth_socket_path points to this userdb socket by default. It's typically
  # used by dovecot-lda, doveadm, possibly imap process, etc. Its default
  # permissions make it readable only by root, but you may need to relax these
  # permissions. Users that have access to this socket are able to get a list
  # of all usernames and get results of everyone's userdb lookups.
  unix_listener auth-userdb {
    mode = 0600
    user = vmail
    group = vmail
  }
........................................
........................................
service dict {
  # If dict proxy is used, mail processes should have access to its socket.
  # For example: mode=0660, group=vmail and global mail_access_groups=vmail
  unix_listener dict {
    mode = 0600
    user = vmail
    group = vmail
  }
}

Configure Dovecot to access user info from MySQL

As with Postfix, we need to create another file containing the database settings. There's a sample of this file in the documentation that comes with Dovecot (/usr/share/doc/dovecot-XXX), so you can copy that to the /etc/ folder. As an alternative you can copy the one presented here. This file is responsible for Dovecot to connect with MySQL server.

Terminal Window
[root@mail1 ~]# vim /etc/dovecot/dovecot-mysql.conf
driver = mysql
connect = host=localhost dbname=postfixdb  user=mailadmin password=your_password
default_pass_scheme = CRAM-MD5
user_query    = SELECT CONCAT('/mailboxes/vmail/',domain,'/',local_part) AS home,901 AS uid, \
901 AS gid, CONCAT('*:bytes=', quota) as quota_rule FROM mailbox WHERE username = '%u' AND active='1'
password_query = SELECT username AS user, password, CONCAT('/mailboxes/vmail/',domain,'/',local_part ) \
AS userdb_home, 901 AS userdb_uid, 901 AS userdb_gid,CONCAT('*:bytes=', quota) as userdb_quota_rule \
FROM mailbox WHERE username = '%u' AND active='1'
Please note that the user_query and password_query are all on the same line. Also note the default_pass_scheme is set to
CRAM-MD5.

Configure Dovecot Transports in Postfix

We are trying to make dovecot to deliver user mail to their mailboxes. In other words Dovecot will act as a Local Delivery Agents (LDA), so when a user tries to login Dovecot will assess user credentials(SASL) and when that passes, postfix hands over the delivery job to Dovecot to locate the respective mail box and put the mail there. A Local Delivery Agent (LDA) is the program that finally places the messages in a user's inbox. Postfix has its own component that can do this, but using Dovecot's LDA has some advantages. It offers some extra features such as quota enforcement, and autoresponders. Furthermore, it does indexing-on-delivery that reportedly makes it faster to access email with IMAP.

Terminal Window
[root@mail1 ~]# vim /etc/postfix/main.cf
# TRANSPORT MAP
#
##   Either one of the options "virtual" or "dovecot" should work.
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1

We need to define transports in another major postfix files that /etc/postfix/master.cf. Add these lines to the very
end of file.

Terminal Window
[root@mail1 ~]# vim /etc/postfix/master.cf
# Dovecot LDA, as explained here: http://wiki2.dovecot.org/LDA/Postfix
# The following should be one single line.
dovecot   unix  -       n       n       -       -       pipe flags=DRhu user=vmail:vmail \
argv=/usr/libexec/dovecot/dovecot-lda -f ${sender} -d ${recipient}



STEP: 14 Test the installation

We have now configured the server half way and it's time for some stocktake of the installation. We should now see that
all services are started without any errors or warnings. Open another window or terminal and check live logs using the tail command. And now in the original window or terminal restart the services as follows:

Terminal Window
[root@mail1 ~]# service mysqld  restart
[root@mail1 ~]# service postfix restart
[root@mail1 ~]# service dovecot restart
[root@mail1 ~]# service httpd   restart

If any of the services did not restart or gave an error "failed" then something is wrong and needs immediate attention. Using your other windows or terminals you should check what those errors or warnings in the log files, and rectify them now to avoid further confusion. If everything works alright, you should take a back up of the configuration files of postix and dovecot.




STEP: 15 Install RoundCube Webmail

  • Prepare MySQL Database for Roundcube Webmail.
  • Access Roundcube webmail over the web
  • Further configuration of Roundcube Webmail
  • Enable vacation,managesieve,userinfo,serverinfo plugins

Before we install Rounducube webmail, we need to decompress the tar file and put it under document root (/var/www/html). And give complete rights to apache (755) over the whole roundcube folder which must be owned be apache. Next we need to create an apache virtual host for roundcube webmail so that it can be accessed over the web.

Prepare MySQL Database for Roundcube Webmail.

We need to prepare the MySQL database for roundcube webmail. This involves creating the database and a user in MySQL who has all the privileges on that database. And this is how this is done:

Terminal Window
[root@mail1 ~]# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 763
Server version: 5.1.54-ius Distributed by The IUS Community Project
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> create database roundcube;
Query OK, 1 row affected (0.02 sec)
mysql> grant all privileges on roundcube.* to 'mailadmin'@'localhost' identified by 'your_password';
Query OK, 0 rows affected (0.02 sec)

We now have successfully created the roundcube database and given all privileges to mailadmin over the database. we need to import the table information from the roundcube SQL file which is supplied by roundcube tar file. Follow the steps below

Terminal Window
[root@mail1 ~]# mysql -u root -p  -D roundcube < /var/www/html/roundcubemail/SQL/mysql.initial.sql
## you will be asked the root password, just suppy the password and 
## you are good to go.

Access Roundcube webmail over the web

We have filled the database with the required table information and that will bring us to the last but one part of the installation. Fireup the web browser and point the address to http://you-roundcube-server-name/installer, to check whether you have completed the initial configuration correctly or not. It will also tell you where you have been wrong and lets you know what needs to be done. Satfisfy all the requirements as installer lets you know.

Further configuration of Roundcube Webmail

Once you have completed the installer requirements then we need to setup how Roundcube can access your IMAP folders and SMTP to use CRAM-MD5 passwords. You can also do this in the installer section of roundcube webmail. Just incase you have missed the part here you can do it manually.

Terminal Window
 vim /var/www/html/roundcubemail/config/main.inc.php
........................................
........................................
........................................
## IN the IMAP SECTION
$rcmail_config['imap_auth_type'] = 'CRAM-MD5';
........................................
........................................
........................................
## then in the SMTP SECTION
$rcmail_config['smtp_auth_type'] = 'CRAM-MD5';
........................................
........................................
........................................

Enable vacation,managesieve,userinfo,serverinfo plugins

Vacation Plugin
We want to make sure that users will be able to send vacation messages on their own from roundcube webmail. To enable this first we must ensure we have installed the vacation script in postfixadmin. Only after that we can use the vacation plugin that you can download from the roundcube webmail plugins site. This is because the vacation plugin uses the same database structure as the postfixadmin SQL schema. So first make sure you have that working first. Next within the vacation plugin folder which is /var/www/html/roundcubemail/plugins/vacation copy the file config.inc.php.dist to config.inc.php and edit the file as below:

Before you can install this plugin make sure that you install jquery ui plugin as you will be shown a calendar to choose the range of dates your vacation script would be active.
Terminal Window
[root@mail1 ~]# cd /var/www/html/roundcubewebmail/plugins/vacation/
[root@mail1 vacation]# cp config.inc.php.dist config.inc.php
[root@mail1 vacation]# vim config.inc.php
........................................
........................................
// allow vacation start/end dates
$rcmail_config['vacation_gui_vacationdate'] = TRUE;
// allow vacation subject
$rcmail_config['vacation_gui_vacationsubject'] = TRUE;
// allow HTML for vacation message 
$rcmail_config['vacation_gui_vacationmessage_html'] = FALSE;
// allow sending message to be keep in inbox
$rcmail_config['vacation_gui_vacationkeepcopyininbox'] = FALSE;
// allow vacation forwarder
$rcmail_config['vacation_gui_vacationforwarder'] = TRUE;
// default vacation subject
$rcmail_config['vacation_subject_default'] = 'Out of office';
// default vacation message
$rcmail_config['vacation_message_default'] = 'I\'m currently out of office.';
// vacation start/end date format
$rcmail_config['vacation_dateformat'] = 'm/d/Y';
// jquery calendar (jqueryui plugin must be enabled)
$rcmail_config['vacation_jquery_calendar'] = TRUE;
$rcmail_config['vacation_jquery_dateformat'] = 'mm/dd/yy';
........................................
........................................
// driver used for backend storage
$rcmail_config['vacation_driver'] = 'sql';
/*
 * SQL driver
 */
// database DSN
$rcmail_config['vacation_sql_dsn'] =
	'mysql://mailadmin:your_password@localhost/postfix';

You can configure the rest of the options in that file as you can see fit. The key point you can remember is this once your vacation script is working with postfixadmin this plugin would work the same way. If does not work in postfix admin this would probably not work here as well.

ManageSieve
We want users to create their own mail filters and store them at the server level,so that they would not lose their mail settings, and how they would like their mail be delivered etc,. The big advantage with this is that all users will be able to deliver their mail to designated folders by subject, content,who sent the email and so on. When using dovecot ManageSieve is a small server within the Dovecot service, that enables this facility. We have not done the configuration regarding this in Dovecot but since we want this facility we should do it here. Further down I'll talk to you about ManageSieve service even further. Now, go to the managesieve plugin folder that is /var/www/roundcubemail/plugins/managesieve and copy the file config.inc.php.dist config.inc.php and edit it as follows:

Terminal Window
[root@mail1 ~]# cd /var/www/html/roundcubewebmail/plugins/managesieve/
[root@mail1 managesieve]# cp config.inc.php.dist config.inc.php
[root@mail1 managesieve]# vim config.inc.php
// managesieve server port
$rcmail_config['managesieve_port'] = 4190;
// managesieve server address, default is localhost.
// Replacement variables supported in host name:
// %h - user's IMAP hostname
// %n - http hostname ($_SERVER['SERVER_NAME'])
// %d - domain (http hostname without the first part)
// For example %n = mail.domain.tld, %d = domain.tld
$rcmail_config['managesieve_host'] = 'localhost';
// authentication method. Can be CRAM-MD5, DIGEST-MD5, PLAIN, LOGIN, EXTERNAL
// or none. Optional, defaults to best method supported by server.
$rcmail_config['managesieve_auth_type'] = 'CRAM-MD5';
// change the other settings as you see fit.

The userinfo and the serverinfo plugins can be downloaded from the plugins website of roundcube and can be configured as per you liking. There are also heaps of other plugins that you can install and play with. However for clarity sake I am offering you my roundcube installation as a download. Change the settings of main.inc.php and db.in.php and all the plugins are also enabled, so enjoy. [DOWNLOAD HERE]

STEP: 16 Install ClamAV Antivirus

Installing Clam Antivirus in an rpm based system is much easier. Just enable RPMForge repository, and run the following commands.

Terminal Window
[root@mail1 ~]# yum install clamav clamav-devel clamd clamav-db
### That should install all the nececessary software as far as
### ClamAV is concerned.  We will look into this further.

STEP: 17 DSPAM (Anti-Spam software)

  • Prepare the system before installing DSPAM
  • Install DSPAM
  • Configure DSPAM with MySQL
  • Further Configure DSPAM and integrate ClamAV
  • Configure Postfix to integrate DSPAM
  • Install and configure Dspam WebUI
  • Configure DSPAM WebUI configure.pl
  • Complete the configuration of DSPAM WebUI
  • Change permissions of DSPAM data directory (/var/lib/dspam)
  • Integrate DSPAM AntiSpam Plugin in Dovecot
  • Creating DSPAM Groups and configuring a global group for all users
  • Test Dspam is tagging and delivering email as intended

Prepare the system before installing DSPAM

Before we install DSPAM we need to create a user and group called dspam with a userid and groupid higher than 500, this is because when you install dspam the package installs a user dspam whose id is less than 500. This causes a lot of problems when you want to configure the DSPAM WebUI with suexec. We also need to make sure that we put the user dspam in other groups such as mail, vmail and postfix. Follow the instructions below as is and you will avoid a lot of headache.
Terminal Window
[root@mail1 ~]# mkdir -p /var/lib/dspam
[root@mail1 ~]# groupadd -g 590 dspam
[root@mail1 ~]# useradd -g 590 -u 590 -s /sbin/nologin -d /var/lib/dspam 
                -c "User to own dspam directories and default processess" dspam
// we need to add the dspam user in some groups.
[root@mail1 ~]# gpasswd -a dspam mail
[root@mail1 ~]# gpasswd -a dspam vmail
[root@mail1 ~]# gpasswd -a apache dspam
[root@mail1 ~]# gpasswd -a vmail dspam
//if you do not find postfix in the mail group
[root@mail1 ~]# gpasswd -a postfix mail

Installing DSPAM

Installing DSPAM (Anti-Spam Software) is quite important. We can put filters on incoming mail at the server level and clean up without much administrator intervention. Please note DSPAM can only tag emails and cannot automatically remove suspicious and virus email. We need to use another technique for that. The best part is once DSPAM is trained we can have 99% accuracy in detecting spam and tagging that email. Training DSPAM is all the more important than just keeping it like that after intalling it. We can install DSPAM using the following command. This will not only install DSPAM but will also install all the perl dependencies.

I have manually created DSPAM RPMS from source, with some modifications compared to ones you get in all the repositories. I have added support for domain-scale and debug options. You can download them for RHEL/CENTOS 6 only. My earlier download of mailserver.tar.gz contains the folder for DSPAM. However here is the link again. [DOWNLOAD HERE]

Once you have downloaded the tar file extract the contents. When you install the packages through yum you might get the error that the packages are not signed. Issue the flag "--nogpgcheck" to the yum command to get around it.

Terminal Window
[root@mail1 ~]# cd /to/dspam/rpms/
[root@mail1 ~]# yum localinstall dspam-*  --nogpgcheck

Now you have successfully installed DSPAM. It is time that you had a look at the permissions of the directory /var/lib/dspam it should be owned by dspam and mail as user and group respectively. It would be better if you changed the complete ownership and group ownership to dspam and give it all rights to all users as this would get rid of humungus load of crap later in the form of permission denied errors. It would also help to change the permissions of dspam binary file.

Terminal Window
[root@mail1 ~]# cd /var/lib/
[root@mail1 ~]# chown -R dspam:dspam dspam/; chmod -R 777 dspam/
[root@mail1 ~]# chmod 755 /usr/bin/dspam

Configure DSPAM with MySQL

Our whole mail server setup is using virtual users, that means that users are not on the system, but MySQL database, So we need to use DSPAM with MySQL so as to correctly identify the users and their spam ratings. In RPM based systems the locations of DSPAM files is quite tricky. And configuring DSPAM on the whole is quite tricky in itself, but we'll try to configure it so as that it will have minimal administrative overhead. To configure DSPAM with MySQL, DSPAM installs it's MySQL scripts in /usr/share/dspam/sql-scripts folder. We create a database and a user and use the scripts in the above mentioned folder to populate the database with tables. So here we go

Terminal Window
[root@mail1 ~]# cd /usr/share/dspam/sql-scripts/
[root@mail1 sql-scripts]# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 763
Server version: 5.1.54-ius Distributed by The IUS Community Project
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> create database dspam;
Query OK, 1 row affected (0.02 sec)
mysql> grant all privileges on dspam.* to 'spamadmin'@'localhost' identified by 'your_password';
Query OK, 0 rows affected (0.02 sec)
mysql>\q
[root@mail1 sql-scripts]# mysql -u root -p  -D dspam < mysql/mysql_objects-speed.sql
##  you will be asked for the root password, give it and you are good to go.
[root@mail1 sql-scripts]# mysql -u root -p  -D dspam < mysql/virtual_users.sql
## the same as above.

Since we are using virtual users in our setup we would like to use the virtual_users.sql tables that comes with the dspam scripts. And also insert a record for vmail user as this user has access to all mailboxes.

Terminal Window
## in the MySQL prompt insert a record into the 
## dspam_virtual_uids table.
mysql > insert into dspam_virtual_uids values('901', 'vmail');

Further Configure DSPAM and integrate ClamAV

Now is the time that we need to configure DSPAM itself of how its gonna tag email, and how it will integrate ClamAV in it's operations. This is how its done. The set up uses the content filter feature of postfix, that means that all mail is handed over to DSPAM for processing and DSPAM reinjects the mail after tagging it into postfix queue, which in turn hands over mail to dovecot to be put in the appropriate mailbox. This approach is good because all incoming and outgoing mail are checked. We can also implement rules so that postfix can stop some mail from going out. For example you might want to ban all emails that have '.exe' as an attachment, or sensitive documents that have valid extensions. We can write restrictions in posfix to ban all such emails either from coming in or going out. We can also introduce Postfix UCE(unsolicited commercial email) from reaching our servers.

Configure DSPAM as follows as these might give a clearer understanding.

Terminal Window
[root@mail1 ~]# vim /etc/dspam.conf
.....................................
........................................
........................................
## configure and check the location of this,
## if you have built the DSPAM on your own
## this location may differ.
Home /var/lib/dspam
........................................
........................................
##  We are using mysql to store all user data
##  so we need to tell DSPAM to use MySQL 
##  to use it.  Also check the location of the 
##  socket file.
StorageDriver /usr/lib/dspam/libmysql_drv.so
........................................
........................................
........................................
##  We are asking dovecot to deliver mail to 
##  the mailboxes.  So when DSPAM is finised 
##  scanning mail it will hand over the 
##  deliverjob to Dovecot.  So here is the 
##  setting that does this.
TrustedDeliveryAgent "/usr/libexec/dovecot/deliver-lda -d %u"
........................................
........................................
# If you would like to set up DeliveryHost's on a per-domain basis, use
# the syntax: DeliveryHost.domain.com 1.2.3.4
#
DeliveryHost		127.0.0.1
DeliveryPort		10024
DeliveryIdent		localhost
DeliveryProto		SMTP
........................................
........................................
........................................
........................................
........................................
........................................
OnFail unlearn
........................................
........................................
........................................
# Trusted Users: Only the users specified below will be allowed to perform
# administrative functions in DSPAM such as setting the active user and
# accessing tools. All other users attempting to run DSPAM will be restricted;
# their uids will be forced to match the active username and they will not be
# able to specify delivery agent privileges or use tools.
#
Trust root
Trust dspam
Trust apache
Trust mail
Trust mailnull
Trust smmsp
Trust daemon
Trust amavis
Trust vmail
Trust postfix
#Trust nobody
#Trust majordomo
........................................
........................................
........................................
### DEBUG OPTIONS to verify that dspam is 
### indeed working.  Comment them when you 
### feel its working all right.
Debug *
# Debug bob bill
DebugOpt process spam fp
TrainingMode teft
........................................
........................................
#
# TestConditionalTraining: By default, dspam will retrain certain errors
# until the condition is no longer met. This usually accelerates learning.
# Some people argue that this can increase the risk of errors, however.
#
TestConditionalTraining on
........................................
........................................
........................................
........................................
Feature whitelist
........................................
........................................
........................................
Algorithm graham burton
........................................
........................................
Tokenizer chain
........................................
........................................
PValue bcr
#
# WebStats: Enable this if you are using the CGI, which writes .stats files
WebStats on
........................................
........................................
........................................
Preference "trainingMode=TEFT"		# { TOE | TUM | TEFT | NOTRAIN } -> default:teft
Preference "spamAction=tag"	# { quarantine | tag | deliver } -> default:quarantine
Preference "spamSubject=[SPAM]"		# { string } -> default:[SPAM]
Preference "statisticalSedation=5"	# { 0 - 10 } -> default:0
Preference "enableBNR=on"		# { on | off } -> default:off
Preference "enableWhitelist=on"		# { on | off } -> default:on
Preference "signatureLocation=headers"	# { message | headers } -> default:message
Preference "tagSpam=on"		# { on | off }
Preference "tagNonspam=off"		# { on | off }
Preference "showFactors=on"		# { on | off } -> default:off
Preference "optIn=off"			# { on | off }
Preference "optOut=off"			# { on | off }
Preference "whitelistThreshold=10"	# { Integer } -> default:10
Preference "makeCorpus=off"		# { on | off } -> default:off
Preference "storeFragments=off"		# { on | off } -> default:off
Preference "localStore="		# { on | off } -> default:username
Preference "processorBias=on"		# { on | off } -> default:on
Preference "fallbackDomain=off"		# { on | off } -> default:off
Preference "trainPristine=off"		# { on | off } -> default:off
Preference "optOutClamAV=off"		# { on | off } -> default:off
Preference "ignoreRBLLookups=off"	# { on | off } -> default:off
Preference "RBLInoculate=off"		# { on | off } -> default:off
Preference "notifications=off"		# { on | off } -> default:off
........................................
........................................
........................................
........................................
........................................
........................................
##  Check the location of the mysql.sock file 
##  in your system.
MySQLServer             /var/lib/mysql/mysql.sock
MySQLPort               3306
MySQLUser               spamadmin
MySQLPass               your_password
MySQLDb                 dspam
MySQLCompress		true
MySQLReconnect		true
........................................
........................................
........................................
MySQLVirtualTable               dspam_virtual_uids
MySQLVirtualUIDField            uid
MySQLVirtualUsernameField       username
........................................
........................................
MySQLUIDInSignature     on
........................................
........................................
........................................
........................................
# --- Hash ---
........................................
........................................
HashRecMax		98317
........................................
........................................
HashAutoExtend		on
........................................
........................................
HashMaxExtents		0
........................................
........................................
HashExtentSize		49157
........................................
........................................
HashPctIncrease		10
........................................
........................................
HashMaxSeek		100
........................................
........................................
#HashConcurrentUser	user
........................................
........................................
HashConnectionCache	10
........................................
........................................
........................................
........................................
Notifications	off
#
# Purge configuration: Set dspam_clean purge default options, if not otherwise
# specified on the commandline
#
PurgeSignatures 14	# Stale signatures
PurgeNeutral	90	# Tokens with neutralish probabilities
PurgeUnused	90	# Unused tokens
PurgeHapaxes	30	# Tokens with less than 5 hits (hapaxes)
PurgeHits1S	15	# Tokens with only 1 spam hit
PurgeHits1I	15	# Tokens with only 1 innocent hit
........................................
........................................
........................................
LocalMX 127.0.0.1
#
# Logging: Disabling logging for users will make usage graphs unavailable to
# them. Disabling system logging will make admin graphs unavailable.
#
SystemLog	on
UserLog		on
........................................
........................................
Opt out
........................................
........................................
TrackSources spam ham virus
........................................
........................................
ParseToHeaders on
ChangeModeOnParse on
ChangeUserOnParse full
........................................
........................................
........................................
ClamAVPort              3310
ClamAVHost              127.0.0.1
ClamAVResponse          spam
........................................
........................................
ServerHost		127.0.0.1
ServerPort		11124
ServerQueueSize  	32
ServerPID		/var/run/dspam/dspam.pid
........................................
........................................
ServerMode auto
........................................
........................................
ServerPass.Relay1       "secret"
........................................
........................................
ServerParameters        "--deliver=innocent -d %u"
ServerIdent             "localhost.localdomain"
........................................
........................................
ServerDomainSocketPath  "/var/run/dspam/dspam.sock"
........................................
........................................
........................................
ClientHost	127.0.0.1
ClientPort	11124
ClientIdent	"secret@Relay1"
........................................
........................................
ProcessorURLContext on
........................................
........................................
ProcessorBias on
........................................
........................................
StripRcptDomain off
........................................

It is time now to test whether dspam is able to start or not. If it does not start normally then you must figure out how to start dspam. Remember this is a very important part in our mail server setup. Google if possible, but get this thing working otherwise we will walk into unwanted confusion. You should see something similar when we start dspam for the first time.

Terminal Window
[root@mail ~]# service dspam start
Starting dspam:                                            [  OK  ]
[root@mail ~]# 

Configure Postfix to integrate DSPAM

We need to configure Postfix to integrate DSPAM. Here we are installing DSPAM as a content filter and not as a proxy between postfix and dovecot, since dovecot is dealing with mail delivery. To do this we have to change some options in the main.cf.

Terminal Window
[root@mail1 ~]# vim /etc/postfix/main.cf
........................................
........................................
transport_maps = hash:/etc/postfix/transport
dspam_destination_recipient_limit = 1
##  Append this to the virtual_mailbox_maps: 
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf,
		       hash:/etc/postfix/dspam_aliases.
##  The contents of the dspam_aliases files.
[root@mail1 ~]# cat /etc/postfix/dspam_aliases
spam@example.com      2
ham@example.com       6
##   The contents of the transport file is as follows:
[root@mail1 ~]# cat /etc/postfix/transport
spam@example.com  dspam-spam:{$1}
ham@example.com   dspam-notspam:{$1}
vmail@example.com  dspam-eatvmail:{$1)
autoreply.example.com	vacation:

We need to define dspam content filter settings,transport in the master.cf for spam,ham and vacation, This we need to do so that we can forward spam and ham for retraining purposes. Suppose user A gets spam in his inbox then forwarding that email to spam@example.com will train DSPAM to identify and tag those emails as spam in the future. Do this right after the smtp line in the master.cf file.

Terminal Window
[root@mail1 ~]# vim /etc/postfix/master.cf
smtp      inet  n       -       n       -       -       smtpd
############################################################################
#  DSPAM Specific Configuration						   #
############################################################################
## DSPAM CONTENT FILTER BEGIN
smtp  inet     n      -       n       -          -    smtpd
   -o content_filter=lmtp:unix:/var/run/dspam/dspam.sock
## DSPAM ->POSTFIX => REINJECTION
localhost:10024 inet  n -       n       -       -        smtpd
  -o content_filter=
  -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
  -o smtpd_helo_restrictions=
  -o smtpd_client_restrictions=
  -o smtpd_sender_restrictions=
  -o smtpd_recipient_restrictions=permit_mynetworks,reject
  -o mynetworks=127.0.0.0/8
  -o smtpd_authorized_xforward_hosts=127.0.0.0/8
## DSPAM CONTENT FILTER END
## DSPAM RETRAIN BEGIN
#handle dspam retrain
## This path is used when a user sends in a piece of mail and 
## wants to classify it as SPAM
dspam-spam           unix   -   n   n   -   -   pipe
    flags=Rhq user=vmail argv=/usr/bin/dspam --mode=teft --user vmail 
    --class=spam --source=error ${sender} --deliver=spam
## This path is used when a user sends in a piece of mail and 
## wants to classify it as INNOCENT
 
dspam-notspam        unix   -   n   n   -   -   pipe
    flags=Rhq user=vmail argv=/usr/bin/dspam --mode=teft --user vmail 
    --class=innocent --source=error ${sender} --deliver=innocent
## This path is used to prevent goofy delivery problems when 
## mail reclassification is going on.
 dspam-eatvmail        unix   -   n   n   -   -   pipe
   flags=Rhq user=vmail argv=/bin/cat /dev/null
## DSPAM RETRAIN END 
############################################################################
## ADD THIS TO THE VERY END OF master.cf file AFTER  dovecot transport     #
############################################################################
#  Vacation Auto Responder						   #
############################################################################
vacation   unix  -       n       n       -       -       pipe  
   flags=Rq user=vacation argv=/var/spool/vacation/vacation.pl -f ${sender} -- ${recipient}

We need to restart postfix and dspam now, take care there are no errors or warnings, if you come across some issues try to resolve them now. As we have come this far it's not wise to leave that to the very end otherwise debugging would be very nerve wrecking. Before you go about doing that just follow the steps presented here.

Terminal Window
[root@mail1 ~]# postmap /etc/postfix/dspam_aliases
[root@mail1 ~]# postmap /etc/postfix/transport
[root@mail1 ~]# service postfix restart
[root@mail1 ~]# chkconfig --levels 345 dspam on
[root@mail1 ~]# service dspam start

Install and configure Dspam WebUI

We have already installed DSPAM WebUI, the perl script from which you can manage your DSPAM installation. This is a really nice feature of DSPAM, it also confirms to us that mail has indeed been tagged by DSPAM, we can independently tag or quarantine mail so that each user can manage his or her own spam settings. When you install dspam-web package it installs in /var/www/dspam directory. And the configuration file for it is saved in /etc/httpd/conf.d/dspam.conf file in the apache configuration directory.

It is highly advised to run /var/www/dspam folder under dspam user even when webserver is operating under apache. So suexec is a feature of apache that allows to execute a directory as another user apart from apache. Before we do this we need to see what the minimum requirements of suexec are. We can find out by giving the following command.

Terminal Window
[root@mail1 ~]# suexec -V
 -D AP_DOC_ROOT="/var/www"
 -D AP_GID_MIN=100
 -D AP_HTTPD_USER="apache"
 -D AP_LOG_EXEC="/var/log/httpd/suexec.log"
 -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
 -D AP_UID_MIN=500
 -D AP_USERDIR_SUFFIX="public_html"

Here suexec says that the AP_DOC_ROOT must in under /var/www/ directory for suexec to work correctly, that means if you want to run suexec on any directory it should be in under /var/www/. The AP_UID_MIN means the minimun uid of any user that wants to suexec must be greater than 500, and the AP_GID_MIN means minimun gid of any group should be greater than 100, and the log file can be found in /var/log/httpd/suexec.log.

Now let us have a look under the directory /var/www/dspam. If it is owned by dspam and mail, change it like follows:
Remember when we installed dspam we changed the uid and gid of dspam user and group to 590.

Terminal Window
[root@mail1 ~]# cd /var/www/
[root@mail1 ~]# chmod -R 755 dspam
[root@mail1 ~]# chown -R dspam:dspam dspam/ 
[root@mail1 ~]# chmod 777 dspam/default.prefs

Configure DSPAM WebUI configure.pl

We need to configure the configure.pl file inside the dspam directory. which you must edit the following values as follows:

Terminal Window
[root@mail1 ~]# cd /var/www/dspam
[root@mail1 ~]# vim configure.pl
........................................
........................................
$CONFIG{'DSPAM_ARGS'}	= "--class=innocent " .
                          "--source=error $ENV{'REMOTE_USER'}
                           --user $ENV{'REMOTE_USER'} --rcpt-to ";
........................................
........................................
........................................
........................................
# Add customized settings below
$CONFIG{'LOCAL_DOMAIN'}	= "example.com";
........................................
........................................
# Autodetect filesystem layout and preference options
$CONFIG{'AUTODETECT'}	= 1;
........................................
........................................
# Or, if you're running dspam.cgi as untrusted, it won't be able to auto-detect
# so you will need to specify some features manually:
#$CONFIG{'AUTODETECT'}	= 0;
$CONFIG{'LARGE_SCALE'}	= 0;
$CONFIG{'DOMAIN_SCALE'}= 1;
$CONFIG{'PREFERENCES_EXTENSION'} = 1;
The preferences Extension should always be 1 if not user spam ratings are not recordred in mysql. If your dspam installation supports domain scale dspam ratings you can make to 1, else large scale will do. You can get a through rundown of all the options with which dspam was built by giving the command dspam --version.

Complete the configuration of DSPAM WebUI

Install mod_auth_imap for apache.
HTTP based authentication is the most common and easy-to-setup way of protecting content in apache. But with normal .htaccess/.htpasswd based protection, the problem is, .htpasswd file should be present in the webserver's filesystem, and in most cases those users are not local unix users.

mod_auth_imap attempts to overcome this limitation by allowing apache to authenticate against an IMAP server, local/remote/whatever. Setting up authentication with mod_auth_imap is also straightforward.

  • Download the mod_auth_imap tarball from
    http://ben.brillat.net/projects/mod_auth_imap/,
    and extract the contents.
  • Make sure apxs is installed (its available in httpd-devel)
  • Run # apxs -i -a -c mod_auth_imap.c as root user to
    build the apache module and install it in apache.
  • Make sure that mod_auth_imap module is enabled in your apache
    configuration.

Now let us look at the file /etc/httpd/conf.d/dspam-web.conf it will seem as a very simple virtual host configuration. But we need each of our users to manage their own spam ratings, preferences whether they want to tag email or quarantine spam email. In order to do just that I want each of my users to login with their email and password and manage their own spam. I had a choice whether I should be using mod_auth_mysql or mod_auth_imap, I chose the later cause I was using cram-md5 authentication with dovecot and I could not figure out a way to do that in Mysql.

Terminal Window
[root@mail1 ~]# vim /etc/httpd/conf.d/dspam-web.conf
#
# Web-UI for DSPAM.
#
Listen 8009
NameVirtualHost *:8009
<VirtualHost *:8009>
    ServerAdmin postmaster@localhost
    ServerName dspam.example.com
    DocumentRoot /var/www/dspam
    SuexecUserGroup dspam dspam
    Options Indexes FollowSymLinks ExecCGI
    # Given we are using Basic auth SSL would be handy.
    # You can use the same cert:key pair Apache uses.
    #SSLEngine on
    #SSLCertificateFile /etc/pki/tls/certs/hostname.cert
    #SSLCertificateKeyFile /etc/pki/tls/private/hostname.key 
    <Directory "/var/www/dspam">
            AllowOverride       None
            Options -Indexes +ExecCGI
            Order               allow,deny
            Allow               from all
            AuthBasicAuthoritative off 
	    Auth_IMAP_Enabled   on
 	    Auth_IMAP_Authoritative  on
	    AuthType            Basic
            AuthName            "DSPAM WebUI login"
            Auth_IMAP_Server    mail.example.com
	    Auth_IMAP_Port      143
            Auth_IMAP_Log   	on
            Require             valid-user
            
	    DirectoryIndex dspam.cgi
            AddHandler cgi-script .cgi .pl
    </Directory>
    ErrorLog /var/log/httpd/dspam-webgui-error_log
    CustomLog /var/log/httpd/dspam-webgui-access_log common
</VirtualHost>
Note the directives Listen and NameVirtualHost were added by us. We are just asking apache to advertise and listen for requests on the port 8009. Also look at the directive SuexecUserGroup is set to dspam, as its uid and gid is greater than 500 and 100 respecitvely. Remember UID and GID of dspam is 590 in our setup. Also look at the directives for mod_auth_imap.

Change permissions of DSPAM data directory (/var/lib/dspam)

We need to change the permissions of the /var/lib/dspam directory so that dspam webui will be able to write in /var/lib/dspam/data directory. Make the whole tree world writable. I know this might not be desirable, but it worked for me.

Terminal Window
[root@mail1 ~]# cd /var/lib
[root@mail1 lib]# chmod -R 777 dspam/

There is one thing that needs to be done here. As you keep adding new virtual users, they will be assigned a new folder to store their spam ratings at /var/lib/dspam/data/example.com/new_user. The new_user folder will be created all right, but dspam will not be able write into it, resulting in permission denied errors if you check your mail logs. That means dspam will not be able to keep track of spam and ham mail. In order to overcome this issue I have created a cron job to make the dspam data directory world writable every one minute.

Terminal Window
[root@mail1 ~]# vim /usr/bin/dspam-data-perm.sh
/bin/chmod -R 777 /var/lib/dspam/data
//save the file
:wq
[root@mail1 ~]# crontab -e
*	*	*	*	* 	/usr/bin/dspam-data-perm.sh
//save the cron job
:wq
[root@mail1 ~]# chmod 755 /usr/bin/dspam-data-perm.sh

This would run the above cron job every minute and dspam will be able to write new user settings in their respective directories,without any errors in the maillogs.

Integrate DSPAM AntiSpam Plugin in Dovecot

I would like to train DSPAM when the user puts any mail that is not legitimate into the spam folder. That way I do not let my users forward the mail to spam@example.com or ham@example.com. Even though that would be a good proposition, that consumes a little time and efforts on part of the users to train DSPAM. But looking at the possibility of dragging the mails to spam folder itself training DSPAM automatically is quite exciting. Remember with this setup you can forward yours mails to spam@example.com and ham@example.com to train DSPAM. You need to first download the Dovecot Antispam Plugin, and install it.

The configuration of the Antispam Plugin could be tricky but you need to first read all that is there from the urls below
http://wiki2.dovecot.org/Plugins/Antispam
Download the source code of the antispam plugin for Dovecot version2 from here
http://hg.dovecot.org/dovecot-antispam-plugin/
and install the dovecot antispam plugin as explained in the first URL. For convinience sake I have supplied the anitspam plugin in the dovecot packages download in step 3. You need to install the plugin in the /usr/lib/dovecot/ and change the file permission to 755 as follows:

Terminal Window
[root@mail1 ~]# cd /to/download/location
[root@mail1 ~]# cp lib90_antispam_plugin.so /usr/lib/dovecot/
[root@mail1 ~]# chmod 755 /usr/lib/dovecot/lib90_antispam_plugin.so

We need to configure the plugin in dovecot so that it will be able to forward spam and ham mail information to DSPAM. The settings might differ for different OS, but for CENTOS,REDHAT and FEDORA, the settings presented here should match. The settings are to be typed or edited in the 90-sieve.conf file.

Terminal Window
[root@mail1 ~]# cd /etc/dovecot/conf.d
[root@mail1 ~]# vim 90-sieve.conf
........................................
........................................
........................................
........................................
........................................
........................................
### AFTER the sieve_after stanza add the following:
antispam_backend = dspam
antispam_dspam_args = --source=error;--signature=%%s;--deliver;--user;%u
antispam_spam = spam;Spam
antispam_trash = trash;Trash;Deleted Items; Deleted Messages
antispam_unsure = trash;Trash
antispam_signature_missing = move
antispam_signature = X-DSPAM-Signature
antispam_dspam_binary = /usr/bin/dpsam
antispam_dspam_spam = --class=spam
antispam_dspam_notspam = --class=innocent
} ##this closing bracket would be the last or end of the file statement.

After that you can restart dovecot to see whether its restarting in the first place or not. Check you maillog for errors, as this could be very critical to see the setup is actually working. If you find any errors, google and find answers.

Terminal Window
[root@mail1 ~]# service dovecot restart
Stopping Dovecot Imap:			[ OK ]
Starting Dovecot Imap:			[ OK ]

If you did not find any errors or warning in the maillog files, then I can say now your email client will be training dspam as an when you put unwanted mails into your spam folder.

Creating DSPAM Groups and configuring a global group for all users

Global groups allows DSPAM to provide a "SpamAssassin type out-of-the-box filtering" for all new users until they have built their own useful dictionaries. In order to create a global group for new accounts to use until they have trained enough of their own spam, we need to create a file by the name "group" in /var/lib/dspam

Terminal Window
[root@mail1 ~]# echo "exampleGroup:classification:*globaluser@example.com" > /var/lib/dspam/group
[root@mail1 ~]# chown dspam:dspam /var/lib/dspam/group
[root@mail1 ~]# chmod 777 /var/lib/dspam/group

Run the following command so that dspam_clean doesn't purge your global definitions because the data is old

Terminal Window
[root@mail1 ~]# dspam_admin add pref globaluser@example.com trainingMode TOE

In order to provide a base of spam and ham for a global group, we'll use SpamAssassin's public corpus files. First, download them:

Terminal Window
[root@mail1 ~]# cd; mkdir /root/tmp/corpus -p; cd /root/tmp/corpus
[root@mail1 ~]# wget http://spamassassin.apache.org/publiccorpus/20030228_easy_ham.tar.bz2 
[root@mail1 ~]# wget http://spamassassin.apache.org/publiccorpus/20030228_easy_ham_2.tar.bz2 
[root@mail1 ~]# wget http://spamassassin.apache.org/publiccorpus/20030228_spam.tar.bz2 
[root@mail1 ~]# wget http://spamassassin.apache.org/publiccorpus/20050311_spam_2.tar.bz2

Then run dspam_train on the first set, 2500 non-spam and 500 spam:

Terminal Window
[root@mail1 ~]# tar -xvjf 20030228_easy_ham.tar.bz2
[root@mail1 ~]# tar -xvjf 20030228_spam.tar.bz2
[root@mail1 ~]# /usr/bin/dspam_train globaluser@example.com spam easy_ham
# Repeat with the second corpus set, 1400 non-spam and 1397 spam
[root@mail1 ~]# tar -xvjf 20030228_easy_ham_2.tar.bz2
[root@mail1 ~]# tar -xvjf 20050311_spam_2.tar.bz2
[root@mail1 ~]# /usr/bin/dspam_train globaluser@example.com spam_2 easy_ham_2

Once all your training has been completed, you need to use the spam and ham corpus you built to be used by other users, till they can build their own spam and ham corpus database. For that we will merge the globaluser@example.com corpus with all the other users of the mailserver. This way all users will be able to take advantage of the globaluser spam and ham corpus without starting from scratch. We can merge all users spam and ham corpus with the globaluser like follows:

Terminal Window
[root@mail1 ~]# dspam_merge user1@example.com, user2@example.com,user3@example.com...
                userN@example.com –o globaluser@example.com 

The above command will merge all users spam and ham corpus with globaluser@example.com. From now on all users (the number does not matter) will be able to identify spam and ham mail even though they did not build any corpus database of their own. They will use the same corpus database of globaluser@example.com and build their own from there.

For every new user you create you will need to merge that account with globaluser@example.com.
Like
dspam_merge newuser@example.com –o globaluser@example.com.

Suggested Readings:
http://dspam.git.sourceforge.net/git/gitweb.cgi?p=dspam/dspam;a=blob_plain;f=README;hb=HEAD
http://www.productionmonkeys.net/guides/qmail-server/content-filtering/spam/dspam/global-group

Test Dspam is tagging and delivering email as intended

We need to make sure that recieved emails are tagged and lmtp content filter and local deliver agent that is dovecot is in fact doing the job that they should be doing in real time. To do that we need to check the log files that is /var/log/maillog primarily. Here is a short excerpt from my maillog file which might be handy, to show that lmtp and lda infact are working.

Terminal Window
[root@mail1 ~]# multitail -i /var/log/maillog
Feb 13 16:39:23 mail postfix/smtpd[1785]: connect from mail.example.com[192.168.1.252]
Feb 13 16:39:23 mail postfix/smtpd[1785]: D4AA6E79: client=mail.example.com[192.168.1.252]
Feb 13 16:39:23 mail postfix/cleanup[1793]: D4AA6E79: message-id=<d6e252d4a7c63626aa5f74f9b69d1fb5@example.com>
Feb 13 16:39:24 mail postfix/qmgr[1322]: D4AA6E79: from=<john@example.com>, size=577, nrcpt=1 (queue active)
Feb 13 16:39:24 mail postfix/smtpd[1785]: disconnect from mail.example.com[192.168.1.252]
Feb 13 16:39:24 mail postfix/smtpd[1800]: connect from localhost[127.0.0.1]
Feb 13 16:39:24 mail postfix/smtpd[1800]: 8AA2AE7A: client=localhost[127.0.0.1]
Feb 13 16:39:24 mail postfix/cleanup[1793]: 8AA2AE7A: message-id=<d6e252d4a7c63626aa5f74f9b69d1fb5@example.com>
Feb 13 16:39:24 mail postfix/qmgr[1322]: 8AA2AE7A: from=<john@example.com>, size=1336, nrcpt=1 (queue active)
Feb 13 16:39:24 mail postfix/smtpd[1800]: disconnect from localhost[127.0.0.1]
Feb 13 16:39:24 mail postfix/lmtp[1795]: D4AA6E79: to=<john@example.com>, relay=mail.example.com
[/var/run/dspam/dspam.sock], delay=0.93, delays=0.18/0.06/0/0.69, dsn=2.6.0, status=sent 
(250 2.6.0 <john@example.com> Message accepted for delivery)
Feb 13 16:39:24 mail postfix/qmgr[1322]: D4AA6E79: removed
Feb 13 16:39:26 mail postfix/pipe[1801]: 8AA2AE7A: to=<john@example.com>, relay=dovecot,
delay=1.7, delays=0.23/0.05/0/1.4, dsn=2.0.0, status=sent (delivered via dovecot service)
Feb 13 16:39:26 mail postfix/qmgr[1322]: 8AA2AE7A: removed

Multitail is very good utility which you can download to view more than two or even three log files simultaneously. So here we see that postfix has indeed picked up the mail and handed it over to dspam lmtp (content filter) and dspam reinjected it back into postfix queue and dovecot has delivered the mail to its final destination. And the received email is tagged like follows in the header section.

Terminal Window
// This is a small excerpt from a mail which i sent to myself from roundcube
// Have a careful look at the header.
Return-Path: <john@example.com>
Delivered-To: john@example.com
Received: from localhost (localhost [127.0.0.1])
    by mail.example.com (Postfix) with SMTP id 8AA2AE7A
    for <john@example.com>; Mon, 13 Feb 2012 16:39:24 +1300 (NZDT)
Received: from mail.example.com (mail.example.com [192.168.1.252])
    by mail.example.com (Postfix) with ESMTP id D4AA6E79
    for <john@example.com>; Mon, 13 Feb 2012 16:39:23 +1300 (NZDT)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8;
    format=flowed
Content-Transfer-Encoding: 7bit
Date: Mon, 13 Feb 2012 16:39:23 +1300
From: john@example.com
To: <john@example.com>
Subject: [SPAM] ham not spam
Message-ID: <d6e252d4a7c63626aa5f74f9b69d1fb5@example.com>
X-Sender: john@example.com
User-Agent: Roundcube Webmail/0.7.1
X-DSPAM-Result: Spam
X-DSPAM-Processed: Mon Feb 13 16:39:24 2012
X-DSPAM-Confidence: 0.6327
X-DSPAM-Probability: 0.9999
X-DSPAM-Signature: 903,4f3885ec10361957051199
X-DSPAM-Factors: 15,
    Date*13, 0.15435,
    Date*16, 0.84176,
    Received*2012+16, 0.83905,
    Date*2012+16, 0.83905,
    Received*16, 0.83905,
    fas, 0.20433,
    Date*Mon, 0.77566,
    Received*example.com>+Mon, 0.77566,
    Received*Mon, 0.77566,
    Date*Feb+2012, 0.71284,
    Received*Feb, 0.71284,
    Date*Feb, 0.71284,
    Received*Feb+2012, 0.71284,
    From*john@example.com, 0.29357,
    Date*23+1300, 0.31229

STEP: 18 Install and Configure SQLGrey

SQLGrey is a policy server implementing greylisting to filter spam on Postfix mail servers. The principle of greylisting works on the basis that much spam is sent by spambots and other non RFC compliant MTAs. SQLGrey will temporarily reject new mail with error 450 "try again later" for a set period of time and will log the triplet CLIENT_IP / SENDER / RECIPIENT in it's database. If the sending server is RFC compliant, then it should resend the message at which point SQLGrey will check it's database for a match and accept the message.

However, a typical spambot mailer is likely to receive a huge number of bounced or rejected mail so spammers typically do not resend messages when they are temporarily rejected. Thus, any mail received from such sources is simply dropped by the mail server. This has the added advantage of reducing the filtering and processing overhead on the mail server as a large percentage of messages will simply be dropped before entering the MTA and will not need to be otherwise filtered or processed.

To install SQLGrey, run the following command

Terminal Window
[root@mail1 ~]# yum install SQLGrey

Then we need to configure SQLGrey in mysql. Just follow the steps shown below:

Terminal Window
[root@mail1 ~]# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 763
Server version: 5.1.54-ius Distributed by The IUS Community Project
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> create database sqlgrey;
Query OK, 1 row affected (0.02 sec)
mysql> grant all privileges on sqlgrey.* to 'spamadmin'@'localhost' identified by 'your_password';
Query OK, 0 rows affected (0.02 sec)
mysql>\q

SQLGrey needs to be configured before it can be used in postfix, we need to configure sqlgrey first in /etc/sqlgrey/sqlgrey.conf file so that the database details, configuration settings can be set.

Terminal Window
[root@mail1 ~]# vim /etc/sqlgrey/sqlgrey.conf
........................................
........................................
........................................
db_type = mysql
db_name = sqlgrey
db_host = localhost
db_user = spamadmin
db_pass = your_password
........................................
........................................
........................................

SQLGrey needs to be integrated with postfix so edit /etc/postfix/main.cf to include the following check_policy_service line within the smtpd_recipient_restrictions section as shown below (if you don't have a smtpd_recipient_restrictions section, then the following example will work fine):

Terminal Window
[root@mail1 ~]# vim /etc/postfix/main.cf
smtpd_recipient_restrictions = permit_sasl_authenticated, 
			       permit_mynetworks, 
			       reject_unauth_destination, 
			       check_policy_service inet:127.0.0.1:2501
#save main.cf
:wq
[root@mail1 ~]# service sqlgrey start

Everything should be working fine as far as sqlgrey is concerned. Otherwise you might have to cross check the maillog for errors.

Terminal Window
## Ensure SQLGrey automatically starts when the machine is booted: 
[root@mail1 ~]# chkconfig --levels 345 sqlgrey on
## Finally, we need to start the SQLGrey service and reload Postfix settings: 
[root@mail1 ~]# service sqlgrey start
[root@mail1 ~]# service postfix restart

STEP: 19 Configure SASL with Dovecot in Postfix

Since version 2.3, Postfix supports SMTP AUTH through Dovecot SASL as introduced in the Dovecot 1.0 series. If using Postfix obtained from a binary (such as a .rpm or .deb file), you can check if Postfix was compiled with support for Dovecot SASL by running the command:

Terminal Window
[root@mail1 ~]# postconf -a
cyrus
dovecot

By default, postfix uses the $mynetworks parameter to control access, i.e. who can send or relay mail through the mail server. There is no other authentication performed other than checking that the IP address of the user trying to send mail is part of a trusted network as specified in $mynetworks.

If you are only implementing a mail server where all your users are based on the same network then it is unlikely that you will need to use SASL or SSL/TLS. However, if there are mobile users that wish to use the mail server whilst away from base, we need a mechanism to authenticate them as trusted users so that they are able to send mail through the mail server.

SASL (Simple Authentication and Security Layer) provides a mechanism of authenticating users using their username and password. Probably the most well known implementation of SASL is provided by the Cyrus SASL library, but dovecot also has it’s own SASL implementation built in, and as we are already running dovecot we may as well use it for SASL rather than having to install and configure another package.

Firstly we need to make some changes in the file /etc/dovecot/conf.d/10-master.conf file, so that dovecot create /var/spool/postfix/private/auth file with postfix as userid and gid.

Terminal Window
[root@mail1 ~]# vim /etc/dovecot/conf.d/10-master.conf
........................................
........................................
........................................
# uncomment the following so that SASL will work
unix_listener /var/spool/postfix/private/auth {
	mode = 0666
	user = postfix
	group = postfix
}
........................................
........................................
........................................

Next we need to make certain changes in postfix so that SASL authentication can be enabled. Check carefully how this is done.

Terminal Window
[root@mail1 ~]# vim /etc/postfix/main.cf
........................................
........................................
........................................
####################################################################
###SERVER SIDE SASL AUTHENTICATION##################################
dovecot_destination_recipient_limit = 1
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl2_auth_enable = yes
smtpd_sasl_security_options = noanonymous,noplaintext
broken_sasl_auth_clients = yes
smtpd_sasl_local_domain =
smtpd_recipient_restrictions = permit_sasl_authenticated,
                               permit_mynetworks,
                               reject_unauth_destination,
			       check_policy_service inet:127.0.0.1:2501
#####################################################################
#####################################################################

Now restart Postfix and Dovecot Servers to see all is well.

STEP: 20 Configure SSL/TLS in Postfix for SMTP

So SASL is able to provide a mechanism to authenticate remote users by username and password who wish to send mail through the mail server. Additionally, remote users are able to retrieve mail through IMAP and/or POP3 mechanisms provided by dovecot. However, we have a problem in that these mechanisms are sending usernames and passwords in plain text across the Internet (SASL does support various encrypted authentication methods such as DIGEST-MD5 but these aren’t always universally supported by email client software). In this setup we are using CRAM-MD5 passwords. This poses a security risk as anyone can potentially intercept this information and steal login details so we need to encrypt the connection. SSL (Secure Sockets Layer), and more recently TLS (Transport Layer Security), offer a mechanism to encrypt communications between two hosts, in our case our mail server and our remote client. SSL was renamed TLS by the IETF as of version 3.1.

First we need to install a package called crypto-utils which provides genkey, which can be used to generate self signed certificates.

Terminal Window
[root@mail1 ~]# yum install crypto-utils
[root@mail1 ~]# genkey --days 3650 mail.example.com

We are trying to generate a self-signed certificate for a period of ten years for our server whose hostname is mail.example.com. Then the certificate and the key once generated will be placed in the /etc/pki/tls/certs and /etc/pki/tls/private respectively. We need to further configure /etc/postfix/main.cf as follows:

Terminal Window
[root@mail1 ~]# vim /etc/postfix/main.cf
........................................
........................................
........................................
........................................
........................................
........................................
#smtpd_use_tls = yes
smtpd_tls_auth_only = yes
smtpd_tls_security_level = may
smtpd_tls_key_file = /etc/pki/tls/private/mail.example.com.key
smtpd_tls_cert_file = /etc/pki/tls/certs/mail.example.com.cert
# smtpd_tls_CAfile = /etc/pki/tls/root.crt
smtpd_tls_loglevel = 1
smtpd_tls_session_cache_timeout = 3600s
smtpd_tls_session_cache_database = btree:/var/spool/postfix/smtpd_tls_cache
tls_random_source = dev:/dev/urandom
smtpd_tls_received_header = yes

'smtpd_tls_security_level = may' replaces the old 'smtpd_use_tls = yes' in postfix 2.3 and enables the use of tls. We have commented out smtpd_tls_CAfile but would use this setting to specify the certificate of any issuing root authority when using signed certificates. 'smtpd_tls_loglevel = 1' will log tls sessions to the postfix mail log (setting to level 0 turns off TLS logging and level 2 may be useful for debugging purposes). The smtpd_tls_session_cache settings cache TLS session keys for 1 hour between sessions and is recommended due to the relatively high cost of repeatedly negotiating TLS session keys for each connection.

The final setting, smtpd_tls_auth_only = yes, forces the use of TLS for SASL authentication and will not allow plain text authentication to occur unless a SSL/TLS session has been established. (It may be useful to commented out 'smtpd_tls_auth_only = yes' during testing so we can test that SSL/TLS is working but still fall back to plain text SASL authentication if SSL/TLS fails).

We now reload or restart postfix and check whether there are any errors or warnings. If not very good. We also need to check whether the mail server is offering any SSL/TLS connections. To check that we do as follows:

Terminal Window
[root@mail1 ~]# service postfix restart
[root@mail1 ~]# telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
220 mail.example.com ESMTP Postfix
EHLO example.com
250-mail.example.com
250-PIPELINING
250-SIZE 20480000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
quit
221 2.0.0 Bye
Connection closed by foreign host.

If everything is working as expected, we should see the server offering STARTTLS and because we have specified 'smtpd_tls_auth_only = yes', plain text SASL authentication (AUTH PLAIN LOGIN and AUTH=PLAIN LOGIN) is no longer available. Finally we need to configure our email clients to use encryption when sending mail:

Finally, if you found that that postfix is not advertising STARTTLS in the telnet session and your mail clients are unable to connect and send email through SSL there might be one small thing what we may have forgotten. Postfix comes with another configuration file that master.cf. Make the necessary changes as follows:

Terminal Window
[root@mail1 ~]# vim /etc/postfix/master.cf
........................................
........................................
........................................
smtps     inet  n     -     n     -     -     smtpd
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,\
     permit_mynetworks,reject
........................................
........................................
........................................

This should solve most of the problems. If this has not solved your errors, then you need to check with the offical documentation or goggle it.

STEP: 21 Configure Dovecot to use Sieve for Mail Filtering

In our installation section in STEP: 3 we have installed two packages called dovecot-sieve and dovecot-pigeonhole. These are helpful in writing and executing scripts over mailboxes. This also gives us the privilege of directing mail to various folders within the user email store. It is vital that at an enterprise level we have scripts that work on all user mailboxes so to maintain a universal level of control. We can refine the messages depending on the headers, body and attachments and various other criteria. We have the choice to redirect the mail to a particular folder, reject the message or accept it and discard it. It's completly up to us to do whatever we want with incoming email. To configure dovecot to use sieve scripts we need to make certain changes in /etc/dovecot.conf.

Sieve Configuration

To use Sieve, you will first need to make sure you are using Dovecot LDA or LMTP for delivering incoming mail to users' mailboxes. Then, you need to enable the Sieve plugin in your configuration files that i.e 15-lda.conf and 20-lmtp.conf as follows

Terminal Window
[root@mail1 ~]# vim /etc/dovecot/conf.d/15-lda.conf
........................................
........................................
protocol lda{
mail_plugins = $mail_plugins quota sieve
}
........................................
........................................
# and in lmtp
[root@mail1 ~]# vim /etc/dovecot/conf.d/20-lmtp.conf
........................................
........................................
protocol lmtp {
  mail_plugins = $mail_plugins quota sieve
}
# go to the dovecot 2 wiki page for more configurations at 
# http://wiki2.dovecot.org/Pigeonhole/Sieve

ManageSieve Configuration

Along with all other binaries that Dovecot uses, the managesieve and managesieve-login binaries are installed during the install of the Pigeonhole package. The only thing you need to do to activate the ManageSieve protocol support in Dovecot is to add sieve to the protocols= configuration line in your /etc/dovecot/dovecot.conf. The managesieve daemon will listen on port 4190 by default. As the implementation of the managesieve daemon is largely based on the original IMAP implementation, it is very similar in terms of configuration.

Terminal Window
[root@mail1 ~]# vim /etc/dovecot/dovecot.conf
........................................
........................................
protocols = imap pop3 lmtp sieve

Then we again we edit /etc/dovecot/conf.d/20-managesieve.conf file as follows:

Terminal Window
[root@mail1 ~]# vim /etc/dovecot/conf.d/20-managesieve.conf
#uncomment to enable managesieve protocol
protocols = $protocols sieve
service managesieve-login{
   inet_listener sieve{
   port = 4190
}
service_count = 1
process_min_avail = 0
vsz_limit = 64M
}
# go to the dovecot 2 wiki page for more configurations at 
# http://wiki2.dovecot.org/Pigeonhole/ManageSieve/Configuration

Sieve Script Locations

We want to store all users sieve scripts in secure and a clear location, so that it does not interfere with mail files inside the mail store. Remember our mail store is at /mailboxes/vmail/example.com/user1, user2,user3 ...... Now we have to store the sieve scripts in /mailboxes/vmail/SieveStore/example.com/user1 user2 user3 ........... and so on. It also recommended to store the sieve scripts outside the mail store. In order to tell dovecot to store the sieve scripts in the above locations we need to edit /etc/dovecot/conf.d/90-sieve.conf.

All sieve scripts must end with a .sieve extension.
Terminal Window
[root@mail1 ~]# mkdir -p /var/dovecot/conf.d/example.com/
[root@mail1 ~]# vim /etc/dovecot/conf.d/90-sieve.conf
........................................
........................................
# %d means domain part
# %n means user part
# within the plugin stanza
 sieve =  /mailboxes/vmail/SieveStore/%d/%n/sieve/.dovecot.sieve
........................................
........................................
sieve_global_path = /var/dovecot/conf.d/%d/global.sieve
........................................
........................................
sieve_dir = /mailboxes/vmail/SieveStore/%d/%n/sieve
........................................
........................................
sieve_global_dir = /var/dovecot/conf.d/%d
........................................
........................................
sieve_extensions = fileinto envelope encoded-character copy +body variables
		   vacation imap4flags reject regex +include +notify +imapflags
........................................
........................................
sieve_before = /var/dovecot/conf.d/%d
........................................
........................................
sieve_after = /mailboxes/vmail/SieveStore/%d/%n/sieve	

A little explanation for the above settings:
sieve = /mailboxes/vmail....................... is the path to the individual sieve script file. This file gets executed first if its there.
sieve_global_path is the global sieve script. It gets executed only if there is NO user script
sieve_dir is the path to personal include scripts that user wants to execute apart from the first script
global_include script is the path to include scripts so that all users can execute on their mailboxes
sieve_extensions list of the sieve extensions that we want to have for this mail server setup
sieve_before is the path to a script store location where all scripts can be executed before the execution of the user script(s)
sieve after is the path to a script store location where all the scripts can be executed after the execution of the user script(s)

Order of Sieve Scripts Execution

The order of executiion of sieve scipts in dovecot is very straight forward . All the sieve_before scripts are executed first (if setting done) then user scripts are executed and then sieve_after scripts are executed in the end.

Using RoundCube managesieve plugin

Here are a few screen shots of using the managesieve plugins. In Step 15 roundcube managesieve configuration has already been explained.


Test Sieve Scripts are working as intended

To test and see whether sieve scripts are really working we must enable logging in debug mode and that can be done in /etc/dovecot/conf.d/10-logging.conffile.

Terminal Window
[root@mail1 ~]# vim /etc/dovecot/conf.d/10-logging.conf
........................................
........................................
info_log_path = /etc/dovecot/conf.d/example.com/dovecot-deliver.log
........................................
........................................
debug_log_path = /var/log/dovecot/sieve.log
mail_debug = yes
#save the file
:wq
# you should see some thing like the one below in your deliver logs to know that 
# sieve is indeed working.
Feb 21 23:38:25 lda(johndoe@example.com): Info: sieve: 
msgid=<22c217ac11cbe0f1ccea180a4d5f7ac6@example.com>: stored mail in
to mailbox 'INBOX.Spam'
#  I have already written scripts for such kind of email.

Then we need to create a directory under /var/ called dovecot/conf.d/example.com which will hold the global sieve script and log file for dovecot-deliver.log which will log all mail deliveries by dovecot local delivery agent.

Terminal Window
[root@mail1 ~]# mkdir -p /var/dovecot/conf.d/example.com/
[root@mail1 ~]# touch /var/dovecot/conf.d/example.com/dovecot-deliver.log 
[root@mail1 ~]# touch /var/dovecot/conf.d/example.com/global.sieve
[root@mail1 ~]# chown -R vmail:vmail /var/dovecot
[root@mail1 ~]# chmod -R 700 /var/dovecot

Now we are ready to write scripts to filter mail boxes. an example script has been given here as an example so that you can make an attempt to write your own. The following script checks for DSPAM headers and if a spam message is found the message is put into the users Spam folder. And finally you might have to start the dovecot service again to see that there are no errors or warnings.

Terminal Window
[root@mail1 ~]#  vim /var/dovecot/conf.d/example.com/global.sieve
require ["regex", "fileinto", "imap4flags"];
# Catch mail tagged as Spam, except Spam retrained and delivered to the mailbox
if allof (header :regex "X-DSPAM-Result" "^(Spam|Virus|Bl[ao]cklisted)$",
          not header :contains "X-DSPAM-Reclassified" "Innocent") {
  # Mark as read
  #setflag "\\Seen";
  # Move into the Junk folder
  fileinto "INBOX.Spam";
}
else{
keep;
}
## save the file
:wq
## DON'T FORGET TO COMPILE SIEVE SCRIPTS AND YOU SHOULD NOT GET ANY ERRORS
[root@mail1 ~]# sievec /var/dovecot/conf.d/example.com/global.sieve
## change the ownership and permissions of the sieve script and the
## compiled version.svbin
[root@mail1 ~]# chown vmail:vmail /var/dovecot/conf.d/example.com/global.*
[root@mail1 ~]# chmod 755  /var/dovecot/conf.d/example.com/global.*
[root@mail1 ~]# service dovecot restart
[root@mail1 ~]# service postfix restart

Make sure there are no errors or warnings, fix them immediately if you find any. More information can be obtained at the following URL's:
http://www.tty1.net/blog/2011-07-16-sieve-tutorial_en.html
http://fastmail.wikia.com/wiki/SieveExamples
http://fastmail.wikia.com/wiki/SieveExamples

STEP: 22 Test Postfix Server for smtp and smtps over telnet session

We need to check some hard facts here. Check whether the ports are being advertised properly. We need to see that Port 25 and Port 465 which is SMTP port and SMTP port over SSL respectively are open and functioning in the server. To do that we can check like this:

Terminal Window
[root@mail1 ~]# netstat -tulpn | grep master
tcp   0  0 0.0.0.0:465   0.0.0.0:*     LISTEN  5165/master 
tcp   0  0 0.0.0.0:25    0.0.0.0:*     LISTEN  5165/master 

Check the ports with telnet:

Terminal Window
[root@mail ~]# telnet localhost 25
Trying ::1...
Connected to localhost.
Escape character is '^]'.
220 mail.example.com ESMTP Postfix
ehlo example.com
250-mail.example.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN

We see from the above that both the ports are functioning and the above telnet session is also evidence enough that port 25 is ready to accept mail. Now we need to test whether the port 465 SSL is working or not. Use the openssl command appending your servers ip address followed by a colon and the port number.

Terminal Window
[root@mail ~]# openssl s_client -crlf -connect 192.168.1.252:465
CONNECTED(00000003)
depth=0 C = NZ, ST = Albany, L = Waiuki, O = Linux Documentation, OU = Documentation Department, 
CN = mail.example.com verify error:num=18:self signed certificate verify return:1
depth=0 C = NZ, ST = Albany, L = Waiuki, O = Linux Documentation, OU = Documentation Department, 
CN = mail.example.com verify return:1
---
Certificate chain
 0 s:/C=NZ/ST=Albany/L=Waiuki/O=Linux Documentation/OU=Documentation Department/CN=mail.example.com
   i:/C=NZ/ST=Albany/L=Waiuki/O=Linux Documentation/OU=Documentation Department/CN=mail.example.com
---
Server certificate
-----BEGIN CERTIFICATE-----
........................................
........................................
........................................
........................................
-----END CERTIFICATE-----
subject=/C=NZ/ST=Albany/L=Waiuki/O=Linux Documentation/OU=Documentation Department/CN=mail.example.com
issuer=/C=NZ/ST=Albany/L=Waiuki/O=Linux Documentation/OU=Documentation Department/CN=mail.example.com
---
No client certificate CA names sent
---
SSL handshake has read 1412 bytes and written 311 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: zlib compression
Expansion: zlib compression
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: 5406C5853EEE1E4101F9B860E0CD3B8E1F9CE49D992A2A653D76614971B9CF1B
    Session-ID-ctx: 
    Master-Key: 058609533B9286DEA6911FE393463B97C2253A2115BA9407CE3CEAF2DE0ECEDA7861D591E72E5CD721A9494D342976BD
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    TLS session ticket:
........................................
........................................
........................................
........................................    
    Compression: 1 (zlib compression)
    Start Time: 1329849011
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---
220 mail.example.com ESMTP Postfix

Both the tests were successful. We can now be rest assured that postfix will be working with various mail clients.

STEP: 23 Test Dovecot for pop3,pop3s, Imap and Imaps over telnet session

Terminal Window
[root@mail1 ~]# netstat -tulpn | grep dovecot
tcp   0  0 0.0.0.0:993     0.0.0.0:*    LISTEN      2839/dovecot
tcp   0  0 0.0.0.0:995     0.0.0.0:*    LISTEN      2839/dovecot
tcp   0  0 0.0.0.0:110     0.0.0.0:*    LISTEN      2839/dovecot
tcp   0  0 0.0.0.0:143     0.0.0.0:*    LISTEN      2839/dovecot
tcp   0  0 0.0.0.0:4190    0.0.0.0:*    LISTEN      1244/dovecot
tcp   0  0 :::993          :::*         LISTEN      2839/dovecot
tcp   0  0 :::995          :::*         LISTEN      2839/dovecot
tcp   0  0 :::110          :::*         LISTEN      2839/dovecot
tcp   0  0 :::143          :::*         LISTEN      2839/dovecot

We see from above that all four ports are open as we have set dovecot to advertise pop3, pop3s, Imap and Imap additionally manage sieve port is also working. In this setup we are more concerned about IMAP and IMAPS ports which are ports 143 and 993. To test port 143 over telnet we can proceed as follows:

Terminal Window
[root@mail1 ~]#  telnet imap.example.com 143
Trying 1.2.3.4...
Connected to imap.example.com.
Escape character is '^]'.
* OK Dovecot ready.

The above shows that Dovecot is ready to accept logins and would display the messages if a username and password is supplied. In the same manner we can connect to the IMAPS protocol using the openssl command as follows:

Terminal Window
[root@mail ~]# openssl s_client  -connect localhost:993
CONNECTED(00000003)
depth=0 C = NZ, ST = Albany, L = Waiuki, O = Linux Documentation, OU = Documentation Department, 
CN = mail.example.com verify error:num=18:self signed certificate verify return:1
depth=0 C = NZ, ST = Albany, L = Waiuki, O = Linux Documentation, OU = Documentation Department, 
CN = mail.example.com verify return:1
---
Certificate chain
 0 s:/C=NZ/ST=Albany/L=Waiuki/O=Linux Documentation/OU=Documentation Department/CN=mail.example.com
   i:/C=NZ/ST=Albany/L=Waiuki/O=Linux Documentation/OU=Documentation Department/CN=mail.example.com
---
Server certificate
-----BEGIN CERTIFICATE-----
........................................
........................................
........................................
........................................
........................................
........................................
-----END CERTIFICATE-----
subject=/C=NZ/ST=Albany/L=Waiuki/O=Linux Documentation/OU=Documentation Department/CN=mail.example.com
issuer=/C=NZ/ST=Albany/L=Waiuki/O=Linux Documentation/OU=Documentation Department/CN=mail.example.com
---
No client certificate CA names sent
---
SSL handshake has read 1396 bytes and written 311 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: zlib compression
Expansion: zlib compression
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: 3FF183DC575980141F4FA4394674122FE9F87D2BDB33538EC6EF68D058597923
    Session-ID-ctx: 
    Master-Key: BE94BA9B96DDFB49F72C050334FA917317F681696F55BFCCDAD30BA28DA2B75AAB361E043B72DB1218D0BFDA136D1D7C
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    TLS session ticket:
........................................
........................................
........................................
........................................
........................................
........................................
    Compression: 1 (zlib compression)
    Start Time: 1329850356
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE 
AUTH=PLAIN AUTH=LOGIN AUTH=CRAM-MD5] Dovecot ready.

You would receive a lot of output with that command. If you see the last line that reads Dovecot ready, then you are good to go and configure your email clients.

Like wise you can test for pop3 and pop3s for ports 110 and 995

Terminal Window
[root@mail1 ~]#  telnet localhost 110
Trying 1.2.3.4...
Connected to localhost.
Escape character is '^]'.
* OK Dovecot ready.

And for pop3s use the openssl command

Terminal Window
[root@mail ~]# openssl s_client  -connect localhost:995
CONNECTED(00000003)
depth=0 C = NZ, ST = Albany, L = Waiuki, O = Linux Documentation, OU = Documentation Department, 
CN = mail.example.com verify error:num=18:self signed certificate verify return:1
depth=0 C = NZ, ST = Albany, L = Waiuki, O = Linux Documentation, OU = Documentation Department, 
CN = mail.example.com verify return:1
---
Certificate chain
 0 s:/C=NZ/ST=Albany/L=Waiuki/O=Linux Documentation/OU=Documentation Department/CN=mail.example.com
   i:/C=NZ/ST=Albany/L=Waiuki/O=Linux Documentation/OU=Documentation Department/CN=mail.example.com
---
Server certificate
-----BEGIN CERTIFICATE-----
........................................
........................................
........................................
........................................
........................................
........................................
-----END CERTIFICATE-----
subject=/C=NZ/ST=Albany/L=Waiuki/O=Linux Documentation/OU=Documentation Department/CN=mail.example.com
issuer=/C=NZ/ST=Albany/L=Waiuki/O=Linux Documentation/OU=Documentation Department/CN=mail.example.com
---
No client certificate CA names sent
---
SSL handshake has read 1396 bytes and written 311 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: zlib compression
Expansion: zlib compression
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: 3FF183DC575980141F4FA4394674122FE9F87D2BDB33538EC6EF68D058597923
    Session-ID-ctx: 
    Master-Key: BE94BA9B96DDFB49F72C050334FA917317F681696F55BFCCDAD30BA28DA2B75AAB361E043B72DB1218D0BFDA136D1D7C
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    TLS session ticket:
........................................
........................................
........................................
........................................
........................................
........................................
    Compression: 1 (zlib compression)
    Start Time: 1329850356
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE 
AUTH=PLAIN AUTH=LOGIN AUTH=CRAM-MD5] Dovecot ready.

And finally for the mangesieve protocol to check whether its working or

Terminal Window
[root@mail ~]# telnet localhost 4190
Trying ::1...
Connected to localhost.
Escape character is '^]'.
"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 imapflags notify"
"NOTIFY" "mailto"
"SASL" "PLAIN LOGIN CRAM-MD5"
"STARTTLS"
"VERSION" "1.0"
OK "Dovecot ready."

With that we can conclude that all ports are functioning as normal.

STEP: 24 Implement Postfix custom Bounce messages and UCE Restrictions

I wanted this feature as an addition so that when you want to customise the bounce messages from your mail server, postifx send its own bounce messages. This did not seem to be the right way to configure a mail server in an enterprise. So here is the correct way to do this.

This is based on the tutorial at http://www.howtoforge.com/configure-custom-postfix-bounce-messages

First you should find out about your Postfix version to make sure it supports custom bounce messages:

Terminal Window
[root@mail ~]# postconf -d | grep mail_version
mail_version = 2.8.5
milter_macro_v = $mail_name $mail_version
# If your Postfix is 2.3 or newer, then you're good to go.

We need to set two parameters in postfix main.cf so that bounce messages can be sent back to recipients who have not been responded to in time. These are maximal_queue_lifetime and delay_warning_time The postconf -n command shows the settings that are currently configured in /etc/postfix/main.cf , whereas the postconf -d command shows the default settings that are valid unless something else is set in /etc/postfix/main.cf.

Next we configure postfix /etc/postfix/main.cf as follows:

Terminal Window
[root@mail ~]# vim /etc/postfix/main.cf
####################################################################
# CUSTOM BOUNCE MESSAGE AND UNSOLICITED MAIL (UCE) CONFIGURATION   #
####################################################################
maximal_queue_lifetime = 1d
delay_warning_time = 0h
bounce_template_file = /etc/postfix/bounce.cf
mime_header_checks = regexp:/etc/postfix/block_attachments

Next we need to configure the bounce template as follows:

Terminal Window
[root@mail ~]# vim /etc/postfix/bounce.cf
#
# The failure template is used when mail is returned to the sender;
# either the destination rejected the message, or the destination
# could not be reached before the message expired in the queue.
#
failure_template = <<EOF
Charset: us-ascii
From: MAILER-DAEMON (Mail Delivery System)
Subject: Undelivered Mail Returned to Sender from example.com
Postmaster-Subject: Postmaster Copy: Undelivered Mail
This is the mail system at host $myhostname.
I'm sorry to have to inform you that your message could not
be delivered to one or more recipients. It's attached below.
Please note that we do neither accept nor send  certain attachments
in mails that have the following extensions.  This is 
security measure that we undertake to avoid spam.
[dll,afx,ini,dat,wdx,ade ,adp ,app ,bas ,bat ,chm ,cmd ,cpl
,crt ,csh ,exe ,fxp ,hlp ,hta ,inf ,ins ,isp ,js ,jse ,ksh
,Lnk ,mda ,mdb ,mde ,mdt ,mdt ,mdw ,mdz ,msc ,msi ,msp ,mst
,ops ,pcd ,pif ,prf ,prg ,pst ,reg ,scf ,scr ,sct ,shb ,shs
,url ,vb ,vbe ,vbs ,wsc ,wsf ,wsh]
For further assistance, please send mail to <postmaster@example.com>
If you do so, please include this problem report. You can
delete your own text from the attached returned message.
                   The mail system
EOF
#
# The delay template is used when mail is delayed. Note a neat trick:
# the default template displays the delay_warning_time value as hours
# by appending the _hours suffix to the parameter name; it displays
# the maximal_queue_lifetime value as days by appending the _days
# suffix.
#
# Other suffixes are: _seconds, _minutes, _weeks. There are no other
# main.cf parameters that have this special behavior.
#
# You need to adjust these suffixes (and the surrounding text) if
# you have very different settings for these time parameters.
#
delay_template = <<EOF
Charset: us-ascii
From: MAILER-DAEMON (Mail Delivery System)
Subject: Delayed Mail (still being retried)
Postmaster-Subject: Postmaster Warning: Delayed Mail
This is the mail system at host $myhostname.
####################################################################
# THIS IS A WARNING ONLY.  YOU DO NOT NEED TO RESEND YOUR MESSAGE. #
####################################################################
Your message could not be delivered for more than $delay_warning_time_hours hour(s).
It will be retried until it is $maximal_queue_lifetime_days day(s) old.
For further assistance, please send mail to <postmaster>
If you do so, please include this problem report. You can
delete your own text from the attached returned message.
                   The mail system
EOF
#
# The success template is used when mail is delivered to mailbox,
# when an alias or list is expanded, or when mail is delivered to a
# system that does not announce DSN support. It is an error to specify
# a Postmaster-Subject: here.
#
success_template = <<EOF
Charset: us-ascii
From: MAILER-DAEMON (Mail Delivery System)
Subject: Successful Mail Delivery Report
This is the mail system at host $myhostname.
Your message was successfully delivered to the destination(s)
listed below. If the message was delivered to mailbox you will
receive no further notifications. Otherwise you may still receive
notifications of mail delivery errors from other systems.
                   The mail system
EOF
#
# The verify template is used for address verification (sendmail -bv
# address...). or for verbose mail delivery (sendmail -v address...).
# It is an error to specify a Postmaster-Subject: here.
#
verify_template = <<EOF
Charset: us-ascii
From: MAILER-DAEMON (Mail Delivery System)
Subject: Mail Delivery Status Report
This is the mail system at host $myhostname.
Enclosed is the mail delivery report that you requested.
                   The mail system
EOF

Next we want to block certain emails with attachements that could be dangerous for our network. These could be but not limited to dll,afx,ini,dat,wdx,ade ,adp ,app ,bas ,bat ,chm ,cmd ,cpl ,crt ,csh ,exe ,fxp ,hlp ,hta ,inf ,ins ,isp ,js ,jse ,ksh ,Lnk ,mda ,mdb ,mde ,mdt ,mdt ,mdw ,mdz ,msc ,msi ,msp ,mst ,ops ,pcd ,pif ,prf ,prg ,pst ,reg ,scf ,scr ,sct ,shb ,shs ,url ,vb ,vbe ,vbs ,wsc ,wsf ,wsh. In the above configuration of /etc/postfix/main.cf we can see a setting pertaining to mime_header_checks This will take care of blocking the attacments and the mail for good.

The contents of the block_attchments file is as follows.

Terminal Window
[root@mail ~]# vim /etc/postfix/block_attachments
/name=[^>]*\.(dll|afx|ini|dat|wdx|ade|adp|app|bas|bat|chm|cmd|cpl|crt|csh|exe
              |fxp|hlp|hta|inf|ins|isp|js|jse|ksh|Lnk|mda|mdb|mde|mdt|mdt|mdw
              |mdz|msc|msi|msp|mst|ops|pcd|pif|prf|prg|pst|reg|scf|scr|sct|shb
              |shs|url|vb|vbe|vbs|wsc|wsf|wsh)/ REJECT

Well that completes our bounce messages and UCE configurations in postfix. you can get further information about these at the following URL's
http://www.akadia.com/services/postfix_uce.html
http://jimsun.linxnet.com/misc/postfix-anti-UCE.txt
http://www.hsc.fr/ressources/cours/postfix/doc/uce.html

STEP: 25 Implement Postfix DKIM keys for signing your emails

Many thanks to Steve Jenkins for this tutorial at
http://stevejenkins.com/blog/2011/08/installing-opendkim-rpm-via-yum-with-postfix-or-sendmail-for-rhel-centos-fedora/

DomainKeys Identified Mail (DKIM) is a method for associating a domain name to an email message, thereby allowing a person, role, or organization to claim some responsibility for the message. The association is set up by means of a digital signature which can be validated by recipients. Responsibility is claimed by a signer —independently of the message's actual authors or recipients— by adding a DKIM-Signature: field to the message's header. The verifier recovers the signer's public key using the DNS, and then verifies that the signature matches the actual message's content. We install opendkim as follows:

Terminal Window
[root@mail1 ~]# yum install opendkim

Generate keys for signing

You need to generate a private and a public key for each of the domains for which you wish to sign mail. The private key is stored away from prying eyes on your server, while the public key gets published in your domain’s DNS records so that receiving mail servers can verify your DKIM-signed mail.

Create your keys with:

Terminal Window
[root@mail1 ~]#  mkdir /etc/opendkim/keys/example.com
[root@mail1 ~]#  opendkim-genkey -D /etc/opendkim/keys/example.com/ -d example.com -s default
[root@mail1 ~]#  chown -R opendkim:opendkim /etc/opendkim/keys/example.com
[root@mail1 ~]#  mv /etc/opendkim/keys/example.com/default.private /etc/opendkim/keys/example.com/default

Edit the configuration files

You need to create and/or edit four files:

  • /etc/opendkim.conf – OpenDKIM’s main configuration file
  • /etc/opendkim/KeyTable – a list of keys available for signing
  • /etc/opendkim/SigningTable - a list of domains and accounts allowed to sign
  • /etc/opendkim/TrustedHosts – a list of servers to “trust” when signing or verifying

On install, the RPM package should have created a simple /etc/opendkim.conf file on your system. By default, this file is set up for verification only. In order to sign outgoing mail, you’ll have to comment, uncomment, and configure some additional options in the configuration file. Use your favorite text editor to open /etc/opendkim.conf and make it look like this:

Terminal Window
[root@mail1 ~]# vim /etc/opendkim.conf
## CONFIGURATION OPTIONS
# Specifies the path to the process ID file.
PidFile /var/run/opendkim/opendkim.pid
# Selects operating modes. Valid modes are s (signer) and v (verifier). Default is v.
Mode    sv
# Log activity to the system log.
Syslog  yes
# Log additional entries indicating successful signing or verification of messages.
SyslogSuccess yes
# If logging is enabled, include detailed logging about why or why not a message was
# signed or verified. This causes a large increase in the amount of log data generated
# for each message, so it should be limited to debugging use only.
#LogWhy yes
# Attempt to become the specified user before starting operations.
UserID  opendkim:opendkim
# Create a socket through which your MTA can communicate.
Socket  inet:8891@localhost
# Required to use local socket with MTAs that access the socket as a non-
# privileged user (e.g. Postfix)
Umask   002
# This specifies a file in which to store DKIM transaction statistics.
#Statistics              /var/spool/opendkim/stats.dat
## SIGNING OPTIONS
# Selects the canonicalization method(s) to be used when signing messages.
Canonicalization        relaxed/simple
# Domain(s) whose mail should be signed by this filter. Mail from other domains will
# be verified rather than being signed. Uncomment and use your domain name.
# This parameter is not required if a SigningTable is in use.
Domain                  example.com
# Defines the name of the selector to be used when signing messages.
Selector                default
# Gives the location of a private key to be used for signing ALL messages.
#KeyFile                 /etc/opendkim/keys/default.private
# Gives the location of a file mapping key names to signing keys. In simple terms,
# this tells OpenDKIM where to find your keys. If present, overrides any KeyFile
# setting in the configuration file.
KeyTable                 refile:/etc/opendkim/KeyTable
# Defines a table used to select one or more signatures to apply to a message based
# on the address found in the From: header field. In simple terms, this tells
# OpenDKIM how to use your keys.
SigningTable                 refile:/etc/opendkim/SigningTable
# Identifies a set of "external" hosts that may send mail through the server as one
# of the signing domains without credentials as such.
ExternalIgnoreList      refile:/etc/opendkim/TrustedHosts
# Identifies a set internal hosts whose mail should be signed rather than verified.
InternalHosts           refile:/etc/opendkim/TrustedHosts
Uncomment the Domain option (and include your actual domain name), the KeyTable, SigningTable, ExternalIgnoreList, and InternalHosts options. Also, since you’ll be using a KeyTable, you can comment the KeyFile option.

Next, you’ll need to create the three text files that you just uncommented in your config file. First, using your favorite text editor, create an /etc/opendkim/KeyTable file that looks like this:

Terminal Window
[root@mail1 ~]#  vim /etc/opendkim/KeyTable
default._domainkey.example.com example.com:default:/etc/opendkim/keys/example.com/default

The KeyTable file tells OpenDKIM where to find your keys. Each entry in the KeyTable file is a single line for each key location (for example, all of the text in the above example should be on a single line in your file). If you’re going to use multiple keys (to sign mail for virtual domains with different keys, for example), you will need to create a separate line in the KeyTable file for each domain, like this:

Terminal Window
[root@mail1 ~]# vim /etc/opendkim/KeyTable
default._domainkey.example.com example.com:default:/etc/opendkim/keys/example.com/default
default._domainkey.example2.com example2.com:default:/etc/opendkim/keys/example2.com/default

Next, you need to create or edit the /etc/opendkim/SigningTable file. A default version of this file should have been installed in /etc/opendkim when you installed the RPM, so just uncomment the following line (or edit the file to include this line) so it reads:

Terminal Window
[root@mail1 ~]# vim /etc/opendkim/SigningTable
*@example.com default._domainkey.example.com

Next, create an /etc/opendkim/TrustedHosts file that looks like this:

Terminal Window
[root@mail1 ~]# vim /etc/opendkim/TrustedHosts
127.0.0.1
192.168.1.0/24
hostname1.example1.com
hostname2.example1.com
example1.com
hostname1.example2.com
hostname2.example2.com
example2.com

The TrustedHosts file tells OpenDKIM who to let use your keys. Because it’s referenced by the ExternalIgnoreList directive in your conf file, OpenDKIM will ignore this list of hosts when verifying incoming mail. And, because it’s also referenced by the InternalHosts directive, this same list of hosts will be considered “internal,” and OpenDKIM will sign their outgoing mail.

IMPORTANT: Make sure you list the IP address for localhost (127.0.0.1) in the TrustedHosts file or OpenDKIM won’t sign mail sent from this server. If you have multiple servers on the same network that relay mail through this server and you want to sign their mail as well, they must be listed in the TrustedHosts file. Put each entry on its own line. An entry can be a hostname, domain name (e.g. “example.com”), IP address, an IPv6 address (including an IPv4 mapped address), or a CIDR-style IP specification (e.g. “192.168.1.0/24?).

Edit Postfix MTA configuration

Now you’re ready to tell your MTA about OpenDKIM.

Terminal Window
[root@mail1 ~]# vim /etc/postfix/main.cf
smtpd_milters           = inet:127.0.0.1:8891
non_smtpd_milters       = $smtpd_milters

Adding DNS Records

Now that your mail server is signing outgoing mail and verifying incoming mail, you’ll need to put some information in your DNS records to tell other mail servers how your keys are set up, and provide the public key for them to check that your mail is properly signed. Do:

Terminal Window
[root@mail1 ~]#  cat /etc/opendkim/keys/example.com/default.txt

If you manage your own DNS or have full access to your domain’s zone file, you’ll need to paste the entire contents of the default.txt file at the bottom of your domain’s zone file. If you’re using a web interface to manage your zone file, be careful that the long lines of the public key don’t wrap and create line-feed characters (or fix them if they do). Otherwise, your public key won’t work.

The output should look something like this:

Terminal Window
default._domainkey IN TXT "v=DKIM1; g=*; k=rsa; 
p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHY7Zl+n3SUldTYRUEU1BErHkKN0Ya52gazp1R
7FA7vN5RddPxW/sO9JVRLiWg6iAE4hxBp42YKfxOwEnxPADbBuiELKZ2ddxo2aDFAb9U/lp47k45
u5i2T1AlEBeurUbdKh7Nypq4lLMXC2FHhezK33BuYR+3L7jxVj7FATylhwIDAQAB" ; 
----- DKIM default for example.com
The whole lot should be in a single line

You should also add another TXT Record to your zone file that reads:

Terminal Window
_adsp._domainkey.example.com    IN    TXT    "dkim=unknown"

Now start OpenDKIM with:

Terminal Window
[root@mail1 ~]#  service opendkim start
Starting OpenDKIM Milter:     [  OK  ]
[root@mail1 ~]# service postfix restart
[root@mail1 ~]# chkconfig --level 345 opendkim on

And finally to test the things out view your maillog file to see whether opendkim is working or not. If successful you should see something like follows:

Terminal Window
opendkim[22254]: 53D0314803B: DKIM-Signature header added

STEP: 26 Conclusion

That concludes our mail server setup with all the components as stated. With that in place I would like to thank you for taking time and working this through. I need to thank many people and resources for giving me the knowledge that is required to get this going. I have researched over for many hours and read so much, that you are seeing the result of that here. Best of luck. And finally I have created a complete set of rpms with configurations of these packages as a tar ball, so you can quickly configure your mailserver and do the same thing in less amount of time. [DOWNLOAD HERE]