[article_overview]
Install and configure an email server on Debian Lenny
Software to use:
postfix - mail transfer agent; to accept and send email on your server to/from other servers
dovecot - mail delivery; to read email on your server
openssl - encrypt your email connection
amavisd - interface between postfix and content checkers
spamaassasin - check email for spam
clamav - check email for virus/malware
mysql - store/manage virtual email addresses
[/article_overview]
Instructions and base configuration pillaged from
http://workaround.org/articles/ispmail-etch/
Instructions changed a bit for my preferences, Debian Lenny, and based on some other references
Note:
The server install of Debian might have exim installed.
exim is another MTA similar to postfix.
Installing postfix will remove exim.
Note:
The following ports are required to be open - so check your firewall
110 - pop3
995 - pop3s
143 - imap
993 - imaps
25 - smtp
2525 - random custom port to also be used for smtp, as some ISPs block port 25
List current firewall rules and presuming your using arnos firewall, configure
1
2
|
iptables -L
dpkg-reconfigure -plow arno-iptables-firewall
|
Install the email server components
1
|
aptitude install postfix-mysql dovecot-pop3d dovecot-imapd amavisd-new spamassassin clamav-daemon openssl
|
During install, postfix will ask some questions
Select Internet Site and enter the common domain of your server
Install some common needed archiving programs
1
|
aptitude install cpio arj zoo nomarch lzop cabextract pax lha unrar
|
The email server users (ie email addresses) will be stored in a mysql database so email users can be independent of system users
So create a mysql database and the mysql user postfix/dovecot will use to access it
If you need to install MySQL, try this tutorial
MySQL innodb on Debian Lenny
1
2
3
4
5
6
|
mysqladmin create mailserver
mysql
mysql>
GRANT SELECT ON mailserver.*
TO mailuser@localhost
IDENTIFIED BY 'mailuserpassword';
|
Now create the database tables
`virtual_domains` - domain of email
`virtual_users` - email username
`virtual_aliases` - where to forward emails too
`view_users` - combines username and domain and get user email password
`view_aliases` - combine alias username and domain and where to forward to
`virtual_users`.client_id and/or `virtual_users`.real_name can be used as references, if desired
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
mysql
mysql>
use mailserver;
CREATE TABLE `virtual_domains` (
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
enabled TINYINT(4) NOT NULL
) ENGINE = InnoDB;
CREATE TABLE `virtual_users` (
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
domain_id INT(11) NOT NULL,
client_id INT(11) NOT NULL,
real_name VARCHAR(64) NOT NULL,
user VARCHAR(64) NOT NULL,
password VARCHAR(64) NOT NULL,
enabled TINYINT(4) NOT NULL,
CONSTRAINT UNIQUE_EMAIL UNIQUE (domain_id,user),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE = InnoDB;
CREATE TABLE `virtual_aliases` (
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
domain_id INT(11) NOT NULL,
source VARCHAR(64) NOT NULL,
destination VARCHAR(128) NOT NULL,
enabled TINYINT(4) NOT NULL,
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE = InnoDB;
CREATE VIEW `view_users` AS
SELECT CONCAT(virtual_users.user, '@', virtual_domains.name) AS email, virtual_users.password, virtual_users.enabled
FROM virtual_users
LEFT JOIN virtual_domains ON virtual_users.domain_id = virtual_domains.id
WHERE virtual_domains.enabled = 1 AND virtual_users.enabled = 1;
CREATE VIEW `view_aliases` AS
SELECT CONCAT(virtual_aliases.source, '@', virtual_domains.name) AS email, destination, virtual_aliases.enabled
FROM virtual_aliases
LEFT JOIN virtual_domains ON virtual_aliases.domain_id = virtual_domains.id
WHERE virtual_aliases.enabled = 1 AND virtual_domains.enabled = 1;
quit;
|
Tell postfix to use the mysql tables to authenticate domains against
1
|
vi /etc/postfix/mysql-virtual-mailbox-domains.cf
|
Add
1
2
3
4
5
|
user = mailuser
password = mailuserpassword
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_domains WHERE name = '%s' AND enabled = 1
|
Enable
1
|
postconf -e virtual_mailbox_domains=mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
|
Create a test email account
<domain>.com is your server domain name
1
2
3
4
|
mysql mailserver
mysql>
INSERT INTO virtual_domains (id, name, enabled) VALUES (1, '<domain>.com', 1);
quit;
|
Test the domain mapping
1
|
postmap -q <domain>.com mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
|
Should return 1
Tell postfix to use the mysql tables to authenticate users against
1
|
vi /etc/postfix/mysql-virtual-mailbox-maps.cf
|
Add
1
2
3
4
5
|
user = mailuser
password = mailuserpassword
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM view_users WHERE email = '%s' AND enabled = 1
|
Enable
1
|
postconf -e virtual_mailbox_maps=mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
|
Create a test email user named <test>
1
2
3
4
|
mysql mailserver
mysql>
INSERT INTO virtual_users (id, domain_id, user, password, enabled) VALUES (1, 1, 'test', MD5('test'), 1);
quit;
|
Test the user mapping
1
|
postmap -q test@<domain>.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
|
Should return 1
Tell postfix to use the aliases
1
|
vi /etc/postfix/mysql-virtual-alias-maps.cf
|
Add
1
2
3
4
5
|
user = mailuser
password = mailuserpassword
hosts = 127.0.0.1
dbname = mailserver
query = SELECT destination FROM view_aliases WHERE email = '%s' AND enabled = 1
|
Add some email aliases
1
2
3
4
5
6
|
mysql mailserver
mysql>
INSERT INTO virtual_aliases (id, domain_id, source, destination, enabled)
VALUES (1, 1, 'test', 'test@<domain>.com', 1),
(2, 1, 'test', '<your username>@yahoo.com', 1);
|
Test the alias mapping
1
|
postmap -q test@<domain>.com mysql:/etc/postfix/mysql-virtual-alias-maps.cf
|
Should return test@<domain>.com,<your username>@yahoo.com
Tell postfix to check for specific user emails before aliases
1
|
vi /etc/postfix/mysql-email2email.cf
|
Add
1
2
3
4
5
|
user = mailuser
password = mailuserpassword
hosts = 127.0.0.1
dbname = mailserver
query = SELECT email FROM view_users WHERE email='%s' AND enabled = 1
|
Test the user mapping
1
|
postmap -q test@<domain>.com mysql:/etc/postfix/mysql-email2email.cf
|
Should return test@<domain>.com
Add to postfix configuration
1
|
postconf -e virtual_alias_maps=mysql:/etc/postfix/mysql-virtual-alias-maps.cf,mysql:/etc/postfix/mysql-email2email.cf
|
Create the system user <vmail> which postfix will use to access the virtual mailboxes
5000 is an arbitrary userid which most likely is not in use
check /etc/passwd to be sure
1
2
3
4
5
|
groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /home/users/vmail -m
postconf -e virtual_uid_maps=static:5000
postconf -e virtual_gid_maps=static:5000
|
Set permissions to postfix
1
2
|
chgrp postfix /etc/postfix/mysql-*.cf
chmod u=rw,g=r,o= /etc/postfix/mysql-*.cf
|
Tell postfix to use dovecot for delivery
1
|
vi /etc/postfix/master.cf
|
Add at the bottom
1
2
|
dovecot unix - n n - - pipe
flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -d ${recipient}
|
Enable
1
2
3
|
postconf -e virtual_transport=dovecot
postconf -e dovecot_destination_recipient_limit=1
postconf -e dovecot_destination_concurrency_limit = 1
|
Reload postfix configuration
Create the directories where emails will be saved
1
2
|
mkdir /home/domains/<domain>.com/mailboxes
chown -R vmail:vmail /home/domains/<domain>.com/mailboxes
|
Configure dovecot
1
|
vi /etc/dovecot/dovecot.conf
|
Modify to match
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
protocols = imap imaps pop3 pop3s
disable_plaintext_auth = no # ideally yes, but some clients (outlook) suck; esp with self signed certs
mail_location = maildir:/home/domains/%d/mailboxes/%n/Maildir
auth default {
mechanisms = plain login
#passdb pam {
#}
passdb sql {
args = /etc/dovecot/dovecot-sql.conf
}
#userdb passwd {
#}
userdb static {
args = uid=5000 gid=5000 home=/home/domains/%d/mailboxes/%n allow_all_users=yes
}
socket listen {
master {
path = /var/run/dovecot/auth-master
mode = 0600
user = vmail
}
client {
path = /var/spool/postfix/private/auth
mode = 0660
user = postfix
group = postfix
}
}
protocol lda {
#log_path = /var/log/dovecot/dovecot.log # default is to /var/log/mail.log
auth_socket_path = /var/run/dovecot/auth-master
postmaster_address = postmaster
mail_plugins = cmusieve
global_script_path = /home/vmail/globalsieverc
}
}
|
globalsieverc allows global post processing on emails
1
|
vi /home/users/vmail/globalsieverc
|
Add
1
2
3
4
5
6
|
require ["fileinto"];
# Move spam to spam folder
if header :contains "X-Spam-Flag" ["YES"] {
fileinto "spam";
stop;
}
|
Tell dovecot to use the mysql tables
1
|
vi /etc/dovecot/dovecot-sql.conf
|
Modify to match
1
2
3
4
|
driver = mysql
connect = host=127.0.0.1 dbname=mailserver user=mailuser password=mailuserpassword
default_pass_scheme = PLAIN-MD5
password_query = SELECT email as user, password FROM view_users WHERE email = '%u' AND enabled = 1
|
Now set permissions
1
2
|
chgrp vmail /etc/dovecot/dovecot.conf
chmod g+r /etc/dovecot/dovecot.conf
|
Restart dovecot
1
|
/etc/init.d/dovecot restart
|
Tell postfix to use dovecot
1
|
postconf -e smtpd_sasl_type=dovecot
|
Now create ssl certificates for use with tls and ssl authentication
1
2
3
4
5
6
7
8
9
10
11
|
openssl req -new -x509 -days 3650 -nodes -out /etc/ssl/certs/dovecot.pem -keyout /etc/ssl/private/dovecot.pem
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Texas
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]: <space>
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:<domain>.com
Email Address []:
chmod o= /etc/ssl/private/dovecot.pem
|
Enable tls / ssl auth in postfix
1
2
3
|
postconf -e smtpd_sasl_path=private/auth
postconf -e smtpd_sasl_auth_enable=yes
postconf -e smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination
|
Create ssl certs for postfix similair to as done in dovecot
1
2
3
4
5
6
7
8
9
10
11
|
openssl req -new -x509 -days 3650 -nodes -out /etc/ssl/certs/postfix.pem -keyout /etc/ssl/private/postfix.pem
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Texas
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]: <space>
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:<domain>.com
Email Address []:
chmod o= /etc/ssl/private/postfix.pem
|
Enable
1
2
3
4
5
6
7
|
postconf -e smtpd_tls_cert_file=/etc/ssl/certs/postfix.pem
postconf -e smtpd_tls_key_file=/etc/ssl/private/postfix.pem
postconf -e smtpd_use_tls=yes
postconf -e smtpd_tls_auth_only=yes
postconf -e smtpd_tls_security_level = may
postfix reload
|
ISPs usually block the common smpt port 25 from sending emails from other smtp servers .. like yours
So, you need to create a another port to use for smtp, say 2525
1
|
vi /etc/postfix/master.cf
|
Add below the smtp line
1
2
|
2525 inet n - - - - smtpd
-o smtpd_tls_security_level=may
|
You will also have to configure your email client to use port 2525 instead of port 25 to send out emails
OK, so if everything went well, you should be able to send and receive emails using the test user account created.
Try it.
Note:
Outlook and Thunderbird email clients have an option to send email using secure password authentication (SPA). Do not use as SPA is only for Active Directory ingrated authentication.
You will want to use TLS or SSL.
Now to add spam and antivirus protection
amavis is a mail virus scanner .. which is really just the glue between postfix and clamav (antivirus) and spamassassin (spam)
Configure amavis
1
|
vi /etc/amavis/conf.d/15-content_filter_mode
|
Removing the '#' from the @bypass_
1
2
3
4
5
|
@bypass_virus_checks_maps = (
\%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);
@bypass_spam_checks_maps = (
\%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);
|
Customize spam handling and turn down logging for amavis
1
|
vi /etc/amavis/conf.d/20-debian_defaults
|
Never just drop emails as spam tagging is not perfect
1
2
3
4
5
6
7
|
$final_spam_destiny=D_PASS
$syslog_priority = 'info'; # switch to info to drop debug output, etc
$log_level = 3;
$max_servers = 15; # match postfix call
$child_timeout = 1200; # match postfix call
|
1
|
/etc/init.d/amavis restart
|
Tell postfix to use amavis
1
2
|
postconf -e content_filter=smtp-amavis:[127.0.0.1]:10024
postconf -e receive_override_options=no_address_mappings
|
1
|
vi /etc/postfix/master.cf
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
smtp-amavis unix - - n - 15 smtp
-o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes
-o disable_dns_lookups=yes
-o max_use=15
-o smtp_connect_timeout=2
-o smtp_helo_timeout=2
127.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=
|
Now allow amavis to use clamav
1
2
|
adduser clamav amavis
/etc/init.d/clamav-daemon restart
|
Tell amavis where to check for valid domains
1
|
vi /etc/amavis/conf.d/50-user
|
Add before the end
1
2
3
4
5
6
7
8
|
@lookup_sql_dsn = (
['DBI:mysql:database=mailserver;host=127.0.0.1;port=3306',
'mailuser',
'mailuserpassword']);
$sql_select_policy = 'SELECT 1 as id, 99 as policy_id, "Y" AS local FROM virtual_domains WHERE name IN (%k) AND enabled = 1';
$sql_lookups_no_at_means_domain = 1; # allow matching domian w/o @
$sql_select_white_black_list = undef; # undef disables SQL white/blacklisting
|
Secure the config file
1
|
chmod o= /etc/amavis/conf.d/50-user
|
Restart amavis
1
|
/etc/init.d/amavis restart
|
You should still be able to send and receive emails
If you view the headers of the email, you should see something similar to
1
2
3
4
5
|
X-Virus-Scanned: Debian amavisd-new at <domain>.com
X-Spam-Flag: NO
X-Spam-Score: 3.956
X-Spam-Level: ***
X-Spam-Status: No, score=3.956 tagged_above=2 required=6.31 tests=[ALL_TRUSTED=-1.44, LOCALPART_IN_SUBJECT=2.497, TVD_SPACE_RATIO=2.899]
|
To have root emails forwarded to you
Add at the bottom; and make sure there are no other references of root: <something>
1
|
root: <you>@<domain>.com
|
Update aliases db
If your upgrading a mailserver and the old mailboxes are stored in mbox format, you can convert mbox to maildir
1
2
3
4
5
|
cd /tmp
wget http://batleth.sapienti-sat.org/projects/mb2md/mb2md-3.20.pl.gz
gzip -d mb2md-3.20.pl.gz
chmod 755 mb2md-3.20.pl
./mb2md-3.20.pl -s /tmp/<old mailbox> -d /home/domains/<domain>/mailboxes/<user>/Maildir -R
|
The reuslting out put creates imap style folders (.inbox, .spam, .trash, etc)
If your email user only uses pop, then copy the files in .inbox/cur/* to cur/ and .inbox/new/* to new/
Add some further security related restrictions to postfix
1
|
vi /etc/postfix/main.cf
|
Add toward the bottom
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
smtpd_recipient_restrictions =
reject_invalid_hostname,
reject_non_fqdn_hostname,
reject_non_fqdn_sender,
reject_non_fqdn_recipient,
reject_unknown_sender_domain,
reject_unknown_recipient_domain,
reject_unauth_pipelining,
permit_sasl_authenticated,
permit_mynetworks,
reject_unauth_destination,
# reject_rbl_client zombie.dnsbl.sorbs.net,
# reject_rbl_client relays.ordb.org,
# reject_rbl_client opm.blitzed.org,
# reject_rbl_client list.dsbl.org,
# reject_rbl_client sbl.spamhaus.org,
permit
receive_override_options = no_address_mappings
smtpd_data_restrictions = reject_unauth_pipelining, permit
smtpd_sasl_security_options = noanonymous
smtpd_helo_required = yes
disable_vrfy_command = yes
|
Restart postfix
1
|
/etc/init.d/postfix restart
|
If you already have apache and php running,
you can also check email from the web using
ilohamail
http://ilohamail.org/main.php?page=Features
1
|
aptitude install ilohamail
|
Read the instructions to add mysql support
1
|
vi /usr/share/doc/ilohamail/README.Debian
|
19