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