Re: [exim] configure exim4 against incoming rogue local part…

Αρχική Σελίδα
Delete this message
Reply to this message
Συντάκτης: Alessandro Foddi
Ημερομηνία:  
Προς: exim-users
Αντικείμενο: Re: [exim] configure exim4 against incoming rogue local parts
Thanks for your help.

I've attached the file I got from "exim4 -bP config...".

I'm expecting that any email incoming from my own host (not from
pipeline), whose local part begins with a "." or that contains any of
these "@%!/|`#&?" characters, is going to be blocked.

If the mail is coming from other hosts, I'm expecting that it should be
blocked if the local part begins with any of these "./|", or if it
contains any of these "@%!`#&?" or if it contains the sequence "/../".

The problem is that this is not happening and I can receive any email,
regardless the characters contained in the local parts. I tested it
using a remote client of the same host, and from other hosts.

This is just a virtual machine I use for testing purposes; so I can even
attach the config file containing the real domain if necessary. The same
thing happens even with my "real" servers I only use for personal
purposes. So I assume there is some nuance in the config file I don't
understand.

As far as I know, if in the main part of the config file there is:

acl_smtp_rcpt = acl_check_rcpt

it means that the acl acl_check_rcpt should be applied for every
incoming email.

Cheers

Ale


On 02/06/22 15:53, Jeremy Harris via Exim-users wrote:
> On 01/06/2022 16:28, Alessandro via Exim-users wrote:
>> I installed exim4 4.94.2 on a debian 11.3 machine. I configured it
>> using exim4-config as straight smtp mta. I have just declared a few
>> macros on the exim4.conf.localmacros, so basically I'm using the
>> default configuration created by exim4-config. I've been trying to
>> understand the acl_check_rcpt acl, specifically the part that should
>> be "guarding against incoming rogue local parts"
>
> Run "exim -bP config >my_resolved_config"
>
> (it might be called exim4 rather than exim on your machine, despite
> exim version 3 having gone out of date twenty years ago...)
>
> This gives a file of the configuration with all the .ifdefs resolved,
> which would probably be earier to read than what I've seen of
> the Debian auto-generated one.
>
>> The problem is that it's not working
>
> What is it doing or not doing, versus your expectations?
# Exim Configuration (4.94.2)
# 1 "/var/lib/exim4/config.autogenerated"
MAIN_TLS_ENABLE = yes
DKIM_CANON = relaxed
DKIM_SELECTOR = default
DKIM_DOMAIN = mydomain
DKIM_FILE = /etc/exim4/dkim/dkim.pem
DKIM_PRIVATE_KEY = /etc/exim4/dkim/dkim.pem
REMOTE_SMTP_HELO_DATA = mydomain
MAIN_TLS_CERTIFICATE = /etc/letsencrypt/live/mydomain/fullchain.pem
MAIN_TLS_PRIVATEKEY = /etc/letsencrypt/live/mydomain/privkey.pem
MAIN_QUALIFY_DOMAIN = mydomain
TLS_ON_CONNECT_PORTS = 465
CHECK_RCPT_IP_DNSBLS = zen.spamhaus.org
MAIN_LOCAL_DOMAINS = mydomain
exim_path = /usr/sbin/exim4
CONFDIR = /etc/exim4
disable_ipv6 = true
UPEX4CmacrosUPEX4C = 1
MAIN_PACKAGE_VERSION=4.94.2-7
MAIN_RELAY_TO_DOMAINS=
ETC_MAILNAME=mydomain
LOCAL_DELIVERY=maildir_home
MAIN_RELAY_NETS=: 127.0.0.1 : ::::1
DCreadhost=
DCsmarthost=
DC_eximconfig_configtype=internet
DCconfig_internet=1
domainlist local_domains = mydomain
domainlist relay_to_domains =
hostlist relay_from_hosts = : 127.0.0.1 : ::::1
qualify_domain = mydomain
gecos_pattern = ^([^,:]*)
gecos_name = $1
MAIN_LOG_SELECTOR = +smtp_protocol_error +smtp_syntax_error +tls_certificate_verified +tls_peerdn
MAIN_ACL_CHECK_MAIL = acl_check_mail
acl_smtp_mail = acl_check_mail
MAIN_ACL_CHECK_RCPT = acl_check_rcpt
acl_smtp_rcpt = acl_check_rcpt
MAIN_ACL_CHECK_DATA = acl_check_data
acl_smtp_data = acl_check_data
MAIN_HOST_LOOKUP = *
host_lookup = *
dns_dnssec_ok = 1
prdr_enable = true
local_from_check = false
local_sender_retain = true
untrusted_set_sender = *
MAIN_IGNORE_BOUNCE_ERRORS_AFTER = 2d
ignore_bounce_errors_after = 2d
MAIN_TIMEOUT_FROZEN_AFTER = 7d
timeout_frozen_after = 7d
MAIN_FREEZE_TELL = postmaster
freeze_tell = postmaster
SPOOLDIR = /var/spool/exim4
spool_directory = /var/spool/exim4
MAIN_TRUSTED_USERS = uucp
trusted_users = uucp
keep_environment =
MAIN_SMTPUTF8_ADVERTISE_HOSTS =
smtputf8_advertise_hosts =
MAIN_TLS_ADVERTISE_HOSTS = *
tls_advertise_hosts = *
tls_certificate = /etc/letsencrypt/live/mydomain/fullchain.pem
tls_privatekey = /etc/letsencrypt/live/mydomain/privkey.pem
MAIN_TLS_VERIFY_CERTIFICATES = ${if exists{/etc/ssl/certs/ca-certificates.crt}{/etc/ssl/certs/ca-certificates.crt}{/dev/null}}
tls_verify_certificates = ${if exists{/etc/ssl/certs/ca-certificates.crt}{/etc/ssl/certs/ca-certificates.crt}{/dev/null}}
log_selector = +smtp_protocol_error +smtp_syntax_error +tls_certificate_verified +tls_peerdn

