<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta name="generator" content="HTML Tidy, see www.w3.org"> <title>System-wide virus and spam scanning</title> <meta name="GENERATOR" content= "Modular DocBook HTML Stylesheet Version 1.73 "> <link rel="STYLESHEET" type="text/css" href="docbook-jade.css"> </head> <body class="ARTICLE" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#840084" alink="#0000FF"> <div class="ARTICLE"> <div class="TITLEPAGE"> <h1 class="TITLE"><a name="AEN2">System-wide virus and spam scanning</a></h1> <h2 class="SUBTITLE">Installing <span class= "APPLICATION">qmail-scanner</span>, <span class="APPLICATION">Clam Antivirus</span> and <span class="APPLICATION">SpamAssassin</span> under <span class="SYSTEMITEM">FreeBSD</span></h2> <div class="AUTHORGROUP"> <a name="AEN9"></a> <h3 class="AUTHOR"><a name="AEN10">Paul Hoadley</a></h3> <h3 class="AUTHOR"><a name="AEN13">Eric Parsonage</a></h3> </div> <p class="COPYRIGHT">Copyright © 2002 by Paul Hoadley and Eric Parsonage</p> <p class="PUBDATE">$Date: 2003/08/06 03:05:51 $<br> </p> <div> <div class="ABSTRACT"> <a name="AEN21"></a> <p>This document describes how to effect system-wide virus and spam scanning of incoming email. The approach is based on the <a href="http://www.qmail.org" target="_top"><span class= "APPLICATION">qmail</span></a> mail transport agent, and is not applicable to sites running <a href= "http://www.sendmail.org" target="_top"><span class= "APPLICATION">sendmail</span></a>. This document describes how to install <a href="http://qmail-scanner.sourceforge.net" target="_top"><span class= "APPLICATION">qmail-scanner</span></a>, an enhancement for <span class="APPLICATION">qmail</span> that allows incoming mail to be passed through third-party filters prior to normal local delivery. The two filters described in this document are <a href="http://clamav.elektrapro.com/" target="_top"><span class="APPLICATION">Clam AntiVirus</span></a>, an open source virus scanning package, and <a href= "http://spamassassin.taint.org" target="_top"><span class= "APPLICATION">SpamAssassin</span></a>, an open source spam detector.</p> </div> </div> <hr> </div> <div class="TOC"> <dl> <dt><b>Table of Contents</b></dt> <dt>1. <a href="#AEN34">Pre-requisites</a></dt> <dt>2. <a href="#AEN65">Installing <span class= "APPLICATION">Clam AntiVirus</span></a></dt> <dt>3. <a href="#AEN120">Installing <span class= "APPLICATION">SpamAssassin</span></a></dt> <dt>4. <a href="#AEN214">Installing <span class= "APPLICATION">qmail-scanner</span></a></dt> <dt>A. <a href="#PERL">Fetching and installing Perl modules from CPAN</a></dt> <dt>B. <a href="#AEN292">Contacting the authors</a></dt> </dl> </div> <div class="SECT1"> <hr> <h1 class="SECT1"><a name="AEN34">1. Pre-requisites</a></h1> <p>The following instructions are intended to be comprehensive, but there are at least these pre-requisites:</p> <ul> <li> <p>The system should be running <span class= "APPLICATION">qmail</span> as its mail transport agent. <span class="emphasis"><i class="EMPHASIS">The following instructions are targetted specifically at a <span class= "APPLICATION">qmail</span> installation and will not work with <span class="APPLICATION">sendmail</span></i></span>. Instructions for installing <span class= "APPLICATION">qmail</span> as a replacement for <span class= "APPLICATION">sendmail</span> can be found in the document <a href="qmail-how-to.html" target="_top">Installing <span class= "APPLICATION">qmail</span> under FreeBSD</a>.</p> </li> <li> <p><span class="APPLICATION">qmail</span> must be compiled with the <tt class="OPTION">WITH_QMAILQUEUE_PATCH</tt> option by specifying <span class="emphasis"><i class="EMPHASIS">at least</i></span>:</p> <pre class="SCREEN"> # make WITH_QMAILQUEUE_PATCH=yes </pre> <p>at the build stage. If <span class= "APPLICATION">qmail</span> was built using the instructions in the <a href="qmail-how-to.html" target="_top">Installing <span class="APPLICATION">qmail</span> under FreeBSD</a> document, this patch will have been applied.</p> </li> </ul> <p>It is necessary to install <span class="APPLICATION">Clam AntiVirus</span> and <span class="APPLICATION">SpamAssassin</span> <span class="emphasis"><i class="EMPHASIS">prior</i></span> to installing <span class="APPLICATION">qmail-scanner</span>, as the latter tries to automatically detect available third-party scanners at installation time. There are no dependencies between <span class="APPLICATION">Clam AntiVirus</span> and <span class= "APPLICATION">SpamAssassin</span> in the following approach — installation of either can be omitted if that functionality is not required.</p> </div> <div class="SECT1"> <hr> <h1 class="SECT1"><a name="AEN65">2. Installing <span class= "APPLICATION">Clam AntiVirus</span></a></h1> <div class="SECT2"> <h2 class="SECT2"><a name="AEN68">2.1. Building and installing from source</a></h2> <p>There is no <span class="SYSTEMITEM">FreeBSD</span> Port for <span class="APPLICATION">Clam AntiVirus</span>, so it needs to be built by hand from the source. Firstly, obtain and unpack the source:</p> <pre class="SCREEN"> # cd /usr/local # mkdir clamav # cd clamav # fetch http://clamav.elektrapro.com/stable/clamav-0.51.tar.gz # gunzip clamav-0.51.tar.gz # tar -xvf clamav-0.51.tar.gz </pre> <p>Create new user and group names for <span class= "APPLICATION">Clam AntiVirus</span>:</p> <pre class="SCREEN"> # pw groupadd clamav # pw useradd clamav -g clamav -d /nonexistent -c "Clam Antivirus" \ -s /sbin/nologin </pre> <p>Now configure and install <span class="APPLICATION">Clam AntiVirus</span>:</p> <pre class="SCREEN"> # cd clamav-0.51 # ./configure # make install </pre> </div> <div class="SECT2"> <hr> <h2 class="SECT2"><a name="AEN80">2.2. Testing the installation</a></h2> <p>You should now read the documentation for <b class= "COMMAND">clamscan</b> (<b class="COMMAND">man clamscan</b>, or read the <a href="http://clamav.elektrapro.com/doc/html" target= "_top">online documentation</a>). You can test the scanner by running:</p> <pre class="SCREEN"> # clamscan --recursive --log=/tmp/clamscan.log /usr/home </pre> <p>Obviously this can be run on the base directory of your choice, and the log file location is also arbitrary. Next, use the <b class="COMMAND">freshclam</b> command to update your databases:</p> <pre class="SCREEN"> # freshclam --verbose </pre> </div> <div class="SECT2"> <hr> <h2 class="SECT2"><a name="AEN90">2.3. Running <b class= "COMMAND">freshclam</b> as a daemon</a></h2> <p>The <b class="COMMAND">freshclam</b> database updater can be run as a daemon. Firstly, create a log file for <b class= "COMMAND">freshclam</b>:</p> <pre class="SCREEN"> # touch /var/log/freshclam.log # chmod 644 /var/log/freshclam.log # chown clamav:clamav /var/log/freshclam.log </pre> <p>Create following script as <tt class= "FILENAME">/usr/local/etc/rc.d/clamav.sh</tt> to start up <b class="COMMAND">freshclam</b> as a daemon at boot time, and cause it to die gracefully at shutdown:</p> <pre class="PROGRAMLISTING"> #!/bin/sh # # Startup / shutdown script for Clam Antivirus case "$1" in start) /usr/local/bin/freshclam -d -c 2 -l /var/log/freshclam.log echo -n ' freshclam' ;; stop) /usr/bin/killall freshclam > /dev/null 2>&1 \ && echo -n ' freshclam' ;; *) echo "" echo "Usage: `basename $0` { start | stop }" echo "" exit 64 ;; esac </pre> <p>Ensure that the script is executable:</p> <pre class="SCREEN"> # chmod 744 /usr/local/etc/rc.d/clamav.sh </pre> </div> <div class="SECT2"> <hr> <h2 class="SECT2"><a name="AEN103">2.4. Running <b class= "COMMAND">clamscan</b> on a regular basis</a></h2> <p>If you have a filesystem directory tree that you think would benefit from regular virus scanning (anything accessible from any <span class="SYSTEMITEM">Microsoft Windows</span> machines on your LAN would probably be candidates), you can set up a <b class="COMMAND">cron</b> job to run <b class= "COMMAND">clamscan</b> on a regular basis. Read the <span class= "APPLICATION">Clam AntiVirus</span> documentation and decide which options to <b class="COMMAND">clamscan</b> are appropriate for your site. For example, you may not wish to specify the <tt class="OPTION">--remove</tt> option, and you may wish to <tt class="OPTION">--exclude</tt> any number of files or directories from scanning. As an example, the following entry appended to <tt class="FILENAME">/etc/crontab</tt> will scan <tt class= "FILENAME">/usr</tt> daily at 6.00am:</p> <pre class="PROGRAMLISTING"> 0 6 * * * root /usr/local/bin/clamscan --recursive --infected --exclude /usr/local/share/clamav/viruses.db --exclude /usr/local/share/clamav/viruses.db2 --log=/var/log/clamscan.log /usr/home </pre> <div class="NOTE"> <table class="NOTE" width="100%" border="0"> <tr> <td width="25" align="CENTER" valign="TOP"><img src= "./images/note.gif" hspace="5" alt="Note"></td> <td align="LEFT" valign="TOP"> <p>The line in <tt class="FILENAME">/etc/crontab</tt> is shown broken here to improve readability, but should appear as a single line in the file.</p> </td> </tr> </table> </div> </div> </div> <div class="SECT1"> <hr> <h1 class="SECT1"><a name="AEN120">3. Installing <span class= "APPLICATION">SpamAssassin</span></a></h1> <div class="SECT2"> <h2 class="SECT2"><a name="AEN123">3.1. Building and installing from source</a></h2> <p>There is a <span class="SYSTEMITEM">FreeBSD</span> Port for <span class="APPLICATION">SpamAssassin</span>, though it will build an old version (2.41). Either build that port with:</p> <pre class="SCREEN"> # cd /usr/ports/mail/p5-Mail-SpamAssassin # make # make install </pre> <p>or build the latest version by hand from the source as follows. Firstly, obtain and unpack the source:</p> <pre class="SCREEN"> # cd /usr/local # mkdir spamassassin # cd spamassassin # fetch http://spamassassin.taint.org/released/Mail-SpamAssassin-2.43.tar.gz # gunzip Mail-SpamAssassin-2.43.tar.gz # tar -xvf Mail-SpamAssassin-2.43.tar # cd Mail-SpamAssassin-2.43 </pre> <p>Now, build the <tt class="FILENAME">Makefile</tt> with <b class="COMMAND">perl</b>:</p> <pre class="SCREEN"> # perl Makefile.PL </pre> <div class="NOTE"> <table class="NOTE" width="100%" border="0"> <tr> <td width="25" align="CENTER" valign="TOP"><img src= "./images/note.gif" hspace="5" alt="Note"></td> <td align="LEFT" valign="TOP"> <p>At this point, <b class="COMMAND">perl</b> will warn you of any dependencies on Perl packages your system is missing. Fetching and installing Perl packages is described in an <a href="#PERL">Appendix</a> below. Fetch and install any packages required before proceeding.</p> </td> </tr> </table> </div> <p>Now build <span class="APPLICATION">SpamAssassin</span>:</p> <pre class="SCREEN"> # make # make install </pre> </div> <div class="SECT2"> <hr> <h2 class="SECT2"><a name="AEN142">3.2. Testing the installation</a></h2> <p>You should now test <span class= "APPLICATION">SpamAssassin</span> on the sample files provided. Firstly, test some known spam:</p> <pre class="SCREEN"> # spamassassin -t < sample-spam.txt > spam.out </pre> <p>View the resulting file, <tt class="FILENAME">spam.out</tt>. <span class="APPLICATION">SpamAssassin</span> should add the following headers to the message:</p> <pre class="PROGRAMLISTING"> X-Spam-Status: Yes, hits=14.7 required=5.0 tests=ALL_CAPS_HEADER,CALL_FREE,DATE_IN_PAST_24_48, DRASTIC_REDUCED,FROM_HAS_MIXED_NUMS,HOME_EMPLOYMENT, INVALID_DATE,INVALID_MSGID,LINES_OF_YELLING, MSGID_HAS_NO_AT,NO_REAL_NAME,ONCE_IN_LIFETIME,REMOVE_SUBJ, SMTPD_IN_RCVD,SPAM_PHRASE_21_34,UNDISC_RECIPS version=2.43 X-Spam-Flag: YES X-Spam-Level: ************** X-Spam-Checker-Version: SpamAssassin 2.43 (1.115.2.20-2002-10-15-exp) </pre> <p>Additionally, there will be a banner explaining in detail what tests were failed.</p> <p>Next, test <span class="APPLICATION">SpamAssassin</span> with a piece of genuine email:</p> <pre class="SCREEN"> # spamassassin -t < sample-nonspam.txt > nonspam.out </pre> <p>This should add only the following headers to the mail, indiciating the message is not considered spam:</p> <pre class="PROGRAMLISTING"> X-Spam-Status: No, hits=0.9 required=5.0 tests=GAPPY_TEXT,LINES_OF_YELLING,PGP_SIGNATURE, SPAM_PHRASE_02_03,TO_BE_REMOVED_REPLY version=2.43 X-Spam-Level: </pre> <div class="NOTE"> <table class="NOTE" width="100%" border="0"> <tr> <td width="25" align="CENTER" valign="TOP"><img src= "./images/note.gif" hspace="5" alt="Note"></td> <td align="LEFT" valign="TOP"> <p><span class="APPLICATION">SpamAssassin</span>'s only action is to mark mail that it considers spam with the <tt class="OPTION">X-Spam-</tt> headers. It does not delete or even remove spam. Another agent is required in the chain to move the spam once detected. Instructions are given <a href="#PROCMAIL">below</a> for a simple per-user <a href="www.procmail.org" target="_top"><span class="APPLICATION">procmail</span></a> recipe for moving spam to a separate folder.</p> </td> </tr> </table> </div> </div> <div class="SECT2"> <hr> <h2 class="SECT2"><a name="AEN164">3.3. Running <span class= "APPLICATION">SpamAssassin</span> as a daemon: <b class= "COMMAND">spamd</b></a></h2> <p>If <span class="APPLICATION">SpamAssassin</span> was installed from the Ports System, a startup script for <b class= "COMMAND">spamd</b> will have been placed in <tt class= "FILENAME">/usr/local/etc/rc.d/spamd.sh</tt>. If <span class= "APPLICATION">SpamAssassin</span> was installed by hand, you should now create a startup script for <b class= "COMMAND">spamd</b> (the daemon version of <span class= "APPLICATION">SpamAssassin</span>), similar to the one created above for <b class="COMMAND">freshclam</b>. Create the following script as <tt class= "FILENAME">/usr/local/etc/rc.d/spamd.sh</tt>:</p> <pre class="PROGRAMLISTING"> #!/bin/sh # # Startup / shutdown script for SpamAssassin daemon case "$1" in start) /usr/bin/spamd -a -d && echo -n ' spamd' ;; stop) spamdpid=`ps -ax | grep spamd | grep -v grep | grep -v sh | awk '{ print $1 }'` if [ "$spamdpid" != "" ]; then kill $spamdpid > /dev/null 2>&1 echo -n " spamd" fi ;; *) echo "Usage: `basename $0` {start|stop}" >&2 ;; esac exit 0 </pre> <p>Remember to make the script executable, then use it to start <b class="COMMAND">spamd</b> — <b class= "COMMAND">qmail-scanner</b> will only find the <span class= "APPLICATION">SpamAssassin</span> daemon if it is running at the time of install:</p> <pre class="SCREEN"> # chmod 744 /usr/local/etc/rc.d/spamd.sh # /usr/local/etc/rc.d/spamd.sh start </pre> </div> <div class="SECT2"> <hr> <h2 class="SECT2"><a name="PROCMAIL">3.4. Using <span class= "APPLICATION">procmail</span> to filter the spam</a></h2> <p>As noted above, <span class="APPLICATION">SpamAssassin</span> only tags spam with <tt class="OPTION">X-Spam-</tt> headers. If you don't do anything else, you'll still receive spam in your mailbox — it will just be identified as spam by those headers. One common solution is to use <span class= "APPLICATION">procmail</span> as a mail delivery agent and instruct it to place the spam in a Maildir of its own. There is a lot of good documentation on installing and running <span class="APPLICATION">procmail</span>, and a thorough treatment of that complex program is beyond the scope of this document. If you have <span class="APPLICATION">procmail</span> installed at your site already, though, or even if you are prepared to install it from the Ports System <span class="emphasis"><i class="EMPHASIS">just to redirect <span class= "APPLICATION">SpamAssassin</span>-tagged spam</i></span>, the following is a minimal procmail recipe to redirect spam to the Maildir <tt class="FILENAME">$HOME/Maildir/.Spam/</tt>:</p> <pre class="PROGRAMLISTING"> :0: * ^X-Spam-Status: Yes $HOME/Maildir/.Spam/ </pre> <p>This recipe would be placed in each user's <tt class= "FILENAME">.procmailrc</tt> file. In addition, placing it in the file <tt class="FILENAME">/usr/share/skel/dot.procmailrc</tt> will ensure that any newly created users will have a <tt class= "FILENAME">.procmailrc</tt> file generated in their home directory. Each user will also need to have a <tt class= "FILENAME">.Spam</tt> Maildir created for them. For example, to create the Maildir for <span class="SYSTEMITEM">paulh</span>, enter:</p> <pre class="SCREEN"> # su paulh # cd $HOME # /var/qmail/bin/maildirmake Maildir/.Spam # exit </pre> <p>In order to get <span class="APPLICATION">qmail</span> to call <span class="APPLICATION">procmail</span>, each user's <tt class="FILENAME">.qmail</tt> file should contain the following:</p> <pre class="PROGRAMLISTING"> |IFS=' ' && exec /usr/local/bin/procmail -f- || exit 75 </pre> <p>Again, to ensure all new users have this <tt class= "FILENAME">.qmail</tt> created for them, replace the contents of <tt class="FILENAME">/usr/share/skel/dot.qmail</tt> with the line above.</p> <div class="NOTE"> <table class="NOTE" width="100%" border="0"> <tr> <td width="25" align="CENTER" valign="TOP"><img src= "./images/note.gif" hspace="5" alt="Note"></td> <td align="LEFT" valign="TOP"> <p>Installing and running <span class= "APPLICATION">procmail</span> is non-trivial. Read the documentation and the numerous FAQs and How-Tos if you plan to do this.</p> </td> </tr> </table> </div> </div> </div> <div class="SECT1"> <hr> <h1 class="SECT1"><a name="AEN214">4. Installing <span class= "APPLICATION">qmail-scanner</span></a></h1> <div class="SECT2"> <h2 class="SECT2"><a name="AEN217">4.1. Installing <span class= "APPLICATION">maildrop</span></a></h2> <p><span class="APPLICATION">qmail-scanner</span> depends on the <b class="COMMAND">reformime</b> command, available as part of the <span class="APPLICATION">maildrop</span> package. <span class="APPLICATION">maildrop</span> is available in the <span class="SYSTEMITEM">FreeBSD</span> Ports System, and is easily installed:</p> <pre class="SCREEN"> # cd /usr/ports/mail/maildrop # make # make install </pre> </div> <div class="SECT2"> <hr> <h2 class="SECT2"><a name="AEN227">4.2. Installing and building from source</a></h2> <p>There is no <span class="SYSTEMITEM">FreeBSD</span> Port for <span class="APPLICATION">qmail-scanner</span>, so it needs to be built by hand from the source. Firstly, obtain and unpack the source:</p> <pre class="SCREEN"> # cd /usr/local # mkdir qmail-scanner # fetch http://telia.dl.sourceforge.net/sourceforge/qmail-scanner/qmail-scanner-1.14.tgz # gunzip qmail-scanner-1.14.tgz # tar -xvf qmail-scanner-1.14.tar # cd qmail-scanner-1.14 </pre> <p>Now run the configure script in help mode to view the options:</p> <pre class="SCREEN"> # ./configure --help </pre> <p>You may wish to explicitly specify some of the options for which the defaults are unsuitable at your site. For example, you may wish to change <tt class="OPTION">--admin</tt> and <tt class="OPTION">--notify</tt> at a minimum. The run the configure script using your options and the <tt class= "OPTION">--install</tt> option. For example:</p> <pre class="SCREEN"> # ./configure --admin postmaster --notify "recips,admin" --install </pre> <p>You need to set the SUID bit on the <b class= "COMMAND">suidperl</b> command:</p> <pre class="SCREEN"> # chmod 4511 /usr/bin/suidperl </pre> <div class="NOTE"> <table class="NOTE" width="100%" border="0"> <tr> <td width="25" align="CENTER" valign="TOP"><img src= "./images/note.gif" hspace="5" alt="Note"></td> <td align="LEFT" valign="TOP"> <p><span class="emphasis"><i class="EMPHASIS">This may be a security risk.</i></span> You need to evaluate this action based on the security policy at your site. <b class="COMMAND">qmail-scanner</b> will not operate without this change, however.</p> </td> </tr> </table> </div> <p><b class="COMMAND">qmail-smtpd</b> needs to be instructed to use the <b class="COMMAND">qmail-scanner-queue.pl</b> script in <tt class="FILENAME">/var/qmail/bin</tt> instead of the standard <b class="COMMAND">qmail-queue</b> binary. If your site uses <b class="COMMAND">tcpserver</b> to handle connections to <b class= "COMMAND">qmail-smtpd</b> (as described in <a href= "qmail-how-to.html" target="_top">Installing <span class= "APPLICATION">qmail</span> under FreeBSD</a>), <tt class= "FILENAME">/etc/tcp.smtp</tt> should be updated to set the <tt class="ENVAR">QMAILQUEUE</tt> environment variable. The precise contents of this file will vary between sites depending on you LAN configuration. The <tt class="FILENAME">/etc/tcp.smtp</tt> file constructed in <a href="qmail-how-to.html" target= "_top">Installing <span class="APPLICATION">qmail</span> under FreeBSD</a> would be modified as follows:</p> <pre class="PROGRAMLISTING"> 192.168.0.:allow,RELAYCLIENT="",QMAILQUEUE="/var/qmail/bin/qmail-scanner-queue.pl" 127.:allow,RELAYCLIENT="",QMAILQUEUE="/var/qmail/bin/qmail-scanner-queue.pl" :allow,QMAILQUEUE="/var/qmail/bin/qmail-scanner-queue.pl" </pre> <p>Now rebuild the ruleset for <b class= "COMMAND">tcpserver</b>:</p> <pre class="SCREEN"> # /usr/local/bin/tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp </pre> <p>Finally, stop and restart the <span class= "APPLICATION">qmail</span> binaries:</p> <pre class="SCREEN"> # /usr/local/etc/rc.d/qmail.sh stop # /usr/local/etc/rc.d/qmail.sh start </pre> </div> <div class="SECT2"> <hr> <h2 class="SECT2"><a name="AEN268">4.3. Testing the installation</a></h2> <p>The <span class="APPLICATION">qmail-scanner</span> distribution provides a script and some test files containing virus signatures to test the virus scanner. Run these through <span class="APPLICATION">qmail-scanner</span> now:</p> <pre class="SCREEN"> # cd /usr/local/qmail-scanner/qmail-scanner-1.14 # ./contrib/test_installation.sh -doit </pre> <p>This will send three emails to the address you specified as <tt class="OPTION">--admin</tt> during the <span class= "APPLICATION">qmail-scanner</span> installation. The first should arrive unmodified (though it will have an X-Spam-Status: header if you have set up <span class= "APPLICATION">SpamAssassin</span>), but the second and third should be caught by either the internal (simple) virus scanner of <span class="APPLICATION">qmail-scanner</span> or by <span class="APPLICATION">Clam AntiVirus</span>. Email caught by <span class="APPLICATION">qmail-scanner</span> is deposited in <tt class="FILENAME">/var/spool/qmailscan/quarantine</tt> in Maildir format.</p> </div> </div> <div class="APPENDIX"> <hr> <h1 class="APPENDIX"><a name="PERL">A. Fetching and installing Perl modules from CPAN</a></h1> <p>At several points during the installation of the Perl-based applications, <b class="COMMAND">perl</b> may complain about dependencies on packages not present on your system. This is easily solved by installing the packages it requires from CPAN. The easiest way is to use a CPAN shell:</p> <pre class="SCREEN"> # perl -MCPAN -e shell </pre> <p>If you are running the CPAN module for the first time, there may be some setup required — just follow the prompts. When you get the <tt class="PROMPT">cpan></tt> prompt, install the packages required. For example, to install <tt class= "FILENAME">Time::HiRes</tt>, simply enter:</p> <pre class="SCREEN"> cpan> install Time::HiRes </pre> <p>You can instruct the shell to install as many packages as you need in this manner.</p> </div> <div class="APPENDIX"> <hr> <h1 class="APPENDIX"><a name="AEN292">B. Contacting the authors</a></h1> <p>This document was written by <a href= "mailto:paulh@logicsquad.net" target="_top">Paul Hoadley</a> and <a href="mailto:eric@eparsonage.com" target="_top">Eric Parsonage</a>. This document describes what we did to get <span class="APPLICATION">qmail-scanner</span> co-operating with <span class="APPLICATION">Clam AntiVirus</span> and <span class= "APPLICATION">SpamAssassin</span> on two FreeBSD 4.7 systems. Your mileage may vary. If you notice any errors in this document, or your experience with the software used was vastly different, please <a href="mailto:paulh@logicsquad.net" target="_top">let us know</a>.</p> </div> </div> </body> </html>