{"id":229,"date":"2011-06-12T20:18:58","date_gmt":"2011-06-13T03:18:58","guid":{"rendered":"http:\/\/blog.networkpresence.co\/?p=229"},"modified":"2013-03-28T04:03:24","modified_gmt":"2013-03-28T11:03:24","slug":"installing-spamassassin-clamav-with-amavisd-milter-on-sendmail-on-centos-5","status":"publish","type":"post","link":"http:\/\/blog.networkpresence.co\/?p=229","title":{"rendered":"Installing SpamAssassin &#038; ClamAV with Amavisd-milter on Sendmail on CentOS 5"},"content":{"rendered":"<p>I&#8217;ve previously described the install &#038; setup process for <a href=\"http:\/\/blog.networkpresence.co\/?p=211\">spamass-milter on Sendmail<\/a> for Anti-Spam processing.<\/p>\n<p>This blog post describes a different interface to Sendmail for Anti-Spam &#038; Anti-Virus (AS\/AV), using the Amavis daemon (amavisd-new) along with the Milter interface for Amavis to Sendmail.<\/p>\n<p>1. Software Installs<\/p>\n<p>1.0 Pre-Requisites<\/p>\n<p>This requires (at least during this install process) the C compiler, so to install all the pre-req&#8217;s run:<\/p>\n<p><code>yum -y install gcc make sendmail-devel<\/code><\/p>\n<p>1a. Amavisd-Milter<\/p>\n<p>Please DO NOT install the &#8216;amavisd-new-milter&#8217; package in RPMForge, it&#8217;s old &#038; lacks functionality. Please download the source distribution for amavisd-milter from http:\/\/sourceforge.net\/projects\/amavisd-milter\/<br \/>\nThe latest amavisd-milter in early 2011 delivers the file &#8216;amavisd-milter-1.5.0.tar.gz&#8217;, so extract that file &#038; install that software to its default install locations. <\/p>\n<p>Then do the following in the extract amavisd-milter directory:<\/p>\n<p><code>.\/configure<br \/>\nmake install<\/code><\/p>\n<p>Which yields the \/usr\/local\/sbin\/amavisd-milter exacutable &#038; the &#8216;man amavisd-milter&#8217; manual page.<\/p>\n<p>1b. Amavisd itself and its pre-requisites<\/p>\n<p>Run:<br \/>\n<code>yum -y install amavisd-new<\/code><\/p>\n<p>1c. Check that the SpamAssassin &#038; ClamAV packages are installed with:<\/p>\n<p><code>yum -y install clamav clamav-db clamav-milter clamd spamass-milter perl-Mail-SPF sendmail-cf perl-Mail-DKIM<\/code><\/p>\n<p>1d. There are some scanners that aren&#8217;t installed with amavisd-new&#8217;s Yum install, so bring in these decoders:<\/p>\n<p><code>yum -y install tnef unzip lrzip p7zip-plugins<\/code><br \/>\n(updated for CentOS 5.9)<\/p>\n<p>2 Configuring components &#038; Amavisd<\/p>\n<p>2a. See our previously posted SpamAssassin\/ClamAV &#038; Sendmail page for the <a href=\"http:\/\/blog.networkpresence.co\/?p=211\">SpamAssassin &#038; ClamAV setup<\/a>, but the important difference here is that ClamAV (clamd) must be reconfigured to run as the same pid\/user that runs the Amavisd software (amavis username &#038; group).<br \/>\nWe <strong>set the pid &#038; gid of the clamav user in \/etc\/passwd to be the same pid\/gid as the amavis user<\/strong> that&#8217;s installed when using Yum to install the amavisd-new package.<br \/>\nThen you need to chown the ClamAV run &#038; log directories to the new pid\/gid of the clamav user with:<br \/>\n<code>chown -R clamav.amavis \/var\/run\/clamav \/var\/log\/clamav\/ \/var\/clamav\/<\/code><br \/>\nThen restart clamd with:<br \/>\n<code>service clamd restart<\/code><br \/>\nAnd check that it comes up ok with no errors in \/var\/log\/maillog and \/var\/log\/messages<\/p>\n<p>2b. Amavisd-Milter Sysconfig file isn&#8217;t provided, as we&#8217;ve installed it from source, not a pre-build Package, so we need to create the file &#038; I&#8217;ve used the following, from the site http:\/\/users.on.net\/~hilton\/amavisd-milter-sysconfig.txt<\/p>\n<p><code>### \/etc\/sysconfig\/amavisd-milter<br \/>\n### Configuration options for amavisd-milter<br \/>\n### Suitable for Redhat & SuSE systems.<br \/>\n#<br \/>\n#<br \/>\n### Amavisd's homedir.<br \/>\n### This should match the '$MYHOME' directive in amavisd.conf<br \/>\nAMAVISD_HOME=\"\/var\/amavis\"<\/p>\n<p>### Location of milter binary.<br \/>\nMILTER=\"\/usr\/local\/sbin\/amavisd-milter\"<\/p>\n<p>### User that amavisd-milter will run as.<br \/>\n### For RH\/CentOS\/Fedora set to \"amavis\"<br \/>\n### For SuSE set to \"vscan\"<br \/>\nAMAVISD_MILTER_USER=\"amavis\"<\/p>\n<p>### This is the socket used for communication between sendmail <--> milter<br \/>\n### It must correspond to the \"S=\" variable of the milter definition in sendmail.cf<br \/>\n### Note the variable substitution!<br \/>\nMILTER_SOCKET=\"local:$AMAVISD_HOME\/amavisd-milter.sock\"<\/p>\n<p>### This is the socket used for communication between amavisd <--> milter<br \/>\n### It must correspond to the value of \"$unix_socketname\" in amavisd.conf<br \/>\n### Note the variable substitution!<br \/>\nAMAVISD_SOCKET=\"$AMAVISD_HOME\/amavisd.sock\"<\/p>\n<p>### Pid file<br \/>\n### Note the variable substitution!<br \/>\nMILTER_PID=\"$AMAVISD_HOME\/amavisd-milter.pid\"<\/p>\n<p>### All the args to milter<br \/>\nMILTER_FLAGS=\"-s $MILTER_SOCKET -p $MILTER_PID -w $AMAVISD_HOME -S $AMAVISD_SOCKET\"<\/code><\/p>\n<p>2c. Amavisd-Milter init.d file isn&#8217;t provided, as we&#8217;ve installed it from source, not a pre-build Package, so we need to create the file &#038; I&#8217;ve used the following, from the site http:\/\/users.on.net\/~hilton\/amavisd-milter-init.d.txt<\/p>\n<p><code>#!\/bin\/bash<br \/>\n# Init script for Amavisd-Milter.<br \/>\n# Written by Ben Tisdall<br \/>\n# chkconfig: 2345 78 31<br \/>\n# description: Amavisd Milter Interface<br \/>\n# processname: amavisd-milter<\/p>\n<p>### Read in the standard init functions<br \/>\nsource \/etc\/rc.d\/init.d\/functions<\/p>\n<p>### Default variables<br \/>\nAMAVIS_USER=\"amavis\"<br \/>\nMILTER_SOCKET=\"\"<br \/>\nMILTER_FLAGS=\"\"<br \/>\ndesc=\"Amavisd Milter Interface\"<br \/>\nRETVAL=0<br \/>\nSYSCONFIG=\"\/etc\/sysconfig\/amavisd-milter\"<\/p>\n<p>### Read configuration<br \/>\n[ -r \"$SYSCONFIG\" ] && source \"$SYSCONFIG\"<\/p>\n<p>### MILTER set in \/etc\/sysconfig\/amavisd<br \/>\nprog=\"${MILTER##*\/}\"<br \/>\nprogdir=\"${MILTER%\/*}\"<\/p>\n<p>### Check we have the milter<br \/>\nif ! [ -x $progdir\/$prog ]; then<br \/>\n        echo -e \"\\nFATAL ERROR: $progdir\/$prog not found and\/or not executable, please check your installation.\\n\"<br \/>\nexit 1<br \/>\nfi<\/p>\n<p>### Functions<br \/>\nstart() {<br \/>\n                if [ \"$MILTER_SOCKET\" -a -x \"$progdir\/$prog\" ]; then<br \/>\n                        echo -n $\"Starting $desc ($prog): \"<br \/>\n                        daemon --user \"$AMAVIS_USER\" $progdir\/$prog \"$MILTER_FLAGS\"<br \/>\n                        RETVAL=$?<br \/>\n                        echo<br \/>\n                        if [ $RETVAL -eq 0  -a -n \"$MILTER_PID\" -a ! -L \"\/var\/run\/${MILTER_PID##*\/}\" ]; then<br \/>\n                                ln -s \"$MILTER_PID\" \"\/var\/run\/${MILTER_PID##*\/}\"<br \/>\n                                touch \/var\/lock\/subsys\/$prog<br \/>\n                        fi<br \/>\n                fi<br \/>\n}<\/p>\n<p>stop() {<br \/>\n        if [ \"$MILTER_SOCKET\" -o -f \/var\/lock\/subsys\/$prog ]; then<br \/>\n                echo -n $\"Shutting down $desc ($prog): \"<br \/>\n                killproc $prog<br \/>\n                RETVAL=$?<br \/>\n                echo<br \/>\n                [ $RETVAL -eq 0 ] && rm -f \/var\/lock\/subsys\/$prog<br \/>\n        fi<br \/>\n        return $RETVAL<br \/>\n}<\/p>\n<p>reload() {<br \/>\n        echo -n $\"Reloading $desc ($prog): \"<br \/>\n        killproc -HUP $prog<br \/>\n        RETVAL=$?<br \/>\n        echo<br \/>\n        return $RETVAL<br \/>\n}<\/p>\n<p>restart() {<br \/>\n        stop<br \/>\n        start<br \/>\n}<\/p>\n<p>case \"$1\" in<br \/>\n  start)<br \/>\n        start<br \/>\n        ;;<br \/>\n  stop)<br \/>\n        stop<br \/>\n        ;;<br \/>\n  restart)<br \/>\n        restart<br \/>\n        ;;<br \/>\n  reload)<br \/>\n        restart<br \/>\n        ;;<br \/>\n  condrestart)<br \/>\n        [ -e \/var\/lock\/subsys\/$prog ] && restart<br \/>\n        RETVAL=$?<br \/>\n        ;;<br \/>\n  status)<br \/>\n        status $prog<br \/>\n        status $prog<br \/>\n        RETVAL=$?<br \/>\n        ;;<br \/>\n  *)<br \/>\n        echo $\"Usage: $0 {start|stop|restart|reload|condrestart|status}\"<br \/>\n        RETVAL=1<br \/>\nesac<\/p>\n<p>exit $RETVAL<\/code><\/p>\n<p>Download those two text files &#038; copy them to the relevant system files with the commands:<\/p>\n<p>Install amavisd-milter sysconfig script:<\/p>\n<p><code>wget http:\/\/users.on.net\/~hilton\/amavisd-milter-sysconfig.txt<br \/>\nmv amavisd-milter-sysconfig.txt \/etc\/sysconfig\/amavisd-milter<\/code><\/p>\n<p>Install amavisd-milter init.d script:<\/p>\n<p><code>wget http:\/\/users.on.net\/~hilton\/amavisd-milter-init.d.txt<br \/>\nmv amavisd-milter-init.d.txt \/etc\/init.d\/amavisd-milter<br \/>\nchmod u+x \/etc\/init.d\/amavisd-milter<br \/>\nchkconfig --add amavisd-milter<\/code><\/p>\n<p>2d. Configuring Amavis<\/p>\n<p>Amavis config file is \/etc\/amavisd.conf and it&#8217;s a large text config file, but the relevant settings to check\/set are:<\/p>\n<p><code>$protocol = \"AM.PDP\"; # Use AM.PDP protocol.<br \/>\n$unix_socketname = \"$MYHOME\/amavisd.sock\"; # uncomment when using milter.<br \/>\n#$inet_socket_port = 10024; #comment out with milter.<br \/>\n$notify_method = 'pipe:flags=q argv=\/usr\/sbin\/sendmail -Ac -i -odd -f ${sender} -- ${recipient}';<br \/>\n$forward_method = undef; #must be set like this with sendmail milter.<br \/>\n$mydomain = \"example.com\" #Your domain<br \/>\n$myhostname = \"mail.example.com\"; #The FQDN of your Mail Server host<br \/>\n$virus_admin = \"root\\@$mydomain\"; #NDR recipient if virus found<br \/>\n$mailfrom_notify_admin = \"virusalert\\@$mydomain\"; #NDR --> admin sender<\/code><\/p>\n<p>Then the following affect the inclusion of mail message headers about the Amavis activity:<\/p>\n<p><code>$sa_tag_level_deflt  = -9999; # add spam info headers if at, or above that level<br \/>\n$sa_tag2_level_deflt = 3.4; # add 'spam detected' headers at that level<br \/>\n#sa_kill_level_deflt = 6.31; # triggers spam evasive actions<br \/>\n#sa_dsn_cutoff_level = 9; # spam level beyond which a DSN is not sent<br \/>\n#$sa_quarantine_cutoff_level = 20; # spam level beyond which quarantine is off<br \/>\n$sa_spam_subject_tag = '[SPAM] '; # Prepended to the subject line if defined.<\/code><\/p>\n<p>2e. Create the &#8216;virusalert@yourdomain&#8217; email address or alias, enter the following to \/etc\/aliases &#038; run &#8216;newaliases&#8217;<br \/>\n<code>virusalert:     root<br \/>\nspam-police:    root<\/code><\/p>\n<p>2f. Setting domains which will be passed to Scanners<br \/>\nAmavis (Amavisd-New) only hands of messages which are deemed able to be &#8216;locally delivered&#8217; by Sendmail, but you can include domains for SA (SpamAssassin) processing by loading them to the @local_domains_maps variable in <strong>\/etc\/amavisd.conf<\/strong>, which by default is set to the value of $mydomain &#038; its subdomains:<\/p>\n<p><code>@local_domains_maps = ( [\".$mydomain\", \".foo.com\"] );<\/code><\/p>\n<p>You may want to list in @local_domains_maps all hosts &#038; domain names that you have in \/etc\/mail\/local-host-names &#038; \/etc\/mail\/relay-domains<\/p>\n<p>2g. Further down in the amavisd.conf file you need to enable the ClamAV sections and set the \/var\/run\/clamav\/clamd.sock file (matching the value in \/etc\/clamd.conf)<\/p>\n<p><code>['ClamAV-clamd',<br \/>\n  \\&ask_daemon, [\"CONTSCAN {}\\n\", \"\/var\/run\/clamav\/clamd.sock\"],<br \/>\n  qr\/\\bOK$\/m, qr\/\\bFOUND$\/m,<br \/>\n  qr\/^.*?: (?!Infected Archive)(.*) FOUND$\/m ],<\/code><\/p>\n<p>Now save all these edits to \/etc\/amavisd.conf<\/p>\n<p>2h. Set relevant entry in \/etc\/sysconfig\/amavisd<\/p>\n<p><code>AMAVIS_SENDMAIL_MILTER=\"no\"<\/code><\/p>\n<p>2i. Sendmail configs to enable use of Amavis-Milter<\/p>\n<p>Add the following MILTER definition to \/etc\/mail\/sendmail.mc &#038; remove any\/all other Milter definitions (eg: remove clamav &#038; spamass milter entries in sendmail.mc<\/p>\n<p><code>define(`MILTER', 1)dnl<br \/>\nINPUT_MAIL_FILTER(`milter-amavis', `S=local:\/var\/amavis\/amavisd-milter.sock, F=T, T=S:10m;R:10m;E:10m')dnl<\/code><\/p>\n<p>If you want your Sendmail server to be available on port 25 (SMTP), then also ensure:<\/p>\n<p><code>DAEMON_OPTIONS(`Port=smtp, Name=MTA')dnl<\/code><\/p>\n<p>Then save that update &#038; recreate the sendmail.cf &#038; submit.cf files by running<\/p>\n<p><code>make<\/code><\/p>\n<p>in \/etc\/mail, then restart sendmail (when ready) with<\/p>\n<p><code>service sendmail restart<\/code><\/p>\n<p>3. Start daemons up &#038; monitor \/var\/log\/maillog for their logging<\/p>\n<p><code>service sendmail restart<br \/>\nservice amavisd start<br \/>\nservice amavisd-milter start<br \/>\nservice clamd restart<\/code><\/p>\n<p>4. Test \/ Check<\/p>\n<p>4a. Send an email through the server, either with manual &#8220;telnet your-mail-server 25&#8221; or such.<\/p>\n<p>4b. Monitor \/var\/log\/maillog<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve previously described the install &#038; setup process for spamass-milter on Sendmail for Anti-Spam processing. This blog post describes a different interface to Sendmail for Anti-Spam &#038; Anti-Virus (AS\/AV), using the Amavis daemon (amavisd-new) along with the Milter interface for &hellip; <a href=\"http:\/\/blog.networkpresence.co\/?p=229\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[45,44,18,42,43,78],"class_list":["post-229","post","type-post","status-publish","format-standard","hentry","category-network-presence","tag-amavisd-new","tag-clamav","tag-linux","tag-sendmail","tag-spamassassin","tag-sysadmin"],"_links":{"self":[{"href":"http:\/\/blog.networkpresence.co\/index.php?rest_route=\/wp\/v2\/posts\/229","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.networkpresence.co\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.networkpresence.co\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.networkpresence.co\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.networkpresence.co\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=229"}],"version-history":[{"count":12,"href":"http:\/\/blog.networkpresence.co\/index.php?rest_route=\/wp\/v2\/posts\/229\/revisions"}],"predecessor-version":[{"id":3178,"href":"http:\/\/blog.networkpresence.co\/index.php?rest_route=\/wp\/v2\/posts\/229\/revisions\/3178"}],"wp:attachment":[{"href":"http:\/\/blog.networkpresence.co\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=229"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.networkpresence.co\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=229"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.networkpresence.co\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=229"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}