begin acl

  acl_local_deny_exceptions:
    accept
    hosts = ${if exists{/etc/exim4/host_local_deny_exceptions}{/etc/exim4/host_local_deny_exceptions}{}}
    accept
    senders = ${if exists{/etc/exim4/sender_local_deny_exceptions}{/etc/exim4/sender_local_deny_exceptions}{}}
    accept
    hosts = ${if exists{/etc/exim4/local_host_whitelist}{/etc/exim4/local_host_whitelist}{}}
    accept
    senders = ${if exists{/etc/exim4/local_sender_whitelist}{/etc/exim4/local_sender_whitelist}{}}


  acl_check_mail:
    accept
    CHECK_RCPT_LOCAL_LOCALPARTS = ^[.] : ^.*[@%!/|`#&?]
    CHECK_RCPT_REMOTE_LOCALPARTS = ^[./|] : ^.*[@%!`#&?] : ^.*/\\.\\./


  acl_check_rcpt:
    accept
    hosts = :
    control = dkim_disable_verify
    deny
    domains = +local_domains
    local_parts = ^[.] : ^.*[@%!/|`#&?]
    message = restricted characters in address
    deny
    domains = !+local_domains
    local_parts = ^[./|] : ^.*[@%!`#&?] : ^.*/\\.\\./
    message = restricted characters in address
    accept
    local_parts = postmaster
    domains = +local_domains : +relay_to_domains
    deny
    !acl = acl_local_deny_exceptions
    senders = ${if exists{/etc/exim4/local_sender_callout}{/etc/exim4/local_sender_callout}{}}
    !verify = sender/callout
    deny condition = ${if and {{>{$rcpt_count}{10}}{<{$recipients_count}{${eval:$rcpt_count/2}}} }}
    message = Rejected for too many bad recipients
    logwrite = REJECT [$sender_host_address]: bad recipient count high [${eval:$rcpt_count-$recipients_count}]
    accept
    hosts = +relay_from_hosts
    control = submission/sender_retain
    control = dkim_disable_verify
    accept
    authenticated = *
    control = submission/sender_retain
    control = dkim_disable_verify
    require
    condition = ${if def:sender_helo_name}
    message = nice hosts say HELO first
    require
    message = relay not permitted
    domains = +local_domains : +relay_to_domains
    require
    verify = recipient
    deny
    !acl = acl_local_deny_exceptions
    recipients = ${if exists{/etc/exim4/local_rcpt_callout}{/etc/exim4/local_rcpt_callout}{}}
    !verify = recipient/callout
    deny
    !acl = acl_local_deny_exceptions
    senders = ${if exists{/etc/exim4/local_sender_blacklist}{/etc/exim4/local_sender_blacklist}{}}
    message = sender envelope address $sender_address is locally blacklisted here. If you think this is wrong, get in touch with postmaster
    log_message = sender envelope address is locally blacklisted.
    deny
    !acl = acl_local_deny_exceptions
    hosts = ${if exists{/etc/exim4/local_host_blacklist}{/etc/exim4/local_host_blacklist}{}}
    message = sender IP address $sender_host_address is locally blacklisted here. If you think this is wrong, get in touch with postmaster
    log_message = sender IP address is locally blacklisted.
    warn
    dnslists = zen.spamhaus.org
    add_header = X-Warning: $sender_host_address is listed at $dnslist_domain ($dnslist_value: $dnslist_text)
    log_message = $sender_host_address is listed at $dnslist_domain ($dnslist_value: $dnslist_text)
    accept
    domains = +relay_to_domains
    endpass
    verify = recipient
    accept


  acl_check_data:
    deny
    condition = ${if > {$max_received_linelength}{998}}
    message = maximum allowed line length is 998 octets, got $max_received_linelength
    deny
    !acl = acl_local_deny_exceptions
    !verify = header_syntax
    message = header syntax
    log_message = header syntax ($acl_verify_message)
    accept


begin routers

  hubbed_hosts:
    debug_print = "R: hubbed_hosts for $domain"
    driver = manualroute
    domains = "${if exists{/etc/exim4/hubbed_hosts}{partial-lsearch;/etc/exim4/hubbed_hosts}fail}"
    same_domain_copy_routing = yes
    route_data = ${lookup{$domain}partial-lsearch{/etc/exim4/hubbed_hosts}}
    transport = remote_smtp


  dnslookup_relay_to_domains:
    debug_print = "R: dnslookup_relay_to_domains for $local_part@$domain"
    driver = dnslookup
    domains = ! +local_domains : +relay_to_domains
    transport = remote_smtp
    same_domain_copy_routing = yes
    no_more
    ROUTER_DNSLOOKUP_IGNORE_TARGET_HOSTS = <; 0.0.0.0 ; 127.0.0.0/8 ; 192.168.0.0/16 ; 172.16.0.0/12 ; 10.0.0.0/8 ; 169.254.0.0/16 ; 255.255.255.255 ; ::/128 ; ::1/128 ; fc00::/7 ; fe80::/10 ; 100::/64


  dnslookup:
    debug_print = "R: dnslookup for $local_part@$domain"
    driver = dnslookup
    domains = ! +local_domains
    transport = remote_smtp
    same_domain_copy_routing = yes
    ignore_target_hosts = <; 0.0.0.0 ; 127.0.0.0/8 ; 192.168.0.0/16 ; 172.16.0.0/12 ; 10.0.0.0/8 ; 169.254.0.0/16 ; 255.255.255.255 ; ::/128 ; ::1/128 ; fc00::/7 ; fe80::/10 ; 100::/64
    no_more
    COND_LOCAL_SUBMITTER = "${if match_ip{$sender_host_address}{:@[]}{1}{0}}"


  real_local:
    debug_print = "R: real_local for $local_part@$domain"
    driver = accept
    domains = +local_domains
    condition = "${if match_ip{$sender_host_address}{:@[]}{1}{0}}"
    local_part_prefix = real-
    check_local_user
    transport = maildir_home


  system_aliases:
    debug_print = "R: system_aliases for $local_part@$domain"
    driver = redirect
    domains = +local_domains
    allow_fail
    allow_defer
    data = ${lookup{$local_part}lsearch{/etc/aliases}}


  userforward:
    debug_print = "R: userforward for $local_part@$domain"
    driver = redirect
    domains = +local_domains
    check_local_user
    file = $home/.forward
    require_files = $local_part_data:$home/.forward
    no_verify
    no_expn
    check_ancestor
    allow_filter
    forbid_smtp_code = true
    directory_transport = address_directory
    file_transport = address_file
    pipe_transport = address_pipe
    reply_transport = address_reply
    skip_syntax_errors
    syntax_errors_to = real-$local_part@$domain
    syntax_errors_text = This is an automatically generated message. An error has\nbeen found in your .forward file. Details of the error are\nreported below. While this error persists, you will receive\na copy of this message for every message that is addressed\nto you. If your .forward file is a filter file, or if it is\na non-filter file containing no valid forwarding addresses,\na copy of each incoming message will be put in your normal\nmailbox. If a non-filter file contains at least one valid\nforwarding address, forwarding to the valid addresses will\nhappen, and those will be the only deliveries that occur.


  procmail:
    debug_print = "R: procmail for $local_part@$domain"
    driver = accept
    domains = +local_domains
    check_local_user
    transport = procmail_pipe
    require_files = ${local_part_data}:${if exists{/etc/procmailrc}{/etc/procmailrc}{${home}/.procmailrc}}:+/usr/bin/procmail
    no_verify
    no_expn


  maildrop:
    debug_print = "R: maildrop for $local_part@$domain"
    driver = accept
    domains = +local_domains
    check_local_user
    transport = maildrop_pipe
    require_files = ${local_part_data}:${home}/.mailfilter:+/usr/bin/maildrop
    no_verify
    no_expn
    FIRST_USER_ACCOUNT_UID = 0
    DEFAULT_SYSTEM_ACCOUNT_ALIAS = :fail: no mail to system accounts
    COND_SYSTEM_USER_AND_REMOTE_SUBMITTER = "${if and{{! match_ip{$sender_host_address}{:@[]}}{<{$local_user_uid}{0}}}{1}{0}}"


  lowuid_aliases:
    debug_print = "R: lowuid_aliases for $local_part@$domain (UID $local_user_uid)"
    check_local_user
    driver = redirect
    allow_fail
    domains = +local_domains
    condition = "${if and{{! match_ip{$sender_host_address}{:@[]}}{<{$local_user_uid}{0}}}{1}{0}}"
    data = ${if exists{/etc/exim4/lowuid-aliases}{${lookup{$local_part}lsearch{/etc/exim4/lowuid-aliases}{$value}{:fail: no mail to system accounts}}}{:fail: no mail to system accounts}}


  local_user:
    debug_print = "R: local_user for $local_part@$domain"
    driver = accept
    domains = +local_domains
    check_local_user
    local_parts = ! root
    transport = maildir_home
    cannot_route_message = Unknown user


  mail4root:
    debug_print = "R: mail4root for $local_part@$domain"
    driver = redirect
    domains = +local_domains
    data = /var/mail/mail
    file_transport = address_file
    local_parts = root
    user = mail
    group = mail


begin transports
REMOTE_SMTP_SMARTHOST_TLS_VERIFY_HOSTS = *

  address_file:
    debug_print = "T: address_file for $local_part@$domain"
    driver = appendfile
    delivery_date_add
    envelope_to_add
    return_path_add


  address_pipe:
    debug_print = "T: address_pipe for $local_part@$domain"
    driver = pipe
    return_fail_output


  address_reply:
    debug_print = "T: autoreply for $local_part@$domain"
    driver = autoreply


  mail_spool:
    debug_print = "T: appendfile for $local_part@$domain"
    driver = appendfile
    file = /var/mail/$local_part_data
    delivery_date_add
    envelope_to_add
    return_path_add
    group = mail
    mode = 0660
    mode_fail_narrower = false


  maildir_home:
    debug_print = "T: maildir_home for $local_part@$domain"
    driver = appendfile
    directory = $home/Maildir
    delivery_date_add
    envelope_to_add
    return_path_add
    maildir_format
    directory_mode = 0700
    mode = 0600
    mode_fail_narrower = false


  maildrop_pipe:
    debug_print = "T: maildrop_pipe for $local_part@$domain"
    driver = pipe
    path = "/bin:/usr/bin:/usr/local/bin"
    command = "/usr/bin/maildrop"
    message_prefix =
    message_suffix =
    return_path_add
    delivery_date_add
    envelope_to_add


  procmail_pipe:
    debug_print = "T: procmail_pipe for $local_part@$domain"
    driver = pipe
    path = "/bin:/usr/bin:/usr/local/bin"
    command = "/usr/bin/procmail"
    return_path_add
    delivery_date_add
    envelope_to_add


  remote_smtp:
    debug_print = "T: remote_smtp for $local_part@$domain"
    driver = smtp
    message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}}
    helo_data=mydomain
    dkim_domain = mydomain
    dkim_selector = default
    dkim_private_key = /etc/exim4/dkim/dkim.pem
    dkim_canon = relaxed


  remote_smtp_smarthost:
    debug_print = "T: remote_smtp_smarthost for $local_part@$domain"
    driver = smtp
    multi_domain
    message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}}
    hosts_try_auth = <; ${if exists{/etc/exim4/passwd.client} {${lookup{$host}nwildlsearch{/etc/exim4/passwd.client}{$host_address}}}{} }
    tls_verify_hosts = *
    helo_data=mydomain


  address_directory:
    debug_print = "T: address_directory for $local_part@$domain"
    driver = appendfile
    delivery_date_add
    envelope_to_add
    return_path_add
    check_string = ""
    escape_string = ""
    maildir_format


