Re: [exim] ${perl or ${run ?

Top Page
Delete this message
Reply to this message
Author: Lena
Date:  
To: exim-users
Subject: Re: [exim] ${perl or ${run ?
W B Hacker replied:

> > For me memory is more important because I run Exim on VPS/VDS with
> > 64M RAM (not counting kernel) and 128M swap along with BIND,
> > a web-server with Perl CGI and inetd (sshd, popa3d).
>
> I thought that trick with one live-round in a revolver was called
> *Russian* roulette.
> Did it actually originate in Ukrainaya?
> ;-)


Well, it was one country then. :-)
One month - all OK. I just took this to heart:
"The only good Indian is a dead Indian." ;-)
Meaning Apache. The "mathopd" one-process, no-threads web-server
(set up for up to 20 simultaneous connections) eats just 1.5M RAM,
CGI in separate processes without memory overhead unlike Apache
in default pre-fork mode preinstalled on the VPS. And tuned Exim instead of
preinstalled sendmail, popa3d instead of dovecot, sshd/FISH instead of ftpd,
no sql. So, other VPS users have to buy more RAM, I haven't.

> low-traffic domains see a far higher amount of spam and malicious
> connections *as a percentage* of connections than high traffic MTA do.
>
> Ergo, the later you can run any resource-intensive process, the better
> you can protect yourself against resource exhaustion.


I just don't run resource-intensive processes. :)
Looks like server-side virus-filters lately became superfluous: executable
nasties in messages penetrating antispam barriers are few and far between.
My users are enough smart to run antivirus software on windoze workstations
(with plenty RAM) and to not click on trojan or phishing URLs.

> To the extent you use all of the more efficient tools to shed bad-stuff
> as early as possible, and run custom scripts only on the probable-good
> traffic, you can cut the load by - just in our experience - 85% to 90%.
>
> That said, acl_smtp_recpt is pretty early to have shed the majority of
> potentially 'sheddable' message traffic w/o false-positives.


The cause why I moved from an usual virtual web-hosting account (with Exim
controlled by cPanel) to VPS is that I have to exclude false positives
or as the very last resort in exceptional cases report refusal to sender
during SMTP session. cPanel began to silently filter out some ham.
Exim tuned by me (below) does surprisingly good job fending spam though
I use two external whitelists, local whitelist, no callouts, neither
SpamAssasin nor similar heavy content-filters, and I greylist only
messages which usually are rejected outright (in CBL or black-at-hostkarma,
no FQDN in HELO, or (\d{1,3}[-.]){3}\d in HELO or hostname).
Not one ham message was greylisted so far, so no delays.

> And greylisting, unfortunately, is a double-edged tool. Even with a fast
> compiled-C binary, there is still fs I/O & storage to manage [1], so in
> some circumstances and implementations, it can consume as much as it saves.
>
> Personally, I wouldn't want the burden of greylisting *at all* on such
> light resources


Even greylisting using Perl copes well so far.

> [1] a file system *is* a DB of sorts


But with much less memory expense.

I deleted most comments for brevity, @ changed to () in few places:

accept_8bitmime = true
untrusted_set_sender = *
local_from_check = false
smtp_accept_max = 20
smtp_accept_max_per_host=7
smtp_accept_queue = 10
smtp_accept_queue_per_connection = 10
helo_accept_junk_hosts = *
tls_require_ciphers = AES : 3DES : !SSLv2
message_body_newlines = true
smtp_return_error_details = true
bounce_return_size_limit = 7K
delay_warning = 4h:99d
delay_warning_condition = ${if !eq{$domain}{nym.alias.net}}
freeze_tell = Lena()lena.kiev.ua
message_id_header_domain = lena.kiev
log_selector = +smtp_confirmation +queue_time -retry_defer \
           +smtp_incomplete_transaction +smtp_no_mail +deliver_time
perl_startup = do '/usr/local/etc/exim/perl.pl'
# from http://wiki.exim.org/DbLessGreyListing , but defer_timeout 3 min
hostlist whitelisted_hosts = \
        # yahooGroups:
69.147.64.0/23  : \
69.147.102.0/23 : \
66.94.237.0/24  : \
66.163.168.0/23 : \
66.218.66.0/23  : \
209.73.160.0/24 : \
209.73.164.0/24 : \
209.131.38.0/24 : \
        # rambler.ru:
81.19.66.0/23   : \
81.19.88.0/24   : \
        # mail.ru:
194.67.23.0/24  : \
194.67.57.0/24  : \
        # yandex.ru:
77.88.32.0/24   : \
87.250.248.0/24 : \
213.180.200.0/24 : \
213.180.223.0/24 : \
        # pochta.ru:
81.211.64.0/24  : \
82.204.219.0/24 : \
        # aha.ru/go.ru:
195.2.83.0/24   : \
        # beelinegprs:
217.118.66.233  : \
        # ngs.ru:
81.176.214.0/24 : \
195.93.186.0/24 : \
212.164.71.0/24 : \
                # kyivstar.net:
193.41.60.22    : \
                # from exim-users May 8, 2008:
                # Blueyonder:
195.188.213.0/29 : 195.188.213.8/31 : \
                # Freeserve:
193.252.22.156/30 : 193.252.22.128/32 : \
                # Tucows:
64.97.168.37/32 : 64.97.136.128/26 : \
                # Hotmail:
65.54.246.0/24  : \
                # Google:
209.85.132.130/32 : 209.85.132.184/29 : 209.85.132.241/32 : \
209.85.132.244/32 : 209.85.132.250/32 : 212.159.30.228/32 : \
64.233.162.176/28 : 64.233.162.224/27 : 64.233.182.167/32 : \
64.233.184.130/32 : 64.233.184.224/27 : 66.249.82.224/28 : \
66.249.92.171/32 : 66.249.93.114/32 : 66.249.93.27/32 : \
                # Messagelabs:
134.159.150.64/26 : 193.109.254.0/23 : 194.106.220.0/23 : \
195.245.230.0/23 : 203.129.72.208/28 : 203.129.72.240/28 : \
203.129.74.224/27 : 203.166.119.128/26 : 212.125.75.0/27 : \
216.82.240.0/20 : 62.173.108.16/28 : 62.173.108.208/28 : \
62.231.131.0/24 : 64.124.170.128/28 : 85.158.136.0/21
tls_advertise_hosts = *
tls_certificate = /etc/ssl/exim.crt
tls_privatekey = /etc/ssl/exim.pem
domainlist local_domains = lsearch;/usr/local/etc/exim/multi-domains
domainlist relay_to_domains = 
hostlist   relay_from_hosts = localhost : (my IP)
acl_smtp_rcpt = acl_check_rcpt
acl_smtp_data = acl_check_data
acl_smtp_predata = acl_check_predata
acl_smtp_mime = acl_check_mime
acl_smtp_auth = acl_check_auth
exim_user = mailnull
exim_group = mail
never_users = root
host_lookup = *
rfc1413_hosts = *
rfc1413_query_timeout = 2s
ignore_bounce_errors_after = 2d
timeout_frozen_after = 7d
begin acl
acl_check_rcpt:
  accept  hosts = :
  deny    message       = Restricted characters in address
          domains       = +local_domains
          local_parts   = ^[.] : ^.*[@%!/|]
  deny    message       = Restricted characters in address
          domains       = !+local_domains
          local_parts   = ^[./|] : ^.*[@] : ^.*/\\.\\./
                    # was ^[./|] : ^.*[@%!] : ^.*/\\.\\./
  accept  local_parts   = postmaster
          domains       = +local_domains
  require verify        = sender
  accept  hosts         = +relay_from_hosts
          control       = submission/domain=
  accept  authenticated = *
          control       = submission/domain=


  deny message = rejected because `HELO $sender_helo_name` means \
                 impersonation/forgery of one of my domains by a spammer
       condition = ${if match_domain{$sender_helo_name}{+local_domains}}


  deny message = rejected because HELO is my (recipient server) IP-address \
                 as some spammers lie instead of sender hostname
       condition = ${if match{$sender_helo_name}\
                             {\N^\[?\N$interface_address\N\]?$\N}}


  deny message = `HELO $sender_helo_name` locally blacklisted
       condition = ${lookup{$sender_helo_name}nwildlsearch\
                     {/usr/local/etc/exim/blacklist_re_helo}{1}{0}}


  require message = relay not permitted
          domains = +local_domains : +relay_to_domains


require verify = recipient

  accept hosts = +whitelisted_hosts
         logwrite = $sender_host_address locally whitelisted


  deny   message = sender hostname $sender_host_name locally blacklisted \
                   because of too much spam from it
         log_message = sender hostname locally blacklisted
         condition = ${lookup{$sender_host_name}nwildlsearch\
                     {/usr/local/etc/exim/blacklist_re_hostname}{1}{0}}


  deny   message = sender IP-address $sender_host_address locally \
                   blacklisted because of too much spam from it
         log_message = sender IP locally blacklisted
         condition = ${lookup{$sender_host_address}iplsearch\
                     {/usr/local/etc/exim/blacklist_hostaddress}{1}{0}}


  accept dnslists = list.dnswl.org : \
                    nobl.junkemailfilter.com=127.0.0.1,127.0.0.5
         logwrite = $sender_host_address whitelisted in \
                $dnslist_domain=$dnslist_value
         # http://www.dnswl.org/ ,
         # http://wiki.junkemailfilter.com/index.php/Spam_DNS_Lists


  deny   message = rejected because $sender_host_address is in a black list \
           at $dnslist_domain. $dnslist_text
         dnslists = list.dsbl.org : dul.ru


  deny   message = I don`t accept mail from China,HongKong,Taiwan, Korea, \
                   Vietnam because of too much spam from there. Your \
                   IP-address seems to belong to: $dnslist_text.
         dnslists = zz.countries.nerd.dk=127.0.0.156,127.0.1.88,127.0.0.158,\
                                         127.0.1.154,127.0.2.192


accept condition = ${if def:tls_cipher}

  defer     condition = ${if def:acl_c_grey_checked}
         message = $acl_c_grey_checked
     condition = $acl_c_grey_result


accept condition = ${if def:acl_c_grey_checked}

  defer  log_message = greylisted because of HELO $sender_helo_name
         condition = ${if or{\
                             {!match{$sender_helo_name}{\\.}}\
                             {match{$sender_helo_name}\
                                   {\N^\[?(\d{1,3}\.){3}\d{1,3}\]?$\N}}\
                            }}
         condition = ${if !def:acl_c_grey_checked}
         set acl_c_grey_checked = deferred/greylisted because \
                                  HELO `$sender_helo_name` is not a domain name
         message = $acl_c_grey_checked
         set acl_c_grey_result = ${perl{greylist}{$sender_host_address}\
                       {$sender_address}{$local_part@$domain}}
                                 # 1 - defer, 0 - allow
         condition = $acl_c_grey_result


  accept condition = ${if def:acl_c_grey_checked}
         add_header = X-OOOOOOOOOOOOOOOOOOOOOOOOOO: passed greylisting helo
         log_message = passed greylisting helo \
                       ${sg{$sender_rcvhost}{\N[\n\t]+\N}{\040}}


  defer  log_message = greylisted because $sender_host_name looks dynamic
         condition = ${if match{$sender_host_name}\
                               {\N(\d{1,3}[-.]){3}\d\N}}
         condition = ${if !match{$sender_host_name}{sta}}
         condition = ${if !def:acl_c_grey_checked}
         set acl_c_grey_checked = deferred/greylisted because sender hostname \
                                  $sender_host_name looks like dynamic
         message = $acl_c_grey_checked
         set acl_c_grey_result = ${perl{greylist}{$sender_host_address}\
                       {$sender_address}{$local_part@$domain}}
         condition = $acl_c_grey_result


  accept condition = ${if def:acl_c_grey_checked}
         add_header = X-OOOOOOOOOOOOOOOOOOOOOOOOOO: passed greylisting dyn
         log_message = passed greylisting dyn \
                       ${sg{$sender_rcvhost}{\N[\n\t]+\N}{\040}}


  defer  log_message = greylisted because `HELO $sender_helo_name` looks \
                       dynamic
         condition = ${if match{$sender_helo_name}\
                               {\N(\d{1,3}[-.]){3}\d\N}}
         condition = ${if !match{$sender_helo_name}{sta}}
         condition = ${if !def:acl_c_grey_checked}
         set acl_c_grey_checked = deferred/greylisted because \
                                  `HELO $sender_helo_name` looks like dynamic
         message = $acl_c_grey_checked
         set acl_c_grey_result = ${perl{greylist}{$sender_host_address}\
                       {$sender_address}{$local_part@$domain}}
         condition = $acl_c_grey_result


  accept condition = ${if def:acl_c_grey_checked}
         add_header = X-OOOOOOOOOOOOOOOOOOOOOOOOOO: passed greylisting helo dyn
         log_message = passed greylisting helo dyn \
                       ${sg{$sender_rcvhost}{\N[\n\t]+\N}{\040}}


accept !dnslists = cbl.abuseat.org : hostkarma.junkemailfilter.com=127.0.0.2

  defer  log_message = greylisted because in $dnslist_domain: $dnslist_text
         set acl_c_grey_checked = deferred/greylisted because \
                                  $sender_host_address is in a black list at \
                                  $dnslist_domain. $dnslist_text
         message = $acl_c_grey_checked
         set acl_c_grey_result = ${perl{greylist}{$sender_host_address}\
                       {$sender_address}{$local_part@$domain}}
         condition = $acl_c_grey_result


  accept add_header = X-OOOOOOOOOOOOOOOOOOOOOOOOOO: passed greylisting cbl
         log_message = passed greylisting cbl \
                       ${sg{$sender_rcvhost}{\N[\n\t]+\N}{\040}}


acl_check_predata:
  deny message = too many invalid recipients
       condition = ${if >{$rcpt_fail_count}{3}}
  accept


acl_check_mime:
  deny message = Windows-executable attachments forbidden. Use zip.
       condition = ${if !eqi{$recipients}{lena()lena.kiev.ua}}
       condition = ${if def:sender_host_address}
       condition = ${if !def:sender_host_authenticated}
       log_message = forbidden attachment: filename=$mime_filename, \
             content-type=$mime_content_type, recipients=$recipients
       condition = ${if or{\
               {match{$mime_content_type}{(?i)executable}}\
               {match{$mime_filename}{\N(?i)\.(exe|com|vbs|bat|pif|scr|hta|js|cmd|chm|cpl|jsp|reg|vbe|lnk|dll|sys)$\N}}\
              }}


accept condition = ${if !match{$recipients}{\N(?i)mail2ftp[^,]*@tg.org.ua\N}}

  deny message = You must set up your mail client to send plain text, \
                 no HTML, no attachments: http://www.expita.com/nomime.html
       condition = ${if match{$mime_content_type}{(?i)html|multipart}}


  require message = Command in the first line of letter body \
                    not recognized - send HELP
          mime_regex = \N(?i)\Amail2ftp(verbose)?\s :\
                         (?i)\Ahttp(post|get)[swtn]?\s :\
                         (?i)\Alogin\s :\
                         (?i)\A\"?help[\"\s\n]
  accept


acl_check_auth:
  drop message = authentication is allowed only once per message in order \
                 to slow down bruteforce cracking
       condition = ${if def:acl_m_auth}
       condition = ${if >{$acl_m_auth}{2}}
       delay = 20s


  warn condition = ${if !def:acl_m_auth}
       set acl_m_auth = 0


accept set acl_m_auth = ${eval:$acl_m_auth+1}

acl_check_data:
accept hosts = : +whitelisted_hosts

require verify = header_sender

  deny message = rejected because recognized as spam sent by a \
                 virus/trojan/zombie/bot
       condition = ${if def:acl_c_grey_checked}
       condition = ${if eq{$received_protocol}{smtp}}
       condition = ${if match{$rheader_Content-Transfer-Encoding:}{7bit}}
       condition = ${if match{$message_body}\
            {\Nhttp://[a-z]+\.com\n\n[A-Z][a-z]+ [A-Z][a-z]+\n\n\Z\N}}
       condition = ${if !match{$message_body}{http://.+http://}}


accept condition = ${if !match{$recipients}{\N(?i)mail2ftp[^,]*@tg.org.ua\N}}

  deny message = You must set up your mail client to send plain text, \
                 no HTML, no attachments: http://www.expita.com/nomime.html
       condition = ${if match{$rheader_Content-Type:}{(?i)html|multipart}}


accept

begin transports
remote_smtp:
driver = smtp
serialize_hosts = *

(skipped for brevity)

In blacklist_re_hostname the main is the first line:

^smtp\d\w*\.orange\.fr$
bzq-179-112-209.static.bezeqint.net
^dsl\d+\.\d+-\d+\.ttnet\.net\.tr$
^\w+\.mdp2\.net$
222.ksu.ru
*.neoplus.adsl.tpnet.pl
^.*gprs.*pool
^dhcp\d+\.myzipnet\.com$
^dyn-\d+-\d+-\d+-\d+\.ppp\.tiscali\.fr$
^cklist\d+\.starspecials\.co\.uk$
^ppp\d+-\d+\.adsl\.forthnet\.gr$
server5.cool-dns.com
cornflower.propagation.net
^host-\d+-\d+\.xdsl\.telecet\.ru$
^\d+\.red-\d+-\d+-\d+\.dynamicip\.rima-tde\.net$
^p[a-f\d]{8}\.dip\.t-dialin\.net$
^\d+-\d+-\d+-\d+\.static\.germania\.com\.ar$
^nat-\d+\.megalan\.ru$
^\d+\.pool\d+-\d+-\d+\.dynamic\.orange\.es$
^l\d+-\d+-\d+\.cn\.ru$
^adsl-\d+-\d+-\d+\.\w+\.bellsouth\.net$
^chello\d+\.\w+\.surfer\.at$
^a\d+-\d+\.adsl\.paltel\.net$

blacklist_re_helo:

^dsl\d+[\.-]\d+-\d+\.ttnet\.net\.tr$
^dsl\.(static|dynamic)\d+\.ttnet\.net\.tr$
^\d+\.user\.veloxzone\.com\.br$
^p[a-fA-F\d]{8}\.dip\d+\.t-ipconnect\.de$
^[a-f\d]{8}\.virtua\.com\.br$
mail.peakok.in
^host\d+-\d+-dynamic\.\d+-\d+-r\.retail\.telecomitalia\.it$
^node-\d+-\d+\.adsl\.tula\.net$
^Dynamic-IP-\d+\.cable\.net\.co$
dsldevice.lan
^whosting\d+\.virtualandes\.cl$
^\d+\.smed\.net$

blacklist_hostaddress:

69.38.137.67
212.143.230.10
200.108.210.162
87.12.136.209
74.52.66.138
82.186.248.58
58.105.229.148
195.42.89.114
65.254.50.90
207.251.86.16