EXIM
What is Exim?
Well this is Exim defined by their webpage (http://www.exim.org)
“Exim is a mail transfer agent (MTA) for hosts that are running Unix or Unix-like operating systems. It was designed on the assumption that it would be run on hosts that are permanently connected to the Internet.”
Basically Exim takes email in to your server and stores it in a mailbox for you to retrieve at a later date. It also takes email you send and sends it to another server.
About this documentation:
The domain we will use as an example is: mydomain.com
How does it know how to deliver mail?
Well first it reads through a configuration file (/etc/exim.conf) and gets rules from there. These rules tell it how to handle the file. One of the rules tells it to check (/etc/valiases/domainname.tld), the valias file.
What is a valias file and how does it work?
Well this is a simple valias file:
Quote:
ajz@mydomain.com: ajz@otherdomain.com
ajz@mydomain.com: ajz@otherdomain.net
*: :blackhole:
Lets take a look at the first line “ajz@mydomain.com: ajz@otherdomain.com”
This takes any email to ajz@mydomain.com and forwards it to ajz@otherdomain.com
The second line is very similar “ajz@mydomain.com: ajz@otherdomain.net”
This takes any email send to ajz@mydomain.com and forwards it to "ajz@otherdomain.net"
Now as you can see it goes from top to bottom. If it cant find a specific email address it goes to the last line *: :blackhole: in this case. Now, * means anything else. The :blackhole: is a special system call, basically it sends everything to /dev/null also known as deleted.
So anything else sent to mydomain.com will be immediately deleted.
The other option besides :blackhole: is :fail:. This send a bounce back email saying that the email could not be sent.
You can use also :blackhole: with any other email address also (like xyz@mydomain.com : :blackhole
What is the config file and how does it work?
The config file is located at /etc/exim.conf and has many parts to it (you can also see this in WHM under Service Configuration -> Exim Configuration Editor). It is how Exim separates and sends email. Now let us take a look at the default config file that comes with cPanel.
Code:
#!!# cPanel Exim 4 Config
Well this is just as it looks, the comment letting us know that this is cPanel’s Exim config file.
After this comes a text box, you can put some configuration options. This is always referred to as “Exim box 1”.
Code:
acl_smtp_rcpt = check_recipient
This option defines the ACL that is run when an SMTP RCPT command is received. Here it runs a separate part of code that is defined later as a sub routine or ACL. This sub routine is the check_recipient routine.
Code:
acl_smtp_data = check_message
This option defines the ACL that is run after an SMTP DATA command has been processed and the message itself has been received, but before the final acknowledgement is sent.
In this code the ACL that is ran is check_message
Code:
domainlist local_domains = lsearch;/etc/localdomains
This setting defines a named domain list called local_domains, created from the old options that referred to local domains. It will be referenced later on by the syntax "+local_domains".
Basically it open /etc/localdomains and reads each line as a separate “local domain” so that it can be called later as +local_domains
Code:
domainlist relay_domains = lsearch;/etc/localdomains : \
lsearch;/etc/secondarymx
This defines +relay_domains the same way as +local_domains, but this time it also includes /etc/secondarymx
Code:
hostlist relay_hosts = lsearch;/etc/relayhosts : \
localhost
Once again this defines +relay_hosts from /etc/relayhosts and also adds in the localhost hostname.
Code:
hostlist auth_relay_hosts = *
This sets +auth_relay_hosts as * or all
Now lets look more into the MAIN CONFIGURATION SETTINGS
Code:
perl_startup = do '/etc/exim.pl'
This runs the perl script /etc/exim.pl on startup.
Code:
smtp_banner = "${primary_hostname} ESMTP Exim ${version_number} \
\#${compile_number} ${tod_full} \n\
We do not authorize the use of this system to transport unsolicited, \n\
and/or bulk e-mail."
This shows the Exim login from smtp. To test it out “telnet mydomain.com 110” from a dos prompt. You should see what is there (with variables replaces).
Code:
no_local_from_check
Prevents user ‘nobody’ from sending email (this is set under tweak settings)
Code:
rfc1413_query_timeout = 2s
This sets the timeout on RFC 1413 identification calls. If it is set to zero, no RFC 1413 calls are ever made.
Taken from the RFC Documentation about what RFC 1413 (http://www.faqs.org/rfcs/rfc1413.html) is:
“This is a connection based application on TCP. A server listens for TCP connections on TCP port 113 (decimal). Once a connection is established, the server reads a line of data which specifies the connection of interest. If it exists, the system dependent user identifier of the connection of interest is sent as the reply. The server may then either shut the connection down or it may continue to read/respond to multiple queries.”
Code:
smtp_connect_backlog = 50
This option specifies a maximum number of waiting SMTP connections. Exim passes this value to the TCP/IP system when it sets up its listener. Once this number of connections are waiting for the daemon's attention, subsequent connection attempts are refused at the TCP/IP level. At least, that is what the manuals say; in some circumstances such connection attempts have been observed to time out instead. For large systems it is probably a good idea to increase the value (to 50, say). It also gives some protection against denial-of-service attacks by SYN flooding.
Code:
smtp_accept_max = 100
This option specifies the maximum number of simultaneous incoming SMTP calls that Exim will accept. It applies only to the listening daemon; there is no control (in Exim) when incoming SMTP is being handled by inetd. If the value is set to zero, no limit is applied.
Code:
deliver_queue_load_max = 3
When this option is set, a queue run is abandoned if the system load average becomes greater than the value of the option.
Code:
auto_thaw = 1h
If this option is set to a time greater than zero, a queue runner will try a new delivery attempt on any frozen message if this much time has passed since it was frozen. This may result in the message being re-frozen if nothing has changed since the last attempt.
Code:
system_filter = /etc/antivirus.exim
This runs all email through a filter located at /etc/antivirus.exim
Code:
message_body_visible = 5000
This option specifies how much of a message's body is to be included in the $message_body and $message_body_end expansion variables. (will be used later on)
Code:
never_users = root
This is a safety concern so that email is never attempted to be sent as the root user.
Code:
Timeout_frozen_after = 7d
Any email that is frozen after 7d will be removed. (This email is basically undeliverable)
Code:
tls_certificate = /etc/exim.crt
The Cert for secure (TLS) Exim port.
Code:
tls_privatekey = /etc/exim.key
The private key for secure (TLS) Exim port.
Code:
tls_advertise_hosts = *
When Exim is built with support for TLS encrypted connections, the availability of the STARTTLS command to set up an encrypted session is advertised in response to EHLO only to those client hosts that match this option
Makes all domains able to use TLS
Code:
helo_accept_junk_hosts = *
Exim checks the syntax of HELO and EHLO commands for incoming SMTP mail, and gives an error response for invalid data. Unfortunately, there are some SMTP clients that send syntactic junk. They can be accommodated by setting this option.
Code:
smtp_enforce_sync = false
The SMTP protocol specification requires the client to wait for a response from the server at certain points in the dialogue. Without PIPELINING these synchronization points are after every command; with PIPELINING they are fewer, but they still exist. Some spamming sites send out a complete set of SMTP commands without waiting for any response. Exim protects against this by rejecting a message if the client has sent further input when it should not have. The error response “554 SMTP synchronization error” is sent, and the connection is dropped. Testing for this error cannot be perfect because of transmission delays (unexpected input may be on its way but not yet received when Exim checks).
Code:
begin acl
This lets Exim know that we will begin making the ACL sub routines (the ones we defined above).
Next we have Exim Box 2 (this should be empty by default)
Then we have Exim Box 3, this will have a lot of text in it (all of the ACL’s)
Code:
accept hosts = :
This starts the accept_hosts calls
Code:
warn message = X-WhitelistedRCPT-nohdrfromcallback: Yes
condition = \
${if and {{match{$local_part}{(.*)-bounces\+.*}} \
{exists {/usr/local/cpanel/3rdparty/mailman/lists/${lc:$1}/config.pck}}} \
{yes}{no}}
accept condition = \
${if and {{match{$local_part}{(.*)-bounces\+.*}} \
{exists {/usr/local/cpanel/3rdparty/mailman/lists/${lc:$1}/config.pck}}} \
{yes}{no}}
This accepts bounces to lists even if callbacks or other checks would fail
Code:
require verify = sender
accept domains = +local_domains
endpass
This verifies all message senders that are not sent to a mailman list and if it can’t verify the sender it bounces it.
Code:
message = "The recipient cannot be verified. Please check all recipients of this message to verify they are valid."
verify = recipient
This verifies the recipient, if it cannot it bounces it and says “The recipient cannot be verified. Please check all recipients of this message to verify they are valid.”
Code:
accept domains = +relay_domains
Accepts domains that are in +relay_domains (that we set earlier)
Code:
warn message = ${perl{popbeforesmtpwarn}{$sender_host_name}}
hosts = +relay_hosts
accept hosts = +relay_hosts
Checks to see if the sending host name is in +relay_hosts(we set this earlier) and if it is not it run it through the perl script (we also sent earlier)
Code:
warn message = ${perl{popbeforesmtpwarn}{$sender_host_address}}
condition = ${perl{checkrelayhost}{$sender_host_address}}
accept condition = ${perl{checkrelayhost}{$sender_host_address}}
Runs the user host address through the perl script.
Code:
accept hosts = +auth_relay_hosts
endpass
message = $sender_fullhost is currently not permitted to \
relay through this server. Perhaps you \
have not logged into the pop/imap server in the \
last 30 minutes or do not have SMTP Authentication turned on in your email client.
authenticated = *
Accepts hosts that are in +auth_relay_hosts or if they are authenticated otherwise it errors out.
Code:
deny message = $sender_fullhost is currently not permitted to \
relay through this server. Perhaps you \
have not logged into the pop/imap server in the \
last 30 minutes or do not have SMTP Authentication turned on in your email client.
If they are denied it errors with this message
Code:
check_message:
require verify = header_sender
accept
Checks the message and makes sure it has correct headers.
That is the end of this box!
Code:
begin authenticators
fixed_plain:
driver = plaintext
public_name = PLAIN
server_condition = "${perl{checkuserpass}{$1}{$2}{$3}}"
server_set_id = $2
fixed_login:
driver = plaintext
public_name = LOGIN
server_prompts = "Username:: : Password::"
server_condition = "${perl{checkuserpass}{$1}{$2}}"
server_set_id = $1
Does the login authentication for SMTP.
This is followed by another blank box (if you need it)
Code:
begin rewrite
Begins the rewrite section
Code:
nobody@lsearch;/etc/localdomains "${if !eq {$header_From:}{}{$header_sender:$header_From:}fail}" Fs
cpanel@lsearch;/etc/localdomains "${if !eq {$header_From:}{}{$header_sender:$header_From:}fail}" Fs
Tries to rewrite the cpanel & nobody to the domain name instead of server name.
Followed by another blank box (for more rewrites)
Code:
begin routers
Lets Exim know you are beginning the routers (how Exim handles non-local email)
Code:
mailman_virtual_router:
driver = accept
require_files = /usr/local/cpanel/3rdparty/mailman/lists/${lc::$local_part}_${lc::$domain}/config.pck
local_part_suffix_optional
local_part_suffix = -admin : \
-bounces : -bounces+* : \
-confirm : -confirm+* : \
-join : -leave : \
-owner : -request : \
-subscribe : -unsubscribe
transport = mailman_virtual_transport
mailman_virtual_router_nodns:
driver = accept
require_files = /usr/local/cpanel/3rdparty/mailman/lists/${lc::$local_part}/config.pck
condition = \
${if or {{match{$local_part}{.*_.*}} \
{eq{$local_part}{mailman}}} \
{1}{0}}
local_part_suffix_optional
local_part_suffix = -admin : \
-bounces : -bounces+* : \
-confirm : -confirm+* : \
-join : -leave : \
-owner : -request : \
-subscribe : -unsubscribe
transport = mailman_virtual_transport_nodns
If we are trying to deliver to a remote mailman domain that is on the localhost let it go though even if its not in /etc/localdomains since mailman will eat up 100% of the cpu if we don't
Next we have another Blank box (for routers this time)
Code:
lookuphost:
driver = dnslookup
condition = "${perl{checkspam}}"
domains = ! +local_domains
#ignore verisign to prevent waste of bandwidth
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8 : 64.94.110.0/24
headers_add = "${perl{mailtrapheaders}}"
transport = remote_smtp
This router routes to remote hosts over SMTP using a DNS lookup with default options.
Code:
literal:
driver = ipliteral
condition = "${perl{checkspam}}"
domains = ! +local_domains
headers_add = "${perl{mailtrapheaders}}"
transport = remote_smtp
This router routes to remote hosts over SMTP by explicit IP address, given as a "domain literal" in the form [nnn.nnn.nnn.nnn]. The RFCs require this facility, which is why it is enabled by default in Exim. If you want to lock it out, set forbid_domain_literals in the main configuration section above.
Code:
fail_remote_domains:
driver = redirect
domains = ! +local_domains
allow_fail
data = :fail: unrouteable mail domain "$domain"
This new router is put here to fail all domains that were not in local_domains in the Exim 3 configuration.
Another Blank Box
DIRECTORS CONFIGURATION (Specifies how local addresses are handled)
Code:
virtual_sa_user:
driver = accept
headers_add="${perl{gensaheader_virtual}{$domain}}"
condition = "${perl{checksa_deliver}{$domain}{$local_part}{$received_protocol}}"
domains = lsearch;/etc/userdomains
retry_use_local_part
transport = virtual_sa_userdelivery
sa_localuser:
driver = accept
check_local_user
headers_add="${perl{gensaheader}{$local_part}}"
condition = "${perl{checkusersa}{$local_part}{$received_protocol}}"
domains = ! lsearch;/etc/userdomains
transport = local_sa_delivery
central_filter:
#!!# filter renamed allow_filter
driver = redirect
allow_filter
no_check_local_user
file = /etc/vfilters/${domain}
file_transport = address_file
pipe_transport = virtual_address_pipe
reply_transport = address_reply
retry_use_local_part
user = "${lookup{$domain}lsearch* {/etc/userdomains}{$value}}"
no_verify
central_user_filter:
driver = redirect
allow_filter
check_local_user
domains = ! lsearch;/etc/userdomains
condition = "${perl{hasfilterfile}{$local_part}}"
file = "${perl{getfilterfile}{$local_part}}"
file_transport = address_file
pipe_transport = virtual_address_pipe
reply_transport = address_reply
retry_use_local_part
no_verify
virtual_aliases_nostar:
driver = redirect
allow_defer
allow_fail
data = ${if exists{/etc/valiases/$domain}{${lookup{$local_part@$domain}lsearch{/etc/valiases/$domain}}}}
file_transport = address_file
group = mail
pipe_transport = virtual_address_pipe
retry_use_local_part
domains = lsearch;/etc/localdomains
unseen
virtual_user_spam:
driver = accept
condition = "${perl{check_deliver_spam}{$domain}{$local_part}}"
headers_remove="x-spam-exim"
domains = lsearch;/etc/userdomains
retry_use_local_part
transport = virtual_userdelivery_spam
virtual_user:
driver = accept
condition = "${perl{check_deliver}{$domain}{$local_part}}"
headers_remove="x-spam-exim"
domains = lsearch;/etc/userdomains
retry_use_local_part
transport = virtual_userdelivery
has_alias_but_no_mailbox_discarded_to_prevent_loop:
driver = redirect
condition = "${perl{checkvalias}{$domain}{$local_part}}"
domains = lsearch;/etc/localdomains
data="#Exim Filter\nseen finish"
group = "${lookup{$domain}lsearch* {/etc/userdomains}{$value}}"
user = "${lookup{$domain}lsearch* {/etc/userdomains}{$value}}"
allow_filter
disable_logging = true
virtual_aliases:
driver = redirect
allow_defer
allow_fail
data = ${if exists{/etc/valiases/$domain}{${lookup{*}lsearch{/etc/valiases/$domain}}}}
file_transport = address_file
group = mail
pipe_transport = virtual_address_pipe
domains = lsearch;/etc/localdomains
retry_use_local_part
Verifies that the user exists on the server and if so puts the email in that mail box (I grouped them all together because they are all pretty much the same)
Code:
system_aliases:
driver = redirect
allow_defer
allow_fail
data = ${lookup{$local_part}lsearch{/etc/aliases}}
file_transport = address_file
pipe_transport = address_pipe
retry_use_local_part
# user = exim
local_aliases:
driver = redirect
allow_defer
allow_fail
data = ${lookup{$local_part}lsearch{/etc/localaliases}}
file_transport = address_file
pipe_transport = address_pipe
check_local_user
userforward:
#!!# filter renamed allow_filter
driver = redirect
allow_filter
check_ancestor
check_local_user
domains = ! lsearch;/etc/userdomains
no_expn
file = $home/.forward
file_transport = address_file
pipe_transport = address_pipe
reply_transport = address_reply
no_verify
localuser_spam:
driver = accept
headers_remove="x-spam-exim"
condition = "${perl{checkuserspambox}{$local_part}}"
check_local_user
domains = ! lsearch;/etc/userdomains
transport = local_delivery_spam
localuser:
driver = accept
headers_remove="x-spam-exim"
check_local_user
domains = ! lsearch;/etc/userdomains
transport = local_delivery
Allows the .forward that some people like
Another Box
TRANSPORTS CONFIGURATION (the configurations of the transports used by exim)
Code:
begin transports
Tells Exim that we define the transports here
Code:
remote_smtp:
driver = smtp
This is straight forward, the remote_smtp transport uses the smtp protocol
Code:
local_delivery:
driver = appendfile
delivery_date_add
envelope_to_add
file = "${extract{5}{:}{${lookup{$local_part}lsearch{/etc/passwd}{$value}}}}/mail/inbox"
group = mail
mode = 0660
return_path_add
user = $local_part
Normal email is sent to the mail/inbox folder for the user
Code:
local_delivery_spam:
driver = appendfile
delivery_date_add
envelope_to_add
file = "${extract{5}{:}{${lookup{$local_part}lsearch{/etc/passwd}{$value}}}}/mail/spam"
group = mail
mode = 0660
return_path_add
user = $local_part
This sends email marked as spam to the mail/spam folder
Code:
local_sa_delivery:
driver = pipe
command = /usr/sbin/sendmail -bS
use_bsmtp = true
transport_filter = "/usr/bin/spamc"
user = $local_part
group = mail
log_output = true
current_directory = "/tmp"
home_directory = "/tmp"
return_fail_output = true
return_path_add = false
message_prefix =
message_suffix =
Sends the email through spamassasin
Code:
address_pipe:
driver = pipe
return_output
This pipes email through
Code:
virtual_address_pipe:
driver = pipe
group = "${lookup{$domain}lsearch* {/etc/userdomains}{$value}}"
return_output
user = "${lookup{$domain}lsearch* {/etc/userdomains}{$value}}"
Also just helps with piping the email through to the location request in the valias.
Code:
address_file:
driver = appendfile
delivery_date_add
envelope_to_add
return_path_add
This transport is used for handling deliveries directly to files that are generated by aliasing or forwarding.
Code:
virtual_sa_userdelivery:
driver = pipe
command = /usr/sbin/sendmail -bS
use_bsmtp = true
transport_filter = "/usr/bin/spamc"
user = "${lookup{$domain}lsearch* {/etc/userdomains}{$value}}"
group = mail
log_output = true
current_directory = "/tmp"
home_directory = "/tmp"
return_fail_output = true
return_path_add = false
message_prefix =
message_suffix =
virtual_userdelivery_spam:
driver = appendfile
delivery_date_add
envelope_to_add
file = "${extract{5}{:}{${lookup{${lookup{$domain}lsearch*{/etc/userdomains}{$value}}}lsearch{/etc/passwd}{$value}}}}/mail/${domain}/${local_part}/spam"
group = mail
mode = 0660
quota = "${if exists{${extract{5}{:}{${lookup{${lookup{$domain}lsearch*{/etc/userdomains}{$value}}}lsearch{/etc/passwd}{$value}}}}/etc/${domain}/quota} {${lookup{$local_part}lsearch*{${extract{5}{:}{${lookup{${lookup{$domain}lsearch*{/etc/userdomains}{$value}}}lsearch{/etc/passwd}{$value}}}}/etc/${domain}/quota}{$value}}} {}}"
return_path_add
user = "${lookup{$domain}lsearch* {/etc/userdomains}{$value}}"
virtual_userdelivery:
driver = appendfile
delivery_date_add
envelope_to_add
file = "${extract{5}{:}{${lookup{${lookup{$domain}lsearch*{/etc/userdomains}{$value}}}lsearch{/etc/passwd}{$value}}}}/mail/${domain}/${local_part}/inbox"
group = mail
mode = 0660
quota = "${if exists{${extract{5}{:}{${lookup{${lookup{$domain}lsearch*{/etc/userdomains}{$value}}}lsearch{/etc/passwd}{$value}}}}/etc/${domain}/quota} {${lookup{$local_part}lsearch*{${extract{5}{:}{${lookup{${lookup{$domain}lsearch*{/etc/userdomains}{$value}}}lsearch{/etc/passwd}{$value}}}}/etc/${domain}/quota}{$value}}} {}}"
return_path_add
user = "${lookup{$domain}lsearch* {/etc/userdomains}{$value}}"
This transport is used for handling autoreplies generated by the filtering option of the forwardfile director.
Code:
address_reply:
driver = autoreply
This is for autoreplies
Code:
mailman_virtual_transport:
driver = pipe
command = /usr/local/cpanel/3rdparty/mailman/mail/mailman \
'${if def:local_part_suffix \
{${sg{$local_part_suffix}{-(\\w+)(\\+.*)?}{\$1}}} \
{post}}' \
${lc:$local_part}_${lc:$domain}
current_directory = /usr/local/cpanel/3rdparty/mailman
home_directory = /usr/local/cpanel/3rdparty/mailman
user = mailman
group = mailman
mailman_virtual_transport_nodns:
driver = pipe
command = /usr/local/cpanel/3rdparty/mailman/mail/mailman \
'${if def:local_part_suffix \
{${sg{$local_part_suffix}{-(\\w+)(\\+.*)?}{\$1}}} \
{post}}' \
${lc:$local_part}
current_directory = /usr/local/cpanel/3rdparty/mailman
home_directory = /usr/local/cpanel/3rdparty/mailman
user = mailman
group = mailman
Mailman transports
RETRY CONFIGURATION
Code:
begin retry
Tells Exim that we are starting the retry rules
Code:
* * F,2h,15m; G,16h,1h,1.5; F,4d,8h
This single retry rule applies to all domains and all errors. It specifies retries every 15 minutes for 2 hours, then increasing retry intervals, starting at 1 hour and increasing each time by a factor of 1.5, up to 16 hours, then retries every 8 hours until 4 days have passed since the first failed delivery.
That is your Exim config files and how Exim works on your cPanel box.
No comments:
Post a Comment