0

I'm having a hard time coming up with a router or filter to basically send ALL incoming emails to a domain name to a Ruby script, for an Exim setup on a CentOS7 board.

The resolution from https://stackoverflow.com/a/32178818/10690518 no longer seems to be valid, the /etc/aliases method doesn't seem to work and the Exim manual, whilst fairly thorough, does not get me to the point where I can create the correct route.

This is my fairly standard Exim config:

# cat /etc/exim/exim.conf |egrep -v '^#|^$|\ \ #'
primary_hostname = MYDOMAIN
domainlist local_domains = @ : localhost : localhost.localdomain : MYDOMAIN
domainlist relay_to_domains = MYDOMAIN
hostlist   relay_from_hosts = localhost
acl_smtp_mail = acl_check_mail
acl_smtp_rcpt = acl_check_rcpt
acl_smtp_data = acl_check_data
acl_smtp_mime = acl_check_mime
av_scanner = clamd:/var/run/clamd.exim/clamd.sock
tls_advertise_hosts = *
tls_certificate = /etc/ssl/certs/MYDOMAIN.pem
daemon_smtp_ports = 25 : 465 : 587
tls_on_connect_ports = 465
never_users = root
host_lookup = *
auth_advertise_hosts =
prdr_enable = true
log_selector = +smtp_protocol_error +smtp_syntax_error \
    +tls_certificate_verified
ignore_bounce_errors_after = 2d
timeout_frozen_after = 7d
keep_environment = ^LDAP
add_environment = PATH=/usr/bin::/bin
begin acl
acl_check_mail:
  deny condition = ${if eq{$sender_helo_name}{} {1}}
       message = Nice boys say HELO first
  warn condition = ${if eq{$sender_host_name}{} {1}}
       set acl_m_greylistreasons = Host $sender_host_address lacks reverse DNS\n$acl_m_greylistreasons
  accept
acl_check_rcpt:
  accept  hosts = :
          control = dkim_disable_verify
  deny    message       = Restricted characters in address
          domains       = +local_domains
          local_parts   = ^[.] : ^.*[@%!/|]
  deny    message       = Restricted characters in address
          domains       = !+local_domains
          local_parts   = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
  accept  local_parts   = postmaster
          domains       = +local_domains
  require verify        = sender
  accept  hosts         = +relay_from_hosts
          control       = submission
          control       = dkim_disable_verify
  accept  authenticated = *
          control       = submission
          control       = dkim_disable_verify
  require message   = nice hosts say HELO first
          condition = ${if def:sender_helo_name}
  require message = relay not permitted
          domains = +local_domains : +relay_to_domains
  require verify = recipient
  accept
acl_check_data:
  deny    message    = maximum allowed line length is 998 octets, \
                       got $max_received_linelength
          condition  = ${if > {$max_received_linelength}{998}}
  deny    !verify = header_syntax
      message = header syntax
      log_message = header syntax ($acl_verify_message)
  warn    condition  = ${if !def:h_Message-ID: {1}}
          set acl_m_greylistreasons = Message lacks Message-Id: header. Consult RFC2822.\n$acl_m_greylistreasons
  accept
acl_check_mime:
  deny message = Blacklisted file extension detected
       condition = ${if match \
                        {${lc:$mime_filename}} \
                        {\N(\.exe|\.pif|\.bat|\.scr|\.lnk|\.com)$\N} \
                     {1}{0}}
  accept
begin routers
dnslookup:
  driver = dnslookup
  domains = ! +local_domains
  transport = remote_smtp
  ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
  no_more
system_aliases:
  driver = redirect
  allow_fail
  allow_defer
  data = ${lookup{$local_part}lsearch{/etc/aliases}}
  file_transport = address_file
  pipe_transport = address_pipe
userforward:
  driver = redirect
  check_local_user
  file = $home/.forward
  allow_filter
  no_verify
  no_expn
  check_ancestor
  file_transport = address_file
  pipe_transport = address_pipe
  reply_transport = address_reply
procmail:
  driver = accept
  check_local_user
  require_files = ${local_part}:+${home}/.procmailrc:/usr/bin/procmail
  transport = procmail
  no_verify
localuser:
  driver = accept
  check_local_user
  transport = local_delivery
  cannot_route_message = Unknown user
begin transports
remote_smtp:
  driver = smtp
  message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}}
remote_msa:
  driver = smtp
  port = 587
  hosts_require_auth = *
procmail:
  driver = pipe
  command = "/usr/bin/procmail -d $local_part"
  return_path_add
  delivery_date_add
  envelope_to_add
  user = $local_part
  initgroups
  return_output
local_delivery:
  driver = appendfile
  file = /var/mail/$local_part
  delivery_date_add
  envelope_to_add
  return_path_add
  group = mail
  mode = 0660
address_pipe:
  driver = pipe
  pipe_as_creator
address_file:
  driver = appendfile
  delivery_date_add
  envelope_to_add
  return_path_add
address_reply:
  driver = autoreply
begin retry
*                      *           F,2h,15m; G,16h,1h,1.5; F,4d,6h
begin rewrite
begin authenticators
zero323
  • 322,348
  • 103
  • 959
  • 935

1 Answers1

0

You have to add the router and the transport. Router should be placed at the top of the routers stack:

begin routers
ruby:
  driver    = accept
  domains   = domain.tld : another.tld
  transport = ruby_script
. . . . .  

And then a transport - at arbitrary position in the transport list:

begin transports
ruby_script:
  driver  = pipe
  user    = someuser
  command = /path/to/the/script.rb

someuser should have enough permissions to run the script.
Content of the message including all the headers will be passed to the standard input of the script.

Kondybas
  • 686
  • 6
  • 15
  • Darn, it all sounds so simple and obvious right now... Thank you very much, this did it! – TheImmortal Nov 23 '18 at 12:39
  • @TheImmortal Unfortunately the original `exim` specification isn't a good reading for beginners. It's absolutely comprehensive and good reference if you already know what and how do you want to do something. But you definitely need some other book for painless jump-in. – Kondybas Nov 23 '18 at 17:17