begin retry
* * F,2h,15m; G,16h,1h,1.5; F,4d,6h

begin rewrite
*@+local_domains "${lookup{${local_part}}lsearch{/etc/email-addresses}{$value}fail}" Ffrs
*@domumia.dynu.net "${lookup{${local_part}}lsearch{/etc/email-addresses}{$value}fail}" Ffrs

begin authenticators

  login_server:
    driver = plaintext
    public_name = LOGIN
    server_prompts = "Username:: : Password::"
    server_condition = "${if crypteq{$auth2}{${extract{1}{:}{${lookup{$auth1}lsearch{/etc/exim4/passwd}{$value}{*:*}}}}}{1}{0}}"
    server_set_id = $auth1
    server_advertise_condition = ${if eq{$tls_in_cipher}{}{}{*}}


  cram_md5:
    driver = cram_md5
    public_name = CRAM-MD5
    client_name = ${extract{1}{:}{${lookup{$host}nwildlsearch{/etc/exim4/passwd.client}{$value}fail}}}
    client_secret = ${extract{2}{:}{${lookup{$host}nwildlsearch{/etc/exim4/passwd.client}{$value}fail}}}
    PASSWDLINE=${sg{${lookup{$host}nwildlsearch{/etc/exim4/passwd.client}{$value}fail}}{\\N[\\^]\\N}{^^}}


  plain:
    driver = plaintext
    public_name = PLAIN
    client_send = "<; ${if !eq{$tls_out_cipher}{}{^${extract{1}{:}{${sg{${lookup{$host}nwildlsearch{/etc/exim4/passwd.client}{$value}fail}}{\\N[\\^]\\N}{^^}}}}^${sg{${sg{${lookup{$host}nwildlsearch{/etc/exim4/passwd.client}{$value}fail}}{\\N[\\^]\\N}{^^}}}{\\N([^:]+:)(.*)\\N}{\\$2}}}fail}"


  login:
    driver = plaintext
    public_name = LOGIN
    client_send = "<; ${if and{{!eq{$tls_out_cipher}{}}{!eq{${sg{${lookup{$host}nwildlsearch{/etc/exim4/passwd.client}{$value}fail}}{\\N[\\^]\\N}{^^}}}{}}}{}fail}; ${extract{1}{::}{${sg{${lookup{$host}nwildlsearch{/etc/exim4/passwd.client}{$value}fail}}{\\N[\\^]\\N}{^^}}}}; ${sg{${sg{${lookup{$host}nwildlsearch{/etc/exim4/passwd.client}{$value}fail}}{\\N[\\^]\\N}{^^}}}{\\N([^:]+:)(.*)\\N}{\\$2}}"