Email server setup
Contents
Note
All that follow is the sum of different how-to. I've based my research on FLURDY therefore a lot of commands are similar.
I'm not an expert of mail server, therefore most of the following content is not mine. I've just aggregate data to make it easier to work with. Only the pictures are mine.
If you want to know more about emails just check out the #Sources section.
Overview
Requirements
An email server requires a lot of components:
- Send / Receive emails [SMTP, POP3, IMAP, ...]
- Tools to check the email content against virus, spam
- Tools to encrypt the communication
- (optional) Database to manage users and emails
Therefore, before going on you need to have:
- MySQL server
- MySQL client such as MySQL workbench
Setup
Create Linux mail user
It's a common good practice to create a dedicated user to send email. That's the user POSTFIX will use.
As usual in Linux, that user should be UID > 1000 so it has more restrictions.
# Server root folder, where all the mails will be stored
mkdir -p /var/spool/mail/virtualMail
# New user
groupadd --system virtualMail -g 5000
useradd --system virtualMail -u 5000 -g 5000
chown -R virtualMail:virtualMail /var/spool/mail/virtualMail
MySQL database
Create and initialize a new database and user for email.
Create database
I assume that:
- Database name: maildb
- Db user: maildb
# log in as root
mysql -u root -p
# Create the mail database
create database maildb;
# Create a new user and grant rights upon mail database
GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON maildb.* TO 'maildb'@'localhost' IDENTIFIED by 'mailDbPASSWORD';
GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON maildb.* TO 'maildb'@'%' IDENTIFIED by 'mailDbPASSWORD';
exit;
Schema
Create the following schema using MySQL workbench:
CREATE TABLE `aliases` (
`pkid` smallint(3) NOT NULL auto_increment,
`mail` varchar(120) NOT NULL default '',
`destination` varchar(120) NOT NULL default '',
`enabled` tinyint(1) NOT NULL default '1',
PRIMARY KEY (`pkid`),
UNIQUE KEY `mail` (`mail`) ) ;
CREATE TABLE `domains` (
`pkid` smallint(6) NOT NULL auto_increment,
`domain` varchar(120) NOT NULL default '',
`transport` varchar(120) NOT NULL default 'virtual:',
`enabled` tinyint(1) NOT NULL default '1',
PRIMARY KEY (`pkid`) ) ;
CREATE TABLE `users` (
`id` varchar(128) NOT NULL default '',
`name` varchar(128) NOT NULL default '',
`uid` smallint(5) unsigned NOT NULL default '5000',
`gid` smallint(5) unsigned NOT NULL default '5000',
`home` varchar(255) NOT NULL default '/var/spool/mail/virtual',
`maildir` varchar(255) NOT NULL default 'blah/',
`enabled` tinyint(3) unsigned NOT NULL default '1',
`change_password` tinyint(3) unsigned NOT NULL default '1',
`clear` varchar(128) NOT NULL default 'ChangeMe',
`crypt` varchar(128) NOT NULL default 'sdtrusfX0Jj66',
`quota` varchar(255) NOT NULL default '',
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`) ) ;
Source: http://flurdy.com/docs/postfix/
POSTFIX (SMTP server)
Installation
POSTFIX SMTP server:
apt-get install postfix postfix-mysql
mkdir -p /var/spool/mail/virtual
Basic configuration
vim /etc/postfix/mail.cf
Put the following configuration:
##########################
# MISC settings #
##########################
# Server name
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no
# appending .domain is the MUA's job.
append_dot_mydomain = no
# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h
readme_directory = no
# Use external SMTP relay?
relayhost =
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
# Bind interfaces
inet_interfaces = all
# Restrict to IPv4 (= avoid IPv6 errors and log spam)
inet_protocols=ipv4
###########################
# Email global settings #
###########################
# Email server name
myhostname = smartcard-mail.smartcards.vehco.com
# Domain name for emails originated from this server
#myorigin = /etc/mailname
myorigin = smartcards.vehco.com
# Local destination (= email server local alias)
mydestination = smartcard-mail.smartcards.vehco.com, localhost.smartcards.vehco.com, , localhost
# Trusted senders
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 172.16.50.0/24 172.16.60.0/24
##############################
# Commands #
##############################
mailbox_command = procmail -a "$EXTENSION"
###################################
# Email accounts / msg settings #
###################################
# Max mailbox size
mailbox_size_limit = 0
# Max number of mailboxes
virtual_mailbox_limit = 0
# Max message size
message_size_limit = 0
# Misc settings
recipient_delimiter = +
###########################
# Connection settings #
###########################
# how long to keep message on queue before return as failed
maximal_queue_lifetime = 1h
# max and min time in seconds between retries if connection failed
minimal_backoff_time = 5m
maximal_backoff_time = 10m
# how long to wait when servers connect before receiving rest of data
smtp_helo_timeout = 60s
# how many address can be used in one message.
# effective stopper to mass spammers, accidental copy in whole address list but may restrict intentional mail shots.
smtpd_recipient_limit = 16
# how many error before back off.
smtpd_soft_error_limit = 3
# how many max errors before blocking it.
smtpd_hard_error_limit = 12
####################################
# Security: protocol enforcement #
####################################
# Requirements for the HELO statement
smtpd_helo_restrictions = permit_mynetworks, warn_if_reject reject_non_fqdn_hostname, reject_invalid_hostname, permit
# Requirements for the sender details
smtpd_sender_restrictions = permit_mynetworks, warn_if_reject reject_non_fqdn_sender, reject_unknown_sender_domain, reject_unauth_pipelining, permit
# Requirements for the connecting server
smtpd_client_restrictions = reject_rbl_client sbl.spamhaus.org, reject_rbl_client blackholes.easynet.nl
# Requirement for the recipient address
smtpd_recipient_restrictions = reject_unauth_pipelining, permit_mynetworks, reject_non_fqdn_recipient, reject_unknown_recipient_domain, reject_unauth_destination, permit
smtpd_data_restrictions = reject_unauth_pipelining
# require proper helo at connections
smtpd_helo_required = yes
# waste spammers time before rejecting them
smtpd_delay_reject = yes
disable_vrfy_command = yes
############################
# Email accounts #
############################
# Alias definitions
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
# Location of the virtual mailbox folder (= Global server mailbox)
# ... This must match the folder you created in [[#Create Linux mail user]]
virtual_mailbox_base = /var/spool/mail/virtualMail
## MySQL settings
# Mailbox location for each user
virtual_mailbox_maps = mysql:/etc/postfix/mysql_mailbox.cf
# List of virtual mailboxes
virtual_alias_maps = mysql:/etc/postfix/mysql_alias.cf
# Domain lookups
virtual_mailbox_domains = mysql:/etc/postfix/mysql_domains.cf
############################
# Security #
############################
## Mail user / group
# Good practice: you should create a dedicated Linux user to send mails. That one is called "virtualMail"
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
## TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
Don't forget to adjust:
- Email global settings
- myhostname
- myorigin
- mydestination
- mynetworks
- Email accounts
- virtual_mailbox_base
- Security
- virtual_uid_maps
- virtual_gid_maps
MySQL mailbox config
How to select a mailbox from MySQL.
vim /etc/postfix/mysql_mailbox.cf
Put the following content, replace mailDbPASSWORD by your own database password:
user=maildb
password=mailDbPASSWORD
dbname=maildb
table=users
select_field=maildir
where_field=id
hosts=127.0.0.1
additional_conditions = and
enabled = 1
MySQL alias config
How to find the email alias from MySQL
vim /etc/postfix/mysql_alias.cf
Put the following content, replace mailDbPASSWORD by your own database password:
user=maildb
password=mailDbPASSWORD
dbname=maildb
table=aliases
select_field=destination
where_field=mail
hosts=127.0.0.1
additional_conditions = and
enabled = 1
MySQL domain config
How to find the domains.
vim /etc/postfix/mysql_domains.cf
Put the following content, replace mailDbPASSWORD by your own database password:
user=maildb
password=mailPASSWORD
dbname=maildb
table=domains
select_field=domain
where_field=domain
hosts=127.0.0.1
additional_conditions = and
enabled = 1
Other
## Security libraries
# SASL is the Simple Authentication and Security Layer, a method for adding authentication support to connection-based protocols.
apt-get install libsasl2-modules libsasl2-modules-sql libgsasl7 libauthen-sasl-cyrus-perl sasl2-bin
# Authentication using MySQL
apt-get install libpam-mysql
## Anti-virus
apt-get install clamav-base libclamav6 clamav-daemon clamav-freshclam
## SPAM killer
apt-get install spamassassin spamc
## Interface to scan emails for virus & spam
apt-get install amavisd-new
## Utility to SEND emails
apt-get install postfix postfix-mysql
## Utility to RECEIVE emails
apt-get install courier-base courier-authdaemon courier-authlib-mysql courier-imap courier-imap-ssl courier-pop courier-pop-ssl courier-ssl