Qmail
From WBITT's Cooker!
(→Todo:) |
(→Todo:) |
||
Line 2,998: | Line 2,998: | ||
ln -s /var/qmail/alias/.qmail-root /var/qmail/alias/.qmail-anonymous | ln -s /var/qmail/alias/.qmail-root /var/qmail/alias/.qmail-anonymous | ||
chmod 644 /var/qmail/alias/.qmail* | chmod 644 /var/qmail/alias/.qmail* | ||
+ | </pre> | ||
+ | |||
+ | Remove SENDMAIL, POSTFIX , EXIM from System: | ||
+ | |||
+ | If you have not removed these packages before, you can do it now. | ||
+ | |||
+ | <pre> | ||
+ | service sendmail stop | ||
+ | service postfix stop | ||
+ | service exim stop | ||
+ | service dovecot stop | ||
+ | </pre> | ||
+ | |||
+ | <pre> | ||
+ | rpm -e sendmail --nodeps | ||
+ | rpm -e sendmail-cf --nodeps | ||
+ | rpm -e postfix --nodeps | ||
+ | rpm -e exim --nodeps | ||
+ | </pre> | ||
+ | |||
+ | Create artificial sendmail path: | ||
+ | |||
+ | <pre> | ||
+ | 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 | ||
</pre> | </pre> | ||
Revision as of 16:39, 1 April 2013
Title: Qmail-Using John Simpson method
Created: 08/07/2009
Last Modified: 08/21/2009
Note: This is a highly volatile document at the moment. It is a research/development work, with VERY SHARP EDGES, and you should not use it in your production servers UNLESS you know what you are doing. With that said, the details are being used on at least two production internet mail server, which I know. :)
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 \ 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 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 -g 700 nofiles useradd -u 701 -g nofiles -d /var/qmail/alias -s /sbin/nologin -p '*' -c 'QMail alias user' alias useradd -u 702 -g nofiles -d /var/qmail -s /sbin/nologin -p '*' -c 'QMail daemon user' qmaild useradd -u 703 -g nofiles -d /var/qmail -s /sbin/nologin -p '*' -c 'QMail log user' qmaill useradd -u 704 -g nofiles -d /var/qmail -s /sbin/nologin -p '*' -c 'QMail password user' qmailp groupadd -g 701 qmail useradd -u 705 -g qmail -d /var/qmail -s /sbin/nologin -p '*' -c 'QMail queue user' qmailq useradd -u 706 -g qmail -d /var/qmail -s /sbin/nologin -p '*' -c 'QMail remote user' qmailr useradd -u 707 -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.
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:
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:-
[root@qmail package]# cat /usr/local/src/qmail-1.03/conf-split 23 This is the queue subdirectory split.
[root@qmail package]# 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. [root@qmail package]#
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:
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!
[root@qmail qmail-1.03]# 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 [root@qmail qmail-1.03]#
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:
[root@qmail qmail-1.03]# cat conf-split 23 This is the queue subdirectory split. [root@qmail qmail-1.03]# 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. [root@qmail qmail-1.03]#
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:
make clean make man make setup check [root@qmail qmail-1.03]# 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 [root@qmail qmail-1.03]#
Configure basic qmail structures
Alhumdulillah. The compilation is done without a problem. According to LWQ, you can go ahead with using either “./config” or “./config-fast server.domain.com” method. QMR asks you to run “./config-fast server.domain.com” directly.
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
First, I will try “./config” only :
[root@qmail qmail-1.03]# ./config Your hostname is qmail.example.com. hard error Sorry, I couldn't find your host's canonical name in DNS. You will have to set up control/me yourself. [root@qmail qmail-1.03]#
As you can see clearly, above, my DNS was not set properly, so qmail told me to do things manually. Instead of doing things manually, I will just run the “./config-fast ... ” script.
[root@qmail qmail-1.03]# ./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! [root@qmail qmail-1.03]#
That's it. qmail is now installed on your system and is ready to be run!
################################################################################ Important from: http://www.antagonism.org/qmr-faq.shtml 7.11 What is the difference between the locals and rcpthosts files in /var/qmail/control? The locals file contains domains which reside locally on the machine. This means accounts listed in locals should have shell accounts on the machine. If you use vpopmail, your locals file should be empty but exist. This problem is prevalent in many qmailrocks installs as the instruction set wrongly instructs users to configure qmail using the "config-fast" shell script. Unless the user desires email accounts for his shell accounts the is not the correct method. The following commands correct this error. If /var/qmail/control/locals exists, run the first command. If not, you may skip to the second command. # rm -f /var/qmail/control/locals # touch /var/qmail/control/locals # chmod 644 /var/qmail/control/locals # chown root.root /var/qmail/control/locals The rcpthosts file contains the domains for which qmail-smtpd will accept email. The rcpthosts file should contain the domain names only. Do not put in email addresses, hostnames or IP addresses into this file. ##################################################################################
Though I have read the note above and implemented on a few live servers. I do not agree with it. The reason is that if I do as advised above, in this note, then mails destined for root, postmaster, etc do not get delivered to the mailbox of postmaster. So we won't act upon this advice. I have only copied this text/note here, for your information.
There is another thing to this note. The config-fast shell script is not provided by QMR. It is mentioned in LWQ. So it had to be from DJB. And at the moment, I consider him (DJB) the authority on Qmail. He put this script for a purpose. And the purpose is being served. Lets move on. By the way, by the time of this writing, the note has apparently moved to another location or changed name. I couldn't find it and I did not spent much time on it either.
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.
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]:
Earlier, you unpacked the qmail, ucspi-tcp, and daemontools tarballs. Now change to the ucspi-tcp directory:
cd /usr/local/src/ucspi-tcp-0.88
In the Do the build section, if you modified conf-cc and conf-ld, you'll need to make the same changes in this directory. (We did not do any changes to conf-cc and conf-ld while compiling / building qmail-1.03 !)
Then do:
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 english, 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 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.
The patch:
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 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. (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 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
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/ [root@qmail downloads]# wget http://qmail.jms1.net/ucspi-tcp/ucspi-rss2.patch [root@qmail downloads]# wget http://qmail.jms1.net/ucspi-tcp/tcpserver-limits-2007-12-22.patch cd /usr/local/src/ucspi-tcp-0.88 [root@qmail ucspi-tcp-0.88]# patch < /downloads/ucspi-rss2.patch patching file rblsmtpd.c [root@qmail ucspi-tcp-0.88]# patch < /downloads/tcpserver-limits-2007-12-22.patch patching file CHANGES.tcpserver-limits-patch patching file README.tcpserver-limits-patch patching file tcpserver.c [root@qmail ucspi-tcp-0.88]# Now run “make” and “make setup check”: [root@qmail ucspi-tcp-0.88]# 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 [root@qmail ucspi-tcp-0.88]# [root@qmail ucspi-tcp-0.88]# make setup check ./install ./instcheck [root@qmail ucspi-tcp-0.88]#
That's it. ucspi-tcp is installed. Alhumdulillah! Good.
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 ... ... Replace : extern int errno; With : /* extern int errno; */ And add another line after it: #include <errno.h> ... ... (save exit).
Change directory one step back :
cd .. OR cd /package/admin/daemontools-0.76/
And run:
package/install OR ./package/install [root@qmail daemontools-0.76]# 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. [root@qmail daemontools-0.76]#
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.
[root@qmail daemontools-0.76]# 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 [root@qmail daemontools-0.76]#
You will also see the following line added to your /etc/inittab file :
[root@qmail daemontools-0.76]# cat /etc/inittab . . . . . . SV:123456:respawn:/command/svscanboot [root@qmail daemontools-0.76]#
Note: CentOS 6 Specific (http://www.productionmonkeys.net/guides/qmail-server/daemontools) Starting daemontools with Upstart (http://qmail.jms1.net/daemontools/upstart.shtml) The installer added a line to /etc/inittab to start svscan automatically, however that is obsolete in CentOS 6.x. Remove the added 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 Also check: http://www.kluner.net/2011/04/04/daemontools-on-redhat-enterprise-6-0 [root@mail init]# initctl reload-configuration [root@mail init]# initctl start svscan svscan start/running, process 5167 [root@mail init]# 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 [root@mail init]#
Alhumdulillah 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.
And believe me, I was stupid and dumb enough to keep following it for all these years blindly, for the same reason JMS accuses it for: “to take the easy way out”. Until I read JMS and Life with Qmail “seriously”, I was living in fool's paradise. Anyway. Everyone learns from mistakes and I learned (and still learning) from mine.
Start qmail:
The /var/qmail/rc file [LWQ]:
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. i.e. it should be ./Maildir/ as per LWQ. Normally it doesn't matter. It works both ways.
Save the above code as above /var/qmail/rc, then execute the following:
chmod 755 /var/qmail/rc
Note: LWQ creates a directory (/var/log/qmail) at this point. This will be used in various run scripts created below. Also the qmail log-run scripts will create files in this directory, “directly”. QMR deviated a little from this and created three sub directories inside /var/log/qmail , named qmail-send, qmail-smtpd, qmail-pop3d . JMS acknowledges here ( 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
At this point you need to decide the default delivery mode for messages that aren't delivered by a .qmail file. Well the most common options are Mailbox or Maildir formats. We are going to use the Maildir format as the default delivery mode.
echo './Maildir/' >/var/qmail/control/defaultdelivery
For more information, see INSTALL.mbox, INSTALL.maildir files in /usr/local/src/qmail-1.03 directory.
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:
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 [root@qmail ~]# vi /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.
Now create the supervise directories for the qmail services [LWQ]:
mkdir -p /var/qmail/supervise/qmail-send/log mkdir -p /var/qmail/supervise/qmail-smtpd/log
Note: QMR also creates these directories, when a script named qmr_install_linux-s1.script is run.
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:
cat > /var/qmail/supervise/qmail-send/run << EOF #!/bin/sh exec /var/qmail/rc EOF
[QMR's send_run file has same contents, for this file.]
Now the qmail-send/log/run file:
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:
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 http://qmail.jms1.net/logfiles.shtml http://qmail.jms1.net/scripts/service-any-log-run
The qmail-smtpd/run file:
Here is the LWQ version of the qmail-smtpd/run file:
#!/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. The differences from LWQ are highlighted:
[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:
/usr/local/bin/tcpserver: error while loading shared libraries: libc.so.6: failed to map segment from shared object: Cannot allocate memory
, then try raising it to 3000000 or 4000000, or whatever you can afford based on your system resources.
Note: You will need to create the concurrencyincoming control file as used in the smtpd/run scripts above (IF you use above script, that is!):
echo 20 > /var/qmail/control/concurrencyincoming chmod 644 /var/qmail/control/concurrencyincoming
The strange thing is that why QMR's author is using vpopmail as QMAILUID and NOFILESGID variables?
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 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 file by JMS
The qmail-smtpd/run file by JMS is quite big. Download-able from (http://qmail.jms1.net/scripts/service-qmail-smtpd-run) . It has a lot of options in it, which are explained here: 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 smtpd-run file to /var/qmail/supervise/qmail-smtpd/run .
cp /downloads/service-qmail-smtpd-run /var/qmail/supervise/qmail-smtpd/run
Before we go 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 wwould definitely help us what to select / enable, and what not.
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.
Edit this file and adjust according to your needs. (The SMTP_CDB needs to be updated. It should not be /etc/tcp/smtp.cdb . This is updated after encountering an error a little later.)
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 will start, but when you try to connect to it, it will show you an error. Such as:
[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.
Time to create the qmail-smtpd/log/run file:
The qmail-smtpd/log/run file:-
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.
Make the run files executable [LWQ]:
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
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 [root@qmail ~]# 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.90:22 ::ffff:192.168.122.1:56432 ESTABLISHED 2031/0 [root@qmail ~]#
Good! No SMTP software 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 is installed.
As mentioned just now, the qmail system would now be running. Lets check:
[root@qmail ~]# 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 [root@qmail ~]#
The qmail-smtpd service seems to be stuck at 1 second. This is not good. Lets try to find the reason:
[root@qmail ~]# 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
Ahan!
Actually the qmail-smtpd/run file by JMS is looking for a the tcprules file named /etc/tcp/smtp.cdb . Whereas LWQ asks us to create a file named /etc/tcp.smtp . (I have still not created the file using the LWQ method as well). This means we have to adjust this value in qmail-smtpd/run script by JMS.
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."
This means the compiled tcprules file is /etc/tcp.smtp.cdb . “not” /etc/tcp/smtp.cdb . This may be a typo from JMS or just a different location by his own preference. Lets adjust that (to /etc/tcp.smtp.cdb) in the qmail-smtpd/run file we downloaded from JMS site accordingly:-
SMTP_CDB="/etc/tcp.smtp.cdb"
It is also the right time to 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 qmail stat [root@qmail ~]# 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 [root@qmail ~]#
Alhumdulillah. 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:
[root@qmail ~]# 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.
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.
[root@qmail ~]# 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 [root@qmail ~]#
qmail-smtpd seems good!
[root@qmail ~]# 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
qmail-send also seems good.
Note: There is no log entry for these (qmail start / stop /error events) in /var/log/messages , or in /var/log/maillog .
Alhumdulillah.
Note: Linking of the supervise script directories in /service directory and the following line added in the /etc/inittab file ensures that the qmail service will be started at system boot time.
tail /etc/inittab SV:123456:respawn:/command/svscanboot
<<<<<<< End of day >>>>>>
Time to remove any other SMTP software from your system.
rpm -e sendmail sendmail-cf exim postfix --nodeps [root@qmail ~]# 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 [root@qmail ~]#
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 .
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:
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
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.
[LWQ]: Create System Aliases
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
Test the 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 a 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:
[root@qmail downloads]# 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 [root@qmail downloads]#
However, if you want to fee happy, and desperate to see the congratulations message, you can try to create this directory and run the test script:
[root@qmail downloads]# mkdir /var/log/qmail/smtpd [root@qmail downloads]# chown qmaill /var/log/qmail/smtpd/ [root@qmail downloads]# ./inst_check Congratulations, your LWQ installation looks good! [root@qmail downloads]#
Well, in this example you fooled the script!
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: ................................................................................................................................................................................................................................................................................................................................................................................................................
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, 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 test:
[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]#
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
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/
# make clean; make; make man; make mysql # make install
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.
# 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 -p '*' 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
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 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 ****************************************************
VQAdmin
Latest version in 2.3.7 , released in Nov 2005 , available at http://www.inter7.com/index.php?page=vqadmin .
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
# 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 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
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
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
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.
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
Todo:
“Qmail Make cert” ???
JMS Queue analyzer : http://qmail.jms1.net/scripts/qlanalyze