Email Gateway
Views:
Contents |
Introduction
See also Email Server for a Virtual Domain, Virtual Users email server with Postfix, Courier Imap, web mail and anti-spam
Back in April 2007, we needed to split out email accounts across two email servers. We also had real issues with spam. The solution was to create an Email Gateway that could handle all incoming email for the @varndean.ac.uk domain, filter our spam and viruses and then route the mail on to the appropriate internal email server.
We had two Novell Netware servers running Groupwise and Netmail and also a Linux server that was tasked with Web and DNS hosting. All of the user account and email address information was stored in Novell eDirectory and was available through a Novell LDAP server.
It was an easy choice to build the email gateway stack on the linux server. We used postfix, amavisd-new, spamassassin, clamav and some cunning scripts to make it all work.
What you see here should translate easily to any number of servers where the account information is stored in LDAP. In fact, with the scripts we've used, it really doesn't matter where the account information is held.
The software used in the internal email servers doesn't matter so long as they know how to talk SMTP.
Servers
ares.varndean.ac.uk
- The email gateway
- OES/Linux server
- Postfix email service
- Anti-virus and anti-spam
- 212.219.118.91
Permissions
FileSystem
Most of the file system is locked down to root, postfix, amavis, and vscan
The following are owned by the it-sup group, who are allowed write access.
- /etc/amavisd.conf
- /etc/postfix
- /var/lib/amavis
- /var/lib/amavis-quarantine
sudo
The following are available to run with the sudo command (to get root permissions)
- sudo /etc/init.d/postfix
- sudo /etc/init.d/amavisd
- sudo /usr/local/sbin/amavisd
- sudo /usr/local/sbin/amavisd-release
- sudo /usr/sbin/postfix
- sudo /usr/sbin/postmap
Postfix
- default mta for ares, also handles local mail
- Installed from YAST, updated via rug
- /etc/postfix/main.cf:
- relay_domains = varndean.ac.uk
- transport_maps = hash:/etc/postfix/transport
- relay_recipient_maps = hash:/etc/postfix/transport, hash:/etc/postfix/aliases, hash:/etc/postfix/groups
- trusted_network = 127.0.0.0/8, 212.219.118.80/28
- smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination
- inet_iterfaces = all
- mynetworks_style = subnet
- virtual_alias_maps = hash:/etc/postfix/aliases, hash:/etc/postfix/groups
- /etc/postfix/master.cf - changes shown further down this page
- /etx/postfix/aliases
- /var/log/mail
- /var/log/mail.err
- /var/log/mail.warn
The /etc/postfix/aliases file is used to define aliases and groups, the format is:
# /etc/postfix/aliases office@varndean.ac.uk mainoffice@varndean.ac.uk # /etc/postfix/groups justAnAddress@varndean.ac.uk theRealMailBox@varndean.ac.uk, someOneElseAswell@varndean.ac.uk
The groups file is updated programmatically - groups are defined in eDirectory email.internet.vsfc.
The alias file needs to be updated manually
Every time the aliases or groups files are updated the following commands must be run to update postfix
$ sudo postmap /etc/postfix/aliases $ sudo postmap /etc/postfix/groups $ sudo postfix reload
The transport map is a text file listing pairs of email addresses and corresponding email servers. The basic format is:
groupwiseuser@varndean.ac.uk relay:[caan.varndean.ac.uk] kjw@varndean.ac.uk relay:[caan.varndean.ac.uk] netmailuser@varndean.ac.uk relay:[artemis.varndean.ac.uk] 12345@student.varndean.ac.uk relay:[artemis.varndean.ac.uk] ac@varndean.ac.uk relay:[artemis.varndean.ac.uk]
The /etc/postfix/transport text file is used to generate a hash table (a binary file used by postfix because it is faster to scan than a text file). Each time the text version of the file is updated the postmap command must be used to update the hash table, then postfix must be reloaded to notice the changes.
$ sudo postmap /etc/postfix/transport $ sudo postfix reload
Any entry in the transport map is required for each and every email account used at the college. To ease the pain and make sure we don't miss any one, the contents of the transport map is generated automatically via some scripts and a cron job.
#!/bin/bash
#######################################################
#######################################################
## I am /etc/cron.hourly/check_postfix_transport_map ##
## I coordinate checking the postfix transport map ##
## is up to date ##
#######################################################
#######################################################
#############
# Settings: #
#############
transport_map=/etc/postfix/transport
transport_generator=/usr/local/bin/generate_postfix_transport_map
tmpfile=/tmp/transport_map.auto
# Message Settings: #
from=postmaster@varndean.ac.uk
recipient=isdept@varndean.ac.uk
subject="Varndean Email Gateway - Transport Map Needs Attention"
default_error_message="There was an error checking the postfix transport map, please
check the scripts. (Details on isWiki, or start looking at
ares:/$0)"
#######################################################
#KEEP OUT!#############################################
#######################################################
#######################################################
message_date=`date +"%a, %e %b %Y %T %z"`
boundary=GvXjxJ+pjyke8COw
message_headers=$(cat <<EOT
Date: $message_date
From: $from
To: $recipient
Subject: $subject
Content-Type:
EOT)
function delete_tmpfile()
{
# Is the temporary file there? Delete it
if [ -e "$tmpfile" ]
then
rm "$tmpfile"
fi
}
function send_emails()
{
# Send an email to each of the recipients defined in the
# settings section above. Bail out if we get a failure,
# other wise just allow the function to return
error_level=0
echo "$message_headers$message" | sendmail -t
if [ $? -ne 0 ]
then
error_level=1
fi
if [ $error_level -eq 1 ]
then
exit 1
fi
}
delete_tmpfile
# Does the directory for the temporary file exist? Can we write to it?
if [ ! -d $(basename "$tmpfile") ] || [ -w $(basename "$tmpfile") ]
then
message=$(cat <<EOT
text/plain; charset=utf-8
*$subject*
*Unable to create temporary file*
$default_error_message
EOT)
send_emails
exit 2
fi
# Output a new transport map to a tempory file, check it
# worked OK or send an error message
$transport_generator > $tmpfile
if [ $? -ne 0 ]
then
message=$(cat <<EOT
text/plain; charset=utf-8
*$subject*
*Transport Generator Failed*
$default_error_message
EOT)
send_emails
delete_tmpfile
exit 3
fi
# Compare the new transport map to the existing (live)
# one, if diff returns text, send a message
transport_diffs=`/usr/bin/diff $transport_map $tmpfile`
if [ "$transport_diffs" != "" ]
then
message=$(cat <<EOT
multipart/mixed; boundary="$boundary"
Content-Disposition: inline
--$boundary
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
*$subject*
The system has detected that the attached changes are required
in the ares:/etc/postfix/transport transport map file
Please edit the file carefully then make absolutely certain to
run the two following commands
# postmap /etc/postfix/transport
# postfix reload
An explaination of our email gateway can be found on the isWiki
--$boundary
Content-Type: text/plain; charset=utf-8
Content-Disposition: attachment; filename="transport.diff"
$transport_diffs
--$boundary--
EOT)
send_emails
delete_tmpfile
exit 0
fi
exit 5
The php script used to generate the transport map;
#!/usr/bin/env php
<?php
// I am /usr/local/bin/generate_postfix_transport_map
ini_set('error_log', '/var/log/php_postfix_errors');
ini_set('display_errors', 0);
ini_set('error_reporting', E_ALL);
define('GROUPWISE_MAP', 'relay:[polymorph.main.varndean.ac.uk]');
define('NETMAIL_MAP', 'relay:[artemis.varndean.ac.uk]');
$connection = ldap_connect('ldap.varndean.ac.uk');
$transport_map = array();
if (!$connection)
{
error_log('Could not connect to an ldap server, whats up with you idiots?!', 0);
}
$binding = ldap_bind($connection);
if (!$binding)
{
error_log('Could not bind to the ldap server', 0);
}
$users = ldap_search($connection, 'o=vsfc', 'objectClass=user', array('nGWObjectID', 'mail'));
if ($users)
{
$user = ldap_first_entry($connection, $users);
while ($user)
{
$user_details = ldap_get_attributes($connection, $user);
if ($user_details['mail'] && $user_details['mail'][0] && trim($user_details['mail'][0]) && stristr($user_details['mail'][0], 'varndean.ac.uk'))
{
$user_transport_map = str_pad(trim($user_details['mail'][0]), 50);
if (strlen($user_transport_map) >= 50) $user_transport_map .= ' ';
if ($user_details['ngwobjectid'][0])
{
$user_transport_map .= GROUPWISE_MAP;
}
else
{
$user_transport_map .= NETMAIL_MAP;
}
$transport_map[] = $user_transport_map;
}
$user = ldap_next_entry($connection, $user);
}
sort($transport_map);
foreach ($transport_map as $user_transport_map)
{
echo $user_transport_map."\n";
}
}
else
{
error_log('No users found when searching the tree! Panic! Some one\'s eaten them!', 0);
}
?>
The cron job which controls updating the groups:
#!/bin/bash
##############################################################
# I am /etc/cron.hourly/update_postfix_groups #
# I update the /etc/postfix/groups file then restart postfix #
##############################################################
# SETTINGS:
subject="*Varndean Email Gateway - Group Maps Need Attention*"
recipient=postfixadmins@varndean.ac.uk
from=postmaster@varndean.ac.uk
footer="Details of the Email Gateway can be found on the isWiki"
##############################################################
# KEEP OUT! ##################################################
##############################################################
##############################################################
retval=0
cp -p /etc/postfix/groups /etc/postfix/groups.auto.backup
cp -p /etc/postfix/groups.db /etc/postfix/groups.db.auto.backup
/usr/local/bin/generate_postfix_groups > /etc/postfix/groups
filesize=`du -b -0 /etc/postfix/groups|cut -f 1`
`/usr/sbin/postmap /etc/postfix/groups 2>&1 >/dev/null` > /dev/null
if [[ $? -eq 0 && $filesize -ne 0 ]]
then
`/usr/sbin/postfix check 2>&1 >/dev/null` > /dev/null
if [ $? -ne 0 ]
then
message=$(cat << EOT
$subject
The postfix configuration has not passed sanity checks.
Please investigate configuration issues and run
sudo /usr/sbin/postfix check && /usr/postfix/reload
$footer
EOT)
retval=1
else
`/usr/sbin/postfix reload 2>&1 >/dev/null` > /dev/null
if [ $? -ne 0 ]
then
$message=$(cat <<EOT
$subject
There was an error reloading the postfix configuration,
please investigate.
$footer
EOT)
retval=2
fi
fi
else
cp -p /etc/postfix/groups.db.auto.backup /etc/postfix/groups.db
cp -p /etc/postfix/groups.auto.backup /etc/postfix/groups
message=$(cat <<EOT
$subject
Failed to update ares:/etc/postfix/groups safely
Please investigate - users might not be receiving
group email
Please look at ares:$0
$footer
EOT)
retval=3
fi
if [ $retval -ne 0 ]
then
echo $message | mail -s "$subject" -r "$sender" "$recipient"
fi
exit $retval
The php script used to generate the groups map:
#!/usr/bin/env php
<?php
// I am /usr/local/bin/generate_postfix_groups
ini_set('error_log', '/var/log/php_postfix_errors');
ini_set('display_errors', 0);
ini_set('error_reporting', E_ALL);
$connection = ldap_connect('ldap.varndean.ac.uk');
if (!$connection)
{
error_log('Could not connect to an ldap server, whats up with you idiots?!', 0);
}
$binding = ldap_bind($connection);
if (!$binding)
{
error_log('Could not bind to the ldap server', 0);
}
$group_members = array();
$groups = ldap_search($connection, 'ou=email,ou=internet,o=vsfc', 'objectClass=groupOfNames', array('cn', 'member'));
if ($groups)
{
$group = ldap_first_entry($connection, $groups);
$group_maps = array();
while ($group)
{
$group_details = ldap_get_attributes($connection, $group);
if (isset($group_details['member']) && isset($group_details['member'][0]))
{
$alias = str_pad($group_details['cn'][0].'@varndean.ac.uk', 50);
if (strlen($group_details['cn'][0].'@varndean.ac.uk') >= 50) $alias .= ' ';
$targets = array();
foreach ($group_details['member'] as $key => $member)
{
// the first element in the array is the 'count' element, containing the number
// of entries in the list. A bit redundant and out of place really, so lets skip
// it!
if ($key === 'count') continue;
$user = ldap_read($connection, $member, 'objectClass=*', array('mail'));
if ($user)
{
$user_details = ldap_get_entries($connection, $user);
if ($user_details && isset($user_details[0]) && isset($user_details[0]['mail']) && isset($user_details[0]['mail'][0]) && trim($user_details[0]['mail'][0]) && stristr($user_details[0]['mail'][0], 'varndean.ac.uk'))
{
$targets[] = $user_details[0]['mail'][0];
}
}
}
if ($targets)
{
sort($targets);
$group_maps[] = $alias.join($targets, str_pad(",\n", 52));
}
}
$group = ldap_next_entry($connection, $group);
}
sort($group_maps);
foreach ($group_maps as $group_map)
{
echo $group_map."\n";
}
}
else
{
error_log('No groups found when searching the tree! Panic! Some one\'s eaten them!', 0);
}
?>
Postfix Daemons /etc/postfix/master.cf - two new entries for Amavisd-new, one is the postfix->amavisd-new daemon and the other is for mail coming back in to postfix
smtp-amavis unix - - n - 2 smtp
-o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes
-o disable_dns_lookups=yes
-o max_use=20
127.0.0.1:10025 inet n - n - - smtpd
-o content_filter=
-o smtpd_restriction_classes=
-o smtpd_delay_reject=no
-o smtpd_client_restrictions=permit_mynetworks,reject
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o smtpd_data_restrictions=reject_unauth_pipelining
-o smtpd_end_of_data_restrictions=
-o mynetworks=127.0.0.0/8
-o smtpd_error_sleep_time=0
-o smtpd_soft_error_limit=1001
-o smtpd_hard_error_limit=1000
-o smtpd_client_connection_count_limit=0
-o smtpd_client_connection_rate_limit=0
-o smtpd_milters=
-o local_header_rewrite_clients=
-o local_recipient_maps=
-o relay_recipient_maps=
-o receive_override_options=no_header_body_checks,no_unknown_recipient_checks
Amavisd-new
- Passes mail to SpamAssassin and ClamAV (Perl VooDoo and the filesystem)
- Communites with postfix via two daemon entries in /etc/postfix/master.cf, one for in bound the other for outbound
- user amavis; group amavis
- /var/lib/amavis
- /var/lib/amavisd-quarantine
- /etc/amavisd.conf
- /var/log/mail
- /var/log/mail.err
- /var/log/mail.warn
- sudo /etc/init.d/amavisd
- sudo /usr/local/sbin/amavisd-release # release quarantined email
- NOTE: Take care with names! Amavisd-new is not the same as amavis or amavisd (this code was forked about 3 or 4 years ago and apparantly no longer bears any resemblence to it's ancestors)
init script:
#!/bin/sh
#/etc/init.d/amavisd
prog="/usr/local/sbin/amavisd"
prog_base="$(basename ${prog})"
niceness=19
RETVAL=0
case "$1" in
start)
echo "Starting ${prog_base}:" `nice -n $niceness ${prog}`
RETVAL=$?
;;
stop)
echo "Shutting down ${prog_base}:" `${prog} stop`
RETVAL=$?
echo
;;
restart)
$0 stop
$0 start
RETVAL=$?
;;
reload)
echo "Reloading ${prog_base}:" `nice -n $niceness ${prog} reload`
RETVAL=$?
;;
*)
echo "Usage: $0 {start|stop|restart|reload}"
exit 1
esac
exit $RETVAL
symlinks for init script
# ln -s /etc/init.d/amavisd /etc/init.d/rc3.d/S18amavisd # ln -s /etc/init.d/amavisd /etc/init.d/rc3.d/K06amavisd # ln -s /etc/init.d/amavisd /etc/init.d/rc5.d/S18amavisd # ln -s /etc/init.d/amavisd /etc/init.d/rc5.d/K06amavisd
Config File (sans comments), a basic first attempt that will need tuning over time.
use strict;
$max_servers = 3; # num of pre-forked children (2..15 is common), -m
$daemon_user = 'amavis'; # (no default; customary: vscan or amavis), -u
$daemon_group = 'amavis'; # (no default; customary: vscan or amavis), -g
$mydomain = 'varndean.ac.uk'; # a convenient default for other settings
$MYHOME = '/var/lib/amavis'; # a convenient default for other settings, -H
$TEMPBASE = "$MYHOME/tmp"; # working directory, needs to exist, -T
$ENV{TMPDIR} = $TEMPBASE; # environment variable TMPDIR
$QUARANTINEDIR = '/var/lib/amavis-quarantine'; # -Q
$db_home = "$MYHOME/db"; # dir for bdb nanny/cache/snmp databases, -D
$helpers_home = "$MYHOME/var"; # working directory for SpamAssassin, -S
$lock_file = "$MYHOME/var/amavisd.lock"; # -L
$pid_file = "$MYHOME/var/amavisd.pid"; # -P
@local_domains_maps = ( [".$mydomain"] );
$log_level = 2; # verbosity 0..5, -d
$log_recip_templ = undef; # disable by-recipient level-0 log entries
$DO_SYSLOG = 1; # log via syslogd (preferred)
$syslog_facility = 'mail'; # Syslog facility as a string
$syslog_priority = 'debug'; # Syslog base (minimal) priority as a string,
$enable_db = 1; # enable use of BerkeleyDB/libdb (SNMP and nanny)
$enable_global_cache = 1; # enable use of libdb-based cache if $enable_db=1
$inet_socket_port = 10024; # listen on this local TCP port(s) (see $protocol)
$unix_socketname = "$MYHOME/amavisd.sock"; # amavisd-release or amavis-milter
$interface_policy{'SOCK'}='AM.PDP-SOCK'; # only relevant with $unix_socketname
$policy_bank{'AM.PDP-SOCK'} = { protocol=>'AM.PDP' };
$sa_tag_level_deflt = undef; # add spam info headers if at, or above that level
$sa_tag2_level_deflt = 5; #6.31; # add 'spam detected' headers at that level
$sa_kill_level_deflt = 7; #6.31; # triggers spam evasive actions
$sa_dsn_cutoff_level = 12; # spam level beyond which a DSN is not sent
$sa_quarantine_cutoff_level = 20; # spam level beyond which quarantine is off
$sa_mail_body_size_limit = 1024000; # don't waste time on SA if mail is larger
$sa_local_tests_only = 0; # only tests which do not require internet access?
$virus_admin = "postmaster\@$mydomain"; # notifications recip.
$mailfrom_notify_admin = "postmaster\@$mydomain"; # notifications sender
$mailfrom_notify_recip = "postmaster\@$mydomain"; # notifications sender
$mailfrom_notify_spamadmin = "spam.police\@$mydomain"; # notifications sender
$mailfrom_to_quarantine = ''; # null return path; uses original sender if undef
@addr_extension_virus_maps = ('virus');
@addr_extension_banned_maps = ('banned');
@addr_extension_spam_maps = ('spam');
@addr_extension_bad_header_maps = ('badh');
$path = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/sbin:/usr/bin:/bin';
$MAXLEVELS = 14;
$MAXFILES = 1500;
$MIN_EXPANSION_QUOTA = 100*1024; # bytes (default undef, not enforced)
$MAX_EXPANSION_QUOTA = 300*1024*1024; # bytes (default undef, not enforced)
$sa_spam_subject_tag = '***SPAM*** ';
$defang_virus = 1; # MIME-wrap passed infected mail
$defang_banned = 1; # MIME-wrap passed mail containing banned name
$defang_by_ccat{+CC_BADH.",3"} = 1; # NUL or CR character in header
$defang_by_ccat{+CC_BADH.",5"} = 1; # header line longer than 998 characters
$defang_by_ccat{+CC_BADH.",6"} = 1; # header field syntax error
$myhostname = 'ares.varndean.ac.uk'; # must be a fully-qualified domain name!
$notify_method = 'smtp:[127.0.0.1]:10025';
$forward_method = 'smtp:[127.0.0.1]:10025'; # set to undef with milter!
$final_virus_destiny = D_DISCARD;
$virus_quarantine_to = 'virus';
$final_banned_destiny = D_BOUNCE;
$final_spam_destiny = D_BOUNCE;
$final_bad_header_destiny = D_PASS;
@keep_decoded_original_maps = (new_RE(
qr'^MAIL-UNDECIPHERABLE$', # recheck full mail if it contains undecipherables
qr'^(ASCII(?! cpio)|text|uuencoded|xxencoded|binhex)'i,
));
$banned_filename_re = new_RE(
qr'^\.(exe|lha|tnef|cab|dll)$', # banned file(1) types
[ qr'^\.(rpm|cpio|tar)$' => 0 ], # allow any in Unix-type archives
qr'.\.(pif|scr)$'i, # banned extensions - rudimentary
qr'^application/x-msdownload$'i, # block these MIME types
qr'^application/x-msdos-program$'i,
qr'^application/hta$'i,
qr'\.[^./]*[A-Za-z][^./]*\.\s*(exe|vbs|pif|scr|bat|cmd|com|cpl|dll)[.\s]*$'i,
qr'.\.(ade|adp|app|bas|bat|chm|cmd|com|cpl|crt|emf|exe|fxp|grp|hlp|hta|inf|ins|isp|js|jse|lnk|mda|mdb|mde|mdw|mdt|mdz|msc|msi|msp|mst|ops|pcd|pif|prg|reg|scr|sct|shb|shs|vb|vbe|vbs|wmf|wsc|wsf|wsh)$'ix, # banned ext - long
);
@score_sender_maps = ({ # a by-recipient hash lookup table,
'.' => [ # the _first_ matching sender determines the score boost
new_RE( # regexp-type lookup table, just happens to be all soft-blacklist
[qr'^(bulkmail|offers|cheapbenefits|earnmoney|foryou)@'i => 5.0],
[qr'^(greatcasino|investments|lose_weight_today|market\.alert)@'i=> 5.0],
[qr'^(money2you|MyGreenCard|new\.tld\.registry|opt-out|opt-in)@'i=> 5.0],
[qr'^(optin|saveonlsmoking2002k|specialoffer|specialoffers)@'i => 5.0],
[qr'^(stockalert|stopsnoring|wantsome|workathome|yesitsfree)@'i => 5.0],
[qr'^(your_friend|greatoffers)@'i => 5.0],
[qr'^(inkjetplanet|marketopt|MakeMoney)\d*@'i => 5.0],
),
{ # a hash-type lookup table (associative array)
'nobody@cert.org' => -3.0,
'cert-advisory@us-cert.gov' => -3.0,
'owner-alert@iss.net' => -3.0,
'slashdot@slashdot.org' => -3.0,
'securityfocus.com' => -3.0,
'ntbugtraq@listserv.ntbugtraq.com' => -3.0,
'security-alerts@linuxsecurity.com' => -3.0,
'mailman-announce-admin@python.org' => -3.0,
'amavis-user-admin@lists.sourceforge.net'=> -3.0,
'amavis-user-bounces@lists.sourceforge.net' => -3.0,
'spamassassin.apache.org' => -3.0,
'notification-return@lists.sophos.com' => -3.0,
'owner-postfix-users@postfix.org' => -3.0,
'owner-postfix-announce@postfix.org' => -3.0,
'owner-sendmail-announce@lists.sendmail.org' => -3.0,
'sendmail-announce-request@lists.sendmail.org' => -3.0,
'donotreply@sendmail.org' => -3.0,
'ca+envelope@sendmail.org' => -3.0,
'noreply@freshmeat.net' => -3.0,
'owner-technews@postel.acm.org' => -3.0,
'ietf-123-owner@loki.ietf.org' => -3.0,
'cvs-commits-list-admin@gnome.org' => -3.0,
'rt-users-admin@lists.fsck.com' => -3.0,
'clp-request@comp.nus.edu.sg' => -3.0,
'surveys-errors@lists.nua.ie' => -3.0,
'emailnews@genomeweb.com' => -5.0,
'yahoo-dev-null@yahoo-inc.com' => -3.0,
'returns.groups.yahoo.com' => -3.0,
'clusternews@linuxnetworx.com' => -3.0,
lc('lvs-users-admin@LinuxVirtualServer.org') => -3.0,
lc('owner-textbreakingnews@CNNIMAIL12.CNN.COM') => -5.0,
'sender@example.net' => 3.0,
'.example.net' => 1.0,
},
], # end of site-wide tables:wq
});
@decoders = (
['mail', \&do_mime_decode],
['asc', \&do_ascii],
['uue', \&do_ascii],
['hqx', \&do_ascii],
['ync', \&do_ascii],
['F', \&do_uncompress, ['unfreeze','freeze -d','melt','fcat'] ],
['Z', \&do_uncompress, ['uncompress','gzip -d','zcat'] ],
['gz', \&do_uncompress, 'gzip -d'],
['gz', \&do_gunzip],
['bz2', \&do_uncompress, 'bzip2 -d'],
['lzo', \&do_uncompress, 'lzop -d'],
['rpm', \&do_uncompress, ['rpm2cpio.pl','rpm2cpio'] ],
['cpio', \&do_pax_cpio, ['pax','gcpio','cpio'] ],
['tar', \&do_pax_cpio, ['pax','gcpio','cpio'] ],
['tar', \&do_tar],
['deb', \&do_ar, 'ar'],
['zip', \&do_unzip],
['rar', \&do_unrar, ['rar','unrar'] ],
['arj', \&do_unarj, ['arj','unarj'] ],
['arc', \&do_arc, ['nomarch','arc'] ],
['zoo', \&do_zoo, ['zoo','unzoo'] ],
['lha', \&do_lha, 'lha'],
['doc', \&do_ole, 'ripole'],
['cab', \&do_cabextract, 'cabextract'],
['tnef', \&do_tnef_ext, 'tnef'],
['tnef', \&do_tnef],
['exe', \&do_executable, ['rar','unrar'], 'lha', ['arj','unarj'] ],
);
@av_scanners = (
['ClamAV-clamd',
\&ask_daemon, ["CONTSCAN {}\n", "/var/lib/clamav/clamd-socket"],
qr/\bOK$/, qr/\bFOUND$/,
qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],
);
@av_scanners_backup = (
['ClamAV-clamscan', 'clamscan',
"--stdout --no-summary -r --tempdir=$TEMPBASE {}",
[0], qr/:.*\sFOUND$/, qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],
);
1; # insure a defined return
There are a lot of useless comments! Trust me ;-) You can this to clean them out before updating this page
cat /etc/amavisd.conf | sed -e 's/^ *#.*$//g' -e '/^ *$/d'
SpamAssassin
- Bayesian filter
- Installed via YAST - however an additional perl module was needed, see below
- The YAST version is too cut down, so the latest from CPAN has been installed to site_perl
- It looks like any SpamAssassin config needs to be set in amavisd-new
ClamAv
- ClamAV_AntiVirus
- Already widely used by systems running on ares
- Interfaced to amavisd-new with perl modules
- /etc/clamd.conf (changes to make it play nice with amavisd-new)
- Disable TCPSocket
- Enable LocalSocket
- AllowAleternativeGroups
- ClamAV is a memeber of the amavis group
postgrey
Postgrey is a greylisting systyem for postfix, installed by hand by Tom and Kieran. Most of its settings are passed by the command line, these are coded into the startup script /etc/init.d/postgrey
- started with /usr/local/sbin/postgrey --daemonize --dbdir=/var/lib/postgrey --pidfile=/var/lib/postgrey/postgrey.pid --inet=127.0.0.1:60000 --user=postgrey --group=postgrey"
- config file = /etc/postfix/postgrey (not much in here)
- runs as user postgrey
- listens on localhost:60000
- has additinal line in /etc/postfix/main.cf "check_policy_service inet:127.0.0.1:60000,"
Perl Modules
Manually installed modules are available from CPAN. They are usually installed with the following commands (as root):
# perl Makefile.PL # make # make test && make install
Always read any README or INSTALL files that come in the tar. It's pretty easy but sometimes you'll get caught out by dependancies between modules.
Source for additional modules stored in /usr/local/src/
- Pretty much all perl modules available to install from YAST are on ares (bar the really obscure ones)
- SpamAssassin:
- Net::DNS - spamasssassin depends on this modules, so YAST get quite upset when it realises it can't install it. Get it from CPAN
- Amavisd-New (Mandatory):
- Archive::Tar (CPAN - YAST lies, it's only installed as part of a crappy CPAN utility)
- Archive::Zip (YAST)
- BerkeleyDB (CPAN)
- Compress::Raw::Zlib (CPAN)
- Compress::Zlib (CPAN - newer version needed)
- Convert::TNEF (CPAN)
- Convert::UUlib (CPAN)
- MIME::Base64 (YAST)
- MIME::Parser (YAST)
- Mail::Internet (YAST)
- Net::Server (YAST)
- Net::SMTP (YAST)
- Digest::MD5 (YAST)
- IO::Stringy (YAST)
- IO::Compress::Base (CPAN)
- IO::Compress::Zlib (CPAN)
- IO::Zlib (CPAN)
- Time::HiRes (YAST)
- Unix::Syslog (CPAN)
- General Desirables Modules for Clam/SpamAssassin/Amavisd-new:
- Algorithm::Diff (CPAN)
- ClamAV::Client (CPAN)
- Class::Base (CPAN)
- Class::MakeMethods (CPAN)
- Convert::Bencode (CPAN)
- Convert::UUlib (CPAN)
- Email::Abstract (CPAN)
- Email::Simple (CPAN)
- Email::Valid (CPAN)
- Error (CPAN)
- Error:TryCatch (CPAN)
- Error::Dumb (CPAN)
- Error::Wait (CPAN)
- Error::Subclasses (CPAN)
- Error::Unhandled (CPAN)
- File::Tempdir (CPAN)
- Inline (CPAN)
- Inline::ASM (CPAN)
- Inline::Awk (CPAN)
- Inline::Basic (CPAN)
- Inline::BC (CPAN)
- Inline::CPP (CPAN)
- Language::Basic (CPAN)
- Log::Log4perl (CPAN)
- Mail::Audi (CPAN)
- Mail::Audit::Razor (CPAN)
- Mail::ClamAV (CPAN)
- Mail::Karmasphere::Client (CPAN)
- Mail::ListDetector (CPAN)
- Mail::SpamAssassin::AuditMessage (CPAN)
- Mail::SpamAssassin::ConfSourceSQL (CPAN)
- Mail::SpamAssassin::CmdLearn (CPAN)
- Mail::SpamAssassin::EncappedMessage (CPAN)
- Mail::SpamAssassin::EncappedMIME (CPAN)
- Mail::SpamAssassin::NoMailAudit (CPAN)
- Mail::SpamAssassin::Plugin::Karmasphere (CPAN)
- Mail::SpamAssassin::Plugin::Razor2 (CPAN)
- Mail::SpamAssassin::Received (CPAN)
- Mail::SpamAssassin::Replier (CPAN)
- Mail::SpamAssassin::SHA1 (CPAN)
- Mail::SpamAssassin::SpamCopURI (CPAN)
- Mail::SpamAssassin::TextCat (CPAN)
- Mail::SpamAssassin::UnixLocker (CPAN)
- Mail::SPF::Query (CPAN)
- NetAddr::IP (CPAN)
- SQL::Statement (CPAN)
- SQL::Translator (CPAN)
- Test::Differences (CPAN)
- Test::More (CPAN)
- Text::CSV (CPAN)
- Text::Diff (CPAN)
- URI (CPAN - YAST only has a cut down URI collection)
- version (CPAN)
NOTE: There is a nasty bug in Text-Tabs+Wrap-2006.1117 to do with regular expressions - something spamassassin uses a lot of! We must stick with Text-Tabs+Wrap-2001.0929. Text Wrap bug reference 1 Text Wrap bug reference 2
Also did a cpan install Bundle::CPAN and cpan upgade to try and pull our perl setup in to the 21st century ;-)
Berkeley DataBase
The Berkeley Database is required for Amavisd and SpamAssassin to play nice. I can't beleive how old and crap the version bundled with OES/Linux is, or how come we've managed to get away with it for so long.
BerkeleyDB is from sleepycat software (now Oracle) and is FLOSS.
The source is in /usr/local/src and the prefix for all the Berkeley DB software is /usr/local
Configuring/building:
# tar zxvf db-4.5.20.tar.gz # cd db-4.5.20/build_unix # ../dist/configure --prefix=/usr/local --enable-cxx --enable-java --enable-pthread_api # make && make install
Others
artemis.varndean.ac.uk
- 212.219118.84 - 212.219.118.85
- NetMail server
- OES/NetWare
- NetMail NMAP and SMTP Agents Bound to 212.219.188.85
- Apache2 bound to 212.219.118.84
- Holds GroupWise Post Office and Post Office Agent for the Student Post Office Object Name Here!!
caan.varndean.ac.uk
- 212.219.118.82
- GroupWise Server
- OES/NetWare
- Main GroupWise server, although Student Post Office and Post Office Agent lives on artemis
- View all pages in the Groupwise category
Diagram
Nice OmniGraffle here please!
