Overall Topology
There are four separate servers in the new system:
DNS/Server Names
MX
records (email DNS records) point to smtp1/smtp2.nextalarm.com; each
has a relative priority of 10, which provide a kind of poor man's round
robin.
See http://en.wikipedia.org/wiki/MX_record for more information. The gateway servers then forward the mail to mail.nextalarm.com.
SPF records for all domains should be set to (using DNS TXT records):
This allows outbound email from servers at that domain, as well as from AuthSMTP, as well as the old Rackspace server which incorrectly heads outbound email with the server name "rs3.netmeme.org"
Virtual Domains and Users
The domains (nextalarm.com, voipalarm.com, lasershield.net ...) hosted by the email system, and the actual email accounts or users, are both referred to as 'virtual'. I.e., virtual domains and virtual users. This is simply terminology specific to the email server applications used in this system. Essentially it means that the domains and users serviced are more dynamic than static. For example, the email accounts need not correspond to unix users.
Virtual domain and user management is done at two places - the gateway mail servers and the internal mail server. At the gateway mail servers, virtual domains are maintained in /etc/postfix/relay_domains and /etc/postfix/transport; users are maintained in /etc/postfix/relay_recipients (relay_recipients is the whitelist). At the internal mail server, both domains and users are maintained in a database.
Detailed configuration for virtual domains and users is discussed later in this document.
authsmtp.com
Many ISPs and email administrators by default reject email from Amazon's EC2 server farm. There are several options for sending email reliably from EC2 (i.e., not having it routinely rejected). Probably the simplest is to use a commercial SMTP relay service, which is what we do. We use AuthSMTP (http://authsmtp.com/) for this purpose. To connect to AuthSMTP securely, we use Cyrus SASL over SSL; see below for detailed configuration.
Webmail
Webmail access is provided for convenience. All users that wish webmail access must have IMAP accounts. Webmail can be accessed at https://webmail.nextalarm.com. Currently, RoundCube (http://roundcube.net/) is being tested as a candidate webmail system. Horde (http://www.horde.org/) will also be tested, as it provides several applications in addition to webmail, including calendaring, file storage/management, todo lists, address book/contact management, and several more.
Nagios Monitoring
A new host configuration file (/etc/nagios/conf/hosts-email.cfg) has been added to define the four new systems. Each system has been added to the standard set of host checks (SSH, disk, CPU), and three of the four have been added to the SMTP host check (webmail has not). Also, POP3/IMAP checks have been added for the internal POP3/IMAP server.
Detailed Configuration
The pertinent/important parameters for each section will be discussed; however, each parameter of each area of configuration will not be covered in detail.
mydestination = local_recipient_maps = local_transport = error:local mail delivery is disabled
mydomain = voipalarm.us
relay_domains = /etc/postfix/relay_domains
transport_maps = hash:/etc/postfix/transport
recipient_delimiter=+
relay_recipient_maps = hash:/etc/postfix/relay_recipients
smtpd_recipient_restrictions =
permit_mynetworks
# reject_unknown_client_hostname
# reject_unknown_reverse_client_hostname
# reject_unauth_destination: destination address not in $mydestination
reject_unauth_destination
# reject_unknown_sender_domain: no A or MX record for domain
reject_unknown_sender_domain
# reject_invalid_hostname: HELO or EHLO syntax is invalid
reject_invalid_hostname
reject_rbl_client cbl.abuseat.org
reject_rbl_client bl.spamcop.net
reject_rbl_client sbl.spamhaus.org
reject_rbl_client dnsbl.njabl.org
reject_rbl_client dnsbl.sorbs.net
permitcontent_filter=smtp-amavis:[localhost]:10024 receive_override_options=no_address_mappings
smtpd_error_sleep_time = 60 smtpd_soft_error_limit = 60 smtpd_hard_error_limit = 10
smtpd_banner = $myhostname ESMTP MTA
/etc/postfix/transportsmtp-amavis unix - - n - 4 smtp
-o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes
-o disable_dns_lookups=yes
-o max_use=20127.0.0.1:10025 inet n - - - - smtpd
-o content_filter=
-o local_recipient_maps=
-o relay_recipient_maps=
-o smtpd_restriction_classes=
-o smtpd_delay_reject=no
-o smtpd_client_restrictions=permit_mynetworks,reject
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o smtpd_data_restrictions=reject_unauth_pipelining
-o smtpd_end_of_data_restrictions=
-o mynetworks=127.0.0.0/8
-o smtpd_error_sleep_time=0
-o smtpd_soft_error_limit=1001
-o smtpd_hard_error_limit=1000
-o smtpd_client_connection_count_limit=0
-o smtpd_client_connection_rate_limit=0
-o receive_override_options=no_header_body_checks,no_unknown_recipient_checks
-o local_header_rewrite_clients=bryan-pop@voipalarm.us x bryan-pop@emacnetwork.com x bryan-imap@voipalarm.us x bryan-imap@emacnetwork.com x dan-pop@voipalarm.us x dan-pop@emacnetwork.com x dan-imap@voipalarm.us x dan-imap@emacnetwork.com x ken-pop@voipalarm.us x ken-pop@emacnetwork.com x ken-imap@voipalarm.us x ken-imap@emacnetwork.com x robert-pop@voipalarm.us x robert-pop@emacnetwork.com x robert-imap@voipalarm.us x robert-imap@emacnetwork.com x postmaster@voipalarm.us x postmaster@emacnetwork.com x
voipalarm.us OK emacnetwork.com OK
voipalarm.us smtp:[174.129.220.253] emacnetwork.com smtp:[174.129.220.253]
$mydomain = 'voipalarm.us';
$MYHOME = '/var/spool/amavisd';
$max_servers = 10;
$virus_quarantine_to = "virusmail\@voipalarm.us";
@local_domains_maps = ( [".$mydomain", ".emacnetwork.com"] );
$inet_socket_port = 10024;
$sa_tag_level_deflt = -999; # add spam info headers if at, or above that level (always add) $sa_tag2_level_deflt = 6.2; # add 'spam detected' headers at that level $sa_kill_level_deflt = 6.9; # triggers spam evasive actions (e.g. blocks mail) $sa_dsn_cutoff_level = 10; # spam level beyond which a DSN is not sent $penpals_threshold_high = $sa_kill_level_deflt; # don't waste time on hi spam $sa_mail_body_size_limit = 400*1024; # don't waste time on SA if mail is larger
$virus_admin = "robert-pop\@voipalarm.us";
$notify_method = 'smtp:[127.0.0.1]:10025';
$recipient_delimiter = '+';
@addr_extension_spam_maps = ('spam');
$sa_spam_subject_tag = '[SPAM] ';$final_virus_destiny = D_DISCARD; $final_banned_destiny = D_BOUNCE; $final_spam_destiny = D_PASS; $final_bad_header_destiny = D_BOUNCE;
@av_scanners = (
['ClamAV-clamd',
#\&ask_daemon, ["CONTSCAN {}\n", "/var/spool/amavisd/amavisd.sock"],
\&ask_daemon, ["CONTSCAN {}\n", '127.0.0.1:3310'],
qr/\bOK$/, qr/\bFOUND$/,
qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ]);loadplugin Mail::SpamAssassin::Plugin::DCC
virtual_uid_maps = static:5100 virtual_gid_maps = static:5100
$ grep 5100 /etc/passwd vmail:x:5100:5100::/home/vmail:/bin/bash $ grep 5100 /etc/group vmail:x:5100:
virtual_transport = dovecot dovecot_destination_recipient_limit = 1
default_destination_concurrency_limit = 4
587 inet n - n - - smtpd
dovecot unix - n n - - pipe
flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop} -n -m ${extension}base_dir = /var/run/dovecot/
ssl_disable = no
ssl_key_file = /etc/pki/dovecot/private/dovecot.pem ssl_cert_file = /etc/pki/dovecot/certs/dovecot.pem ssl_ca_file = /etc/pki/dovecot/certs/dovecot.pem
login_user = dovecot
protocol imap {
imap_client_workarounds = outlook-idle
}protocol pop3 {
pop3_uidl_format = %08Xu%08Xv
}protocol lda {
postmaster_address = postmaster@voipalarm.us
log_path = /home/vmail/dovecot-deliver.log
# UNIX socket path to master authentication server to find users.
auth_socket_path = /var/run/dovecot/auth-master
}smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions= permit_mynetworks permit_sasl_authenticated reject_unauth_destination
smtpd_sasl_authenticated_header = yes
broken_sasl_auth_clients=yes
smtpd_sasl_type=dovecot
smtpd_sasl_path=private/auth
smtpd_sasl_security_options=noanonymous
smtpd_tls_security_level = may
smtpd_use_tls=yes
smtpd_tls_auth_only=yes
smtpd_tls_key_file=/etc/ssl/private/postfix.pem smtpd_tls_cert_file=/etc/ssl/certs/postfix.pem smtpd_tls_CAfile=/etc/ssl/certs/postfix.pem
smtp_sasl_auth_enable = yes
smtp_sasl_type = cyrus
smtp_connection_cache_destinations = mail.authsmtp.com
smtp_sasl_password_maps = hash:/etc/postfix/sasl_credentials
smtp_sasl_security_options = noanonymous
smtp_sasl_mechanism_filter = plain, login
relayhost = [mail.authsmtp.com]
[mail.authsmtp.com] username:password
[root@email-dest ~]# cd /home/vmail/ [root@email-dest vmail]# ls ./ ../ .bash_logout .bash_profile .bashrc dovecot-deliver.log emacnetwork.com/ voipalarm.us/ [root@email-dest vmail]# ls voipalarm.us/ ./ ../ bryan-pop/ ken-pop/ list1/ postmaster/ robert-imap/ robert-pop/ virusmail/ [root@email-dest vmail]# ls voipalarm.us/bryan-pop/Maildir/ ./ .Apple Mail To Do/ dovecot.index dovecot.index.log dovecot-uidlist .Sent Messages/ tmp/ ../ cur/ dovecot.index.cache dovecot-keywords new/ .spam/ .Test Folder/ [root@email-dest vmail]# ls voipalarm.us/robert-imap/Maildir/ ./ ../ cur/ dovecot.index dovecot.index.cache dovecot.index.log dovecot-uidlist new/ .spam/ tmp/
CREATE TABLE `virtual_domains` ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) NOT NULL ) ENGINE = InnoDB;
mysql> select * from virtual_domains; +----+-----------------+ | id | name | +----+-----------------+ | 1 | voipalarm.us | | 2 | emacnetwork.com | +----+-----------------+
CREATE TABLE `virtual_users` ( id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, domain_id INT(11) NOT NULL, user VARCHAR(40) NOT NULL, password VARCHAR(32) NOT NULL, CONSTRAINT UNIQUE_EMAIL UNIQUE (domain_id,user), FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE ) ENGINE = InnoDB;
mysql> select * from virtual_users; +----+-----------+---------------+----------------------------------+ | id | domain_id | user | password | +----+-----------+---------------+----------------------------------+ | 15 | 1 | bryan-pop | 482c811da5d5b4bc6d497ffa98491e38 | | 16 | 2 | bryan-pop | 482c811da5d5b4bc6d497ffa98491e38 | | 17 | 1 | bryan-imap | 482c811da5d5b4bc6d497ffa98491e38 | | 18 | 2 | bryan-imap | 482c811da5d5b4bc6d497ffa98491e38 | | 19 | 1 | dan-pop | 482c811da5d5b4bc6d497ffa98491e38 | | 20 | 2 | dan-pop | 482c811da5d5b4bc6d497ffa98491e38 | | 21 | 1 | dan-imap | 482c811da5d5b4bc6d497ffa98491e38 | ... etc.
CREATE TABLE `virtual_aliases` ( id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, domain_id INT(11) NOT NULL, source VARCHAR(40) NOT NULL, destination VARCHAR(80) NOT NULL, FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE ) ENGINE = InnoDB;
mysql> select * from virtual_aliases; +----+-----------+--------+--------------------------+ | id | domain_id | source | destination | +----+-----------+--------+--------------------------+ | 1 | 1 | list1 | bryan-pop@voipalarm.us | | 2 | 1 | list1 | robert-imap@voipalarm.us | +----+-----------+--------+--------------------------+
CREATE VIEW view_users AS
SELECT CONCAT(virtual_users.user, '@', virtual_domains.name) AS email,
virtual_users.password
FROM virtual_users
LEFT JOIN virtual_domains ON virtual_users.domain_id=virtual_domains.id;mysql> select * from view_users; +-------------------------------+----------------------------------+ | email | password | +-------------------------------+----------------------------------+ | bryan-pop@voipalarm.us | 482c811da5d5b4bc6d497ffa98491e38 | | bryan-pop@emacnetwork.com | 482c811da5d5b4bc6d497ffa98491e38 | | bryan-imap@voipalarm.us | 482c811da5d5b4bc6d497ffa98491e38 | | bryan-imap@emacnetwork.com | 482c811da5d5b4bc6d497ffa98491e38 | | dan-pop@voipalarm.us | 482c811da5d5b4bc6d497ffa98491e38 | | dan-pop@emacnetwork.com | 482c811da5d5b4bc6d497ffa98491e38 | | dan-imap@voipalarm.us | 482c811da5d5b4bc6d497ffa98491e38 | ... etc.
CREATE VIEW view_aliases AS
SELECT CONCAT(virtual_aliases.source, '@', virtual_domains.name) AS email,
destination
FROM virtual_aliases
LEFT JOIN virtual_domains ON virtual_aliases.domain_id=virtual_domains.id;mysql> select * from view_aliases; +--------------------+--------------------------+ | email | destination | +--------------------+--------------------------+ | list1@voipalarm.us | bryan-pop@voipalarm.us | | list1@voipalarm.us | robert-imap@voipalarm.us | +--------------------+--------------------------+
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual_alias_maps.cf,mysql:/etc/postfix/mysql-email2email.cf virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual_mailbox_maps.cf virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual_mailbox_domains.cf
user = [username] password = [password] hosts = 127.0.0.1 dbname = mailserver query = SELECT destination FROM view_aliases WHERE email='%s'
user = [username] password = [password] hosts = 127.0.0.1 dbname = mailserver query = SELECT email FROM view_users WHERE email='%s'
user = [username] password = [password] hosts = 127.0.0.1 dbname = mailserver query = SELECT email FROM view_users WHERE email='%s'
user = [username] password = [password] hosts = 127.0.0.1 dbname = mailserver query = SELECT 1 FROM virtual_domains WHERE name='%s'
./mb2md-3.20.pl -s /root/tmp/mbox -d /root/tmp
insert into virtual_domains(name) values('nextviewcam.com');insert into virtual_users(domain_id, user, password) values(1, 'username', md5('password'));insert into virtual_aliases(domain_id, source, destination) values(1, 'list1', 'robert-imap@voipalarm.us');
insert into virtual_aliases(domain_id, source, destination) values(2, 'alias-source', 'alias-destination@nextalarm.com');
update virtual_users set password = md5('new password') where user = 'user-without-@domain';[root@email-dest postfix-2.5.6]# yum list installed|grep -e cyrus -e dove -e pam -e sasl -e pop -e imap -e smtp -e post -e mysql -e spam cyrus-imapd-devel.i386 2.3.11-1.fc8 installed cyrus-sasl.i386 2.1.22-8.fc8 installed cyrus-sasl-devel.i386 2.1.22-8.fc8 installed cyrus-sasl-lib.i386 2.1.22-8.fc8 installed cyrus-sasl-plain.i386 2.1.22-8.fc8 installed dovecot.i386 1:1.0.15-16.fc8 installed dovecot-mysql.i386 1:1.0.15-16.fc8 installed libdbi-dbd-mysql.i386 0.8.2-1.2.fc8 installed libnss-mysql.i386 1.5-6.fc8 installed mysql.i386 5.0.45-6.fc8 installed mysql++.i386 2.3.2-2.fc8 installed mysql++-devel.i386 2.3.2-2.fc8 installed mysql-devel.i386 5.0.45-6.fc8 installed mysql-libs.i386 5.0.45-6.fc8 installed mysql-server.i386 5.0.45-6.fc8 installed pam.i386 0.99.8.1-17.1.fc8 installed pam_ccreds.i386 4-3.fc8 installed pam_krb5.i386 2.2.18-2.fc8 installed pam_passwdqc.i386 1.0.4-4 installed pam_pkcs11.i386 0.5.3-25 installed pam_smb.i386 1.1.7-7.2.2 installed popt.i386 1.13-4.fc8 installed postfix.i386 2:2.5.5-1.fc8 installed spamassassin.i386 3.2.5-1.fc8 installed
SYSTYPE = LINUX2
AR = ar
ARFL = rv
RANLIB = ranlib
SYSLIBS = -L/usr/lib -L/usr/lib/sasl2 -L/usr/lib/mysql/ -L/usr/lib/openssl/ -lmysqlclient -lz -lm -lssl -lcrypto -lsasl2 -ldb -lnsl -lresolv
CC = gcc $(WARN) -DUSE_SASL_AUTH -DUSE_CYRUS_SASL -DDEF_SERVER_SASL_TYPE=\"dovecot\" -DUSE_TLS -DHAS_MYSQL -I/usr/include/mysql/ -I/usr/include/sasl/
OPT = -O
DEBUG = -g
AWK = awk
STRCASE =
EXPORT = AUXLIBS='-L/usr/lib -L/usr/lib/sasl2 -L/usr/lib/mysql/ -L/usr/lib/openssl/ -lmysqlclient -lz -lm -lssl -lcrypto -lsasl2' CCARGS='-DUSE_SASL_AUTH -DUSE_CYRUS_SASL -DDEF_SERVER_SASL_TYPE=\"dovecot\" -DUSE_TLS -DHAS_MYSQL -I/usr/include/mysql/ -I/usr/include/sasl/' OPT='-O' DEBUG='-g'
WARN = -Wall -Wno-comment -Wformat -Wimplicit -Wmissing-prototypes \
-Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \
-Wunused
SHELL = /bin/sh
WARN = -Wmissing-prototypes -Wformat
OPTS = 'CC=$(CC)'
DIRS = src/util src/global src/dns src/tls src/xsasl src/milter src/master \
src/postfix src/smtpstone \
src/sendmail src/error src/pickup src/cleanup src/smtpd src/local \
src/trivial-rewrite src/qmgr src/oqmgr src/smtp src/bounce \
src/pipe src/showq src/postalias src/postcat src/postconf src/postdrop \
src/postkick src/postlock src/postlog src/postmap src/postqueue \
src/postsuper src/qmqpd src/spawn src/flush src/verify \
src/virtual src/proxymap src/anvil src/scache src/discard src/tlsmgr
MANDIRS = proto man html