Qmail
From WBITT's Cooker!
Introduction
Created: 2009-07-08
Last Modified: 2013-04-05
Note: Please read the steps completely before implementing them. This is not a copy/paste howto. This is a careful comparison of LWQ, QMR and JMS methods to implement a fully functional mail server. The steps shown below were applied on 64 bit CENTOS 6.4 . The server is fully functional and is in production now.
Important sites:-
- Life with Qmail [LWQ] : lifewithqmail.org
- John Simpson's Qmail website [JMS] : http://qmail.jms1.net/
- Qmail Rocks website [QMR]: qmailrocks.org
The intent of this installation is to install qmail the way DJB intended, but bring along those, who are used to installing QMR only. That is the method followed in LifeWithQmail. QMR has made a mix of many of these and other qmail installations and created QMR. John Simpson and others have some serious objections on the way QMR is setup. My objective in this document is to provide an easy to follow approach (as easy as QMR), yet confirming to the suggestions and standards of JMS and LWQ and others.
Basic Information
- OS: CENTOS 5.3 32 bit on a KVM virtual machine
- Hostname: qmail.example.com
- IP: 192.168.122.90
Step: Preparations
- Disable SELINUX
- Disable Default Firewall
Install nmap and disable unnecessary services.
yum -y install nmap [root@qmail ~]# for i in avahi-daemon autofs cups exim sendmail gpm ip6tables iptables lvm2-monitor mdmonitor netfs nfslock pcscd portmap restorecond rpcgssd rpcidmapd xfs yum-updatesd ; do chkconfig --level 35 $i off; service $i stop ; done Shutting down Avahi daemon: [ OK ] Stopping automount: [ OK ] Stopping cups: [ OK ] Shutting down exim: [ OK ] error reading information on service sendmail: No such file or directory sendmail: unrecognized service Shutting down console mouse services: [ OK ] Not stopping monitoring, this is a dangerous operation. Please use force-stop to override. Stopping NFS statd: [ OK ] Stopping PC/SC smart card daemon (pcscd): [ OK ] Stopping portmap: [ OK ] Stopping RPC idmapd: [ OK ] Shutting down xfs: [ OK ] Stopping yum-updatesd: [ OK ] [root@qmail ~]#
Check the open ports:
[root@qmail ~]# nmap localhost ... Not shown: 1679 closed ports PORT STATE SERVICE 22/tcp open ssh Nmap finished: 1 IP address (1 host up) scanned in 0.091 seconds [root@qmail ~]#
Step: Local CENTOS repository (Optional)
Setup the local CentOS repository on the server and update the Yum repository configuration on qmail server. This step is not necessary on servers, which have direct high speed connection to the internet.
[root@qmail ~]# vi /etc/yum.repos.d/CentOS-Local.repo # CentOS-Local.repo # [local] name=CentOS-$releasever - Local baseurl=http://192.168.122.1/centos53-32/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
Step: Kernel update / OS update
It is also right time to update your kernel. Or, better yet, update the entire OS installation.
Current: [root@qmail ~]# uname -r 2.6.18-128.el5 [root@qmail ~]# yum list | grep kernel kernel.i686 2.6.18-128.el5 installed kernel-devel.i686 2.6.18-128.el5 installed kernel-headers.i386 2.6.18-128.el5 installed kernel.i686 2.6.18-128.4.1.el5 updates kernel-PAE.i686 2.6.18-128.4.1.el5 updates kernel-PAE-devel.i686 2.6.18-128.4.1.el5 updates kernel-debug.i686 2.6.18-128.4.1.el5 updates kernel-debug-devel.i686 2.6.18-128.4.1.el5 updates kernel-devel.i686 2.6.18-128.4.1.el5 updates kernel-doc.noarch 2.6.18-128.4.1.el5 updates kernel-headers.i386 2.6.18-128.4.1.el5 updates kernel-xen.i686 2.6.18-128.4.1.el5 updates kernel-xen-devel.i686 2.6.18-128.4.1.el5 updates yum-kernel-module.noarch 1.1.16-13.el5.centos base [root@qmail ~]# [root@qmail ~]# yum -y update kernel kernel-devel kernel-headers or just [root@qmail ~]# yum -y update [root@qmail ~]# cat /etc/grub.conf default=0 timeout=5 title CentOS (2.6.18-128.4.1.el5) root (hd0,0) kernel /boot/vmlinuz-2.6.18-128.4.1.el5 ro root=LABEL=/ initrd /boot/initrd-2.6.18-128.4.1.el5.img title CentOS (2.6.18-128.el5) root (hd0,0) kernel /boot/vmlinuz-2.6.18-128.el5 ro root=LABEL=/ initrd /boot/initrd-2.6.18-128.el5.img [root@qmail ~]#
System reboot needed after kernel update.
Step [optional]: SSH key based authentication
[Details]
Step: Required software components, including basic PERL modules
- httpd, httpd-devel, apr
- php, php-imap, php-mysql, php-gd, php-pear, php-zlib, php-mbstring, php-xml,
- perl, perl-libwww-perl, perl-Digest-SHA1, perl-Digest-HMAC, perl-Net-DNS, perl-HTML-Tagset, perl-HTML-Parser
perl-Time-HiRes, perl-TimeDate, perl-suidperl, perl-DateManip
- gcc, gcc-c++, libtool-ltdl, libtool-ltdl-devel
- mysql-server, mysql-devel, postgresql-devel
- openssl, openssl-devel, openldap-servers
- wget
- patch, patchutils
- pcre-devel
- gdbm-devel
- db4, db4-devel
- fam fam-devel gamin-devel
- net-snmp + net-snmp-utils + net-snmp-libs
- mrtg
- spamassassin, expect, zlib-devel
yum -y install net-snmp net-snmp-utils net-snmp-libs mrtg \ httpd httpd-devel php php-imap php-mysql php-gd php-pear php-zlib php-mbstring php-xml \ gcc gcc-c++ gdbm-devel pcre-devel libtool-ltdl libtool-ltdl-devel \ mysql-server mysql-devel db4 db4-devel postgresql-devel \ openssl openssl-devel openldap-servers \ perl perl-libwww-perl perl-Digest-SHA1 perl-Digest-HMAC perl-Net-DNS perl-HTML-Tagset perl-HTML-Parser perl-Time-HiRes perl-TimeDate perl-suidperl perl-DateManip \ spamassassin expect zlib-devel zlib unzip \ fam fam-devel gamin-devel patch patchutils
Note: Basic PERL modules required are as follows:
Digest::SHA1 Digest::HMAC Net::DNS Time::HiRes HTML::Tagset HTML::Parser
From the yum install command above, you can see that all of these listed PERL modules are installed. However, Time::HiRes will not be installed.
Update: CENTOS 6.3 64 bit will install the Time::HiRes perl module.
Check with:
# yum list installed perl* | egrep -i "sha1|hmac|DNS|HiRes|Target|Parser"
If any perl module is not installed, try installing it manually. You can use the following command to install it through perl -MCPAN option:
perl -MCPAN -e "install Time::HiRes" ... All tests successful. Files=1, Tests=40, 25 wallclock secs (11.49 cusr + 1.32 csys = 12.81 CPU) /usr/bin/make test -- OK Running make install Installing /usr/lib/perl5/5.8.8/i386-linux-thread-multi/auto/Time/HiRes/HiRes.so Installing /usr/lib/perl5/5.8.8/i386-linux-thread-multi/auto/Time/HiRes/HiRes.bs Files found in blib/arch: installing files in blib/lib into architecture dependent library tree Installing /usr/lib/perl5/5.8.8/i386-linux-thread-multi/Time/HiRes.pm Installing /usr/share/man/man3/Time::HiRes.3pm Writing /usr/lib/perl5/5.8.8/i386-linux-thread-multi/auto/Time/HiRes/.packlist Appending installation info to /usr/lib/perl5/5.8.8/i386-linux-thread-multi/perllocal.pod /usr/bin/make install -- OK
How to check if these modules are installed?
Use the perldoc -l command for each PERL module you want to check. You should see a “.pm” line for each module that is installed on the system:-
[root@qmail ~]# perldoc -l Time::HiRes Digest::SHA1 Digest::HMAC Net::DNS Time::HiRes HTML::Tagset HTML::Parser /usr/lib/perl5/5.8.8/i386-linux-thread-multi/Time/HiRes.pm /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/Digest/SHA1.pm /usr/lib/perl5/vendor_perl/5.8.8/Digest/HMAC.pm /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/Net/DNS.pm /usr/lib/perl5/5.8.8/i386-linux-thread-multi/Time/HiRes.pm /usr/lib/perl5/vendor_perl/5.8.8/HTML/Tagset.pm /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/HTML/Parser.pm [root@qmail ~]#
There is a long list of PERL modules, required for the enhanced functionality of SpamAssassin, Razor, DCC, etc. You can install them after you are done with your base qmail installation . Or you may want to install them before (now). It doesn't matter. There is also an option to update your perl CPAN system module. If you want to, you can execute the following two commands to update. This is an optional step though.
Update: CENTOS 6.3 You may need to have perl-CPAN installed through RPM.
perl -MCPAN -e "install Bundle::CPAN" perl -MCPAN -e "reload"
And here is the list of PERL modules, as discussed above:
Digest::SHA1 Digest::HMAC HTML::Tagset HTML::Parser Parse::Syslog Statistics::Distributions ClamAV::Client Mail::SpamAssassin Mail::SPF::Query IP::Country::Fast MIME::Base64 Getopt::Long URI::Escape Mail::SPF IO::Zlib Test::Harness Test::Simple Mail::DKIM Mail::DomainKeys Crypt::OpenSSL::Bignum IO::Socket::INET6 IO::Socket::SSL Mail::SpamAssassin::Plugin::DCC Mail::SpamAssassin::Plugin::Razor2 Socket6 Date::Manip DB_File Archive::Tar Net::Ident Time::HiRes Archive::Tar File::Copy Encode::Detect Razor2::Client::Agent (This will get installed with the Razor software, later)
Here is a tip for checking this whole list: Save this list in a text file, say /tmp/perl-list.txt on the server. Then run a loop to check existence of each module, such as:
[root@qmail ~]# for i in `cat /tmp/perl-list.txt`; do perldoc -l $i ; done
You will get the output such as:-
[root@qmail ~]# for i in `cat /tmp/perl-list.txt`; do perldoc -l $i ; done /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/Digest/SHA1.pm /usr/lib/perl5/vendor_perl/5.8.8/Digest/HMAC.pm /usr/lib/perl5/vendor_perl/5.8.8/HTML/Tagset.pm /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/HTML/Parser.pm No documentation found for "Parse::Syslog". No documentation found for "Statistics::Distributions". ... .
I will use a grep filter to just see which modules are not installed:-
[root@qmail ~]# for i in `cat /tmp/perl-list.txt`; do perldoc -l $i ; done | grep "No documentation" No documentation found for "Parse::Syslog". No documentation found for "Statistics::Distributions". No documentation found for "ClamAV::Client". No documentation found for "Mail::SPF::Query". No documentation found for "IP::Country::Fast". No documentation found for "Mail::SPF". No documentation found for "Mail::DKIM". No documentation found for "Mail::DomainKeys". No documentation found for "Crypt::OpenSSL::Bignum". No documentation found for "Net::Ident". [root@qmail ~]#
As you can see above, I now have a list of modules I will need to install manually. I will utilize the opportunity now and install them. Again, you can install them before you start with Anti-Spam software.
The following will install without a problem:-
perl -MCPAN -e "install Parse::Syslog" perl -MCPAN -e "install Statistics::Distributions" perl -MCPAN -e "install IP::Country::Fast" perl -MCPAN -e "install Crypt::OpenSSL::Bignum"
The following will not install easily with “perl -MCPAN ....” command. But when you do, it will save you from actually downloading the software. When you issue the “perl -MCPAN -e install ........” command, the module will get downloaded and will be saved in the .cpan/build directory of current user's home directory. Since you will be performing these steps as root, you will find them downloaded under /root/.cpan/build directory.
perl -MCPAN -e "install ClamAV::Client" perl -MCPAN -e "install Mail::SPF::Query" perl -MCPAN -e "install Mail::SPF" perl -MCPAN -e "install Mail::DKIM" perl -MCPAN -e "install Mail::DomainKeys" perl -MCPAN -e "install Net::Ident"
At this point, you just need to change into each directory of the module and install it using the actual manual compilation technique.
[root@qmail build]# cd /root/.cpan/build/Net-Ident-1.20/ [root@qmail Net-Ident-1.20]# perl Makefile.PL && make && make install ... ... Installing /usr/lib/perl5/site_perl/5.8.8/Net/Ident.pm Installing /usr/share/man/man3/Net::Ident.3pm Writing /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/auto/Net/Ident/.packlist Appending installation info to /usr/lib/perl5/5.8.8/i386-linux-thread-multi/perllocal.pod [root@qmail Net-Ident-1.20]# [root@qmail ~]# cd /root/.cpan/build/Mail-DKIM-0.36/ [root@qmail Mail-DKIM-0.36]# perl Makefile.PL && make && make install ... ... Installing /usr/share/man/man3/Mail::DKIM::SignerPolicy.3pm Installing /usr/share/man/man3/Mail::DKIM::DkPolicy.3pm Installing /usr/share/man/man3/Mail::DKIM::Canonicalization::DkimCommon.3pm Installing /usr/share/man/man3/Mail::DKIM::Policy.3pm Writing /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/auto/Mail/DKIM/.packlist Appending installation info to /usr/lib/perl5/5.8.8/i386-linux-thread-multi/perllocal.pod [root@qmail build]# cd /root/.cpan/build/Mail-SPF-v2.006/ [root@qmail Mail-SPF-v2.006]# perl Makefile.PL && make && make install This module requires Module::Build to install itself. Install Module::Build now from CPAN? [y] y ... ... Installing /usr/share/man/man3/Mail::SPF::Mod::Exp.3pm Installing /usr/share/man/man3/Mail::SPF::Result.3pm Installing /usr/share/man/man3/Mail::SPF::Term.3pm Installing /usr/share/man/man3/Mail::SPF::v1::Record.3pm Installing /usr/share/man/man3/Mail::SPF::Server.3pm Installing /usr/sbin/spfd Installing /usr/bin/spfquery Writing /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/auto/Mail/SPF/.packlist [root@qmail Mail-SPF-v2.006]# cd /root/.cpan/build/Mail-SPF-Query-1.999.1/ Mail-SPF-Query module expects two more modules. Let's install them too: [root@qmail ~]# perl -MCPAN -e "install Net::CIDR::Lite" [root@qmail ~]# perl -MCPAN -e "install Sys::Hostname::Long" [root@qmail Mail-SPF-Query-1.999.1]# perl Makefile.PL && make && make install Installing /usr/bin/spfd Installing /usr/bin/spfquery Writing /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/auto/Mail/SPF/Query/.packlist Appending installation info to /usr/lib/perl5/5.8.8/i386-linux-thread-multi/perllocal.pod [root@qmail Mail-SPF-Query-1.999.1]# [root@qmail Mail-DomainKeys-1.0]# perl Makefile.PL && make && make install You appear to be directly connected to the Internet. I have some tests that try to query live nameservers. Do you want to enable these tests? [y] y Warning: prerequisite Crypt::OpenSSL::RSA 0 not found. Writing Makefile for Mail::DomainKeys ... ... Installing /usr/lib/perl5/site_perl/5.8.8/Mail/DomainKeys/Key/Private.pm Installing /usr/share/man/man3/Mail::DomainKeys.3pm Writing /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/auto/Mail/DomainKeys/.packlist Appending installation info to /usr/lib/perl5/5.8.8/i386-linux-thread-multi/perllocal.pod [root@qmail Mail-DomainKeys-1.0]# Install the additional module: [root@qmail Mail-DomainKeys-1.0]# cd ../Crypt-OpenSSL-RSA-0.25/ [root@qmail Crypt-OpenSSL-RSA-0.25]# perl Makefile.PL && make && make install ... ... Writing Makefile for Crypt::OpenSSL::RSA Writing /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/auto/Crypt/OpenSSL/RSA/.packlist Appending installation info to /usr/lib/perl5/5.8.8/i386-linux-thread-multi/perllocal.pod [root@qmail Crypt-OpenSSL-RSA-0.25]#
Pit-stop!
From here onwards Qmail installation steps will start. So if you want to take a snapshot of your virtual machine, now is the time.
Downloading and installing Qmail
- LWQ:-
- [Net-]qmail[-1.06], http://www.qmail.org/netqmail-1.06.tar.gz
- ucspi-tcp, http://cr.yp.to/ucspi-tcp/ucspi-tcp-0.88.tar.gz
- daemontools, http://cr.yp.to/daemontools/daemontools-0.76.tar.gz
We will not use NetQmail-1.06, because it is basically qmail-1.03 + “Some patches already applied”. This is what we don't want. We will patch qmail-1.03 with John Simpson's patches.
- QMR, JMS? :-
- [Original-]qmail[-1.03], http://cr.yp.to/software/qmail-1.03.tar.gz
- ucspi-tcp, http://cr.yp.to/ucspi-tcp/ucspi-tcp-0.88.tar.gz
- daemontools, http://cr.yp.to/daemontools/daemontools-0.76.tar.gz
QMR guide asks us to download the packages in /usr/src/qmail. Whereas LWQ asks us to download it in /usr/local/src . Both guides ultimately place daemontools in /package and the first two (qmail and ucspi-tcp) in /var/qmail/*. I will try to be as close to LWQ recommendations. I will also make a directory named /downloads , and will download all the software I will be downloading during this installation, in this location.
Download Software
mkdir /downloads cd /downloads [root@qmail downloads]# wget http://cr.yp.to/software/qmail-1.03.tar.gz [root@qmail downloads]# wget http://cr.yp.to/ucspi-tcp/ucspi-tcp-0.88.tar.gz [root@qmail downloads]# wget http://cr.yp.to/daemontools/daemontools-0.76.tar.gz cp /downloads/*.tar.gz /usr/local/src/
Unpack qmail-1.03.tar.gz and ucspi-tcp-0.88.tar.gz in /usr/local/src/ .
cd /usr/local/src/ tar xzf qmail-1.03.tar.gz tar xzf ucspi-tcp-0.88.tar.gz
Copy and unpack the daemontools package to the /package directory.
mkdir /package chmod 1755 /package
Question: Why do we need to do "chmod 1755 /package" ????
cp /downloads/daemontools-0.76.tar.gz /package/ cd /package tar xzf daemontools-0.76.tar.gz
There should now be directories called /usr/local/src/qmail-1.03, /usr/local/src/ucspi-tcp-0.88, and /package/admin/daemontools-0.76.
Create users and groups
Since qmail's installation program creates the sub-directories as they're needed, you only need to create the qmail "home" directory:
mkdir /var/qmail
Create users and groups:
groupadd nofiles useradd -g nofiles -d /var/qmail/alias -s /sbin/nologin -p '*' -c 'QMail alias user' alias useradd -g nofiles -d /var/qmail -s /sbin/nologin -p '*' -c 'QMail daemon user' qmaild useradd -g nofiles -d /var/qmail -s /sbin/nologin -p '*' -c 'QMail log user' qmaill useradd -g nofiles -d /var/qmail -s /sbin/nologin -p '*' -c 'QMail password user' qmailp groupadd qmail useradd -g qmail -d /var/qmail -s /sbin/nologin -p '*' -c 'QMail queue user' qmailq useradd -g qmail -d /var/qmail -s /sbin/nologin -p '*' -c 'QMail remote user' qmailr useradd -g qmail -d /var/qmail -s /sbin/nologin -p '*' -c 'QMail send user' qmails
Basically, at this time, we are ready to do the build. Remember we have Qmail-1.03, which we need to patch, ideally with the latest combined patch from John Simpson.
conf-split and conf-spawn
QMR, at this stage creates a lot of directories and sets ownerships, which we are not going to do now. We will be careful, and will try to follow LWQ steps. There are, in particular, two files in Qmail source tree, in which QMR pushes some values. Refer to the following code:
# Don't execute the following two lines blindly. # echo 211 > /usr/src/qmail/qmail-1.03/conf-split # echo 255 > /usr/src/qmail/qmail-1.03/conf-spawn
According to the example we are following, these files are actually located in /usr/local/src/qmail-1.03 directory. Let's see these files contents from the default source:-
# cat /usr/local/src/qmail-1.03/conf-split 23 This is the queue subdirectory split.
# cat /usr/local/src/qmail-1.03/conf-spawn 120 This is a silent concurrency limit. You can't set it above 255. On some systems you can't set it above 125. qmail will refuse to compile if the limit is too high.
The details gathered on these two files from internet :-
conf-split:
The conf-split file specifies the number of subdirectories that the qmail directories for mail-queuing: info, local, mess and remote, are divided into. The default value for this parameter is 23. This is the number of split subdirectories for those queue directories which are hashed. The default for qmail is 23. Appropriate values depend on the volume of mail handled, OS filesystem efficiency, and other factors, but this should always be a prime number. (Ref: http://pyropus.ca/software/queue-repair/docs.html ) Research has shown that you get a more even distribution of hash values, and thus fewer collisions, if you choose your table size to be a prime number. Question: Are there any negative sideeffects of setting conf-split too high? Answer: Yes there are . Scanning todo/ takes longer, if you are using the big-todo patch, because every subdir has to be scanned, instead of just one dir.
Reference: http://www.mail-archive.com/qmail@id.wustl.edu/msg46322.html The default, 23, is prime, and in his only message to the list on the topic of conf-split, DJB suggested a value of 401, also prime, for a queue with 100000 entries. Reference: http://www.ornl.gov/its/archives/mailing-lists/qmail/1997/07/msg00295.html
Bottom-line: For smaller sites / mail-servers/ mail-queues, use the default. For larger sites, you can use larger prime numbers, going all the way to 401.
conf-spawn:
The conf-spawn file specifies the maximum number of simultaneous qmail-local and qmail-remote sessions that can be running on the system. The default value for this parameter is 120.
Conclusion for conf-split and conf-spawn:
We will use the default values in these files, unless John Simpson's combined patch makes changes in them.
Patch qmail source with John Simpson's patch
Time to apply the combined patch to qmail-1.03 . Download John Simpson's latest combined patch from his site: http://qmail.jms1.net/patches/combined-details.shtml
cd /downloads wget http://qmail.jms1.net/patches/qmail-1.03-jms1.7.10.patch cd /usr/local/src/qmail-1.03 patch < /downloads/qmail-1.03-jms1.7.10.patch
As you can see below, not a “single” hunk / patch failed!
# patch < /downloads/qmail-1.03-jms1.7.10.patch patching file EXTTODO patching file EXTTODO-INFO ... ... patching file tcp-env.c patching file timeoutconn.c patching file timeoutconn.h
Just for the sake of verification, lets see what the patch has done to the two files: conf-split and conf-spawn. Here they are after patching:
# cat conf-split 23 This is the queue subdirectory split. # cat conf-spawn 120 This is a silent concurrency limit. You can't set it above 65000. Many systems have a "hidden limit" of 509, because a single process cannot have more than 1023 handles open at once, and each concurrent delivery uses two handles. If you set it any higher than your system's "hidden limit", qmail will refuse to compile.
As you can see, there is just a more detailed comment added in the conf-spawn. Rest no values are changed. Good!
Compile qmail
Once the patching is done, you are in line with the step of LWQ. You can go ahead and compile qmail. As shown below:
cd /usr/local/src/qmail-1.03 make clean make man make setup check # make setup check ... ... chmod 755 binm3+df ./compile spfquery.c spfquery.c: In function ‘main’: spfquery.c:30: warning: incompatible implicit declaration of built-in function ‘strdup’ spfquery.c:24: warning: return type of ‘main’ is not ‘int’ ./load spfquery spf.o ip.o ipme.o ipalloc.o strsalloc.o \ now.o dns.o env.o datetime.a stralloc.a alloc.a str.a substdio.a \ case.a error.a fs.a `cat dns.lib` `cat socket.lib` envread.o qregex.o ./compile -DEXTERNAL_TODO qmail-todo.c qmail-todo.c: In function ‘main’: qmail-todo.c:620: warning: return type of ‘main’ is not ‘int’ ./load qmail-todo control.o constmap.o trigger.o fmtqfn.o now.o \ readsubdir.o case.a ndelay.a getln.a sig.a open.a stralloc.a \ alloc.a substdio.a error.a str.a fs.a auto_qmail.o auto_split.o ./install ./instcheck
Configure basic qmail structures
According to LWQ, you can now go ahead with using either “./config” or “./config-fast server.domain.com” method. QMR asks you to run “./config-fast server.domain.com” directly. However there is no harm in executing any of these two scripts. For "./config" you should make sure that your hostname is retrievable from DNS.
According to LWQ:
If your DNS is configured properly, this script should be all you need at this point: ./config If, for some reason, config can't find your hostname in DNS, you'll have to run the config-fast script: ./config-fast the.full.hostname For example, if your domain is example.com and the hostname of your computer is dolphin, your config-fast line would look like this: ./config-fast dolphin.example.com
Run the configuration script:
# ./config-fast qmail.example.com Your fully qualified host name is qmail.example.com. Putting qmail.example.com into control/me... Putting example.com into control/defaultdomain... Putting example.com into control/plusdomain... Putting qmail.example.com into control/locals... Putting qmail.example.com into control/rcpthosts... Now qmail will refuse to accept SMTP messages except to qmail.example.com. Make sure to change rcpthosts if you add hosts to locals or virtualdomains!
That's it. qmail is now installed on your system and is ready to be run!
Please note that you must not put your domain name in the locals file. Means, if you are configuring your server to host emails for the domain example.com using vpopmail, then the locals file must not contain the domain "example.com". It should only contain the hostname of your server, such as "qmail.example.com" .
For reference check the following explanations:
- 7.11 What is the difference between the locals and rcpthosts files in /var/qmail/control?
- Problem with the "locals" file (http://qmail.jms1.net/upgrade-qmr.shtml)
QMR suggests to “make cert” at this point. There is no fun in doing so, as there are couple of things we still need to do. More-over, the “make cert” method suggested by QMR is wrong and is seriously questioned by JMS. We will deal with certificates at a later stage, when we will add SMTPS service.
ucspi-tcp:
ucspi-tcp is DJB's original implementation of UCSPI, the Unix Client-Server Program Interface, using the TCP protocol. In other words, it's a set of programs which make it easy to write and run service programs which accept connections on TCP sockets, as well as client programs which connect to services on TCP sockets. The programs in the ucspi-tcp package take care of the messy networking details, and allow the programmer or system administrator to concentrate on making their service or client work correctly.
ucspi-tcp [LWQ]:
If you modified conf-cc and conf-ld, you'll need to make the same changes in this directory. Note that we did not do any changes to conf-cc and conf-ld while compiling / building qmail-1.03 .
Now change to the ucspi-tcp directory, patch the source code and compile it:
cd /usr/local/src/ucspi-tcp-0.88 patch < /usr/local/src/netqmail-1.06/other-patches/ucspi-tcp-0.88.errno.patch make make setup check
That's it. ucspi-tcp is installed.
Ucspi-tcp [JMS]:
From JMS site (http://qmail.jms1.net/ucspi-tcp/ ):-
ucspi-tcp is DJB's original implementation of UCSPI, the Unix Client-Server Program Interface, using the TCP protocol. In simple words, it's a set of programs which make it easy to write and run service programs which accept connections on TCP sockets, as well as client programs which connect to services on TCP sockets. The programs in the ucspi-tcp package take care of the messy networking details, and allow the programmer or system administrator to concentrate on making their service or client work correctly.
It's mentioned on this web site (http://qmail.jms1.net) because the normal method of running an SMTP or POP3 service is to use the "tcpserver" program, which is part of the ucspi-tcp package. It's also possible to use tcpserver to run other TCP-based services, such as IMAP services. If you're running a qmail server, you should definitely understand how tcpserver works.
Like qmail, the programs in the ucspi-tcp package are lacking in some features which many people, myself included, need on their servers. Below is a list of the ucspi-tcp patches I use on my own systems:
- ucspi-tcp-0.88.errno.patch
- ucspi-rss.diff
- The tcpserver limits patch
ucspi-tcp-0.88.errno patch
The ucspi-tcp package, like all of DJB's other packages, has an issue with the errno variable when compiled using glibc version 2.3 or higher. (e.g. CENTOS 5.3 has glibc 2.5 ). The solution is the same as for DJB's other packages as well.
Edit the file error.h in the source code. Find this line, near the top of the file:
extern int errno;
Comment this line out, and add the following line below it:
/* extern int errno; */ #include <errno.h>
If you would rather not edit the file by hand, the patch file can be used to make the change as well.
ucspi-rss.diff patch
ucspi-rss.diff is a patch by Alan Curry which makes the rblsmtpd program work with A records. This is necessary because the owners of "rss" (one of the first anti-spam "blacklists") removed the TXT records from their zone files, because the DNS server they were using to serve the zone (BIND, which they also wrote) had trouble with large zone files, a problem which the "rbldns" program (from DJB's djbdns package) does not share. I have updated the patch. With the original patch, when rblsmtpd retrieves a TXT record, it scans the value for the string "%IP%" and replaces it with the value of TCPREMOTEIP (i.e. the IP address of the client.) My updated version does the same substitution on the value of the RBLSMTPD environment variable when it starts. You can download the original patch from qmail.org, or from my server. You can download the updated patch here: http://qmail.jms1.net/ucspi-tcp/ucspi-rss2.patch
tcpserver limits patch
The tcpserver limits patch, by Matija Nalis, gives tcpserver the ability to reject connections when the server's load average is above a certain number, when more than a certain number of connections are received from the same IP address, or when more than a certain number of connections are received from machines in the same class-C block (i.e. the "first three numbers" in their IP addresses are the same. "1.2.3.4" and "1.2.3.100" are in the same class-C block.)
The limits are configured by setting the MAXLOAD, MAXCONNIP, and MAXCONNC environment variables before tcpserver runs. If you want tcpserver to send a message to the client before dropping their connection, you can configure this by setting a DIEMSG environment variable. The patch I was using, dated 2006-01-26, does work as advertised, and has saved my own server and several of my clients' servers from being overloaded by over-zealous attackers (i.e. spammers) over the past few months. However, I did notice a few minor cosmetic issues which I thought needed to be fixed, so I updated the patch.
My updates are: When MAXCONNIP or MAXCONNC cause a connection to be rejected, tcpserver adds "MAXCONNIP:" or "MAXCONNC:" with the limit at the end of the "deny line in the logs. This makes it easy to debug- the error message tells you which environment variable caused the connection to be rejected.
However, when MAXLOAD causes a connection to be rejected, it adds "LOAD:" and the current load average to the log. This doesn't match the environment variable, which "feels funny" to me. (I told you it was a minor cosmetic issue.) . For the sake of consistency, I changed the "LOAD:" label to say "MAXLOAD:", so it matches the environment variable name, like the other two messages do.
The older patch only has a provision for a single DIEMSG variable, whose value is sent to a client whose connection is being rejected, regardless of which of the three limits the client triggered. I thought it would be nice to be able to set one message which says something like "Server too busy, try again later" and another message which says "Too many connections from your IP address".
I added three new environment variables: DIEMSG_MAXLOAD, DIEMSG_MAXCONNIP, and DIEMSG_MAXCONNC, whose values are used instead of the generic DIEMSG message. However, to avoid breaking older scripts, if one of these new variables is not set, the DIEMSG value will be used instead. The original author's web page has a link where you can download the previous versions of the patch. As of the time I'm writing this (2007-12-22) the most recent version of his patch is dated 2006-01-26, and is what I used as the starting point for my own changes. Below is the link to download the patch. I also have the CHANGES.tcpserver-limits-patch and README.tcpserver-limits-patch files available, if you want to read them before downloading the patch.
I highly recommend you to read the README.tcpserver-limits-patch file. http://qmail.jms1.net/ucspi-tcp/tcpserver-limits-2007-12-22.patch
Conclusion and actual installation of UCSPI:
We did not do any changes to conf-cc and conf-ld while compiling / building qmail-1.03 . So we don't need to change anything in the ucspi-tcp directory. I cannot use the patch suggested by LWQ, as I am not using netqmail-1.06 . So I will use JMS method and manually edit the error.h file:
cd /usr/local/src/ucspi-tcp-0.88 # vi error.h ... ... Replace : extern int errno; With : /* extern int errno; */ And add another line after it: #include <errno.h> ... ... (save exit).
Then, I would download the two other patches mentioned by JMS and apply them to UCSPI source:
cd /downloads/ wget http://qmail.jms1.net/ucspi-tcp/ucspi-rss2.patch wget http://qmail.jms1.net/ucspi-tcp/tcpserver-limits-2007-12-22.patch cd /usr/local/src/ucspi-tcp-0.88 # patch < /downloads/ucspi-rss2.patch patching file rblsmtpd.c # patch < /downloads/tcpserver-limits-2007-12-22.patch patching file CHANGES.tcpserver-limits-patch patching file README.tcpserver-limits-patch patching file tcpserver.c
Now run “make” and “make setup check”:
# make ... ... ./compile install.c ./compile hier.c ./compile auto-str.c auto-str.c:9: warning: conflicting types for built-in function ‘puts’ ./load auto-str unix.a byte.a ./auto-str auto_home `head -1 conf-home` > auto_home.c ./compile auto_home.c ./load install hier.o auto_home.o unix.a byte.a ./compile instcheck.c ./load instcheck hier.o auto_home.o unix.a byte.a # make setup check ./install ./instcheck
That's it. ucspi-tcp is installed.
Daemontools:
The daemontools package monitors, controls, and logs the execution and output of long-running programs, often called daemons.
Daemontools [LWQ]
Change to the daemontools build directory:
cd /package/admin/daemontools-0.76
Once again, if you modified <conf-cc> and conf-ld during the qmail and ucspi-tcp builds, you'll need to make the same changes in the src directory.
Then do:
cd src patch < /usr/local/src/netqmail-1.06/other-patches/daemontools-0.76.errno.patch cd .. package/install
Daemontools [QMR]:
QMR wants us to patch daemontools, using the patch copied from the netqmail distribution, which is ok to do.
Conclusion and Installation of Daemontools:
We know that are not using LWQ's netqmail. Also we know that the patch applied to daemontools during QMR installation is in-fact a patch copied from LWQ's distribution. Basically this “errno” patch is exactly the same as it was for ucspi-tcp sotware. We just need to disable a line and introduce another line, exactly as before. So here it goes:
cd /package/admin/daemontools-0.76/src/ # vi error.h ... extern int errno; ... ...
Comment out "extern int errno;" , and add another line "#include <errno.h>" , after that.
... /* extern int errno; */ #include <errno.h> ... ...
(save exit).
Change directory one step back (out of src directory):
cd .. or cd /package/admin/daemontools-0.76/
And run "package/install":
# package/install ... ... grep sysdep hasmkffo.h >> sysdeps grep sysdep hasflock.h >> sysdeps grep sysdep hasshsgr.h >> sysdeps Copying commands into ./command... Creating symlink daemontools -> daemontools-0.76... Making command links in /command... Making compatibility links in /usr/local/bin... Creating /service... Adding svscanboot to inittab... init should start svscan now.
At this point your daemontools installation is complete. You should be able to see the “svscan” process running on your machine. Use "ps -ef | grep svscan" , “ps aux | grep svscan” or "ps waux | grep svscan" to verify that svscan is running. See the important note below, if you cannot see the svscan process running.
# ps waux | grep svscan root 25206 0.0 0.1 2452 1044 ? Ss 15:06 0:00 /bin/sh /command/svscanboot root 25208 0.0 0.0 1684 356 ? S 15:06 0:00 svscan /service root 25213 0.0 0.0 3912 676 pts/0 S+ 15:09 0:00 grep svscan
You will also see the following line added to your /etc/inittab file :
# cat /etc/inittab . . . . . . SV:123456:respawn:/command/svscanboot
IMPORTANT NOTE: (CentOS 6 specific)
The installer added a line to /etc/inittab to start svscan automatically, however that is obsolete in CentOS 6.x.
- CentOS 6 Specific (http://www.productionmonkeys.net/guides/qmail-server/daemontools)
- Starting daemontools with Upstart (http://qmail.jms1.net/daemontools/upstart.shtml)
- http://www.kluner.net/2011/04/04/daemontools-on-redhat-enterprise-6-0
Remove the "SV" or "svscanboot" line from /etc/inittab:
SV:123456:respawn:/command/svscanboot
Create a new file /etc/init/svscan.conf, with the startup code in it:
cd /etc/init echo "start on runlevel [12345]" > svscan.conf echo "respawn" >> svscan.conf echo "exec /command/svscanboot" >> svscan.conf
Tell init to re-read its configuration files and start svscanboot:
initctl reload-configuration initctl start svscan
# initctl reload-configuration # initctl start svscan svscan start/running, process 5167 # ps aux | grep svscan root 5167 0.0 0.1 11296 1316 ? Ss 11:44 0:00 /bin/sh /command/svscanboot root 5169 0.0 0.0 4100 444 ? S 11:44 0:00 svscan /service root 5172 0.0 0.0 103236 836 pts/0 S+ 11:44 0:00 grep svscan
This step is done.
Note: This process check (shown above, just now) is what QMR performs at the end of it's “Part 2 - Installing Qmail Itself”. But as soon as QMR does this, it goes on an “Install spree” (same as shopping spree) and installs all sorts of software until it reaches it's “Part-9” where is decides to have mercy on the person doing the install, and finalize the qmail installation. Why did'nt that guy just start the qmail software first and made sure that it worked before moving on to installing bells and whistles ? It is a mystery to me.
Install CDB package from DJB's site
DJB's cdb library and tools contains the cdbmake-12 program, which converts a text file into a cdb file. The cdbmake program will help creating CDB files later on. This package should be installed using the directions on djb's web site.
cd /downloads wget http://cr.yp.to/cdb/cdb-0.75.tar.gz tar xzf cdb-0.75.tar.gz
Fix the error in error.h file. Find:
extern int errno;
, and change it to:
/* extern int errno; */ #include <errno.h>
Now compile and install:
make make setup check
Also install perl-CDB_File either from yum repository or from CPAN:
yum -y install perl-CDB_File
Configure qmail
Qmail log directories
LWQ creates a directory (/var/log/qmail) at this point. This will be used in various log-run scripts created below. The qmail log-run scripts (from LWQ) will create files in this directory, “directly”. QMR deviated a little from this and created three sub directories inside /var/log/qmail: qmail-send, qmail-smtpd, and qmail-pop3d . JMS acknowledges (http://qmail.jms1.net/logfiles.shtml), that is is not standard, however it is not wrong as well. So we will use the QMR log directories.
mkdir /var/log/qmail # LWQ mkdir /var/log/qmail/qmail-send # QMR mkdir /var/log/qmail/qmail-smtpd # QMR mkdir /var/log/qmail/qmail-pop3d # QMR
QMR, also sets up certain ownership and permission to these log directories. Such as:
chown -R qmaill:root /var/log/qmail chmod -R 750 /var/log/qmail
If you check the LWQ run script for qmail-send/log, and qmail-smtpd/log, you will notice that setuidgid program (provided with qmail source code itself), is called with an account name of qmaill. The setuidgid program takes care of the correct ownership of the files being written by the child program it calls. So setting the ownership for /var/log/qmail and it's sub directories , as the user qmaill, is okay. The same is verified/confirmed when LWQ also sets up the log directories and sets up ownership of these files as user qmaill . Also see http://cr.yp.to/qmail/faq/admin.html#multilog
The /var/qmail/rc file [LWQ] (recommended)
The /var/qmail/boot directory contains example qmail boot scripts for different configurations. However for our installation, we'll use the following script and save it as /var/qmail/rc :
#!/bin/sh # Using stdout for logging # Using control/defaultdelivery from qmail-local to deliver messages by default exec env - PATH="/var/qmail/bin:$PATH" \ qmail-start "`cat /var/qmail/control/defaultdelivery`"
Note 1: Notice the back ticks! Note 2: QMR does the same, but doesn't inform us anything about creating this script, or it's contents. Also, QMR places ./Maildir (without quotes) in the /var/qmail/control/defaultdelivery file. That is intended, but an extra slash (/) is what is mentioned in LWQ guide. Normally it doesn't matter; It works both ways.
Save the above code as above /var/qmail/rc, and make it executable:
chmod 755 /var/qmail/rc
At this point you need to decide the default delivery mode for messages that aren't delivered by a .qmail file. The options are Mailbox or Maildir formats. We are going to use the Maildir format as the default delivery mode, which is more efficient and manageable. For more information about mbox and maildir, see INSTALL.mbox, INSTALL.maildir files in /usr/local/src/qmail-1.03 directory.
echo './Maildir/' >/var/qmail/control/defaultdelivery
Note [from LWQ]: defaultdelivery isn't a standard qmail control file. It's a feature of the above /var/qmail/rc file. The defaultdelivery argument to qmail-start is the contents of a .qmail file that specifies delivery instructions to be followed when no actual .qmail is found. Putting these instructions in a separate control file eliminates the need to quote shell metacharacters in the delivery instructions and avoids messy multi-line command arguments.
System start-up files [from LWQ]
The qmailctl script (recommended)
If you were to manually execute the /var/qmail/rc script, qmail would be partially started. But we want qmail started up automatically every time the system is booted and we want it shut down cleanly when the system is halted. This is accomplished by creating a startup/shutdown script like the following in /var/qmail/bin/qmailctl. This script is available via http://lifewithqmail.org/qmailctl-script-dt70 . Create the script using your editor or by downloading it with your web browser (recommended):
cd /downloads wget http://lifewithqmail.org/qmailctl-script-dt70 cp qmailctl-script-dt70 /var/qmail/bin/qmailctl
/var/qmail/bin/qmailctl
#!/bin/sh # For Red Hat chkconfig # chkconfig: - 80 30 # description: the qmail MTA control file PATH=/var/qmail/bin:/bin:/usr/bin:/usr/local/bin:/usr/local/sbin export PATH QMAILDUID=`id -u qmaild` NOFILESGID=`id -g qmaild` case "$1" in start) echo "Starting qmail" if svok /service/qmail-send ; then svc -u /service/qmail-send /service/qmail-send/log else echo "qmail-send supervise not running" fi if svok /service/qmail-smtpd ; then svc -u /service/qmail-smtpd /service/qmail-smtpd/log else echo "qmail-smtpd supervise not running" fi if [ -d /var/lock/subsys ]; then touch /var/lock/subsys/qmail fi ;; stop) echo "Stopping qmail..." echo " qmail-smtpd" svc -d /service/qmail-smtpd /service/qmail-smtpd/log echo " qmail-send" svc -d /service/qmail-send /service/qmail-send/log if [ -f /var/lock/subsys/qmail ]; then rm /var/lock/subsys/qmail fi ;; stat) svstat /service/qmail-send svstat /service/qmail-send/log svstat /service/qmail-smtpd svstat /service/qmail-smtpd/log qmail-qstat ;; doqueue|alrm|flush) echo "Flushing timeout table and sending ALRM signal to qmail-send." /var/qmail/bin/qmail-tcpok svc -a /service/qmail-send ;; queue) qmail-qstat qmail-qread ;; reload|hup) echo "Sending HUP signal to qmail-send." svc -h /service/qmail-send ;; pause) echo "Pausing qmail-send" svc -p /service/qmail-send echo "Pausing qmail-smtpd" svc -p /service/qmail-smtpd ;; cont) echo "Continuing qmail-send" svc -c /service/qmail-send echo "Continuing qmail-smtpd" svc -c /service/qmail-smtpd ;; restart) echo "Restarting qmail:" echo "* Stopping qmail-smtpd." svc -d /service/qmail-smtpd /service/qmail-smtpd/log echo "* Sending qmail-send SIGTERM and restarting." svc -t /service/qmail-send /service/qmail-send/log echo "* Restarting qmail-smtpd." svc -u /service/qmail-smtpd /service/qmail-smtpd/log ;; cdb) tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp chmod 644 /etc/tcp.smtp.cdb echo "Reloaded /etc/tcp.smtp." ;; help) cat <<HELP stop -- stops mail service (smtp connections refused, nothing goes out) start -- starts mail service (smtp connection accepted, mail can go out) pause -- temporarily stops mail service (connections accepted, nothing leaves) cont -- continues paused mail service stat -- displays status of mail service cdb -- rebuild the tcpserver cdb file for smtp restart -- stops and restarts smtp, sends qmail-send a TERM & restarts it doqueue -- schedules queued messages for immediate delivery reload -- sends qmail-send HUP, rereading locals and virtualdomains queue -- shows status of queue alrm -- same as doqueue flush -- same as doqueue hup -- same as reload HELP ;; *) echo "Usage: $0 {start|stop|restart|doqueue|flush|reload|stat|pause|cont|cdb|queue|help}" exit 1 ;; esac exit 0
Make the qmailctl script executable and link it to a directory in your path:
chmod 755 /var/qmail/bin/qmailctl ln -s /var/qmail/bin/qmailctl /usr/bin
Note: QMR also uses the same script which is copied from /downloads/qmailrocks/scripts/finalize location to /var/qmail/bin directory, as a result of running the the /downloads/qmailrocks/scripts/finalize/linux/finalize_linux.script script-file, in the start of QMR step 9. QMR also makes this executable , and link it in /usr/bin the same way.
The supervise scripts:
Note: QMR already has these scripts ready in a specific directory (/downloads/qmailrocks/scripts/finalize/freebsd/) . It just copies these files at the same locations where LWQ suggests. This was revealed from studying the script (finalize_linux.script), which QMR runs in part 9.
Supervise scripts need a location to be created/stored in. Create the supervise directories for the qmail services [LWQ]: (recommended)
mkdir -p /var/qmail/supervise/qmail-send/ mkdir -p /var/qmail/supervise/qmail-send/log mkdir -p /var/qmail/supervise/qmail-smtpd mkdir -p /var/qmail/supervise/qmail-smtpd/log
Notes:
- I did not create qmail-pop3 directories, because I will use POP3 and IMAP from dovecot.
- QMR also creates these directories, when a script named qmr_install_linux-s1.script is run.
The qmail-send run script
The JMS qmail-send run script looks like this:
VQ="/var/qmail" exec env - PATH="$VQ/bin:/usr/local/bin:/usr/bin:/bin" \ qmail-start ./Maildir/
This is in-fact an almost the same as the /var/qmail/rc file. Apparently JMS doesn't want to use /var/qmail/rc in his scripts, and would rather (kind of) hard-code the same.
Create the /var/qmail/supervise/qmail-send/run file (recommended):
cat > /var/qmail/supervise/qmail-send/run << EOF #!/bin/sh exec /var/qmail/rc EOF
Note: QMR's send_run file has same contents, for this file.
The qmail-send/log/run script
The /var/qmail/supervise/qmail-send/log/run file by LWQ, which I will use with some variation (shown later):
#!/bin/sh exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t /var/log/qmail
Note: QMR also uses the same contents with a little variation. These variations are permitted / certified by DJB (http://cr.yp.to/daemontools/multilog.html) , and JMS ( http://qmail.jms1.net/scripts/ ). The QMR's send_log script, later copied in system as /var/qmail/supervise/qmail-send/log/run, looks like:
cat /downloads/qmailrocks/scripts/finalize/freebsd/send_log #!/bin/sh PATH=/var/qmail/bin:/usr/local/bin:/usr/bin:/bin export PATH exec setuidgid qmaill multilog t s100000 n20 /var/log/qmail/qmail-send 2>&1
A little explanation: s1000000 means that the current logfile will be rotated when reached a size of 100KB. And 20 such rotated log files will be retained by qmail / multilog. Older log files will automatically get deleted. We will adopt this variation and use this. I just want to raise the size-limit of the logfile to 50MB and 20 generations of this file. This will result in a total of 1GB of disk consumed by my qmail logs. You can adjust as per your requirements. Note: I think there is no need to "export" the PATH.
JMS provides a script at (http://qmail.jms1.net/scripts/service-any-log-run) location. Which looks like:
VQ="/var/qmail" exec env - PATH="$VQ/bin:/usr/local/bin:/usr/bin:/bin" \ multilog t n1024 s1048576 ./main \ '-*' '+*ver: status:*' =lstatus
JMS calls it “service-any-log-run” because you can use it to log any service you want to, such as qmail-send, qmail-smtpd, etc. He uses the technique of using relative file name instead of absolute file names. That means that if this script it run under qmail-send/log/ directory, it will create a file “main” over there. The cryptic line at the end of the script is basically removal of all log lines except the ones with “ver” and “status” in them. This indicated minimal logging being done. Default is that all lines will be logged. He is keeping 1024 generations of this log file (n1024) , each one being 1MB in size (s1048576).
For detailed explanation of multilog options, look here: http://cr.yp.to/daemontools/multilog.html
Alright, the final version of my /var/qmail/supervise/qmail-send/log/run file looks like: (recommended)
cat > /var/qmail/supervise/qmail-send/log/run << EOF #!/bin/sh PATH=/var/qmail/bin:/usr/local/bin:/usr/bin:/bin exec setuidgid qmaill multilog t s50000000 n20 /var/log/qmail/qmail-send 2>&1 EOF
Look here for more explanations:
- http://cr.yp.to/daemontools/multilog.html
- ttp://qmail.jms1.net/logfiles.shtml
- http://qmail.jms1.net/scripts/service-any-log-run
The qmail-smtpd/run script
Here is the LWQ version of the qmail-smtpd/run file: (not recommended for our setup)
#!/bin/sh QMAILDUID=`id -u qmaild` NOFILESGID=`id -g qmaild` MAXSMTPD=`cat /var/qmail/control/concurrencyincoming` LOCAL=`head -1 /var/qmail/control/me` if [ -z "$QMAILDUID" -o -z "$NOFILESGID" -o -z "$MAXSMTPD" -o -z "$LOCAL" ]; then echo QMAILDUID, NOFILESGID, MAXSMTPD, or LOCAL is unset in echo /var/qmail/supervise/qmail-smtpd/run exit 1 fi if [ ! -f /var/qmail/control/rcpthosts ]; then echo "No /var/qmail/control/rcpthosts!" echo "Refusing to start SMTP listener because it'll create an open relay" exit 1 fi exec /usr/local/bin/softlimit -m 2000000 \ /usr/local/bin/tcpserver -v -R -l "$LOCAL" -x /etc/tcp.smtp.cdb -c "$MAXSMTPD" \ -u "$QMAILDUID" -g "$NOFILESGID" 0 smtp /var/qmail/bin/qmail-smtpd 2>&1
The QMR version of qmail-smtpd/run file is below. When the finalize_linux.script script is run in QMR part 9, this file gets copied as /var/qmail/supervise/qmail-smtpd/run file. (Not recommended for our setup).
[root@qmail freebsd]# cat /downloads/qmailrocks/scripts/finalize/freebsd/smtpd_run #!/bin/sh QMAILDUID=`id -u vpopmail` NOFILESGID=`id -g vpopmail` MAXSMTPD=`cat /var/qmail/control/concurrencyincoming` LOCAL=`head -1 /var/qmail/control/me` if [ -z "$QMAILDUID" -o -z "$NOFILESGID" -o -z "$MAXSMTPD" -o -z "$LOCAL" ]; then echo QMAILDUID, NOFILESGID, MAXSMTPD, or LOCAL is unset in echo /var/qmail/supervise/qmail-smtpd/run exit 1 fi if [ ! -f /var/qmail/control/rcpthosts ]; then echo "No /var/qmail/control/rcpthosts!" echo "Refusing to start SMTP listener because it'll create an open relay" exit 1 fi exec /usr/local/bin/softlimit -m 30000000 \ /usr/local/bin/tcpserver -v -R -l "$LOCAL" -x /etc/tcp.smtp.cdb -c "$MAXSMTPD" \ -u "$QMAILDUID" -g "$NOFILESGID" 0 smtp \ /var/qmail/bin/qmail-smtpd mail.example.com \ /usr/home/vpopmail/bin/vchkpw /usr/bin/true 2>&1 [root@qmail freebsd]#
Note: [LWQ]: concurrencyincoming isn't a standard qmail control file. It's a feature of the above script. Also, that's -1 (dash one) on the LOCAL line and -l (dash ell) on the tcpserver line.
Note: [LWQ]: The memory limit specified in the softlimit command may need to be raised depending upon your operating system and hardware platform. If attempts to connect to port 25 fail or remote systems are unable to send you mail, or you see a message like the following, then try raising softlimit to 3000000 or 4000000, or whatever you can afford, according to available system resources.
/usr/local/bin/tcpserver: error while loading shared libraries: libc.so.6: failed to map segment from shared object: Cannot allocate memory
Note: If you use above script, you will need to create the concurrencyincoming control file as used in the qmail-smtpd/run scripts above. (This is shown below). Since we are not using the qmail-smtpd/run script either from LWQ or QMR, so we don't need to create the concurrencyincoming file.
echo 20 > /var/qmail/control/concurrencyincoming chmod 644 /var/qmail/control/concurrencyincoming
Why QMR's author is using vpopmail as QMAILUID and NOFILESGID variables in the qmail-smtpd/run script?
Answer: The following link ( http://qmail.jms1.net/upgrade-qmr.shtml) from JMS website clearly indicates the problems you may run into, IF you run qmail-smtpd as uid of vpopmail. Here is the explanation from the mentioned web-link:
The qmail-smtpd program handles the server end of an SMTP connection. It was originally designed to run as the userid qmaild. However, the /service/qmail-smtp/run script that qmailrocks installs sets things up so that qmail-smtpd runs as the vpopmail user, which means that a bug in qmail-smtpd (or in any of the programs that it calls, such as qmail-scanner, clamav, or spamassassin) could possibly erase all of your users' mailboxes. Not cool.
My (JMS) scripts set things up so that qmail-smtpd runs as the qmaild user, as djb originally designed it. Why did qmailrocks change from djb's standard? qmailrocks sets things up to use vpopmail's vchkpw program to validate any AUTH commands. And in order for vchkpw to read the files which actually contain the passwords (or the MD5 hashes of the passwords, or the file containing login information to a mysql server with that information) it needs to run as the vpopmail user.
At some point in the past, somebody decided that the best way to allow vchkpw to access these files was to run qmail-smtpd as the vpopmail user, and apparently qmailrocks blindly copied that person's "run" script when putting the qmailrocks package together.
There are two alternatives to this, both of which are more secure: You can give vchkpw the permissions it needs by making it "setuid", so that no matter which userid starts the program, it will always run as the vpopmail user. To me this option makes more sense than running qmail-smtpd itself as the vpopmail user, since a malicious email crafted to take advantage of some as-yet unknown security hole in clamav, spamassassin, or qmail-scanner, would not be able to access or delete any messages from your users' mailboxes- becasue only vchkpw runs as the vpopmail user (which owns all of the vpopmail mailbox directories) while the other programs continue to run as the qmaild user (or the qscand user, if you run qmail-scanner the same way I do.)
The vfixpermissions script will make your vchkpw binary setuid, along with fixing the ownership and permissions of everything else under the vpopmail user's home directory (which is where vpopmail stores everything.)
The AUTH_CDB patch, which is part of the newer versions of the combined patch, allows you to create a .cdb file (I use the name "auth.cdb" for this) which contains the valid userids and their encrypted passwords, and make that one file readable to the userid as which qmail-smtpd runs.
Either option is preferable to making qmail-smtpd, plus all of the child processes it runs, run as the vpopmail user.
The qmail-smtpd/run script by JMS
The qmail-smtpd/run file by JMS is quite big. It is download-able from (http://qmail.jms1.net/scripts/service-qmail-smtpd-run) . It has a lot of options in it, which are explained at: http://qmail.jms1.net/scripts/service-qmail-smtpd-run.shtml
cd /downlaods wget http://qmail.jms1.net/scripts/service-qmail-smtpd-run
Let's have a look at the script:
[root@qmail downloads]# cat service-qmail-smtpd-run #!/bin/sh # # service-qmail-smtpd-run (formerly "run.smtp" and "run.smtp.sslserver") # John Simpson <jms1@jms1.net> 2003-07-05 to 2008-03-24 # # Generic daemontools "run" script for qmail "smtp" or "smtpssl" service. # # Documentation: http://qmail.jms1.net/scripts/service-qmail-smtpd-run.shtml exec 2>&1 VQ="/var/qmail" PATH="$VQ/bin:/usr/local/bin:/usr/bin:/bin" QUSER=qmaild LOCAL=`head -1 $VQ/control/me` ############################################################################### # # options for tcpserver/sslserver IP=unset PORT=25 SSL=0 SSL_CERT="$VQ/control/servercert.pem" SMTP_CDB="/etc/tcp/smtp.cdb" MAX=30 # these require the "tcpserver limits" patch for ucspi-tcp, available here: # http://linux.voyager.hr/ucspi-tcp/ #MAXLOAD=750 #MAXCONNIP=2 #MAXCONNC=5 #DIEMSG="421 $LOCAL Service temporarily unavailable" # my newer version of the tcpserver limits patch allows you to specify # individual DIEMSG values for each policy. # http://qmail.jms1.net/ucspi-tcp/ #DIEMSG_MAXLOAD="421 $LOCAL Server busy, try again later." #DIEMSG_MAXCONNIP="421 $LOCAL Too many connections from your IP." #DIEMSG_MAXCONNC="421 $LOCAL Too many connections from your network." ############################################################################### # # options for programs which run before qmail-smtpd #RBLSMTPD_PROG="rblsmtpd" #RBL_GOOD="" #RBL_BAD="zen.spamhaus.org dnsbl.njabl.org dnsbl.sorbs.net bl.spamcop.net" #GREYLIST="jgreylist" #JGREYLIST_DIR="$VQ/jgreylist" #JGREYLIST_NOREV=1 #JGREYLIST_BY_IP=0 #JGREYLIST_HOLDTIME=120 #JGREYLIST_LOG=1 #JGREYLIST_LOG_PID=1 #JGREYLIST_LOG_SMTP=0 #JGREYLIST_TIMEOUT=60 #JGREYLIST_LIMIT=0 #RECORDIO="recordio" ############################################################################### # # options for qmail-smtpd itself SMTPD="qmail-smtpd" #SMTPGREETING="$LOCAL NO UCE" #GREETDELAY=30 #DROP_PRE_GREET=1 FORCE_TLS=0 DENY_TLS=0 MFCHECK=3 #MAXRCPT=100 #RELAYREJ=1 QMAILSMTPD_LOG_MAIL=1 QMAILSMTPD_LOG_RCPT=1 #QMAILSMTPD_HELP_VERSION=1 ############################################################################### # # options pertaining to the AUTH command. AUTH=0 REQUIRE_AUTH=0 ALLOW_INSECURE_AUTH=0 # if using the AUTH_CDB method #AUTH_CDB="$VQ/control/auth.cdb" # if using the CHECKPW method CHECKPW=~vpopmail/bin/vchkpw TRUE=`which true` # to change the environment whenever somebody authenticates #AUTH_SET_MFCHECK=0 #AUTH_SET_MAXRCPT=0 #AUTH_SET_DATABYTES=0 #AUTH_SET_SPFBEHAVIOR=1 #AUTH_SET_VALIDRCPTTO_LIMIT=10 #AUTH_SET_VALIDRCPTTO_LOG=1 #AUTH_SET_SPF_LOG=1 #AUTH_SET_RELAYREJ=0 #AUTH_SET_VALIDRCPTTO_CDB="" #AUTH_SET_QMAILSMTPD_LOG_MAIL=1 #AUTH_SET_QMAILSMTPD_LOG_RCPT=1 #AUTH_SET_QMAILSMTPD_HELP_VERSION=1 ############################################################################### # # options pertaining to the "validrcptto.cdb" mechanism. # see http://qmail.jms1.net/patches/validrcptto.cdb.shtml for details. VALIDRCPTTO_CDB="$VQ/control/validrcptto.cdb" VALIDRCPTTO_LIMIT=10 VALIDRCPTTO_LOG=2 ############################################################################### # # options pertaining to the SPF mechanism. SPFBEHAVIOR=3 SPF_LOG=1 SPF_BLOCK_PLUS_ALL=1 ############################################################################### # # options pertaining to the Domainkeys mechanism. # this requires an add-on patch. #DOMAINKEYS=0 #DKVERIFY=DEfGhIJK #AUTH_SET_DKSIGN=/etc/domainkeys/%/default ############################################################################### # # options for programs which run after qmail-smtpd # if you are using simscan... #QMAILQUEUE="$VQ/bin/simscan" NOP0FCHECK=1 #SIMSCAN_DEBUG=0 #SIMSCAN_DEBUG_FILES=0 # if you are using qmail-scanner, un-comment ONE of these lines. #QMAILQUEUE="$VQ/bin/qmail-scanner-queue" #QMAILQUEUE="$VQ/bin/qmail-scanner-queue.pl" # if you're using some other qmail-queue replacement, add your own line here # with the correct value. ############################################################################### ############################################################################### ############################################################################### # # THERE SHOULD BE NO NEED TO CHANGE ANYTHING BELOW THIS LINE. of course, the # script is on your system and you're free to edit it however you want, but # changing things below this point may cause strange things to happen. make # sure you understand what you're doing if you change anything below... QDUID=`id -u $QUSER` QDGID=`id -g $QUSER` if [ -z "$IP" -o "$IP" = "unset" ] then echo "The IP variable is not set in the run script. Cannot start." sleep 5 exit 1 fi if [ -z "$QDUID" -o -z "$QDGID" -o -z "$MAX" -o -z "$LOCAL" \ -o -z "$SSL" -o -z "$AUTH" ] then echo "One of the variables QDUID, QDGID, MAX, LOCAL, SSL, or AUTH" echo "is not set in the run script. Cannot start." sleep 5 exit 1 fi if [ ! -f $VQ/control/rcpthosts ] then echo Creating emtpy $VQ/control/rcpthosts file to prevent open relay. touch $VQ/control/rcpthosts chmod 644 $VQ/control/rcpthosts fi if [ "$SSL" = "1" ] then if ! which sslserver > /dev/null 2>&1 then echo ERROR: sslserver not found in PATH [$PATH] exit 1 fi if [ ! -f $SSL_CERT ] then echo ERROR: $SSL_CERT does not exist exit 1 fi export CERTFILE=${SSL_CERT} export KEYFILE="" export DHFILE="" SCMD="sslserver -e" else if [ -n "$SSL_CERT" ] then export TLS_SERVER_CERT=${SSL_CERT} fi SCMD="tcpserver" fi if [ "$IP" = "127.0.0.1" ] then export RELAYCLIENT="" RBLSMTPD_PROG="" ACMD="" elif [ -z "${SMTP_CDB:-}" ] then ACMD="" else if [ ! -f "$SMTP_CDB" ] then echo ERROR: $SMTP_CDB does not exist exit 1 fi ACMD="-x $SMTP_CDB" fi if [ "$AUTH" = "1" ] then if [ -n "$AUTH_CDB" ] then if [ ! -f $AUTH_CDB ] then echo ERROR: AUTH_CDB file [$AUTH_CDB] does not exist exit 1 fi export AUTH_CDB ARGS="" elif [ -n "$CHECKPW" ] then if [ ! -f $CHECKPW ] then echo ERROR: $CHECKPW [$CHECKPW] program does not exist exit 1 fi if [ -z "$LOCAL" ] then echo ERROR: LOCAL is not set in the run script exit 1 elif [ -z "$TRUE" ] then echo ERROR: TRUE is not set in the run script exit 1 elif [ ! -e $TRUE ] then echo ERROR: $TRUE [$TRUE] is not an executable exit 1 fi ARGS=" $LOCAL $CHECKPW $TRUE" else echo ERROR: AUTH=1 but no AUTH_CDB or CHECKPW exit 1 fi else ARGS="" AUTH_CDB="" fi ######################################## # make RBL command (if needed) RBLCMD="" if [ -n "$RBLSMTPD_PROG" ] then if [ -n "$RBL_GOOD" ] then for name in $RBL_GOOD do RBLCMD="$RBLCMD -a $name" done fi if [ -n "$RBL_BAD" ] then for name in $RBL_BAD do RBLCMD="$RBLCMD -r $name" done fi if [ -n "$RBLCMD" ] then RBLCMD="$RBLSMTPD_PROG -t0 $RBLCMD" fi fi ######################################## # make domainkeys command (if needed) if [ "$DOMAINKEYS" = "1" ] then if [ -f "$VQ/bin/qmail-dk" ] then if [ -n "$QMAILQUEUE" ] then export DKQUEUE="$QMAILQUEUE" fi export AUTH_UNSET_DKVERIFY=1 export QMAILQUEUE="$VQ/bin/qmail-dk" if [ -n "$DKVERIFY" ] ; then export DKVERIFY ; fi if [ -n "$DKSIGN" ] ; then export DKSIGN ; fi else echo ERROR: $VQ/bin/qmail-dk not found, cannot use domainkeys fi fi ######################################## # handle variables which may not have been set, but need to exist even # if they contain blank values if [ -z "$RECORDIO" ] then RECORDIO="" fi if [ -z "$GREYLIST" ] then GREYLIST="" fi ######################################## # do the deed for n in SSL \ MAXLOAD \ MAXCONNIP \ MAXCONNC \ DIEMSG \ DIEMSG_MAXLOAD \ DIEMSG_MAXCONNIP \ DIEMSG_MAXCONNC \ JGREYLIST_DIR \ JGREYLIST_NOREV \ JGREYLIST_BY_IP \ JGREYLIST_HOLDTIME \ JGREYLIST_LOG \ JGREYLIST_LOG_PID \ JGREYLIST_LOG_SMTP \ JGREYLIST_TIMEOUT \ JGREYLIST_LIMIT \ SMTPGREETING \ GREETDELAY \ DROP_PRE_GREET \ FORCE_TLS \ DENY_TLS \ MFCHECK \ MAXRCPT \ RELAYREJ \ QMAILSMTPD_LOG_MAIL \ QMAILSMTPD_LOG_RCPT \ QMAILSMTPD_HELP_VERSION \ REQUIRE_AUTH \ ALLOW_INSECURE_AUTH \ AUTH_CDB \ AUTH_SET_MFCHECK \ AUTH_SET_MAXRCPT \ AUTH_SET_DATABYTES \ AUTH_SET_SPFBEHAVIOR \ AUTH_SET_VALIDRCPTTO_LIMIT \ AUTH_SET_VALIDRCPTTO_LOG \ AUTH_SET_SPF_LOG \ AUTH_SET_RELAYREJ \ AUTH_SET_VALIDRCPTTO_CDB \ AUTH_SET_QMAILSMTPD_LOG_MAIL \ AUTH_SET_QMAILSMTPD_LOG_RCPT \ AUTH_SET_QMAILSMTPD_HELP_VERSION \ VALIDRCPTTO_CDB \ VALIDRCPTTO_LIMIT \ VALIDRCPTTO_LOG \ SPFBEHAVIOR \ SPF_LOG \ SPF_BLOCK_PLUS_ALL \ DKVERIFY \ AUTH_SET_DKSIGN \ QMAILQUEUE \ NOP0FCHECK \ SIMSCAN_DEBUG \ SIMSCAN_DEBUG_FILES do # note: not 100% sure "eval" works under old-school /bin/sh eval "if [ -n \"\$$n\" ];then echo \"$n=\\\"\$$n\\\"\";export $n;fi" done CMD="$SCMD -vR -l $LOCAL -c $MAX -u $QDUID -g $QDGID $ACMD $IP $PORT" CMD="$CMD $RBLCMD $GREYLIST $RECORDIO $SMTPD $ARGS" echo "command-line: exec $CMD 2>&1" exec $CMD 2>&1 ######################################## # this will only be reached if the exec fails echo ERROR: command did not run correctly exit 1 [root@qmail downloads]#
Below is the short summary of the tcpserver options used in the qmail-smtpd/run scripts shown above. Details about the tcpserver command/program can be studied from the following location: http://cr.yp.to/ucspi-tcp/tcpserver.html .
Summary of tcpserver options
Syntax: tcpserver opts host port prog
Where: opts is a series of getopt-style options; host is one argument; port is one argument; prog consists of one or more arguments. tcpserver waits for connections from TCP clients. For each connection, it runs prog, with descriptor 0 reading from the network and descriptor 1 writing to the network. It also sets up several environment variables.
General options:
- -v: Verbose. Print error messages and status messages.
Connection options:
- -c n: Do not handle more than n simultaneous connections. If there are n simultaneous copies of prog running, defer acceptance of a new connection until one copy finishes. n must be a positive integer. Default: 40.
- -x cdb: Follow the rules compiled into cdb by tcprules. These rules may specify setting environment variables or rejecting connections from bad sources. You can rerun tcprules to change the rules while tcpserver is running.
- -g gid: Switch group ID to gid after preparing to receive connections. gid must be a positive integer.
- -u uid: Switch user ID to uid after preparing to receive connections. uid must be a positive integer.
- -1: After preparing to receive connections, print the local port number to standard output.
Data-gathering options:
- -l localname: Do not look up the local host name in DNS; use localname for the environment variable $TCPLOCALHOST. A common choice for localname is 0. To avoid loops, you must use this option for servers on TCP port 53.
- -R: Do not attempt to obtain $TCPREMOTEINFO from the remote host. To avoid loops, you must use this option for servers on TCP ports 53 and 113.
The softlimit program
A little explanation of the softlimit program (by DJB), from the link: http://cr.yp.to/daemontools/softlimit.html
softlimit runs another program with new resource limits. Syntax: softlimit opts child Where: opts is a series of getopt-style options; child consists of one or more arguments. softlimit sets soft resource limits as specified by opts. It then runs child program.
Options In each of the following options, n may be =, indicating that the soft limit should be set equal to the hard limit.
Options controlling memory use:
- -m n: Same as -d n -s n -l n -a n.
- -d n: Limit the data segment per process to n bytes.
- -s n: Limit the stack segment per process to n bytes.
- -l n: Limit the locked physical pages per process to n bytes. This option has no effect on some operating systems.
- -a n: Limit the total of all segments per process to n bytes. This option has no effect on some operating systems.
- -o n: Limit the number of open file descriptors per process to n. This option has no effect on some operating systems.
- -p n: Limit the number of processes per uid to n.
Options controlling file sizes:
- -f n: Limit output file sizes to n bytes.
- -c n: Limit core file sizes to n bytes.
Efficiency options:
- -r n: Limit the resident set size to n bytes. This limit is not enforced unless physical memory is full.
- -t n: Limit the CPU time to n seconds. This limit is not enforced except that the process receives a SIGXCPU signal after n seconds.
Notice that JMS does not use softlimit in his qmail-smtpd/run script. The reason I see is that in modern linux systems the limits can be controlled through /etc/security/limits.conf file. And more importantly most of the limits are now controlled by the kernel itself, in the shape of better resource management. So apparently there is no need to run your programs as a softlimit's child. [Anyone with a better explanation?]
Conclusion for qmail-smtpd/run script
Copy the downloaded JMS smtpd-run file to /var/qmail/supervise/qmail-smtpd/run .
cp /downloads/service-qmail-smtpd-run /var/qmail/supervise/qmail-smtpd/run
Before we move on and edit the file, I would advise you to check the list/details of patches, on this location (http://qmail.jms1.net/patches/combined-details.shtml), which JMS has included in his combined patch. It is a 22 page document , if you print it on A4 size paper! This would definitely help us what to select / enable, and what not in the qmail-smtpd/run script.
It mainly contains vpopmail passwd program, Grey Listing checks, Delays, SPF, RBL, AUTH mechanism, DomainKeys QmailScanner, etc.
I have still not installed the grey-listing software, Qmail-Scanner, and domain keys. So I have not enabled them yet in this qmail-smtpd/run script. I will enable them one by one when the related software is installed and configured.
Edit this file and adjust values according to your needs. (The SMTP_CDB variable needs to be updated. Its value should not be /etc/tcp/smtp.cdb , rather, it's value should be /etc/tcp.smtp.cdb. This is updated after encountering an error a little later.)
The most important variables to fix for the time-being are: IP and SMTP_CDB. You should also disable anything related to VALIDRCPTTO at this moment.
vi /var/qmail/supervise/qmail-smtpd/run #(my configuration part of the script looks like this): exec 2>&1 VQ="/var/qmail" PATH="$VQ/bin:/usr/local/bin:/usr/bin:/bin" QUSER=qmaild LOCAL=`head -1 $VQ/control/me` IP=192.168.122.90 PORT=25 SSL=0 #SSL_CERT="$VQ/control/servercert.pem" SMTP_CDB="/etc/tcp.smtp.cdb" MAX=30 MAXLOAD=150 MAXCONNIP=2 MAXCONNC=5 DIEMSG="421 $LOCAL Service temporarily unavailable" DIEMSG_MAXLOAD="421 $LOCAL Server busy, try again later." DIEMSG_MAXCONNIP="421 $LOCAL Too many connections from your IP." DIEMSG_MAXCONNC="421 $LOCAL Too many connections from your network." RBLSMTPD_PROG="rblsmtpd" RBL_GOOD="" RBL_BAD="zen.spamhaus.org bl.spamcop.net" SMTPD="qmail-smtpd" SMTPGREETING="$LOCAL NO UCE" #GREETDELAY=30 DROP_PRE_GREET=1 FORCE_TLS=0 DENY_TLS=0 MFCHECK=3 MAXRCPT=100 RELAYREJ=1 QMAILSMTPD_LOG_MAIL=1 QMAILSMTPD_LOG_RCPT=1 QMAILSMTPD_HELP_VERSION=1 AUTH=0 REQUIRE_AUTH=0 ALLOW_INSECURE_AUTH=0 #CHECKPW=~vpopmail/bin/vchkpw #TRUE=`which true` #VALIDRCPTTO_CDB="$VQ/control/validrcptto.cdb" #VALIDRCPTTO_LIMIT=10 #VALIDRCPTTO_LOG=2 SPFBEHAVIOR=3 SPF_LOG=1 SPF_BLOCK_PLUS_ALL=1 . . . . . .
Note: If you do not select the options correctly in the run file, your qmail instance may start, but when you try to connect to it, it will show you an error. Such as the following:
[kamran@kworkbee ~]$ telnet qmail.example.com 25 Trying 192.168.122.90... Connected to qmail.example.com. Escape character is '^]'. 421 unable to read controls (#4.3.0) Connection closed by foreign host. [kamran@kworkbee ~]$
So, the tip is to enable few things at a time and work gradually to a securer system.
The qmail-smtpd/log/run script
Now is the time to create the /var/qmail/supervise/qmail-smtpd/log/run file:
cat > /var/qmail/supervise/qmail-smtpd/log/run << EOF #!/bin/sh PATH=/var/qmail/bin:/usr/local/bin:/usr/bin:/bin exec setuidgid qmaill multilog t s50000000 n20 /var/log/qmail/qmail-smtpd 2>&1 EOF
Note: I don't see a need to export the PATH, so I have removed that from the script above.
Set correct permissions for supervise scripts
Make the run files executable [LWQ]: (recommended)
chmod 755 /var/qmail/supervise/qmail-send/run chmod 755 /var/qmail/supervise/qmail-send/log/run chmod 755 /var/qmail/supervise/qmail-smtpd/run chmod 755 /var/qmail/supervise/qmail-smtpd/log/run
Note: Add qmail-pop3/* files to the list above, if you are using qmail-pop3 for POP3 service.
Then set up the log directories[LWQ]: Note: We have already setup log directories a while ago, with a slight modification. So we will NOT execute the following three lines.
# mkdir /var/log/qmail # mkdir -p /var/log/qmail/smtpd # chown qmaill /var/log/qmail /var/log/qmail/smtpd
Finally, link the supervise directories into /service. However, please note that the qmail system will start automatically shortly after these links are created. So at this point you should make sure that no service is running on port 25, such as sendmail, postfix or exim. If they are running, it is time to stop them:
service sendmail stop service exim stop service postfix stop # netstat -antp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 :::22 :::* LISTEN 1799/sshd tcp 0 0 ::ffff:192.168.122.13:22 ::ffff:192.168.122.1:56432 ESTABLISHED 2031/0
Good! No SMTP software/service running. So lets link the qmail supervise directories into /service .
ln -s /var/qmail/supervise/qmail-send /var/qmail/supervise/qmail-smtpd /service
Note: The /service directory is created when daemontools software is installed.
Note: Without linking, the qmailctl command will give the following error:
/service/qmail-send: unable to chdir: file does not exist /service/qmail-send/log: unable to chdir: file does not exist /service/qmail-smtpd: unable to chdir: file does not exist /service/qmail-smtpd/log: unable to chdir: file does not exist messages in queue: 0 messages in queue but not yet preprocessed: 0
After the linking, the qmail system would now be running automatically. Lets check:
# qmailctl stat /service/qmail-send: up (pid 17094) 3 seconds /service/qmail-send/log: up (pid 17095) 3 seconds /service/qmail-smtpd: up (pid 17116) 1 seconds /service/qmail-smtpd/log: up (pid 17098) 3 seconds messages in queue: 0 messages in queue but not yet preprocessed: 0
The qmail-smtpd service seems to be stuck at 1 second. This is not good. Lets try to find the reason:
# tail /var/log/qmail/qmail-smtpd/current @400000004a8d955234dccc7c ERROR: /etc/tcp.smtp.cdb does not exist @400000004a8d955336fb5b04 ERROR: /etc/tcp.smtp.cdb does not exist @400000004a8d9554382e1a5c ERROR: /etc/tcp.smtp.cdb does not exist @400000004a8d95553982bd7c ERROR: /etc/tcp.smtp.cdb does not exist
We know that in qmailctl file, we have a section as :-
cdb) tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp chmod 644 /etc/tcp.smtp.cdb echo "Reloaded /etc/tcp.smtp."
Create the tcprules file. In LWQ, it is titled as SMTP Access Control.
Allow the local host to inject mail via SMTP:
echo '127.:allow,RELAYCLIENT=""' >>/etc/tcp.smtp
Now execute the following command to compile CDB rules: [LWQ]
qmailctl cdb
Now lets stop qmail and start it again.
qmailctl stop qmailctl start # wait for a few seconds here, then qmail stat # qmailctl stat /service/qmail-send: up (pid 18357) 17 seconds /service/qmail-send/log: up (pid 18356) 17 seconds /service/qmail-smtpd: up (pid 18360) 17 seconds /service/qmail-smtpd/log: up (pid 18361) 17 seconds messages in queue: 0 messages in queue but not yet preprocessed: 0
As you can see, now your qmail-send and qmail-smtpd (and their respective log services) are all up for the same amount of time. This indicates all is well. Check through netstat as well:
# netstat -antp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 192.168.122.90:25 0.0.0.0:* LISTEN 2012/tcpserver tcp 0 0 :::22 :::* LISTEN 1799/sshd tcp 0 0 ::ffff:192.168.122.90:22 ::ffff:192.168.122.1:56432 ESTABLISHED 2031/0 [root@qmail ~]#
If you don't see tcpserver running on port 25 listed here, then check the log file (/var/log/qmail/qmail-smtpd/current).
# tail /var/log/qmail/qmail-smtpd/current @400000005152d5fe2e586eec The IP variable is not set in the run script. Cannot start. @400000005152d6032eec4a7c The IP variable is not set in the run script. Cannot start.
As per the error in the log file, we need to set the IP in the qmail-smtpd/run file.
# vi /var/qmail/supervise/qmail-smtpd/run IP=192.168.122.117
When things are good, you will see something similar to the following in the log files.
# tail -f /var/log/qmail/qmail-smtpd/current . . . . . . @400000004a8d98fc2ced80c4 SSL="0" @400000004a8d98fc2cf06adc MAXLOAD="150" @400000004a8d98fc2cf1f564 MAXCONNIP="2" @400000004a8d98fc2cf43784 MAXCONNC="5" @400000004a8d98fc2cf5cdc4 DIEMSG="421 qmail.example.com Service temporarily unavailable" @400000004a8d98fc2cf8a06c DIEMSG_MAXLOAD="421 qmail.example.com Server busy, try again later." @400000004a8d98fc2cfa59d4 DIEMSG_MAXCONNIP="421 qmail.example.com Too many connections from your IP." @400000004a8d98fc2cfca7ac DIEMSG_MAXCONNC="421 qmail.example.com Too many connections from your network." @400000004a8d98fc2d09135c SMTPGREETING="qmail.example.com NO UCE" @400000004a8d98fc2d0cd064 DROP_PRE_GREET="1" @400000004a8d98fc2d0e7a2c FORCE_TLS="0" @400000004a8d98fc2d10106c DENY_TLS="0" @400000004a8d98fc2d123f04 MFCHECK="3" @400000004a8d98fc2d13bdd4 MAXRCPT="100" @400000004a8d98fc2d16425c RELAYREJ="1" @400000004a8d98fc2d180f4c QMAILSMTPD_LOG_MAIL="1" @400000004a8d98fc2d1a3de4 QMAILSMTPD_LOG_RCPT="1" @400000004a8d98fc2d1c0ad4 QMAILSMTPD_HELP_VERSION="1" @400000004a8d98fc2d1e5c94 REQUIRE_AUTH="0" @400000004a8d98fc2d20065c ALLOW_INSECURE_AUTH="0" @400000004a8d98fc2d37cc4c SPFBEHAVIOR="3" @400000004a8d98fc2d394f04 SPF_LOG="1" @400000004a8d98fc2d3bbc1c SPF_BLOCK_PLUS_ALL="1" @400000004a8d98fc2d40964c NOP0FCHECK="1" @400000004a8d98fc2d45aefc command-line: exec tcpserver -vR -l qmail.example.com -c 30 -u 702 -g 700 -x /etc/tcp.smtp.cdb 192.168.122.90 25 rblsmtpd -t0 -r zen.spamhaus.org -r bl.spamcop.net qmail-smtpd 2>&1 @400000004a8d98fc2d6d0d1c tcpserver: status: 0/30
At this point, qmail-smtpd seems good!
And, qmail-send also seems good! (see log below).
# tail -f /var/log/qmail/qmail-send/current . . . @400000004a8d949a05aab4dc status: local 0/10 remote 0/20 @400000004a8d94ab0fdfdd9c status: qmail-todo stop processing asap @400000004a8d94ab0fe000c4 status: exiting @400000004a8d94b32d8c87b4 status: local 0/10 remote 0/20 @400000004a8d95411e2ad8d4 status: qmail-todo stop processing asap @400000004a8d95411e2afbfc status: exiting @400000004a8d95411f7f1664 status: local 0/10 remote 0/20 @400000004a8d98fc29f2ea1c status: qmail-todo stop processing asap @400000004a8d98fc29f3865c status: exiting @400000004a8d98fc2c477cc4 status: local 0/10 remote 0/20
Note: You will not find any log entry for qmail related errors (qmail start / stop /error events) in /var/log/messages , or in /var/log/maillog .
Starting qmail at system startup
Linking of the supervise script directories in /service directory and the following line added in the /etc/inittab file (or the file in /etc/init/ in CENTOS 6+) ensures that the qmail service will be started at system boot time.
tail /etc/inittab SV:123456:respawn:/command/svscanboot
Remove other SMTP software from your system
At this point, you can remove any other SMTP software from your system.
# rpm -e sendmail sendmail-cf exim postfix --nodeps error: package sendmail is not installed error: package sendmail-cf is not installed error: package postfix is not installed
Note [LWQ]: If you're using an RPM-based Linux distribution like Red Hat, removing the MTA package might cause problems down the road. Utilities that update the system might try to reinstall Sendmail, or MUA packages might not install because they can't tell an MTA is installed. Mate Wierdl provides a stub package called "fake_mta" that can be installed to prevent these problems. Simply install the RPM available from ftp://ftp.csi.hu/mw/fake_mta-1-10memphis.noarch.rpm . However, I could not find the fake_mta on the net. (Purely my fault). So I am skipping it.
[LWQ]: Lastly, replace any existing /usr/lib/sendmail with the qmail version: (recommended)
mv /usr/lib/sendmail /usr/lib/sendmail.old # ignore any errors mv /usr/sbin/sendmail /usr/sbin/sendmail.old # ignore any errors chmod 000 /usr/lib/sendmail.old /usr/sbin/sendmail.old # ignore any errors ln -s /var/qmail/bin/sendmail /usr/lib ln -s /var/qmail/bin/sendmail /usr/sbin
Note: QMR does the same in Part-10.
Note[LWQ]: It's important to create the sendmail links, regardless of the previous MTA, if any. The sendmail command is invoked by many applications for sending mail.
Note: QMR , when it runs the finalize_linux.script in part 9, copies the smtpd_ssl and pop3d run scripts as well to the supervise directory. Also sets up links in the /service directory for them. We are not going to use QMR's smtpd_ssl , at least for now. And about pop3, though it seems very tempting, I would not install qmail's own pop3 daemon, because, I will be using the pop3 and IMAP services of either Courier or DoveCot. So no need to go into hassle of installing qmail-pop3 in the first place.
Create System Email Aliases [LWQ]
There are three system aliases that should be created on all qmail installations:
- Alias Purpose
- postmaster RFC 2821 required, points to the mail adminstrator (you)
- mailer-daemon de facto standard recipient for some bounces
- root redirects mail from privileged account to the system administrator
- abuse de facto standard recipient for abuse complaints
To create these aliases, decide where you want each of them to go (a local user or a remote address) and create and populate the appropriate .qmail files. For example, say local user dave is both the system and mail administrator:
#echo dave > /var/qmail/alias/.qmail-root #echo dave > /var/qmail/alias/.qmail-postmaster #ln -s .qmail-postmaster /var/qmail/alias/.qmail-mailer-daemon #ln -s .qmail-postmaster /var/qmail/alias/.qmail-abuse #chmod 644 /var/qmail/alias/.qmail-root /var/qmail/alias/.qmail-postmaster
What I want to do is setup these links to point to postmaster@yourdomain.com . I will set them to postmaster@example.com . Note that QMR also creates these aliases.
echo postmaster@example.com > /var/qmail/alias/.qmail-root echo postmaster@example.com > /var/qmail/alias/.qmail-postmaster ln -s /var/qmail/alias/.qmail-postmaster /var/qmail/alias/.qmail-mailer-daemon ln -s /var/qmail/alias/.qmail-postmaster /var/qmail/alias/.qmail-abuse chmod 644 /var/qmail/alias/.qmail-root /var/qmail/alias/.qmail-postmaster
Check the qmail installation [LWQ]
qmail should now be running. First run qmailctl stat to verify that the services are up and running:
# qmailctl stat /service/qmail-send: up (pid 30303) 187 seconds /service/qmail-send/log: up (pid 30304) 187 seconds /service/qmail-smtpd: up (pid 30305) 187 seconds /service/qmail-smtpd/log: up (pid 30308) 187 seconds messages in queue: 0 messages in queue but not yet preprocessed: 0
All four services should be "up" for more than one second. If they're not, you've probably got a typo in the associated run script or you skipped one or more steps in creating the necessary files, directories, or links. Go back through the installation step-by-step and double check your work. You can also download and run the inst_check script, available from http://lifewithqmail.org/inst_check. For example:
# sh inst_check ! /var/log/qmail has wrong owner, should be qmaill ...try: chown qmaill /var/log/qmail # If inst_check finds problems, fix them and re-run it. When everything looks right, inst_check will report: Congratulations, your LWQ installation looks good!
So let's do that:
cd /downloads/ wget http://lifewithqmail.org/inst_check chmod +x inst_check [root@qmail downloads]# ./inst_check ! /var/qmail/control/concurrencyincoming is missing ...try: echo 20 >/var/qmail/control/concurrencyincoming ! /var/log/qmail has wrong mode, should be 755 ...try: chmod 755 /var/log/qmail ! /var/log/qmail/smtpd is missing ...try: mkdir -p /var/log/qmail/smtpd ! Alias for root is missing ...try: echo me >/var/qmail/alias/.qmail-root ! Alias for postmaster is missing ...try: echo me >/var/qmail/alias/.qmail-postmaster ! Alias for mailer-daemon is missing ...try: echo me >/var/qmail/alias/.qmail-mailer-daemon [root@qmail downloads]#
Wow! So many errors!
Actually I forgot to create the email aliases mentioned above. I created them now. Also created the concurrencyincoming file, and fixed the permissions of /var/log/qmail directory.
echo 20 >/var/qmail/control/concurrencyincoming chmod 755 /var/log/qmail -R
The last check left is about missing /var/log/qmail/smtpd directory:
[root@qmail downloads]# ./inst_check ! /var/log/qmail/smtpd is missing ...try: mkdir -p /var/log/qmail/smtpd [root@qmail downloads]#
You can ignore this error, as we are using a different name (/var/log/qmail/qmail-smtpd) for it. As shown below:
# ls /var/log/qmail/ -l total 12 drwxr-xr-x 2 qmaill root 4096 Aug 18 15:32 qmail-pop3d drwxr-xr-x 2 qmaill root 4096 Aug 21 12:11 qmail-send drwxr-xr-x 2 qmaill root 4096 Aug 21 12:11 qmail-smtpd
If you want to fee happy, and desperate to see the congratulations message, you can create this directory and run the test script. You will only be fooling the script! (Not needed)
# mkdir /var/log/qmail/smtpd # chown qmaill /var/log/qmail/smtpd/ # ./inst_check Congratulations, your LWQ installation looks good!
Note: A little about QMR's qmr_isnt_check script: QMR runs the qmr_inst_check script in part 11. QMR has modified the default inst_check script from LWQ. The following differences exist. The “diff” is shown below with little summary in simple words explained further below:
[root@qmail downloads]# diff /downloads/qmailrocks/scripts/util/qmr_inst_check ./inst_check 3,10d2 < # Qmailrocks, 2003-12-05 < # I've modified Dave Sill's script slightly to accomodate < # the variations between his Qmail installation and the < # Qmailrocks.org installation. The Qmailrocks version < # of this script takes into account the slightly different < # loggind directory setup and a few permissions differences. < # http://www.qmailrocks.org/downloads/scripts/qmr_inst_check < 15,16c7,8 < CHECKPOP=y < CHECKSEND=y --- > CHECKPOP=n > 191c183 < echo "...try: echo 30 >$QMHOME/control/concurrencyincoming" --- > echo "...try: echo 20 >$QMHOME/control/concurrencyincoming" 197c189 < LOGDIRS="/var/log/qmail /var/log/qmail/qmail-smtpd" --- > LOGDIRS="/var/log/qmail /var/log/qmail/smtpd" 199,202c191 < LOGDIRS="$LOGDIRS /var/log/qmail/qmail-pop3d" < fi < if [ "$CHECKSEND" = "y" ]; then < LOGDIRS="$LOGDIRS /var/log/qmail/qmail-send" --- > LOGDIRS="$LOGDIRS /var/log/qmail/pop3d" 213,215c202,204 < elif [ "`ls -ld $i|awk '{print $1}'`" != "drwxr-x---" ]; then < echo "! $i has wrong mode, should be 750" < echo "...try: chmod 750 $i" --- > elif [ "`ls -ld $i|awk '{print $1}'`" != "drwxr-xr-x" ]; then > echo "! $i has wrong mode, should be 755" > echo "...try: chmod 755 $i" 313c302 < echo "Congratulations, your Qmailrocks.org Qmail installation looks good!" --- > echo "Congratulations, your LWQ installation looks good!"
Summary of differences between QMR and LWQ's installation check scripts in plain words:
- QMR's script has CHECKPOP and CHECKSEND enabled as “y”. Whereas LWQ's script uses CHECKPOP=n .
- QMR sets concurrencyincoming as 30, whereas LWQ sets it as 20.
- QMR checks LOGDIRS="/var/log/qmail /var/log/qmail/qmail-smtpd", whereas LWQ checks LOGDIRS="/var/log/qmail /var/log/qmail/smtpd" .
- QMR additionally checks for LOGDIRS="$LOGDIRS /var/log/qmail/qmail-pop3d" .
- QMR also checks for LOGDIRS="$LOGDIRS /var/log/qmail/qmail-send" if CHECKSEND=y
- QMR wants permissions of log directories as “750”, whereas LWQ expects them to be “755”. Not an issue.
LWQ: The readproctitle program keeps a log of error messages generated by services managed by svscan. To see these messages, use ps or some other process listing command. For example, you might see something like:
# ps -efl | grep "service errors" | grep -v grep 000 S root 1006 1001 0 76 0 - 334 pipe_w Mar31 ? 00:00:00 readproctitle service errors: ...unable to start qmail-smtpd/run: exec format error #
In this case, the problem is that there is an error in the first line of the /service/qmail-smtpd/run script--most likely caused by the file being is DOS format (CR-LF line endings instead of Unix's LF-only). It sometimes helps to run a service manually in order to find configuration problems. For example, if your qmail-smtpd/log service isn't running, do:
cd /service/qmail-smtpd/log svc -d . ./run if no errors, enter a line of text and press ENTER if still no errors, enter CTRL-D (end of file)
At this point, you should be able to identify the problem and fix it. Once that's done, return to the service's directory, if necessary, and do:
svc -u .
If there are no problems, your readproctitle will show you dots only, instead of errors:
[root@qmail downloads]# ps -efl | grep "service errors" | grep -v grep 0 S root 2001 1963 0 84 0 - 378 pipe_w 12:11 ? 00:00:00 readproctitle service errors: ................................................................................................................................................................................................................................................................................................................................................................................................................
Test the qmail installation
Once the services are all up with >1 second uptime, follow the instructions in TEST.deliver and TEST.receive to verify that they're working correctly. Note that using these instructions, logging will be accomplished by multilog to /var/log/qmail, not splogger to something like /var/log/maillog.
Note: If you chose maildir mailbox format as the default delivery method, you will need to create a Maildir directory in your home directory and alias's home directory before trying these instructions. See the maildir section to see how to properly create this directory.
If I am to follow these instructions in TEST.deliver and TEST.receive files (inside the /usr/local/src/qmail-1.03/ directory), I need to have some OS accounts to send mail back and forth. Also I need to have a special directory named Maildir in home directories of those users. This is because vpopmail and mysql are not yet installed. So all testing will be done through OS users.
useradd kamran useradd feysal echo 'redhat' | passwd --stdin kamran echo 'redhat'| passwd --stdin feysal mkdir /home/kamran/Maildir mkdir /home/feysal/Maildir chown kamran:kamran /home/kamran/* -R chown kamran:kamran /home/feysal/* -R
Try the tests and check logs in parallel:
[root@qmail qmail-1.03]# echo to: kamran | /var/qmail/bin/qmail-inject
Check the log:-
# tail -F /var/log/qmail/qmail-send/current @400000004a8e95f405201c64 new msg 65096 @400000004a8e95f4052471c4 info msg 65096: bytes 217 from <root@qmail.example.com> qp 3059 uid 0 @400000004a8e95f4052bf78c starting delivery 1: msg 65096 to local kamran@qmail.example.com @400000004a8e95f4053970c4 status: local 1/10 remote 0/20 @400000004a8e95f40be3154c delivery 1: deferral: Temporary_error_on_maildir_delivery._(#4.3.0)/ @400000004a8e95f40be36f24 status: local 0/10 remote 0/20
A note from LWQ , explains the possible reason: Note: qmail-local can deliver mail to maildir mailboxes, but it can't create them. Maildir mailboxes should be created with the maildirmake program that comes with qmail. E.g., "maildirmake ~/Maildir". Be sure to run maildirmake as the owner of the maildir, not as root. Your useradd or adduser command might support a "skeleton" directory, e.g. /etc/skel, where you can create a maildir that will be copied for all new users.
A maildir mailbox is a directory containing three subdirectories, new, cur, and tmp. Each message in a maildir mailbox is in a separate file in one of the subdirectories, depending upon its status: new is for unread messages, cur is for messages that have been seen, and tmp is for messages in the process of being delivered.
So I deleted the old directories and created new ones using the following commands:
[root@qmail qmail-1.03]# rm -fr /home/kamran/Maildir [root@qmail qmail-1.03]# rm -fr /home/feysal/Maildir [root@qmail qmail-1.03]# su -c "/var/qmail/bin/maildirmake ~/Maildir" kamran [root@qmail qmail-1.03]# su -c "/var/qmail/bin/maildirmake ~/Maildir" feysal
The following shows that this command has created the Maildir in the user's home directory with desired permssions, as well as directories cur, new and tmp in the ~/Maildir .
[root@qmail qmail-1.03]# ls -l /home/kamran/ total 4 drwx------ 5 kamran kamran 4096 Aug 21 16:29 Maildir [root@qmail qmail-1.03]# ls -l /home/kamran/Maildir/ total 12 drwx------ 2 kamran kamran 4096 Aug 21 16:29 cur drwx------ 2 kamran kamran 4096 Aug 21 16:29 new drwx------ 2 kamran kamran 4096 Aug 21 16:29 tmp [root@qmail qmail-1.03]#
Try the mail test again:
[root@qmail qmail-1.03]# echo to: kamran | /var/qmail/bin/qmail-inject
This time, it succeeded:
[root@qmail qmail-1.03]# tail -F /var/log/qmail/qmail-send/current @400000004a8ea2321cf0b6dc new msg 65097 @400000004a8ea2321cf206cc info msg 65097: bytes 217 from <root@qmail.example.com> qp 3155 uid 0 @400000004a8ea2321cf3f2fc starting delivery 7: msg 65097 to local kamran@qmail.example.com @400000004a8ea2321cfa05ac status: local 1/10 remote 0/20 @400000004a8ea2321dc3d1d4 delivery 7: success: did_1+0+0/ @400000004a8ea2321dc698c4 status: local 0/10 remote 0/20 @400000004a8ea2321dd1a0fc end msg 65097
If you check inside user kamran's Maildir/new directory, you will find a file:
[root@qmail qmail-1.03]# ls ~kamran/Maildir/new/ -lh total 4.0K -rw------- 1 kamran kamran 294 Aug 21 16:33 1250861608.3158.qmail.example.com [root@qmail qmail-1.03]#
This mail file, has the following contents:
[root@qmail qmail-1.03]# cat ~kamran/Maildir/new/1250861608.3158.qmail.example.com Return-Path: <root@qmail.example.com> Delivered-To: kamran@qmail.example.com Received: (qmail 3155 invoked by uid 0); 21 Aug 2009 16:33:28 +0300 Date: 21 Aug 2009 16:33:28 +0300 Message-ID: <20090821133328.3154.qmail@qmail.example.com> From: root@qmail.example.com to: kamran@qmail.example.com [root@qmail qmail-1.03]#
Try these tests too, and check logs in parallel:
echo to: nonexistantaccount | /var/qmail/bin/qmail-inject echo to: kamran@wbitt.com | /var/qmail/bin/qmail-inject # Will reach your SPAM folder if not in INBOX. echo to: POSTmaster | /var/qmail/bin/qmail-inject
So this seems to be working properly. I can try from another machine, using smtpd protocol and send another mail to the same user. Here is how:
I log on to another machine and try sending the mail:
[kamran@kworkbee ~]$ telnet qmail.example.com 25 Trying 192.168.122.90... Connected to qmail.example.com. Escape character is '^]'. 220 qmail.example.com NO UCE ESMTP ehlo kworkbee.homedomain.com 250-qmail.example.com NO UCE 250-SIZE 0 250-PIPELINING 250 8BITMIME mail from: kamranazeem@homedomain.com 250 ok rcpt to: kamran@example.com 553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1) rcpt to: kamran@qmail.example.com 250 ok data 354 go ahead Subject: test message This is a test over SMTP from another machine. . 250 ok 1250862005 qp 3166 quit 221 qmail.example.com NO UCE Connection closed by foreign host. [kamran@kworkbee ~]$
I have the following in my qmail-send log file:
@400000004a8ea3bf06373d6c new msg 65097 @400000004a8ea3bf0637935c info msg 65097: bytes 379 from <kamranazeem@homedomain.com> qp 3166 uid 702 @400000004a8ea3bf0649a844 starting delivery 8: msg 65097 to local kamran@qmail.example.com @400000004a8ea3bf0649c784 status: local 1/10 remote 0/20 @400000004a8ea3bf071368b4 delivery 8: success: did_1+0+0/ @400000004a8ea3bf07164afc status: local 0/10 remote 0/20 @400000004a8ea3bf071bc16c end msg 65097 @400000004a8ea40502fa17b4 starting delivery 9: msg 65096 to local kamran@qmail.example.com @400000004a8ea4050309dec4 status: local 1/10 remote 0/20 @400000004a8ea40504f5860c delivery 9: success: did_1+0+0/ @400000004a8ea40504f5d814 status: local 0/10 remote 0/20 @400000004a8ea40504f61e64 end msg 65096
And I should have a new file in the Maildir/new of user kamran:
[root@qmail qmail-1.03]# ls ~kamran/Maildir/new/ -lh total 12K -rw------- 1 kamran kamran 294 Aug 21 16:33 1250861608.3158.qmail.example.com -rw------- 1 kamran kamran 460 Aug 21 16:40 1250862005.3171.qmail.example.com [root@qmail qmail-1.03]# cat ~kamran/Maildir/new/1250862005.3171.qmail.example.com Return-Path: <kamranazeem@homedomain.com> Delivered-To: kamran@qmail.example.com Received: (qmail 3166 invoked from network); 21 Aug 2009 16:39:48 +0300 Received: from unknown (HELO kworkbee.homedomain.com) (192.168.122.1) by qmail.example.com with SMTP; 21 Aug 2009 16:39:48 +0300 Received-SPF: none (qmail.example.com: domain at homedomain.com does not designate permitted sender hosts) Subject: test message This is a test over SMTP from another machine. [root@qmail qmail-1.03]#
Great! So this seems to be working. There are a lot of tests explained in the TEST.deliver file in the Qmail source directory, which you can (should) perform , before moving on.
EZMLM (Easy Mailing List Management)
- Original EZMLM was created by D. J. Bernstein , available through http://cr.yp.to/ezmlm.html
- Add-ons to the original EZMLM are known as EZMLM-IDX , and are available through http://untroubled.org/ezmlm/
1.4 What is the difference between ezmlm and ezmlm-idx?
ezmlm-0.53 is a qmail-based mailing list manager written by Dan J. Bernstein. It has all the basic functionality of a mailing list manager, such as subscriber address management including automated bounce handling as well as message distribution and archiving.
ezmlm-idx originated as an add-on to ezmlm. It now exists as a complete package on its own, but can still be considered essentially as an extension to ezmlm. It adds multi-message threaded message retrieval from the archive, digests, message and subscription moderation, and a number of remote administration function. It modifies the configuration program ezmlm-make(1) so that it uses a text file template rather than compiled-in texts in list creation. In this manner, ezmlm-idx allows easy setup of lists in different languages and customization of default list setup. ezmlm-idx also adds MIME handling, and other support to streamline use with languages other than English. Prior to version 7, ezmlm-idx existed as an ezmlm source add-on, and as such did not work without ezmlm. ezmlm-idx tries to be compatible with ezmlm as much as possible in its usage, though the internal structure has changed considerably. ezmlm-idx also modifies the ezmlm subscriber database to be case insensitive to avoid many unsubscribe problems.
This document is a FAQ for ezmlm-idx. However, many of the basic items that are discussed also apply to ezmlm per se.
Install EZMLM-IDX without installing EZMLM 0.53
Install mysql-devel
Download latest version of EZMLM-IDX (ezmlm-idx-7.1.1) from http://www.inter7.com/?page=software . Extract the tarball in a separate directory under /downloads.
Edit conf-cc and conf-ld:
# cat conf-cc gcc -O -g -I/usr/include/mysql -I/usr/include/pgsql # cat conf-ld cc -g -B /usr/lib64/mysql/
Compile:
make clean; make; make man; make mysql make install
EZMLM will get installed under /usr/local/bin/ezmlm/ .
Test:
ln -s /downloads/ezmlm-idx-7.1.1/lang/en_US /downloads/ezmlm-idx-7.1.1/lang/default ./ezmlm-test
MySQL:
mysql> create database ezmlm; mysql> grant all on ezmlm.* to ezmlmdbuser@localhost identified by 'redhat'; mysql> flush privileges; ./ezmlm-test -s mysql -d ezmlm -u ezmlmdbuser -p redhat -h localhost
AutoRespond
Latest version 2.0.5 is at http://www.inter7.com/index.php?page=development , released in 2003. Download and extract it in /downloads.
# make gcc -O2 -Wall -g autorespond.c -o autorespond # make install install -d /usr/bin /usr/share/man/man1 install autorespond /usr/bin install autorespond.1 /usr/share/man/man1
Mail Drop
maildrop is the mail filter/mail delivery agent that's used by the Courier Mail Server. You do not need to download maildrop if you already have the Courier mail server installed. The standalone build of the maildrop mail filter can be used with other mail servers.
maildrop is a replacement for your local mail delivery agent. maildrop reads a mail message from standard input, then delivers the message to your mailbox. maildrop knows how to deliver mail to mbox-style mailboxes, and maildirs. "maildir" is a mailbox format used by the Courier mail server and Qmail.
maildrop optionally reads instructions from a file, which describe how to filter incoming mail. These instructions can direct maildrop to deliver the message to an alternate mailbox, or forward it somewhere else. Unlike procmail, maildrop uses a structured filtering language.
maildrop is written in C++, and is significantly larger than procmail. However, it uses resources much more efficiently. Unlike procmail, maildrop will not read a 10 megabyte mail message into memory. Large messages are saved in a temporary file, and are filtered from the temporary file. If the standard input to maildrop is a file, and not a pipe, a temporary file will not be necessary.
maildrop checks the mail delivery instruction syntax from the filter file, before attempting to deliver a message. Unlike procmail, if the filter file contains syntax errors, maildrop terminates without delivering the message. The user can fix the typo without causing any mail to be lost.
Latest version is 2.6 , released in Sep 2012, available from here: http://www.courier-mta.org/download.php#maildrop
# yum install pcre-devel gcc-c++
groupadd vchkpw useradd -g vchkpw -d /home/vpopmail -s /sbin/nologin vpopmail
./configure --with-devel --enable-userdb --enable-maildirquota --enable-syslog=1 \ --enable-trusted-users='root mail daemon postmaster qmaild mmdf' \ --enable-restrict-trusted=0 --enable-maildrop-uid=root --enable-maildrop-gid=vchkpw make make install-strip make install-man
Mail drop gets installed in /usr/local/bin/ :
# ls /usr/local/bin/maildrop -l -rwxr-xr-x 1 root vchkpw 186624 Apr 4 12:58 /usr/local/bin/maildrop
VPOPMail with MySQL Support
Latest version is 5.4.33 , released in Feb 2011, available from Inter7 website http://www.inter7.com/index.php?page=vpopmail . Download a d extract under /downloads.
Download from: http://sourceforge.net/projects/vpopmail/files/vpopmail-stable/5.4.33/
mkdir ~vpopmail/etc chown vpopmail:vchkpw ~vpopmail/etc echo "localhost|0|vpopmaildbuser|redhat|vpopmail" > ~vpopmail/etc/vpopmail.mysql
mysql -u root mysql> create database vpopmail; mysql> grant all on vpopmail.* to vpopmaildbuser@localhost identified by 'redhat'; mysql> flush privileges;
./configure --enable-logging=p --enable-auth-module=mysql --disable-clear-passwd \ --disable-many-domains --enable-sql-logging --enable-mysql-replication --enable-valias \ --enable-roaming-users --enable-spamassassin --enable-mysql-limits --enable-libdir=/usr/lib64/mysql/
WARNING : DO NOT USE the --enable-maildrop switch in vpopmail otherwise you will not get any mails and will get "Unable to open mailbox" errors in the maillog.
vpopmail 5.4.33 Current settings --------------------------------------- vpopmail directory = /home/vpopmail domains directory = /home/vpopmail/domains uid = 710 gid = 702 roaming users = ON --enable-roaming-users tcpserver file = /etc/tcp.smtp open_smtp file = /home/vpopmail/etc/open-smtp rebuild tcpserver file = ON --enable-rebuild-tcpserver-file (default) password learning = OFF --disable-learn-passwords (default) md5 passwords = ON --enable-md5-passwords (default) file locking = ON --enable-file-locking (default) vdelivermail fsync = OFF --disable-file-sync (default) make seekable = ON --enable-make-seekable (default) clear passwd = OFF --disable-clear-passwd user dir hashing = ON --enable-users-big-dir (default) address extensions = OFF --disable-qmail-ext (default) ip alias = OFF --disable-ip-alias-domains (default) onchange script = OFF --disable-onchange-script (default) domain quotas = OFF --disable-domainquotas (default) auth module = mysql --enable-auth-module=mysql mysql replication = ON --enable-mysql-replication sql logging = ON --enable-sql-logging mysql limits = ON --enable-mysql-limits SQL valias table = ON --enable-valias auth inc = -I/usr/include/mysql auth lib = -Xlinker -R -Xlinker /usr/lib64/mysql/ -L/usr/lib64/mysql/ -lmysqlclient -lz -lm system passwords = OFF --disable-passwd (default) pop syslog = show failed attempts with clear text password --enable-logging=p auth logging = ON --enable-auth-logging (default) one domain per SQL table = --disable-many-domains spamassassin = ON --enable-spamassassin maildrop = OFF --disable-maildrop (default) *** You have MySQL limits enabled. If you are upgrading, please see doc/UPGRADE for information on database schema changes ****
make && make install-strip ... Need to check the following: **************************************************** If you plan to use the vpopmail usage daemon run the following commands: cd vusaged && ./configure && make Then follow the INSTALL file to install ****************************************************
Based on discussion about vchkpw at http://qmail.jms1.net/upgrade-qmr.shtml , I will set the vchkpw program as setuid.
# ls -l /home/vpopmail/bin/vchkpw -rwx--x--x 1 vpopmail vchkpw 133608 Apr 4 13:17 /home/vpopmail/bin/vchkpw # chmod u+s /home/vpopmail/bin/vchkpw # ls -l /home/vpopmail/bin/vchkpw -rws--x--x 1 vpopmail vchkpw 133608 Apr 4 13:17 /home/vpopmail/bin/vchkpw
VQAdmin
Latest version in 2.3.7 , released in Nov 2005 , available at http://www.inter7.com/index.php?page=vqadmin . Download and extract it under /downloads.
mkdir /var/www/vqadmin chown apache:apache /var/www/vqadmin -R
./configure --enable-cgibindir=/var/www/cgi-bin --enable-htmldir=/var/www/vqadmin
If you see this error:
checking build system type... Invalid configuration `x86_64-unknown-linuxoldld': machine `x86_64-unknown' not recognized configure: error: /bin/sh ./config.sub x86_64-unknown-linuxoldld failed
, then add the following in config.sub in the base_machine section
case $basic_machine in ... ... # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;;
, and also add the following in vax section of config.sub:
x86_64-* |
You can compare the config.sub from the vpopmail source code to figure this out.
References:
- http://www.genuinewebhost.com/tech_forum/index.php?p=/discussion/19/error-while-configuring-vqadmin-in-x86_64-host/p1
- http://comments.gmane.org/gmane.mail.qmail.qmr/27496
- http://raman-kumar.blogspot.no/2013/02/configure-error-binsh-configsub-x8664.html
Note: Instead of doing the manual editing above, you can also run "libtoolize --force" in vqadmin's source-root directory, as mentioned at http://wbitt.com/knowledge/how-to-tutorials/127-vqadmin-for-qmail.html
Successful configuration will result in the following:
Current settings --------------------------------------- vpopmail directory = /home/vpopmail uid = 710 gid = 702 cgi-bin dir = /var/www/cgi-bin vqadmin dir = /var/www/cgi-bin/vqadmin
Now do:
make && make install-strip ... ... chown vpopmail /var/www/cgi-bin/vqadmin chgrp vchkpw /var/www/cgi-bin/vqadmin chown -R vpopmail /var/www/cgi-bin/vqadmin/* chgrp -R vchkpw /var/www/cgi-bin/vqadmin/* chown root /var/www/cgi-bin/vqadmin/vqadmin.cgi chgrp `id -g root` /var/www/cgi-bin/vqadmin/vqadmin.cgi chmod u+s,g+s /var/www/cgi-bin/vqadmin/vqadmin.cgi chmod 755 /var/www/cgi-bin/vqadmin chmod 755 /var/www/cgi-bin/vqadmin/html chown vpopmail /var/www/html/images/vqadmin chgrp vchkpw /var/www/html/images/vqadmin chown -R vpopmail /var/www/html/images/vqadmin/* chgrp -R vchkpw /var/www/html/images/vqadmin/* chmod 755 /var/www/html/images/vqadmin if test -f /var/www/cgi-bin/vqadmin/.htaccess ; then \ echo ".htaccess file already in place" ; \ else \ cp htaccess /var/www/cgi-bin/vqadmin/.htaccess ; \ fi chown nobody /var/www/cgi-bin/vqadmin/.htaccess chmod u+rw /var/www/cgi-bin/vqadmin/.htaccess chmod go+r /var/www/cgi-bin/vqadmin/.htaccess make[3]: Leaving directory `/downloads/vqadmin-2.3.7' make[2]: Leaving directory `/downloads/vqadmin-2.3.7' make[1]: Leaving directory `/downloads/vqadmin-2.3.7
Setup a .conf file in /etc/httpd/conf.d/ as vqadmin.conf
cat >> /etc/httpd/conf.d/vqadmin.conf << EOF Alias /vqadmin /var/www/vqadmin <Directory /var/www/vqadmin> Order deny,allow Allow from all </Directory> <Directory "/var/www/cgi-bin/vqadmin"> Allow from all Options ExecCGI AllowOverride AuthConfig Order deny,allow </Directory> EOF
The make process will place a .htaccess file in /var/www/cgi-bin/vqadmin directory. Secure the config file, as well as create a password file. Also remove / comment the "satisfy any" line from it.
chown apache:root /var/www/cgi-bin/vqadmin/.htaccess chmod 0640 /var/www/cgi-bin/vqadmin/.htaccess
htpasswd -bc /etc/httpd/conf/vqadmin.passwd admin redhat chown apache:root /etc/httpd/conf/vqadmin.passwd chmod 0640 /etc/httpd/conf/vqadmin.passwd
Note: Try keeping the username as admin, otherwise you will get problems.
Restart Apache web server
service httpd restart
Try to load vqadmin page using the URL: http://mail.example.com/cgi-bin/vqadmin/vqadmin.cgi .
If you see a page saying "invalid language file", then make a couple of copies of your language file as shown:
cd /var/www/cgi-bin/vqadmin/html cp en-us en-US cp en-us en_US
Reload the page, and you should be able to see the distinctive blue screen of vqadmin.
If you see a white page with Vqadmin menu on it. Check your apache error log.
Apache error log:-
[Thu May 08 16:51:18 2008] [error] [client 203.82.59.56] File does not exist: /var/www/vhosts/example.com/httpdocs/images, referer: http://192.168.0.200/cgi-bin/vqadmin/vqadmin.cgi
The solution is :-
ln -s /var/www/html/images /var/www/vhosts/example.com/httpdocs/ chown apache:apache /var/www/html -R
When vqadmin works, try adding a domain through it's menu system.
You should be able to successfully add/create a domain, say "example.com" through vqadmin.
QmailAdmin
QmailAdmin 1.2.15 has some problem during make. So I used qmailadmin-1.2.16, which is the development version, and it compiles properly. Download and extract under /downloads.
mkdir /var/www/qmailadmin/images -p chown apache:apache /var/www/qmailadmin -R cat >> /etc/httpd/conf.d/qmailadmin.conf << EOF Alias /qmailadmin /var/www/qmailadmin <Directory /var/www/qmailadmin> Order deny,allow Allow from all </Directory> EOF
./configure --enable-cgibindir=/var/www/cgi-bin --enable-htmldir=/var/www/qmailadmin \ --enable-imagedir=/var/www/qmailadmin/images --enable-imageurl=/qmailadmin/images \ --enable-modify-quota ... ... qmailadmin 1.2.16 Current settings --------------------------------------- cgi-bin dir = /var/www/cgi-bin html dir = /var/www/qmailadmin image dir = /var/www/qmailadmin/images image URL = /qmailadmin/images template dir = /usr/local/share/qmailadmin qmail dir = /var/qmail vpopmail dir = /home/vpopmail autorespond dir = /usr/bin ezmlm dir = /usr/local/bin/ezmlm ezmlm idx = yes mysql for ezmlm = yes help = no modify quota = yes domain autofill = no catchall accounts = yes trivial passwords = yes modify spam check = no
make make install-strip
service httpd restart
You should be able to load the qmailadmin page using http://mail.example.com/cgi-bin/qmailadmin .
You should also be able to successfully create a new email address, such as kamran@example.com .
Final Checks
Make sure that the final files exist, and have the proper content:
- /var/qmail/supervise/qmail-send/run
- /var/qmail/supervise/qmail-smtpd/run
- /var/qmail/supervise/qmail-pop3d/run # only if you are using qmail's pop3d
- /var/qmail/supervise/qmail-send/log/run
- /var/qmail/supervise/qmail-smtpd/log/run
- /var/qmail/supervise/qmail-pop3d/log/run # only if you are using qmail's pop3d
- /var/qmail/rc
- /var/qmail/bin/qmailctl
Setup needed permissions:
chmod 755 /var/qmail/rc chmod 755 /var/qmail/bin/qmailctl chmod 751 /var/qmail/supervise/qmail-pop3d/run chmod 751 /var/qmail/supervise/qmail-pop3d/log/run chmod 751 /var/qmail/supervise/qmail-smtpd/run chmod 751 /var/qmail/supervise/qmail-smtpd/log/run chmod 751 /var/qmail/supervise/qmail-send/run chmod 751 /var/qmail/supervise/qmail-send/log/run
Setup default values to various control files. You may want to check the files contents first, before executing the code below:
echo ./Maildir > /var/qmail/control/defaultdelivery echo 30 > /var/qmail/control/concurrencyincoming # The default value is 10 chmod 644 /var/qmail/control/concurrencyincoming echo 255 > /var/qmail/control/concurrencyremote # The default value is 20 chmod 644 /var/qmail/control/concurrencyremote
Create symbolic links. Ideally these links should already be in-place by this time:
ln -s /var/qmail/bin/qmailctl /usr/bin ln -s /var/qmail/supervise/qmail-send /var/qmail/supervise/qmail-smtpd /var/qmail/supervise/qmail-pop3d /service
The /etc/tcp.smtp file should contain the following at the moment:
echo '127.:allow,RELAYCLIENT=""'
You will need to compile the cdb file, each time you make any changes in the /etc/tcp.smtp .
qmailctl stop qmailctl cdb qmailctl start
Also make sure that the necessary system aliases exist. These aliases are going to tell Qmail what to do with common server-generated mails.
echo postmaster@example.com > /var/qmail/alias/.qmail-root echo postmaster@example.com > /var/qmail/alias/.qmail-postmaster echo postmaster@example.com > /var/qmail/alias/.qmail-mailer-daemon ln -s /var/qmail/alias/.qmail-root /var/qmail/alias/.qmail-anonymous chmod 644 /var/qmail/alias/.qmail*
Remove SENDMAIL, POSTFIX , EXIM from System:
If you have not removed these packages before, you can do it now.
service sendmail stop service postfix stop service exim stop service dovecot stop
rpm -e sendmail --nodeps rpm -e sendmail-cf --nodeps rpm -e postfix --nodeps rpm -e exim --nodeps
Create artificial sendmail path:
rm -f /usr/lib/sendmail rm -f /usr/sbin/sendmail ln -s /var/qmail/bin/sendmail /usr/lib/sendmail ln -s /var/qmail/bin/sendmail /usr/sbin/sendmail
Create Qmail SSL certificate
Reference: http://qmail.jms1.net/smtp-service.shtml
cd /var/qmail/control openssl req -newkey rsa:1024 -x509 -nodes -days 3650 -out servercert.pem -keyout servercert.pem
Note: "Common Name" MUST MATCH the name your clients will put into their mail program as their SMTP server name.
chown root:nofiles servercert.pem chmod 640 servercert.pem
The "nofiles" group is the group which "qmaild" belongs to. This combination of ownership and permissions allows qmail-smtpd to read the key, but not change or delete it.
Once you have verified that the certificate is valid, you can copy the "servercert.pem" file to "clientcert.pem", and qmail-remote will be able to use it to encrypt the connection when sending outbound messages to remote SMTP servers which advertise the ability to support TLS.
cp servercert.pem clientcert.pem chown root:qmail clientcert.pem # The "qmail" group is the group with the "qmailr" user belongs to. This user should be able to read, but not write, the "clientcert.pem" file. chmod 640 clientcert.pem
Refer to the the "Permissions on SSL .pem files" section at http://qmail.jms1.net/upgrade-qmr.shtml for more information on Qmail certificate permissions.
Courier IMAP
In May 2008 the developer of courier-imap decided to drop support for vpopmail. This support is not there in courier-authlib-0.60.4 and newer.Similarly courier-imap-4.5.0 does not work, if it doesn't find at least courier-authlib-0.60.6 .
Dovecot as POP3 and IMAP server
Since I cannot use courier, I have to use dovecot. I am using the following as reference, on how to use dovecot with qmail.
Download the latest stable version of Dovecot is 2.1.15 , available from http://www.dovecot.org/download.html. You need to compile the source code because the rpm package, which comes with redhat and family is not compiled with vpopmail option.
./configure \ --without-shadow \ --without-pam \ --without-bsdauth \ --without-gssapi \ --without-sia \ --without-ldap \ --with-vpopmail \ --without-sql \ --without-pgsql \ --without-mysql \ --without-sqlite \ --with-ssl ... ... config.status: executing libtool commands Install prefix . : /usr/local File offsets ... : 64bit I/O polling .... : epoll I/O notifys .... : inotify SSL ............ : yes (OpenSSL) GSSAPI ......... : no passdbs ........ : static passwd passwd-file checkpassword vpopmail : -shadow -pam -bsdauth -sia -ldap -sql userdbs ........ : static prefetch passwd passwd-file checkpassword vpopmail nss : -ldap -sql SQL drivers .... : : -pgsql -mysql -sqlite Full text search : squat : -lucene -solr
Make sure that the configure script detects SSL and the output contains "vpopmail" in passdbs and userdbs modules/lines.
make make install
mkdir -m 0755 /usr/local/var \ /usr/local/var/run \ /usr/local/var/run/dovecot
You will need to create a user to run the dovecot services.
groupadd dovecot useradd -g dovecot -M -s /sbin/nologin -c 'Dovecot user' dovecot useradd -g dovecot -M -s /sbin/nologin -c 'Dovecot Null user' dovenull # -d /nohome ???
Dovecot configuration
References:
You can use the config file provided by JMS. Be mindful, that there are few items which are changed in the config file. You will need to adjust that. Use "dovecot -n" to generate a clean version of current configuration. Please note that dovecot does not use a single config file any more. You have to make use of (and adjust) the files in the conf.d directory too.
cp -rp /usr/local/share/doc/dovecot/example-config/* /usr/local/etc/dovecot/
If you get error messages in /var/log/maillog , about the size mismatch of emails, or something about the "S" size of the email file, the you will need to set an extra variable in 10-mail.conf .
conf.d/10-mail.conf
maildir_broken_filename_sizes = yes
Dovecot SSL certificate
cd /downloads/dovecot-2.1.15/doc/ cp dovecot-openssl.cnf dovecot-openssl.cnf.orig
vi dovecot-openssl.cnf
mkdir /etc/ssl/private # sh mkcert.sh Generating a 1024 bit RSA private key ........++++++ ....++++++ writing new private key to '/etc/ssl/private/dovecot.pem' ----- subject= /C=NO/L=Okern/O=FineDistribution/OU=IMAP server/CN=mail.example.com/emailAddress=postmaster@example.com SHA1 Fingerprint=B2:D8:64:85:5D:BA:28:0D:93:60:FE:71:63:52:26:2D:A1:6D:03:6E
The files /etc/ssl/private/dovecot.pem and /etc/ssl/certs/dovecot.pem must have been created.
Copy dovecot init script to /etc/init.d/ and adjust if necessary.
cp /downloads/dovecot-2.1.15/doc/dovecot-initd.sh /etc/init.d/dovecot chmod +x /etc/init.d/dovecot
Start the dovecot service and verify that dovecot process is listening on the ports.
chkconfig --level dovecot on service dovecot restart # netstat -antp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:110 0.0.0.0:* LISTEN 8791/dovecot tcp 0 0 0.0.0.0:143 0.0.0.0:* LISTEN 8791/dovecot tcp 0 0 192.168.122.117:53 0.0.0.0:* LISTEN 1122/named tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 1122/named tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1159/sshd tcp 0 0 192.168.122.117:25 0.0.0.0:* LISTEN 2005/tcpserver tcp 0 0 0.0.0.0:993 0.0.0.0:* LISTEN 8791/dovecot tcp 0 0 0.0.0.0:995 0.0.0.0:* LISTEN 8791/dovecot tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 1297/mysqld tcp 0 0 192.168.122.117:22 192.168.122.1:52336 ESTABLISHED 1378/sshd tcp 0 0 :::80 :::* LISTEN 1320/httpd tcp 0 0 ::1:53 :::* LISTEN 1122/named tcp 0 0 :::22 :::* LISTEN 1159/sshd tcp 0 0 :::443 :::* LISTEN 1320/httpd
SquirrelMail
Download SquirrelMail from http://squirrelmail.org , and extract it in /downloads.
mkdir /var/www/squirrelmail rsync -av /downloads/squirrelmail-webmail-1.4.22/ /var/www/squirrelmail/ chown apache:apache /var/www/squirrelmail -R cd /var/www/squirrelmail/config/
Create the apache configuration file for squirrelmail and restart apache web service.
cat > /etc/httpd/conf.d/squirrelmail.conf << EOF Alias /squirrelmail /var/www/squirrelmail EOF service httpd restart
Run the squirrelmail configuration script inside the config directory.
./conf.pl
Set the correct values for the following options:
Organization Preferences 1. Organization Name : Example website 4. Organization Title : Example webmail service, powered by SquirrelMail $version Server Settings General ------- 1. Domain : example.com 2. Invert Time : false 3. Sendmail or SMTP : SMTP (Remember, we are using Dovecot in this setup. Still the following IMAP settings should be ok with most of IMAP software/servers) IMAP Settings -------------- 4. IMAP Server : localhost 5. IMAP Port : 143 6. Authentication type : login 7. Secure IMAP (TLS) : false 8. Server software : other 9. Delimiter : detect SMTP Settings ------------- 4. SMTP Server : localhost 5. SMTP Port : 25 6. POP before SMTP : false 7. SMTP Authentication : none 8. Secure SMTP (TLS) : false 9. Header encryption key : General Options 1. Data Directory : /var/www/squirrelmail/data/ 2. Attachment Directory : /var/www/squirrelmail/attach/
Make sure to create data and attach directories. Make sure that they are readable by the web server process. Ideally these directories should be outside your webroot directory.
mkdir -m 733 /var/www/squirrelmail/{attach,data} -p chown apache:apache /var/www/squirrelmail/{attach,data}
RoundCube WebMail
Download roundcube from http://roundcube.net , and extract it in /var/www/roundcube .
chown apache:apache /var/www/roundcube -R
Create apache config file for roundcube:
cat > /etc/httpd/conf.d/roundcube.conf << EOF Alias /roundcube /var/www/roundcube EOF # service httpd restart
Create a mysql database for roundcube.
mysql -u root mysql> create database roundcubemail; mysql> grant all on roundcubemail.* to roundcubeuser@localhost identified by 'redhat'; mysql> flush privileges;
Execute the installer script located at http://mail.example.com/roundcube/installer/
When saving the main.inc.php file, make sure to set the auth type to PLAIN.
$rcmail_config['imap_auth_type'] = plain;
ClamAV Antivirus
Install EPEL repository using : http://fedoraproject.org/wiki/EPEL/FAQ#howtouse
rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
Install CLAMAV from EPEL repository:
yum install clamd
Freshen up virus database:
freshclam
Create user qscand:
groupadd qscand useradd -g qscand -c "Qmail-Scanner Account" -s /bin/false qscand
Question: Why do we need to run clamav as qscand? Why create a separate account? If qmail-scanner needs it's helper programs to run as qscand, then why spamassassin is being run as spamd? Answe: ClamAV needs access to the MIME parts of the mails, separated by Qmail-Scanner. For this, it needs to run as the qmail-scanner user qscand. In newer versions of qmail-scanner, it is supported that ClamAV runs as it's independant user clamav, and it just needs to be a member of the qmail scanner group qscand. See http://qmail.jms1.net/clamav/qmail-scanner.shtml
Edit configuration files.
/etc/clamd.conf
LogFile /var/log/clamav/clamd.log LogFileMaxSize 0 LogTime yes LogSyslog yes PidFile /var/run/clamav/clamd.pid TemporaryDirectory /var/tmp DatabaseDirectory /var/lib/clamav LocalSocket /var/run/clamav/clamd.sock LocalSocketGroup qscand LocalSocketMode 660 FixStaleSocket yes TCPSocket 3310 TCPAddr 127.0.0.1 MaxConnectionQueueLength 30 MaxThreads 50 ReadTimeout 300 User qscand AllowSupplementaryGroups yes ScanPE yes ScanELF yes DetectBrokenExecutables yes ScanOLE2 yes ScanMail yes ScanArchive yes ArchiveBlockEncrypted no
/etc/freshclam.conf
DatabaseDirectory /var/lib/clamav UpdateLogFile /var/log/clamav/freshclam.log LogSyslog yes DatabaseOwner qscand AllowSupplementaryGroups yes DatabaseMirror db.sa.clamav.net DatabaseMirror db.local.clamav.net NotifyClamd /etc/clamd.conf
Create necessary directories and set correct ownerships.
chown qscand:qscand /var/run/clamav -R chown qscand:qscand /var/lib/clamav -R chown qscand:qscand /var/log/clamav -R
service clamd restart chkconfig --level 35 clamd on
Test clamav:
cd /usr/share/doc/clamav-0.97.7/test # clamscan -r -l /tmp/scan.txt ----------- SCAN SUMMARY ----------- Known viruses: 2007060 Engine version: 0.97.7 Scanned directories: 2 Scanned files: 142 Infected files: 46 Data scanned: 19.51 MB Data read: 12.40 MB (ratio 1.57:1) Time: 5.243 sec (0 m 5 s)
Check the file /tmp/scan.txt. It should contain the name of files which are infected with test virus signatures.
You don't need to run freshclam as a daemon, as it will consume memory. Better run it as cronjob.
# crontab -e * * */2 * * /usr/bin/freshclam --quiet
SpamAssassin AntiSpam
SpamAssassin is installed through the available RPM in redhat/centos base repo.
Add a user:
useradd -s /bin/false spamd
Edit the configuration files:
/etc/sysconfig/spamassassin
SPAMDOPTIONS="-x -u spamd -H /home/spamd -d"
spamd Options explained
-c, --create-prefs Create user preferences files (we don't need it) -x, --nouser-config Disable user config files -d, --daemonize Daemonize -m num, --max-children=num Allow maximum num children -u username, --username=username Run as username -g groupname, --groupname=groupname Run as groupname (should we use this too? ) ??? -v, --vpopmail Enable vpopmail config (we "should" need it, but not using at the moment) ??? -x, --nouser-config Disable user config files -H [dir], --helper-home-dir[=dir] Specify a different HOME directory
/etc/mail/spamassassin/local.cf
required_hits 5 report_safe 0 rewrite_header Subject [SPAM]
service spamassassin restart chkconfig --level 35 spamassassin on
A lot of modules can be enabled , which I will enable later.
Later:
- SpamAssassin modules
- Razor
- DCC
QmailScanner
Download latest version of QmailScanner from http://qmail-scanner.sourceforge.net/ .
Create a pre-install config file:
# vi qms-config #!/bin/sh ## File: qms-config ## ## Purpose: Provide a file to save personal qmail-scanner configuration ## options. This file should be edited for your server and ## saved somewhere so that it survives qmail-scanner and ## qms-analog upgrades. ## # Was the "install" option given? if [ "$1" != "install" ]; then INSTALL= else INSTALL="--install" fi # Qmail Scanner 2.11 configuration: ./configure --domain example.com \ --admin postmaster \ --local-domains "example.com,example.net" \ --add-dscr-hdrs yes \ --ignore-eol-check yes \ --notify admin \ --redundant yes \ "$INSTALL"
chmod +x qms-config
Now run the configuration script.
./qms-config
If all ends well, you will need to run the script with install option.
# ./qms-config install ... ... Finished installation of initial directory structure for Qmail-Scanner under /var/spool/qscan and qmail-scanner-queue.pl under /var/qmail/bin. Finished. Please read README(.html) and then go over the script (/var/qmail/bin/qmail-scanner-queue.pl) to check paths/etc. "/var/qmail/bin/qmail-scanner-queue.pl -r" should return some well-known virus definitions to show that the internal perlscanner component is working. That's it!
Note: QMS will get installed in /var/spool/qscan. NOT /var/spool/qmailscan .
Run a couple of self tests:
$ /var/qmail/bin/qmail-scanner-queue.pl -g perlscanner: generate new DB file from /var/spool/qscan/quarantine-events.txt perlscanner: total of 12 entries.
You should not see any permission error in the output above.
Note: Any SMTP sessions that are dropped (due to network outages/etc) may lead to files lying around in /var/spool/qscan . Running "/var/qmail/bin/qmail-scanner-queue.pl -z", at least once daily, will ensure such files are deleted when they're over 30 hours old.
Now run the following:
setuidgid qscand /var/qmail/bin/qmail-scanner-queue.pl -z # also setup a cronjob to do this once a day. setuidgid qscand /var/qmail/bin/qmail-scanner-queue.pl -g # also setup a cronjob to do this once a day.
Set them up to run through cron as well:-
# crontab -e 0 1 * * * /usr/local/bin/setuidgid qscand /var/qmail/bin/qmail-scanner-queue.pl -z 0 1 * * * /usr/local/bin/setuidgid qscand /var/qmail/bin/qmail-scanner-queue.pl -g
Stop qmail at this point.
qmailctl stop
In the qmail SMTPD run file (from JMS), uncomment the line which deals with Qmail scanner.
# vi /var/qmail/supervise/qmail-smtpd/run ... ... QMAILQUEUE="$VQ/bin/qmail-scanner-queue.pl" ... ... ...
Now start qmail and check status.
qmailctl start sleep 5 qmailctl stat
You should try to run a test script in the qmail-scanner contrib directory. It is the famous "do it" script!
cd /downloads/qmail-scanner-2.11/contrib # ./test_installation.sh -doit Sending standard test message - no viruses... done! Sending eicar test virus - should be caught by perlscanner module... done! Sending eicar test virus with altered filename - should only be caught by commercial anti-virus modules (if you have any)... Sending bad spam message for anti-spam testing - In case you are using SpamAssassin... Done! Finished test. Now go and check Email sent to postmaster@example.com
You should have two emails in the postmaster's inbox. One in-offensive and the other marked with SPAM.
From Date Subject ----------------------------------------------------------------------------------------------------- sb55sb55@yahoo.com 1:54 pm [SPAM] Qmail-Scanner anti-spam test (4/4): checkin... Qmail-Scanner Test 1:54 pm Qmail-Scanner test (1/4): inoffensive message
In this case, two out of four mails (second and third) were (and should be) successfully eliminated.
You should have a log similar to the following in the /var/log/maillog when you run the test_installation.sh script.
Apr 2 14:54:44 mail qmail-scanner[7987]: Clear:RC:1(127.0.0.1): 0.005206 323 postmaster@example.com postmaster@example.com Qmail-Scanner_test_(1/4):_inoffensive_message <20130402115444.7986.qmail@mail.example.com> orig-mail.example.com13649036845887987:323 1364903684.7989-0.mail.example.com:68 Apr 2 14:54:45 mail spamd[3139]: spamd: connection from localhost [127.0.0.1] at port 47094 Apr 2 14:54:45 mail spamd[3139]: spamd: processing message <20130402115444.7986.qmail@mail.example.com> for postmaster@example.com:712 Apr 2 14:54:45 mail qmail-scanner[7996]: Perlscan:EICAR_Test_Virus:RC:1(127.0.0.1): 0.450453 971 postmaster@example.com postmaster@example.com Qmail-Scanner_viral_test_(2/4):_checking_perlscanner... <20130402115444.7995.qmail@mail.example.com> 1364903684.7998-0.mail.example.com:300 Eicar.com:69 orig-mail.example.com13649036845887996:971 Apr 2 14:54:45 mail qmail-scanner[8009]: MHR:MHR-82:RC:1(127.0.0.1): 0.031313 1246 postmaster@example.com postmaster@example.com Qmail-Scanner_viral_test_(3/4):_checking_non-perlscanner_AV... <20130402115445.8008.qmail@mail.example.com> sneaky.txt Apr 2 14:54:45 mail spamd[3140]: spamd: connection from localhost [127.0.0.1] at port 47095 Apr 2 14:54:45 mail spamd[3140]: spamd: checking message <9PS291LhupY> for postmaster@example.com:712 Apr 2 14:54:53 mail spamd[3140]: spamd: identified spam (1005.5/5.0) for postmaster@example.com:712 in 8.0 seconds, 1986 bytes. Apr 2 14:54:53 mail spamd[3140]: spamd: result: Y 1005 - DATE_IN_FUTURE_Q_PLUS,EXCUSE_4,FORGED_YAHOO_RCVD,FREEMAIL_FROM,GTUBE,INVALID_MSGID,MSGID_SHORT,NORMAL_HTTP_TO_IP,T_TO_NO_BRKTS_FREEMAIL scantime=8.0,size=1986,user=postmaster@example.com,uid=712,required_score=5.0,rhost=localhost,raddr=127.0.0.1,rport=47095,mid=<9PS291LhupY>,autolearn=no Apr 2 14:54:53 mail spamd[3137]: prefork: child states: BI Apr 2 14:54:53 mail qmail-scanner[8015]: Clear:RC:1(127.0.0.1):SA:1(1005.5/5.0): 8.058205 1881 postmaster@example.com postmaster@example.com Qmail-Scanner_anti-spam_test_(4/4):_checking_SpamAssassin_[if_present]_(There_yo <9PS291LhupY> orig-mail.example.com13649036855888015:1881 1364903685.8017-0.mail.example.com:818 Apr 2 14:54:53 mail spamd[3140]: spamd: connection from localhost [127.0.0.1] at port 47096 Apr 2 14:54:53 mail spamd[3140]: spamd: processing message <9PS291LhupY> for postmaster@example.com:712 Apr 2 14:54:53 mail spamd[3140]: spamd: identified spam (1004.2/5.0) for postmaster@example.com:712 in 0.1 seconds, 2421 bytes. Apr 2 14:54:53 mail spamd[3140]: spamd: result: Y 1004 - EXCUSE_4,FORGED_YAHOO_RCVD,FREEMAIL_FROM,GTUBE,INVALID_MSGID,MSGID_SHORT,NORMAL_HTTP_TO_IP,T_TO_NO_BRKTS_FREEMAIL scantime=0.1,size=2421,user=postmaster@example.com,uid=712,required_score=5.0,rhost=localhost,raddr=127.0.0.1,rport=47096,mid=<9PS291LhupY>,autolearn=no Apr 2 14:54:53 mail spamd[3137]: prefork: child states: BI Apr 2 14:54:54 mail spamd[3139]: spamd: clean message (-0.0/5.0) for postmaster@example.com:712 in 9.3 seconds, 663 bytes. Apr 2 14:54:54 mail spamd[3139]: spamd: result: . 0 - NO_RELAYS scantime=9.3,size=663,user=postmaster@example.com,uid=712,required_score=5.0,rhost=localhost,raddr=127.0.0.1,rport=47094,mid=<20130402115444.7986.qmail@mail.example.com>,autolearn=ham Apr 2 14:54:54 mail spamd[3137]: prefork: child states: II
Final adjustments
The /etc/tcp.smtp file needs to be updated, with the settings you want for your server and network. You may want to (will need to) change the file /etc/tcp.smtp , from a simple:
127.:allow,RELAYCLIENT=""
, to:
# No Qmail-Scanner at all for mail from 127.0.0.1 127.:allow,RELAYCLIENT="",RBLSMTPD="",QMAILQUEUE="/var/qmail/bin/qmail-queue" # Use Qmail-Scanner without SpamAssassin on any mail from the local network # [it triggers SpamAssassin via the presence of the RELAYCLIENT var] # 10.:allow,RELAYCLIENT="",RBLSMTPD="",QMAILQUEUE="/var/qmail/bin/qmail-scanner-queue.pl" # # Use Qmail-Scanner with SpamAssassin on any mail from the rest of the world :allow,QMAILQUEUE="/var/qmail/bin/qmail-scanner-queue.pl"
I have setup my /etc/tcp.smtp as follows:-
/etc/tcp.smtp
# my users loggin on to the web interface may be uploading virus infeced files. 127.:allow,RELAYCLIENT="",RBLSMTPD="",QMAILQUEUE="/var/qmail/bin/qmail-scanner-queue.pl" # No Qmail-Scanner at all for mail from 127.0.0.1 ## 127.:allow,RELAYCLIENT="",RBLSMTPD="",QMAILQUEUE="/var/qmail/bin/qmail-queue" # Use Qmail-Scanner without SpamAssassin on any mail from the local network # [it triggers SpamAssassin via the presence of the RELAYCLIENT var] # 10.:allow,RELAYCLIENT="",RBLSMTPD="",QMAILQUEUE="/var/qmail/bin/qmail-scanner-queue.pl" # # Use Qmail-Scanner with SpamAssassin on any mail from the rest of the world :allow,QMAILQUEUE="/var/qmail/bin/qmail-scanner-queue.pl"
Restart Qmail
qmailctl stop ; qmailctl cdb ; qmailctl start
RBL SMTPD
This is already included in qmail, you just need to enable it.
Valid RCPT TO
Valid RCPT TO is part of the JMS combined patch. In order to enable it, you need a CDB file of all the email accounts on your system. This CDB file can be created using the mkvalidrcptto script from the JMS website.
cd /usr/local/bin wget http://qmail.jms1.net/scripts/mkvalidrcptto chmod 755 mkvalidrcptto
Make sure that your installation of perl is happy with the script and can find the modules. You can do this by running this command as a non-root user:
$ perl -c /usr/local/bin/mkvalidrcptto /usr/local/bin/mkvalidrcptto syntax OK
You should then run it once as root and make sure the output makes sense for your system. The output should be a list of every valid email address on your system, one on each line.
# mkvalidrcptto abuse@mail.example.com alias-abuse@mail.example.com alias-mailer-daemon@mail.example.com alias-postmaster@mail.example.com alias-root@mail.example.com alias@mail.example.com dovecot@mail.example.com dovenull@mail.example.com kamran@example.com kamran@mail.example.com mailer-daemon@mail.example.com postmaster@example.com postmaster@mail.example.com qmaild@mail.example.com qmaill@mail.example.com qmailp@mail.example.com qmailq@mail.example.com qmailr@mail.example.com qmails@mail.example.com qscand@mail.example.com root@mail.example.com spamd@mail.example.com vpopmail@mail.example.com
Generate the CDB file to be used with qmail smtpd:
mkvalidrcptto -c /var/qmail/control/validrcptto.cdb
Note: You must re-create the CDB file (manually) as soon as you create or remove a user from any of the domains managed on this system.
To create a new CDB every hour, schedule it to run on hourly basis.
# crontab -e ... * */1 * * * mkvalidrcptto -c /var/qmail/control/validrcptto.cdb
Enable the VALIDRCPTTO options in the qmail-smtpd/run file:
VALIDRCPTTO_CDB="$VQ/control/validrcptto.cdb" VALIDRCPTTO_LIMIT=10 VALIDRCPTTO_LOG=2
Restart Qmail:
qmailctl restart
Grey Listing using jgreylist [JMS]
Download jgreylist from http://qmail.jms1.net/scripts/jgreylist.shtml .
cd /downloads wget http://qmail.jms1.net/scripts/jgreylist wget http://qmail.jms1.net/scripts/jgreylist-clean wget http://qmail.jms1.net/scripts/jgreylist.c
Create necessary directories:
cd /var/qmail mkdir -m 0700 jgreylist chown qmaild:nofiles jgreylist
Before configuring the jgreylist script, identify the "grey list user". The phrase "greylist user" means the user that your SMTP service runs as. This user will need to own the directory containing the greylist files, so that it will have permission to create files and directories as needed.
You will need to know the userid, as well as their primary login group (the group assigned to them in their /etc/passwd entry. Normally the user is qmaild, which is the member of the group nofiles.
The jgreylist script should be installed in a directory listed in the PATH of your SMTP service's "run" script, which is normally /var/qmail/bin. It should be owned by root, have the same group ID as the greylist user's group ID, and have permissions 0750.
The jgreylist-clean script can be installed anywhere on the system, such as /usr/local/sbin. It should be owned by root and have permissions 0755.
Install the jgreylist script by copying the files to proper locations:
cp /downloads/jgreylist /var/qmail/bin/ cp /downloads/jgreylist-clean /usr/local/sbin chown root:nofiles /var/qmail/bin/jgreylist chown root:root /usr/local/sbin/jgreylist-clean chmod 0750 /var/qmail/bin/jgreylist chmod 0755 /usr/local/sbin/jgreylist-clean
Enable the GREYLIST variable in the qmail-smtpd/run file. It needs to be after tcpserver and before qmail-smtpd in the command which actually runs the qmail-smtpd daemon.
GREYLIST="jgreylist" JGREYLIST_DIR="$VQ/jgreylist" # JGREYLIST_NOREV=1 # JGREYLIST_BY_IP=0 JGREYLIST_HOLDTIME=120 JGREYLIST_LOG=1 JGREYLIST_LOG_PID=1 JGREYLIST_LOG_SMTP=0 JGREYLIST_TIMEOUT=60 JGREYLIST_LIMIT=0
Restart Qmail SMTPD service:
svc -t /service/qmail-smtpd or qmailctl restart
The jgreylist script also has a configuration section, which you may change as per your setup. Most of the time, the default values are good enough.
The jgreylist-clean script can be run as the greylist user, or as root; and can be run at any time, and once a day is good enough. It has also has a configuration section, which can be used to adjust the clean-up timing.
Setup a cronjob to run jgreylist-clean script every day.
# crontab -e ... * * */1 * * /usr/local/sbin/jgreylist-clean
The final crontab
# crontab -l # Run at 0 min (zero minute) of every hour. 0 * * * * /usr/bin/freshclam --quiet # Run at 1 AM every day 0 1 * * * /usr/local/bin/setuidgid qscand /var/qmail/bin/qmail-scanner-queue.pl -z 0 1 * * * /usr/local/bin/setuidgid qscand /var/qmail/bin/qmail-scanner-queue.pl -g # Run at 0 min (zero minute) of every hour. 0 * * * * /usr/local/bin/mkvalidrcptto -c /var/qmail/control/validrcptto.cdb ; killall -HUP qmail-send # Run at 2 AM everyday 0 2 * * * /usr/local/sbin/jgreylist-clean
SMTP-AUTH
Discussion about SMTP auth and two available methods, as per the following links: ????
- http://qmail.jms1.net/scripts/service-qmail-smtpd-run.shtml
- http://qmail.jms1.net/patches/authcdb.shtml
- http://qmail.jms1.net/scripts/mkauth.shtml
Download the JMS mkauth script:
cd /usr/local/bin wget http://qmail.jms1.net/scripts/mkauth chmod 755 mkauth
Run the mkauth program to see if it can pull the users and password information:
# perl -c /usr/local/bin/mkauth /usr/local/bin/mkauth syntax OK # mkauth alias * alias@mail.example.com * dovecot !! dovecot@mail.example.com !! dovenull !! dovenull@mail.example.com !! kamran $6$67BILXM0$653j3t0ZqGviMOrq17j3ym4/8D8v6cRkCmEyy7MrwkiprS0jZYD9ff3jJ8xexLP23uAhkbvfCZFpcDc.UCq4UrNJ. kamran@example.com $1$QkAyMD5Gfuv$csa3tunpQIaCkZaJzE4fK. kamran@mail.example.com $6$67BIH5SLXM0$j3t0ZqGfviMOrq17j3ym4/8D8v6cRkCmEyy7MrwkiprS0jZYD9ff3jJ8xexLP23uAhkbvfCZFpcDc.UCq4UrNJ. postmaster@example.com $1$AMP3vlrE$8CRAE2qVLb4k9LfN2oUgrKiu. qmaild * qmaild@mail.example.com * qmaill * qmaill@mail.example.com * qmailp * qmailp@mail.example.com * qmailq * qmailq@mail.example.com * qmailr * qmailr@mail.example.com * qmails * qmails@mail.example.com * qscand !! qscand@mail.example.com !! spamd !! spamd@mail.example.com !! vpopmail !! vpopmail@mail.example.com !!
Now create the auth.cdb file:
mkauth -c /tmp/new.cdb chown root:nofiles /tmp/new.cdb chmod 0640 /tmp/new.cdb mv /tmp/new.cdb /var/qmail/control/auth.cdb
Note: If there are any active qmail-smtpd services using the auth.cdb file, you should not build the file directly - you should build it using a different name, then set the ownership and permissions correctly, and then rename the new file over the old one. The example above assumes that qmail-smtpd is running as the "qmaild" user (which is the standard way to do it.)
Note: You will need to recreate the CDB file each time you add or remove an email account.
Enable the following options in the qmail-smtpd/run file:
# options pertaining to the AUTH command. AUTH=1 REQUIRE_AUTH=0 ALLOW_INSECURE_AUTH=0 # if using the AUTH_CDB method AUTH_CDB="$VQ/control/auth.cdb" # if using the CHECKPW method # CHECKPW=~vpopmail/bin/vchkpw # TRUE=`which true`
Now restart qmail:
qmailctl restart
Now setup your mail client (Thunderbird, Outlook, etc) to send mail using SMTP-AUTH (LOGIN). Send a test mail, and check logs.
==> /var/log/qmail/qmail-smtpd/current <== @40000000515fed62244466a4 tcpserver: status: 1/30 @40000000515fed62244be0b4 tcpserver: pid 4043 from 195.xxx.yyy.zzz @40000000515fed622453cff4 tcpserver: ok 4043 mail.example.com.com:192.168.122.13:25 :195.18.251.242::41317 @40000000515fed652f8fcddc qmail-smtpd[4043]: AUTH successful [195.xxx.yyy.zzz] kamran@example.com @40000000515fed66058eb8cc qmail-smtpd[4043]: MFCHECK pass [195.xxx.yyy.zzz] example.com @40000000515fed66058fed64 qmail-smtpd[4043]: MAIL FROM:<kamran@example.com> @40000000515fed6612e2fbdc qmail-smtpd[4043]: RCPT TO:<kamran@wbitt.com> @40000000515fed682157b694 tcpserver: end 4043 status 0 @40000000515fed682157ba7c tcpserver: status: 0/30
Todo
- SpamAssassin
- Additional Modules
- DCC
- Razor
- JMS Queue analyzer : http://qmail.jms1.net/scripts/qlanalyze
- Automate creation of CDB files automatically. http://qmail.jms1.net/scripts/qmail-updater.shtml
- Mail graphs ???