use strict; # ============================================================================= # Section I - Essential options # ============================================================================= # $MYHOME serves as a quick default for some other configuration settings. # More refined control is available with each individual setting further down. # $MYHOME is not used directly by the program. No trailing slash! $MYHOME = '/var/amavis'; # (default is '/var/amavis') # $mydomain serves as a quick default for some other configuration settings. # More refined control is available with each individual setting further down. # $mydomain is never used directly by the program. $mydomain = 'my.domain.com'; # (no useful default) $myhostname = 'my.domain.com'; # fqdn of this host, default by uname(3) # Set the user and group to which the daemon will change if started as root # (otherwise just keeps the UID unchanged, and these settings have no effect): $daemon_user = 'vscan'; # (no default; customary: vscan or amavis) $daemon_group = 'vscan'; # (no default; customary: vscan or amavis or sweep) # Runtime working directory (cwd), and a place where # temporary directories for unpacking mail are created. # (no trailing slash, may be a scratch file system) $TEMPBASE = "$MYHOME/tmp"; # prefer to keep home dir /var/amavis clean? $db_home = "$MYHOME/db"; # DB databases directory, default "$MYHOME/db" # $helpers_home sets environment variable HOME, and is passed as option # 'home_dir_for_helpers' to Mail::SpamAssassin::new. It should be a directory # on a normal persistent file system, not a scratch or temporary file system # $helpers_home = $MYHOME; # (defaults to $MYHOME) $helpers_home = "$MYHOME/var"; # Run the daemon in the specified chroot jail if nonempty: # $daemon_chroot_dir = $MYHOME; # (default is undef, meaning: do not chroot) $pid_file = "$MYHOME/var/amavisd.pid"; # (default is "$MYHOME/amavisd.pid") $lock_file = "$MYHOME/var/amavisd.lock"; # (default is "$MYHOME/amavisd.lock") # set environment variables if you want (no defaults): $ENV{TMPDIR} = $TEMPBASE; # wise to set TMPDIR, but not obligatory $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 # ============================================================================= # MTA SETTINGS # ============================================================================= # both $forward_method and $notify_method default to 'smtp:[127.0.0.1]:10025' # POSTFIX, or SENDMAIL in dual-MTA setup, or EXIM V4 # (set host and port number as required; host can be specified # as an IP address or a DNS name (A or CNAME, but MX is ignored) $forward_method = 'smtp:[aaa.bbb.ccc.ddd]:25'; # where to forward checked mail $notify_method = $forward_method; # where to submit notifications # Net::Server pre-forking settings # The $max_servers should match the width of your MTA pipe # feeding amavisd, e.g. with Postfix the 'Max procs' field in the # master.cf file, like the '2' in the: smtp-amavis unix - - n - 2 smtp # $max_servers = 10; # number of pre-forked children (default 2) $max_requests = 20; # retire a child after that many accepts (default 10) $child_timeout=10*60; # abort child if it does not complete each task in # approximately n sec (default: 8*60 seconds) # Here is a QUICK WAY to completely DISABLE some sections of code # that WE DO NOT WANT (it won't even be compiled-in). # For more refined controls leave the following two lines commented out, # and see further down what these two lookup lists really mean. # # @bypass_virus_checks_maps = (1); # uncomment to DISABLE anti-virus code # @bypass_spam_checks_maps = (1); # uncomment to DISABLE anti-spam code # Lookup list of local domains (see README.lookups for syntax details) # # @local_domains_maps list of lookup tables are used in deciding whether a # recipient is local or not, or in other words, if the message is outgoing # or not. This affects inserting spam-related headers for local recipients, # limiting recipient virus notifications (if enabled) to local recipients, # in deciding if address extension may be appended, and in SQL lookups # for non-fqdn addresses. Set it up correctly if you need features # that rely on this setting (or just leave empty otherwise). # @local_domains_maps = (); # default is empty list, no recip. considered local # @local_domains_maps = ( read_hash("$MYHOME/local_domains") ); # using hash @local_domains_maps = ['.']; # every domain local # ============================================================================= # Section II - Postfix specific (defaults should be ok) # ============================================================================= # $insert_received_line = 1; # behave like MTA: insert 'Received:' header # SMTP SERVER (INPUT) PROTOCOL SETTINGS (e.g. with Postfix, Exim v4, ...) # (used when MTA is configured to pass mail to amavisd via SMTP or LMTP) $inet_socket_port = 10024; # accept SMTP on this local TCP port $inet_socket_bind = '127.0.0.1' ; # limit socket bind to interface # (default is '127.0.0.1') @inet_acl = qw( 127.0.0.1 ); # (default is qw(127.0.0.1 ::1) ) # @mynetworks is an IP access list which determines if the original SMTP client # IP address belongs to our internal networks, i.e. mail is coming from inside. # It is much like the Postfix parameter 'mynetworks' in semantics and similar # in syntax, and its value should normally match the Postfix counterpart. # It only affects the value of a macro %l (=sender-is-local), # and the loading of policy 'MYNETS' if present (see below). # Note that '-o smtp_send_xforward_command=yes' (or its lmtp counterpart) # must be enabled in the Postfix service that feeds amavisd, otherwise # client IP address is not available to amavisd-new. # @mynetworks = qw( ); # ============================================================================= # Section III - Logging # ============================================================================= # true (e.g. 1) => syslog; false (e.g. 0) => logging to file $DO_SYSLOG = 1; # (defaults to false) $SYSLOG_LEVEL = 'mail.info'; # (facility.priority, default 'mail.info') # Log file (if not using syslog) # $LOGFILE = "$MYHOME/amavis.log"; # (defaults to empty, no log) #NOTE: levels are not strictly observed and are somewhat arbitrary # 0: startup/exit/failure messages, viruses detected # 1: args passed from client, some more interesting messages # 2: virus scanner output, timing # 3: server, client # 4: decompose parts # 5: more debug details $log_level = 5; # (defaults to 0) # ============================================================================= # Section IV - Notifications/DSN, BOUNCE/REJECT/DROP/PASS destiny, quarantine # ============================================================================= # The following symbolic constants can be used in *_destiny settings: # # D_PASS mail will pass to recipients, regardless of bad contents; # # D_DISCARD mail will not be delivered to its recipients, sender will NOT be # notified. Effectively we lose mail (but will be quarantined # unless disabled). Losing mail is not decent for a mailer, # but might be desired. # # D_BOUNCE mail will not be delivered to its recipients, a non-delivery # notification (bounce) will be sent to the sender by amavisd-new; # Exception: bounce (DSN) will not be sent if a virus name matches # $viruses_that_fake_sender_re, or to messages from mailing lists # (Precedence: bulk|list|junk), or for spam level that exceeds # the $sa_dsn_cutoff_level. # # D_REJECT mail will not be delivered to its recipients, sender should # preferably get a reject, e.g. SMTP permanent reject response # (e.g. with milter), or non-delivery notification from MTA # (e.g. Postfix). If this is not possible (e.g. different recipients # have different tolerances to bad mail contents and not using LMTP) # amavisd-new sends a bounce by itself (same as D_BOUNCE). # Not to be used with Postfix or dual-MTA setups! # # Notes: # D_REJECT and D_BOUNCE are similar, the difference is in who is responsible # for informing the sender about non-delivery, and how informative # the notification can be (amavisd-new knows more than MTA); # With D_REJECT, MTA may reject original SMTP, or send DSN (delivery status # notification, colloquially called 'bounce') - depending on MTA; # Best suited for sendmail milter, especially for spam. # With D_BOUNCE, amavisd-new (not MTA) sends DSN (can better explain the # reason for mail non-delivery or even suppress DSN, but unable # to reject the original SMTP session). Best suited to reporting # viruses, and for Postfix and other dual-MTA setups, which can't # reject original client SMTP session, as the mail has already # been enqueued. $final_virus_destiny = D_DISCARD; # (defaults to D_DISCARD) $final_banned_destiny = D_DISCARD; # (defaults to D_BOUNCE) $final_spam_destiny = D_DISCARD; # (defaults to D_BOUNCE) $final_bad_header_destiny = D_BOUNCE; # (defaults to D_PASS), D_BOUNCE suggested # Treat envelope sender address as unreliable and don't send sender # notification / bounces if name(s) of detected virus(es) match the list. # Note that virus names are supplied by external virus scanner(s) and are # not standardized, so virus names may need to be adjusted. # See README.lookups for syntax, check also README.policy-on-notifications # @viruses_that_fake_sender_maps = (new_RE( qr'nimda|hybris|klez|bugbear|yaha|braid|sobig|fizzer|palyh|peido|holar'i, qr'tanatos|lentin|bridex|mimail|trojan\.dropper|dumaru|parite|spaces'i, qr'dloader|galil|gibe|swen|netwatch|bics|sbrowse|sober|rox|val(hal)?la'i, qr'frethem|sircam|be?agle|tanx|mydoom|novarg|shimg|netsky|somefool|moodown'i, qr'@mm|@MM', # mass mailing viruses as labeled by f-prot and uvscan qr'Worm'i, # worms as labeled by ClamAV, Kaspersky, etc [qr'^(EICAR|Joke\.|Junk\.)'i => 0], [qr'^(WM97|OF97|W95/CIH-|JS/Fort)'i => 0], [qr/.*/ => 1], # true by default (remove or comment-out if undesired) )); # where to send ADMIN VIRUS NOTIFICATIONS (should be a fully qualified address) # - the administrator envelope address may be a simple fixed e-mail address # (a scalar), or may depend on the RECIPIENT address (e.g. its domain). # # Empty or undef lookup disables virus admin notifications. # $virus_admin = undef; # do not send virus admin notifications (default) $virus_admin = undef; # equivalent to $virus_admin, but for spam admin notifications: $spam_admin = undef; # sender envelope address, from which notification reports are sent from; # may be a null reverse path, or a fully qualified address: # (admin and recip sender addresses default to a null return path). # If using strings in double quotes, don't forget to quote @, i.e. \@ # # $mailfrom_notify_admin = "martin.zahn\@$mydomain"; # $mailfrom_notify_recip = "martin.zahn\@$mydomain"; # $mailfrom_notify_spamadmin = "martin.zahn\@$mydomain"; $mailfrom_notify_admin = 'amavis@mydomain.com'; $mailfrom_notify_recip = 'amavis@mydomain.com'; $mailfrom_notify_spamadmin = 'amavis@mydomain.com'; # Location to put infected mail into: (applies to 'local:' quarantine method) # empty for not quarantining, may be a file (Unix-style mailbox), # or a directory (no trailing slash) # (the default value is undef, meaning no quarantine) # $QUARANTINEDIR = '/var/virusmails'; # $virus_quarantine_method = 'local:virus-%i-%n'; # default # $spam_quarantine_method = 'local:spam-%b-%i-%n'; # default # $banned_files_quarantine_method = 'local:banned-%i-%n'; # default # $bad_header_quarantine_method = 'local:badh-%i-%n'; # default # Separate quarantine subdirectories virus, spam, banned and badh within # the directory $QUARANTINEDIR may be specified by the following settings # (the subdirectories need to exist - must be created manually): $virus_quarantine_method = 'local:virus/virus-%i-%n'; $spam_quarantine_method = 'local:spam/spam-%b-%i-%n'; $banned_files_quarantine_method = 'local:banned/banned-%i-%n'; $bad_header_quarantine_method = 'local:badh/badh-%i-%n'; # Add X-Virus-Scanned header field to mail? $X_HEADER_TAG = 'X-Virus-Scanned'; # (default: 'X-Virus-Scanned') # Set to empty to add no header field # (dflt "$myproduct_name at $mydomain") # $X_HEADER_LINE = "$myproduct_name at $mydomain"; # $X_HEADER_LINE = "by $myproduct_name using ClamAV at $mydomain"; # $X_HEADER_LINE = "$myproduct_name $myversion_id ($myversion_date) at $mydomain"; $X_HEADER_LINE = "SA + ClamAV"; # a string to prepend to Subject (for local recipients only) if mail could # not be decoded or checked entirely, e.g. due to password-protected archives $undecipherable_subject_tag = undef; # undef disables it # ============================================================================= # Section V - Per-recipient and per-sender handling, whitelisting, etc. # ============================================================================= # In the following example a list of lookup tables @virus_lovers_maps # contains three elements, the first is a reference to an ACL lookup table # (brackets in Perl indicate a ref to a list), the second is a reference # to a hash lookup table (curly braces in Perl indicate a ref to a hash), # the third is a regexp lookup table, indicated by the type of object # created by new_RE() : # #@virus_lovers_maps = ( # [ qw( me@lab.xxx.com !lab.xxx.com .xxx.com yyy.org ) ], # { "postmaster\@$mydomain" => 1, # double quotes permit variable evaluation # 'postmaster@example.com'=> 1, # in single quotes the '@' need not be quoted # 'abuse@example.com'=> 1, # 'some.user@' => 1, # this recipient, regardless of domain # 'boss@example.com' => 0, # never, even if domain matches # 'example.com' => 1, # this domain, but not its subdomains # '.example.com' => 1, # this domain, including its subdomains # }, # new_RE( qr'^(helpdesk|postmaster)@example\.com$'i ), #); #@spam_lovers_maps = ( # ["postmaster\@$mydomain", 'postmaster@example.com', 'abuse@example.com'], #); #@bad_header_lovers_maps = ( # ["postmaster\@", "abuse\@$mydomain"], #); # to save some typing of quotes and commas, a Perl operator qw can be used # to split its argument on whitespace and to quote resulting elements: #@bypass_spam_checks_maps = ( # [ qw( some.ddd !butnot.example.com .example.com ) ], #); # don't run spam check for these RECIPIENT domains: # @bypass_spam_checks_maps = ( [qw( d1.com .d2.com a.d3.com )] ); # or the other way around (bypass check for all BUT these): # @bypass_spam_checks_maps = ( [qw( !d1.com !.d2.com !a.d3.com . )] ); # a practical application: don't check outgoing mail for spam: # @bypass_spam_checks_maps = ( [ "!.$mydomain", "." ] ); # (a downside of which is that such mail will not count as ham in SA bayes db) # # Note that 'outgoing' is not the same as 'originating from inside'. # The internal-to-internal mail is not outgoing, but is originating from # inside. To base rules on 'originating from inside', the use of policy bank # MYNETS is needed, in conjunction with XFORWARD Postfix extension to SMTP. # Where to find SQL server(s) and database to support SQL lookups? # A list of triples: (dsn,user,passw). (dsn = data source name) # More than one entry may be specified for multiple (backup) SQL servers. # See 'man DBI', 'man DBD::mysql', 'man DBD::Pg', ... for details. # When chroot-ed, accessing SQL server over inet socket may be more convenient. # # @lookup_sql_dsn = # ( ['DBI:mysql:database=mail;host=127.0.0.1;port=3306', 'user1', 'passwd1'], # ['DBI:mysql:database=mail;host=host2', 'username2', 'password2'] ); # # ('mail' in the example is the database name, choose what you like) # With PostgreSQL the dsn (first element of the triple) may look like: # 'DBI:Pg:host=host1;dbname=mail' # The SQL select clause to fetch per-recipient policy settings. # The %k will be replaced by a comma-separated list of query addresses # (e.g. full address, domain only (stripped level by level), and a catchall). # Use ORDER if there is a chance that multiple records will match - the first # match wins. If field names are not unique (e.g. 'id'), the later field # overwrites the earlier in a hash returned by lookup, which is why we use # '*,users.id' instead of just '*'. No need to uncomment the following # assignment if the default is ok. # $sql_select_policy = 'SELECT *,users.id FROM users,policy'. # ' WHERE (users.policy_id=policy.id) AND (users.email IN (%k))'. # ' ORDER BY users.priority DESC'; # # The SQL select clause to check sender in per-recipient whitelist/blacklist # The first SELECT argument '?' will be users.id from recipient SQL lookup, # the %k will be sender addresses (e.g. full address, domain only, catchall). # The default value is: # $sql_select_white_black_list = 'SELECT wb FROM wblist,mailaddr'. # ' WHERE (wblist.rid=?) AND (wblist.sid=mailaddr.id)'. # ' AND (mailaddr.email IN (%k))'. # ' ORDER BY mailaddr.priority DESC'; # # To disable SQL white/black list, set to undef (otherwise comment-out # the following statement, leaving it at the default value): $sql_select_white_black_list = undef; # undef disables SQL white/blacklisting # If passing malware to certain recipients ($final_*_destiny=D_PASS or # *_lovers), the recipient-based lookup tables @addr_extension_*_maps may # return a string, which (if nonempty) will be added as an address extension # to the local-part of the recipient's address. This extension may be used # by the final local delivery agent (LDA) to place such mail into different # subfolders (the extension is usually interpreted as a folder name). # This is sometimes known as the 'plus addressing'. Appending address # extensions is prevented when: # - recipient does not match lookup tables @local_domains_maps; # - lookup into corresponding @addr_extension_*_maps results # in an empty string or undef; # - $recipient_delimiter is empty (see below) # LDAs usually default to stripping away address extension if no special # handling is specified or if a named subfolder or alias does not exist, # so adding address extensions normally does no harm. # @addr_extension_virus_maps = ('virus'); # defaults to empty # @addr_extension_spam_maps = ('spam'); # defaults to empty # @addr_extension_banned_maps = ('banned'); # defaults to empty # @addr_extension_bad_header_maps = ('badh'); # defaults to empty # # A more complex example: # @addr_extension_virus_maps = ( # {'sub.example.com'=>'infected', '.example.com'=>'filtered'}, 'virus' ); # Delimiter between local part of the envelope recipient address and address # extension (which can optionally be added, see @addr_extension_*_maps. E.g. # recipient address is changed to . # # Delimiter must match the equivalent (final) MTA delimiter setting. # (e.g. for Postfix add 'recipient_delimiter = +' to main.cf) # Setting it to an empty string or to undef disables adding extensions # regardless of $addr_extension_*_maps. # $recipient_delimiter = '+'; # (default is undef, i.e. disabled) # true: replace extension; false: append extension # $replace_existing_extension = 1; # (default is false) # Affects matching of localpart of e-mail addresses (left of '@') # in lookups: true = case sensitive, false = case insensitive $localpart_is_case_sensitive = 0; # (default is false) # ENVELOPE SENDER SOFT-WHITELISTING / SOFT-BLACKLISTING # Instead of hard black- or whitelisting, a softer approach is to add # score points (penalties) to the SA score for mail from certain senders. # Positive points lean towards blacklisting, negative towards whitelisting. # This is much like adding SA rules or using its white/blacklisting, except # that here only envelope sender addresses are considered (not addresses # in a mail header), and that score points can be assigned per-recipient # (or globally), and the assigned penalties are customarily much lower # than the default SA white/blacklisting score. # # The table structure is similar to $per_recip_blacklist_sender_lookup_tables # i.e. the first level key is recipient, pointing to by-sender lookup tables. # The essential difference is that scores from _all_ matching by-recipient # lookups (not just the first that matches) are summed to give the final # score boost. That means that both the site and domain administrators, # as well as the recipient can have a say on the final score. # # NOTE: keep hash keys in lowercase, either manually or by using function lc @score_sender_maps = ({ # a by-recipient hash lookup table # # per-recipient personal tables (NOTE: positive: black, negative: white) # 'user1@example.com' => [{'bla-mobile.press@example.com' => 10.0}], # 'user3@example.com' => [{'.ebay.com' => -3.0}], # 'user4@example.com' => [{'cleargreen@cleargreen.com' => -7.0, # '.cleargreen.com' => -5.0}], # site-wide opinions about senders (the '.' matches any recipient) '.' => [ # 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], ), # read_hash("/var/amavis/sender_scores_sitewide"), { # 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, 'bugtraq@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, '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, # soft-blacklisting (positive score) # 'sender@example.net' => 3.0, # '.example.net' => 1.0, }, ], # end of site-wide tables }); # ============================================================================= # Section VI - Resource limits # ============================================================================= # Sanity limit to the number of allowed recipients per SMTP transaction $smtpd_recipient_limit = 5000; # (default is 1100) # Resource limits to protect unpackers, decompressors and virus scanners # against mail bombs (e.g. 42.zip) # Maximum recursion level for extraction/decoding (0 or undef disables limit) $MAXLEVELS = 30; # (default is undef, no limit) # Maximum number of extracted files (0 or undef disables the limit) $MAXFILES = 5000; # (default is undef, no limit) # For the cumulative total of all decoded mail parts we set max storage size # to defend against mail bombs. Even though parts may be deleted (replaced # by decoded text) during decoding, the size they occupied is _not_ returned # to the quota pool. # # Parameters to storage quota formula for unpacking/decoding/decompressing # Formula: # quota = max($MIN_EXPANSION_QUOTA, # $mail_size*$MIN_EXPANSION_FACTOR, # min($MAX_EXPANSION_QUOTA, $mail_size*$MAX_EXPANSION_FACTOR)) # In plain words (later condition overrules previous ones): # allow MAX_EXPANSION_FACTOR times initial mail size, # but not more than MAX_EXPANSION_QUOTA, # but not less than MIN_EXPANSION_FACTOR times initial mail size, # but never less than MIN_EXPANSION_QUOTA # $MIN_EXPANSION_QUOTA = 100*1024*10; # bytes (default undef, not enforced) $MAX_EXPANSION_QUOTA = 300*1024*1024*10; # bytes (default undef, not enforced) $MIN_EXPANSION_FACTOR = 5; # times original mail size (default is 5) $MAX_EXPANSION_FACTOR = 500; # times original mail size (default is 500) # expiration time of cached results: time to live in seconds # (how long the result of a virus/spam test remains valid) $virus_check_negative_ttl= 3*60; # time to remember that mail was not infected $virus_check_positive_ttl= 30*60; # time to remember that mail was infected $spam_check_negative_ttl = 30*60; # time to remember that mail was not spam $spam_check_positive_ttl = 30*60; # time to remember that mail was spam # # NOTE: # Cache size will be determined by the largest of the $*_ttl values. # Depending on the mail rate, the cache database may grow quite large. # Reasonable compromise for the max value is 15 minutes to 2 hours. # ============================================================================= # Section VII - External programs, virus scanners # ============================================================================= # Specify a path string, which is a colon-separated string of directories # (no trailing slashes!) to be assigned to the environment variable PATH # and to serve for locating external programs below. # NOTE: if $daemon_chroot_dir is nonempty, the directories will be # relative to the chroot directory specified; $path = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/sbin:/usr/bin:/bin'; # optional: $gzip = 'gzip'; $bzip2 = 'bzip2'; $lzop = 'lzop'; $rpm2cpio = ['rpm2cpio.pl','rpm2cpio']; $cabextract = 'cabextract'; $uncompress = ['uncompress', 'gzip -d', 'zcat']; $unfreeze = ['unfreeze', 'freeze -d', 'melt', 'fcat']; $arc = ['nomarch', 'arc']; $unarj = ['arj', 'unarj']; # both can extract, arj is recommended $unrar = ['rar', 'unrar']; # both can extract, same options $zoo = 'zoo'; $lha = 'lha'; $cpio = ['gcpio','cpio']; # gcpio is a GNU cpio on OpenBSD, which supports # the options needed; the rest of us use cpio $ar = 'ar'; # Unix binary archives and Debian binary packages # ============================================================================= # SpamAssassin settings # ============================================================================= # $sa_local_tests_only is passed to Mail::SpamAssassin::new as a value # of the option local_tests_only. See Mail::SpamAssassin man page. # If set to 1, no SA tests that require internet access will be performed. # $sa_local_tests_only = 0; # (default: false) # $sa_auto_whitelist = 1; # turn on AWL in SA 2.63 or older (irrelevant # for SA 3.0, its cf option is use_auto_whitelist) $sa_mail_body_size_limit = 200*1024; # don't waste time on SA if mail is larger # (less than 1% of spam is > 64k) # default: undef, no limitations # default values, customarily used in the @spam_*_level_maps as the last entry # $sa_tag_level_deflt = 2.0; # add spam info headers if at, or above that level; # undef is interpreted as lower than any spam level # $sa_tag2_level_deflt = 5.0; # add 'spam detected' headers at that level to # passed mail (e.g. when $final_spam_destiny=D_PASS # or for spam_lovers or when below kill_level) # $sa_kill_level_deflt = $sa_tag2_level_deflt; # triggers spam evasive actions # at or above that level: bounce/reject/drop, # quarantine, and adding mail address extension # $sa_dsn_cutoff_level = 10; # spam level beyond which a DSN is not sent, # effectively turning D_BOUNCE into D_DISCARD; # undef disables this feature and is a default; $sa_tag_level_deflt = undef; $sa_tag2_level_deflt = 5.0; $sa_kill_level_deflt = 10; # Since we are using D_DISCARD, this setting will serve no purpose, but if you were using D_BOUNCE, # you can use this to set a level at which the sender will no longer be notified $sa_dsn_cutoff_level = 15; # advanced example specifying per-recipient values using a hash lookup: #@spam_tag_level_maps = (\$sa_tag_level_deflt); # this is a default #@spam_tag2_level_maps = ( # { 'user1@example.com' => 8.0, '.example.com' => 6.0 }, # \$sa_tag2_level_deflt, # catchall default #); #@spam_kill_level_maps = ( # { 'user1@example.com' => 8.0, '.example.com' => 6.0 }, # \$sa_kill_level_deflt, # catchall default #); #@spam_dsn_cutoff_level_maps = ( # { 'user1@example.com' => 10, '.example.com' => 15 }, # \$sa_dsn_cutoff_level, # catchall default #); # a quick reference: # tag_level controls adding the X-Spam-Status and X-Spam-Level headers, # tag2_level controls adding 'X-Spam-Flag: YES', editing (tagging) Subject, # and adding address extensions, # kill_level controls 'evasive actions' (reject, quarantine); # it only makes sense to maintain the relationship: # tag_level <= tag2_level <= kill_level < dsn_cutoff_level # string to prepend to Subject header field when message exceeds tag2 level $sa_spam_subject_tag = 'SPAM: '; # (defaults to undef, disabled) # (only seen when spam is passed and recipient is # in local_domains*) $sa_spam_modifies_subj = 1; # in @sa_spam_modifies_subj_maps, default is true # Example: modify Subject for all local recipients except user@example.com #@sa_spam_modifies_subj_maps = ( [qw( !user@example.com . )] ); $sa_spam_level_char = '*'; # char for X-Spam-Level bar, defaults to '*'; # undef or empty disables inserting X-Spam-Level $sa_spam_report_header = 1; # insert X-Spam-Report header field? default false # stop anti-virus scanning when the first scanner detects a virus? $first_infected_stops_scan = 1; # default is false, all scanners in a section # are called # @av_scanners is a list of n-tuples, where fields semantics is: # 1. av scanner plain name, to be used in log and reports; # 2. scanner program name; this string will be submitted to subroutine # find_external_programs(), which will try to find the full program path # name during startup; if program is not found, this scanner is disabled. # Besides a simple string (full program path name or just the basename # to be looked for in PATH), this may be an array ref of alternative # program names or full paths - the first match in the list will be used; # As a special case for more complex scanners, this field may be # a subroutine reference, and the whole n-tuple is passed to it as args. # 3. command arguments to be given to the scanner program; # a substring {} will be replaced by the directory name to be scanned, i.e. # "$tempdir/parts", a "*" will be replaced by base file names of parts; # 4. an array ref of av scanner exit status values, or a regexp (to be # matched against scanner output), indicating NO VIRUSES found; # 5. an array ref of av scanner exit status values, or a regexp (to be # matched against scanner output), indicating VIRUSES WERE FOUND; # Note: the virus match prevails over a 'not found' match, so it is safe # even if the no. 4. matches for viruses too; # 6. a regexp (to be matched against scanner output), returning a list # of virus names found, or a sub ref, returning such a list when given # scanner output as argument; # 7. and 8.: (optional) subroutines to be executed before and after scanner # (e.g. to set environment or current directory); # see examples for these at KasperskyLab AVP and NAI uvscan. # NOTES: # # - NOT DEFINING @av_scanners (e.g. setting it to empty list, or deleting the # whole assignment) TURNS OFF LOADING AND COMPILING OF THE ANTIVIRUS CODE # (which can be handy if all you want to do is spam scanning); # # - the order matters: although _all_ available entries from the list # are tried regardless of their verdict, scanners are run in the order # specified: the report from the first one detecting a virus will be used # (providing virus names and scanner output); REARRANGE THE ORDER TO WILL; # see also $first_infected_stops_scan; # # - it doesn't hurt to keep an unused command line scanner entry in the list # if the program can not be found; the path search is only performed once # during the program startup; # # COROLLARY: to disable a scanner that _does_ exist on your system, # comment out its entry or use undef or '' as its program name/path # (second parameter). An example where this is almost a must: disable # Sophos 'sweep' if you have its daemonized version Sophie or SAVI-Perl # (same for Trophie/vscan, and clamd/clamscan), or if another unrelated # program happens to have a name matching one of the entries ('sweep' # again comes to mind); # # - it DOES HURT to keep unwanted entries which use INTERNAL SUBROUTINES # for interfacing (where the second parameter starts with \&). # Keeping such entry and not having a corresponding virus scanner daemon # causes an unnecessary connection attempt (which eventually times out, # but it wastes precious time). For this reason the daemonized entries # are commented in the distribution - just remove the '#' where needed. # # CERT list of av resources: http://www.cert.org/other_sources/viruses.html @av_scanners = ( # ### http://www.clamav.net/ ['ClamAV-clamd', \&ask_daemon, ["CONTSCAN {}\n", "/var/run/clamav/clamd.sock"], qr/\bOK$/, qr/\bFOUND$/, qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ], # # NOTE: run clamd under the same user as amavisd; match the socket # # name (LocalSocket) in clamav.conf to the socket name in this entry # # When running chrooted one may prefer: ["CONTSCAN {}\n","$MYHOME/clamd"], ); # # ============================================================================= # Section VIII - Debugging # ============================================================================= # # The most useful debugging tool is to run amavisd-new non-detached # from a terminal window using command: # amavisd debug # Some more refined approaches: # If sender matches ACL, turn debugging fully up, just for this one message #@debug_sender_maps = ( ["test-sender\@$mydomain"] ); #@debug_sender_maps = ( [qw( debug@example.com debug@example.net )] ); # May be useful along with @debug_sender_maps: # Prevent all decoded originals being deleted (replaced by decoded part) #@keep_decoded_original_maps = (1); # Turn on SpamAssassin debugging (output to STDERR, use with 'amavisd debug') $sa_debug = 1; # defaults to false # # ============================================================================= # Section IX - Policy banks (dynamic policy switching) # ============================================================================= # ## Define some policy banks (sets of settings) and give them ## arbitrary names (the '' and 'MYNETS' have special meaning): # # $policy_bank{'ALT'} = { # log_level => 3, # inet_acl => [qw( 10.0.1.14 )], # final_spam_destiny => D_PASS, final_bad_header_destiny => D_PASS, # forward_method => 'smtp:*:*', # notify_method => 'smtp:[127.0.0.1]:10025', # virus_admin_maps => "abuse\@$mydomain", # spam_lovers_maps => [@spam_lovers_maps, [qw( abuse@example.com )]], # spam_tag_level_maps => 2.1, # spam_tag2_level_maps => 6.32, # spam_kill_level_maps => 6.72, # spam_dsn_cutoff_level_maps => 9, # defang_spam => 1, # local_client_bind_address => '10.11.12.13', # localhost_name => 'amavis.example.com', # smtpd_greeting_banner => # '${helo-name} ${protocol} ${product} ${version-id} (${version-date}) TEST service ready'; # auth_mech_avail => [qw(PLAIN LOGIN)], # auth_required_inp => 1, # auth_required_out => 1, # amavis_auth_user => 'amavisd', amavis_auth_pass = 'tOpsecretX', # av_scanners => [ # provide only 'free' scanners # ['ClamAV-clamd', # \&ask_daemon, ["CONTSCAN {}\n", "/var/run/clamav/clamd"], # qr/\bOK$/, qr/\bFOUND$/, # qr/^.*?: (?!Infected Archive)(.*) FOUND$/, # ], # ], # av_scanners_backup => [ # ['ClamAV-clamscan', 'clamscan', # "--stdout --disable-summary -r --tempdir=$TEMPBASE {}", [0], [1], # qr/^.*?: (?!Infected Archive)(.*) FOUND$/, # ], # ], # }; # NOTE: the use of policy banks for changing protocol on the input socket is # only needed when different protocols need to be spoken on different sockets # at the same time. For normal use just set e.g.: $protocol='AM.PDP'; # # $policy_bank{'AM.PDP'} = { # log_level => 3, # protocol=>'AM.PDP', # Amavis policy delegation protocol (new milter helper) # }; ## the name 'MYNETS' has special semantics: this policy bank gets loaded ## whenever MTA supplies the original SMTP client IP address (Postfix XFORWARD ## extension or a new AM.PDP protocol) and that address matches @mynetworks. # # $policy_bank{'MYNETS'} = { # mail originating from @mynetworks # spam_kill_level_maps => 6.9, # spam_admin_maps => ["spamalert\@$mydomain"], # alert of internal spam # bypass_spam_checks_maps => [1], # or: don't spam-check internal mail # bypass_banned_checks_maps => [1], # don't banned-check internal mail # }; ## Now we can assign policy banks to amavisd tcp port numbers listed in ## $inet_socket_port. Whenever the connection from MTA is received, first ## a built-in policy bank $policy_bank{''} gets loaded, which bringings-in ## all the global/legacy settings, then it gets overlaid by the bank ## named in the $interface_policy{$port} if any, and finally the bank ## 'MYNETS' is overlaid if it exists and the SMTP client IP address ## is known (by XFORWARD command from MTA) and it matches @mynetworks. # $interface_policy{'10026'} = 'ALT'; # $interface_policy{'9998'} = 'AM.PDP'; # $interface_policy{'SOCK'} = 'AM.PDP'; #------------- 1; # insure a defined return