This is an old revision of the document!
Exim4 - Install Exim4 Complete
Our mail server supports virtual accounts using the MySQL database (enable set like MySQL, I spoke here ), SMTP-authentication and secure connection TLS / SSL.
To use TLS / SSL create a certificate.
mkdir -p /etc/ssl/certs cd /etc/ssl/certs openssl req -x509 -newkey rsa:1024 -keyout mail.pem -out mail.pem \ ? -days 9999 -nodes
Less than 9999 days exist before the Unix / Linux 32-bit date wrap-around occurs.
Country Name (2 letter code) [CA]: State or Province Name (full name) [Quebec]: Locality Name (eg, city) [Montreal]: Organization Name (eg, company) [Open Network Architecture]: Organizational Unit Name (eg, section) [Internet Department]: Common Name (eg, YOUR name) []: Email Address []:
Fills as your heart desires (because you're not going to pay for the certificate), except for the string Common Name (eg, YOUR name) []. Here you need to enter the name of our server:
Common Name (eg, YOUR name) []: sharewiz.net
In the directory /etc/ssl/certs appeared certificate file mail.pem, which in the future we will use for the secure connection to our mail server. We carry on this file two more opertsii:
chmod 440 /etc/ssl/certs/mail.pem chgrp mail /etc/ssl/certs/mail.pem
The certificate is over, now the loans directly to Exim.
For Exim we need a non-privileged user that belongs to the group mail. Create it.
pw useradd exim -c "Exim" -d /var/spool/mqueue -s /sbin/nologin -g mail exit cat /etc/passwd | grep exim
The last command we find that your account has exim uid = 1003, and gid = 6. These data we need in the configuration.
Pick the latest version of Exim (as of this writing - 4.50) from site www.exim.org. Do not take the earlier version. This is due to the fact that, since version 4.50, previously separately existing patch exiscan-acl is integrated in the source code.
cd $HOME/install links www.exim.org tar xzfv exim-4.50.tar.gz cd exim-4.50 cp src/EDITME Local/Makefile
Edit the Local/Makefile
ee Local/Makefile
changing
- Local/Makefile
BIN_DIRECTORY = /usr/exim/bin on BIN_DIRECTORY = /usr/local/exim/bin Here we specify the installation path Exim executable files. CONFIGURE_FILE = /usr/exim/configure on CONFIGURE_FILE = /usr /local/exim/configure Here we specify the name and path of the configuration file. EXIM_USER = on EXIM_USER = 1003 # EXIM_GROUP = on EXIM_GROUP = 6 Remember I talked about the uid and gid? Right now we need them. Please enter a numeric user and group IDs on whose behalf will run Exim. SPOOL_DIRECTORY = /var/spool/exim on SPOOL_DIRECTORY = /var/spool/mqueue Here we specify the name of the spool-directory. # SUPPORT_MAILDIR = yes on SUPPORT_MAILDIR = yes Here we include support for Maildir. # LOOKUP_MYSQL = yes on LOOKUP_MYSQL = yes Here we include support for MySQL.
To find the path to library files and MySQL headers, execute:
/usr/local/mysql/bin/mysql_config
Result
Usage: /usr/local/mysql/bin/mysql_config [OPTIONS] Options: --cflags [-I /usr/local/mysql/include/mysql -fomit-frame-pointer] --include [-I /usr/local/mysql/include/mysql] --libs [-L /usr/local/mysql/ lib/mysql -lmysqlclient -lz -lcrypt -lm] --libs_r [-L /usr/local/mysql/lib/mysql -lmysqlclient_r -lz -lcrypt -lm -lpthread] --socket [/tmp/mysql.sock] --port [3306] --version [4.1.10a] --libmysqld-libs [-L /usr/local/mysql/lib/mysql -lmysqld -lcrypt -lm -lpthread]
These values are substituted into the lines below …
# LOOKUP_INCLUDE = -I /usr/local/ldap/include -I /usr/local/mysql/include # LOOKUP_LIBS = -L /usr/local/lib -lldap -llber -lmysqlclient -lpq on LOOKUP_INCLUDE = -I /usr/local/mysql/include/mysql LOOKUP_LIBS = -L /usr/local/mysql/lib/mysql -lmysqlclient -lz -lcrypt -lm EXIM_MONITOR = eximon.bin on # EXIM_MONITOR = eximon.bin Here, we turn off support for Exim Monitor. For Exim Monitor requires X11, contact is not used. # WITH_CONTENT_SCAN = yes on WITH_CONTENT_SCAN = yes # WITH_OLD_DEMIME = yes on WITH_OLD_DEMIME = yes Here we include an option that will help Exim work with ClamAV and Spamassassin. These are the same options that were not available prior to version 4.50. He saved patch exiscan-acl. # AUTH_CRAM_MD5 = yes # AUTH_PLAINTEXT = yes on AUTH_CRAM_MD5 = yes AUTH_PLAINTEXT = yes Here we include of SMTP-authentication support for PLAIN and CRAM-MD5. # SUPPORT_TLS = yes on SUPPORT_TLS = yes Here we include TLS / SSL support for secure connection. # TLS_LIBS = -lssl -lcrypto on TLS_LIBS = -lssl -lcrypto Here we specify the names of libraries for TLS / SSL. # LOG_FILE_PATH = /var/log/exim_%slog on LOG_FILE_PATH = /var/log/exim/exim_%slog Putting log files to a separate directory. EXICYCLOG_MAX = 10 on EXICYCLOG_MAX = 20 Number of saved log files do I increase to 20 in the event debriefing with his superiors: "Where's my letter, which I sent two weeks ago?" # EXIM_PERL = perl.o on EXIM_PERL = perl.o Here we include support perl, to ensure the use of Perl-compatible regular expressions, etc ... # CHOWN_COMMAND = /usr/bin/chown on CHOWN_COMMAND = /usr/sbin/chown Here we specify the correct path to the chown command. # SUPPORT_MOVE_FROZEN_MESSAGES = yes on SUPPORT_MOVE_FROZEN_MESSAGES = yes Here we include support for the automatic movement "frozen" posts of the input directories and directories msglog Finput and Fmsglog main spool.
Save the changes. It remains to compile and install Exim.
make su make install
After the installation is complete, you need to create a symbolic link, this will do the following:
ln -fs /usr/local/exim/bin/exim /usr/lib/sendmail ln -fs /usr/local/exim/bin/exim /usr/sbin/sendmail ln -fs /usr/local/exim/bin/exim /usr/bin/mailq ln -fs /usr/local/exim/bin/exim /usr/bin/runq
After that you want to remove from the object files Exim table name and line number information for this issue:
strip /usr/local/exim/bin/exim* exit
Before configuring Exim, you need to create a database, the user and the appropriate table for this issue:
/usr/local/mysql/bin/mysql -u myadmin -p
Result
Welcome to the MySQL monitor. Commands end with; or \ g. Your MySQL connection id is 3760 to server version: 4.1.10a-log Type 'help;' or '\ h' for help. Type '\ c' to clear the buffer. mysql>
Create the database.
mysql> CREATE DATABASE exim; mysql> GRANT ALL PRIVILEGES ON exim.* TO sqlmail@localhost -> IDENTIFIED BY 'my_password' WITH GRANT OPTION; mysql> quit
When the database and user created, you need to create the table structure, and enter data about users. You can do this in the MySQL console, but we will create exim.sql file, which will then create us everything we need.
ee exim.sql
- exim.sql
# Create the aliases table. CREATE TABLE aliases ( local_part varchar(64) NOT NULL default '', domain varchar(128) NOT NULL default 'sharewiz.net', recipients text, PRIMARY KEY (local_part,domain) ); # Populate the aliases table. INSERT INTO aliases VALUES ('postmaster', 'sharewiz.net', 'admin'); INSERT INTO aliases VALUES ('mailer-daemon', 'sharewiz.net', 'postmaster'); INSERT INTO aliases VALUES ('root', 'sharewiz.net', 'postmaster'); INSERT INTO aliases VALUES ('bin', 'sharewiz.net', 'root'); INSERT INTO aliases VALUES ('daemon', 'sharewiz.net', 'root'); INSERT INTO aliases VALUES ('sync', 'sharewiz.net', 'root'); INSERT INTO aliases VALUES ('mail', 'sharewiz.net', 'root'); INSERT INTO aliases VALUES ('pop', 'sharewiz.net', 'root'); INSERT INTO aliases VALUES ('uucp', 'sharewiz.net', 'root'); INSERT INTO aliases VALUES ('ftp', 'sharewiz.net', 'root'); INSERT INTO aliases VALUES ('nobody', 'sharewiz.net', 'root'); INSERT INTO aliases VALUES ('www', 'sharewiz.net', 'root'); INSERT INTO aliases VALUES ('named', 'sharewiz.net', 'root'); INSERT INTO aliases VALUES ('postgres', 'sharewiz.net', 'root'); INSERT INTO aliases VALUES ('mysql', 'sharewiz.net', 'root'); INSERT INTO aliases VALUES ('squid', 'sharewiz.net', 'root'); INSERT INTO aliases VALUES ('operator', 'sharewiz.net', 'root'); INSERT INTO aliases VALUES ('abuse', 'sharewiz.net', 'root'); INSERT INTO aliases VALUES ('hostmaster', 'sharewiz.net', 'root'); INSERT INTO aliases VALUES ('webmaster', 'sharewiz.net', 'root'); # Create the domains table. CREATE TABLE domains ( domain varchar(128) NOT NULL default '', type enum('LOCAL','RELAY','VIRTUAL') default 'LOCAL', PRIMARY KEY (domain) ); # Populate the domains table. INSERT INTO domains VALUES ('sharewiz.net', 'LOCAL'); # Create the userforward table. CREATE TABLE userforward ( local_part varchar(64) NOT NULL default '', domain varchar(128) NOT NULL default '', recipients text, PRIMARY KEY (local_part,domain) ); # Create the users table. CREATE TABLE users ( login varchar(64) NOT NULL default '', name varchar(128) NOT NULL default '', password varchar(64) NOT NULL default '', decrypt varchar(64) NOT NULL default '', uid int(10) unsigned default '1003', gid int(10) unsigned default '6', domain varchar(128) NOT NULL default 'sharewiz.net', quota tinyint(4) default '0', status enum('0','1') default '1', PRIMARY KEY (login,domain) );
Create the tables, data, and the first user.
/usr/local/mysql/bin/mysql -u sqlmail -p exim mysql> \. exim.sql mysql> INSERT INTO users (login,name,password,decrypt) -> VALUES ('admin','John',encrypt('my_password'),'my_password'); mysql> quit
It's time now to configure Exim. Go to the directory where configuration file and do the following:
cd /usr/local/exim su mv configure configure.default
Edit the configuration file.
ee configure
and populate as:
- configure
###################################################################### # Runtime configuration file for Exim # ###################################################################### ####################################################################### # MAIN CONFIGURATION SETTINGS # ###################################################################### primary_hostname = sharewiz.net domainlist local_domains = ${lookup mysql{SELECT domain FROM domains \ WHERE domain='${domain}' AND \ (type='LOCAL' OR type='VIRTUAL')}} domainlist relay_to_domains = ${lookup mysql{SELECT domain FROM domains \ WHERE domain='${domain}' AND type='RELAY'}} hostlist relay_from_hosts = 127.0.0.1 auth_advertise_hosts = * daemon_smtp_ports = 25 : 465 tls_on_connect_ports = 465 tls_advertise_hosts = * tls_certificate = /etc/ssl/certs/mail.pem tls_privatekey = /etc/ssl/certs/mail.pem log_selector = \ +all_parents \ +lost_incoming_connection \ +received_sender \ +received_recipients \ +smtp_confirmation \ +smtp_syntax_error \ +smtp_protocol_error \ -queue_run acl_smtp_rcpt = acl_check_rcpt acl_smtp_mime = acl_check_mime qualify_domain = sharewiz.net allow_domain_literals = false never_users = root host_lookup = * rfc1413_hosts = * rfc1413_query_timeout = 0s ignore_bounce_errors_after = 30m timeout_frozen_after = 3d freeze_tell = postmaster message_size_limit = 10M smtp_accept_max = 100 smtp_accept_max_per_connection = 5 smtp_accept_max_per_host = 2 split_spool_directory = true remote_max_parallel = 15 smtp_banner = "Welcome on our mail server!\n\ This system does not accept Unsolicited \ Commercial Email\nand will blacklist \ offenders via our spam processor.\nHave a \ nice day!\n\n${primary_hostname} ESMTP" hide mysql_servers = localhost/exim/sqlmail/my_password ###################################################################### # ACL CONFIGURATION # # Specifies access control lists for incoming SMTP mail # ###################################################################### begin acl acl_check_rcpt: accept hosts = : deny domains = +local_domains local_parts = ^[.] : ^.*[@%!/|] deny domains = !+local_domains local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./ accept local_parts = postmaster domains = +local_domains require verify = sender deny message = HELO/EHLO required by SMTP RFC condition = ${if eq{$sender_helo_name}{}{yes}{no}} deny message = Go Away! You are spammer. condition = ${if match{$sender_host_name} \ {bezeqint\\.net|net\\.il|dialup|dsl|pool|peer|dhcp} \ {yes}{no}} deny message = rejected because \ $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text log_message = found in $dnslist_domain dnslists = relays.ordb.org deny message = message from \ $sender_host_address rejected - see http://njabl.org/ log_message = found in $dnslist_domain dnslists = dnsbl.njabl.org deny message = rejected because \ $sender_host_address for bad WHOIS info, see http://www.rfc-ignorant.org/ log_message = found in $dnslist_domain dnslists = ipwhois.rfc-ignorant.org deny message = rejected because $sender_host_address \ is in a black list at $dnslist_domain\n$dnslist_text log_message = found in $dnslist_domain dnslists = dialups.mail-abuse.org deny message = rejected because $sender_host_address \ is in a black list at $dnslist_domain\n$dnslist_text log_message = found in $dnslist_domain dnslists = list.dsbl.org deny message = Spam blocked see: \ http://www.spamcop.net/w3m?action=checkblock&ip=$sender_host_address log_message = found in $dnslist_domain dnslists = bl.spamcop.net deny message = rejected, $sender_host_address \ Open Proxy, see: $dnslist_domain\n$dnslist_text log_message = found in $dnslist_domain dnslists = dnsbl.void.ru accept domains = +local_domains endpass message = unknown user verify = recipient accept domains = +relay_to_domains endpass message = unrouteable address verify = recipient accept hosts = +relay_from_hosts accept authenticated = * deny message = relay not permitted acl_check_mime: warn decode = default deny message = Blacklisted file extension detected ($mime_filename) condition = ${if match \ {${lc:$mime_filename}} \ {\N(\.exe|\.pif|\.bat|\.scr|\.lnk|\.com|\.vbs|\.cpl)$\N} \ {1}{0}} deny message = Sorry, noone speaks chinese here condition = ${if eq{$mime_charset}{gb2312}{1}{0}} accept ###################################################################### # ROUTERS CONFIGURATION # # Specifies how addresses are handled # ###################################################################### # THE ORDER IN WHICH THE ROUTERS ARE DEFINED IS IMPORTANT! # # An address is passed to each router in turn until it is accepted. # ###################################################################### 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 mysql{SELECT recipients FROM aliases \ WHERE local_part='${local_part}' AND domain='${domain}'}} userforward: driver = redirect allow_fail allow_defer data = ${lookup mysql{SELECT recipients FROM userforward \ WHERE local_part='${local_part}' AND domain='${domain}'}} virtual_localuser: driver = accept domains = ${lookup mysql{SELECT domain from domains WHERE domain='${domain}'}} local_parts = ${lookup mysql{SELECT login from users \ WHERE login='${local_part}' AND domain='${domain}'}} transport = local_delivery ###################################################################### # TRANSPORTS CONFIGURATION # ###################################################################### # ORDER DOES NOT MATTER # # Only one appropriate transport is called for each delivery. # ###################################################################### begin transports remote_smtp: driver = smtp local_delivery: driver = appendfile check_string = "" create_directory delivery_date_add directory = /var/mail/$domain/$local_part directory_mode = 770 envelope_to_add group = mail maildir_format maildir_tag = ,S=$message_size message_prefix = "" message_suffix = "" mode = 0660 quota = ${lookup mysql{SELECT quota FROM users \ WHERE login='${local_part}' AND domain='${domain}'}{${value}M}} quota_size_regex = S=(\d+)$ quota_warn_threshold = 75% return_path_add address_pipe: driver = pipe return_output address_file: driver = appendfile delivery_date_add envelope_to_add return_path_add address_reply: driver = autoreply ###################################################################### # RETRY CONFIGURATION # ###################################################################### begin retry * quota * * F,2h,15m; G,16h,1h,1.5; F,4d,6h ###################################################################### # REWRITE CONFIGURATION # ###################################################################### begin rewrite ###################################################################### # AUTHENTICATION CONFIGURATION # ###################################################################### begin authenticators auth_plain: driver = plaintext public_name = PLAIN server_condition = ${lookup mysql{SELECT login FROM users \ WHERE login = '${quote_mysql:${local_part:$2}}' \ AND domain = '${quote_mysql:${domain:$2}}' \ AND decrypt = '${quote_mysql:$3}' \ AND status = '1'}{yes}{no}} server_prompts = : server_set_id = $2 auth_login: driver = plaintext public_name = LOGIN server_condition = ${lookup mysql{SELECT login FROM users \ WHERE login = '${quote_mysql:${local_part:$1}}' \ AND domain = '${quote_mysql:${domain:$1}}' \ AND decrypt = '${quote_mysql:$2}' \ AND status = '1'}{yes}{no}} server_prompts = Username:: : Password:: server_set_id = $1 auth_cram_md5: driver = cram_md5 public_name = CRAM-MD5 server_secret = ${lookup mysql{SELECT decrypt FROM users \ WHERE login = '${quote_mysql:${local_part:$1}}' \ AND domain = '${quote_mysql:${domain:$1}}' \ AND status = '1'}{$value}fail} server_set_id = $1 # End of Exim configuration file
Create a directory for the log files and deal with the rights to it in the directory where we will develop a post office, and the spool-directory.
mkdir /var/log/exim chown -R exim:mail /var/log/exim /var/mail /var/spool/mqueue
Create a script that will run our mail server at system startup.
ee /usr/local/etc/rc.d/exim.sh
as
- exim.sh
#!/bin/sh ### file exim.sh ### case "$1" in start) echo "Starting Exim..." /usr/local/exim/bin/exim -bd -q15m ;; stop) echo "Stopping Exim..." kill -TERM `cat /var/spool/mqueue/exim-daemon.pid` ;; restart) $0 stop sleep 2 $0 start ;; reload) echo "Exim reloading..." kill -HUP `cat /var/spool/mqueue/exim-daemon.pid` ;; *) echo "Usage: $0 {start|stop|restart|reload}" exit 1 ;; esac
and make it executable
chmod +x /usr/local/etc/rc.d/exim.sh
Validate the syntax of the configuration file /usr/local/exim/configure.
/usr/local/exim/bin/exim -bV
Result
Exim version 4.50 #1 built 02-Apr-2005 19:12:40 Copyright (c) University of Cambridge 2004 Probably Berkeley DB version 1.8x (native mode) Support for: Perl OpenSSL Content_Scanning Old_Demime Lookups: lsearch wildlsearch nwildlsearch iplsearch dbm dbmnz mysql Authenticators: cram_md5 plaintext Routers: accept dnslookup ipliteral manualroute queryprogram redirect Transports: appendfile/maildir autoreply pipe smtp Fixed never_users: 0 Configuration file is /usr/local/exim/configure
If no errors are found, go on … Now we need to check whether you will be recognition of messages for local users, for this issue:
/usr/local/exim/bin/exim -bt postmaster
Result
admin@sharewiz.net <-- postmaster@sharewiz.net router = virtual_localuser, transport = local_delivery
If no errors are found, go on … Now we need to check whether you will be recognition of messages to external users, for this issue:
/usr/local/exim/bin/exim -bt someuser@msn.com
Result
someuser@msn.com router = dnslookup, transport = remote_smtp host mx1.hotmail.com [65.54.166.99] MX=5 host mx1.hotmail.com [65.54.252.99] MX=5 host mx1.hotmail.com [64.4.50.99] MX=5 host mx1.hotmail.com [64.4.50.50] MX=5 host mx4.hotmail.com [65.54.190.230] MX=5 host mx4.hotmail.com [65.54.190.179] MX=5 host mx4.hotmail.com [65.54.167.230] MX=5 host mx4.hotmail.com [65.54.253.230] MX=5 host mx3.hotmail.com [65.54.253.99] MX=5 host mx3.hotmail.com [65.54.167.5] MX=5 host mx3.hotmail.com [64.4.50.239] MX=5 host mx3.hotmail.com [64.4.50.179] MX=5 host mx2.hotmail.com [65.54.190.50] MX=5 host mx2.hotmail.com [65.54.190.7] MX=5 host mx2.hotmail.com [65.54.252.230] MX=5 host mx2.hotmail.com [65.54.166.230] MX=5
If no errors are found, go on … Now we need to check whether you will be the delivery of messages to local users, for this issue:
/usr/local/exim/bin/exim -v postmaster@sharewiz.net From: admin@sharewiz.net To: postmaster@sharewiz.net Subject: Testing Exim This is a test message. ^D
Result
LOG: MAIN <= root@sharewiz.net U=root P=local S=325 # delivering 1DOs2P-000HAY-0E LOG: MAIN => admin R=virtual_localuser T=local_delivery LOG: MAIN Completed
Press <CTRL-C>
If no errors are found, go on … Now we need to check whether you will be delivering messages to external users, for this issue:
exim -v someuser@msn.com From: admin@sharewiz.net To: someuser@msn.com Subject: Testing Exim This is a test message. ^D
Result
LOG: MAIN <= root@sharewiz.net U=root P=local S=303 # LOG: MAIN => someuser R=dnslookup T=remote_smtp LOG: MAIN Completed
Press <CTRL-C>
At this stage, we are convinced that Exim is correctly configured and working, now it is necessary to check the SMTP authentication, but before us be editing. SMTP authentication is necessary when sending us soobschny with virtual host (if you have any) or when the user is outside the office, send mail through your account. I do not use authentication for intranet. Therefore, change in the file /usr/local/exim/configure line
hostlist relay_from_hosts = 127.0.0.1 на hostlist relay_from_hosts = 127.0.0.1 : 192.168.10.0/24
Run Exim, by typing:
/usr/local/etc/rc.d/exim.sh start
To verify authentication, we need the converter, install it from ports:
cd /usr/ports/converters/mmencode # make install # exit
Form a line PLAIN authentication (Netscape), for this issue:
printf 'admin@mydomain.ru\0admin@mydomain.ru\0my_password' | mmencode
Shows
YWRtaW5AbXlkb21haW4ucnUAYWRtaW5AbXlkb21haW4ucnUAbXlfcGFzc3dvcmQ=
Now
telnet localhost 25
Result
Trying ::1... telnet: connect to address ::1: Connection refused Trying 127.0.0.1... Connected to localhost.ru. Escape character is '^]'. 220-Welcome on our mail server! 220-This system does not accept Unsolicited Commercial Email 220-and will blacklist offenders via our spam processor. 220-Have a nice day! 220- 220 mydomain.ru ESMTP
Then ehlo.
ehlo localhost
Result
250-sharewiz.net Hello localhost.ru [127.0.0.1] 250-SIZE 10485760 250-PIPELINING 250-AUTH PLAIN LOGIN CRAM-MD5 250 HELP