How to MailServer on Ubuntu+Amazon EC2+Scripts to generate mail users
We are going to build a mail server in Amazon ecosystem…
First we need to launch the instance with Ubuntu 10.04, maybe you can find this ami-cf4d67bb in europe, and this ami-c997c68c in USA west or this ami-2d4aa444 in USA East.
Once the AMI is launched we connect by ssh:
ssh -i KEY_PAIR ubuntu@ip_server
1.- Update the sources:
aptitude update & aptitude safe-upgrade
2.- Install Mysql server, and select internet site when you’ll be asked.
aptitude install mysql-client mysql-server
3.- Install Postfix and SASL
aptitude install postfix postfix-mysql libsasl2-modules libsasl2-modules-sql libgsasl7 libauthen-sasl-cyrus-perl sasl2-bin libpam-mysql
4.- Install ClamAV
aptitude install clamav-base libclamav6 clamav-daemon clamav-freshclam
5.- Install Amavis, SpamAssassin and postgrey
aptitude install amavisd-new spamassassin spamc postgrey
6.- Install phpMyadmin
aptitude install phpmyadmin
7.- Install Shorewall
aptitude install shorewall-common shorewall-perl shorewall-doc
8.- Install courier, we say no to the directory creation.
aptitude install courier-base courier-authdaemon courier-authlib-mysql courier-imap courier-imap-ssl courier-ssl
SHOREWALL PENDIENT
9.- Configure MTA
Set the server name
nano /etc/mailname
Open the postfix conf file, and change the next values “domain.com” is the name of our domain:
nano /etc/postfix/main.cf
myorigin = domain.com
Then decide what the greeting text will be. Enough info so it is useful, but not divelge everything to potential hackers.
smtpd_banner = $myhostname ESMTP $mail_name
We are going to send mails from our server…maybe later we’ll try by Gmail, so…
relayhost =
Next is network details. You will accept connection from anywhere, and you only trust this machine
inet_interfaces = all
mynetworks_style = host
As we will be using virtual domains, these need to be empty.
local_recipient_maps =
mydestination =
Then will set a few numbers.
# how long if undelivered before sending warning update to sender
delay_warning_time = 4h
# will it be a permanent error or temporary
unknown_local_recipient_reject_code = 450
# how long to keep message on queue before return as failed.
maximal_queue_lifetime = 3d
# max and min time in seconds between retries if connection failed
minimal_backoff_time = 1000s
maximal_backoff_time = 8000s
# 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
Now we can specify some restrictions. Be carefull that each setting is on one line only.
# 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, reject_rbl_client dnsbl.njabl.org
# 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
Further restrictions:
# require proper helo at connections
smtpd_helo_required = yes
# waste spammers time before rejecting them
smtpd_delay_reject = yes
disable_vrfy_command = yes
Next we need to set some maps and lookups for the virtual domains.
# not sure of the difference of the next two # but they are needed for local aliasing
alias_maps = hash:/etc/postfix/aliases
alias_database = hash:/etc/postfix/aliases
# this specifies where the virtual mailbox folders will be located
virtual_mailbox_base = /var/spool/mail/virtual
# this is for the mailbox location for each user
virtual_mailbox_maps = mysql:/etc/postfix/mysql_mailbox.cf
# and this is for aliases
virtual_alias_maps = mysql:/etc/postfix/mysql_alias.cf
# and this is for domain lookups
virtual_mailbox_domains = mysql:/etc/postfix/mysql_domains.cf
# this is how to connect to the domains (all virtual, but the option is there)
# not used yet
# transport_maps = mysql:/etc/postfix/mysql_transport.cf
You can use a lookup for the uid and gid of the owner of mail files. But I tend to have one owner(virtual), so instead add this:
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
Let’s set up a alias file
cp /etc/aliases /etc/postfix/aliases
Add some aliases if needed
postalias /etc/postfix/aliases
Next you need to set up the folder where the virtual mail will be stored. This may have already been done by the apt-get. And also create the user whom will own the folders.
# to add if there is not a virtual user
mkdir /var/spool/mail/virtual
groupadd –system virtual -g 5000
useradd –system virtual -u 5000 -g 5000
chown -R virtual:virtual /var/spool/mail/virtual
Now we are going to connect MySQL with Postfix…
nano /etc/postfix/mysql_mailbox.cf
user=mail password=mailPASSWORD dbname=maildb table=users select_field=maildir where_field=id hosts=www.notesfromchechu.com additional_conditions = and enabled = 1
user=mail
password=PASSWORD
dbname=maildb
table=users
select_field=maildir
where_field=id
hosts=www.notesfromchechu.com
additional_conditions = and enabled = 1
Create how to find the e-mail alias:
nano /etc/postfix/mysql_alias.cf
user=mail
password=PASSWORD
dbname=maildb
table=aliases
select_field=destination
where_field=mail
hosts=www.notesfromchechu.com
additional_conditions = and enabled = 1
Create how to find the domains:
nano /etc/postfix/mysql_domains.cf
user=mail
password=PASSWORD
dbname=maildb
table=domains
select_field=domain
where_field=domain
hosts=www.notesfromchechu.com
additional_conditions = and enabled = 1
MySQL
Once logged into our MySQL server:
# then we create the mail database
create database maildb;
# then we create a new user: “mail”
GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON maildb.* TO ‘mail’@’localhost’ IDENTIFIED by ‘mailPASSWORD’;
GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON maildb.* TO ‘mail’@’%’ IDENTIFIED by ‘mailPASSWORD’;
exit;
mysql -u mail -p maildb
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 ”, `procmailrc` varchar(128) NOT NULL default ”, `spamassassinrc` varchar(128) NOT NULL default ”, PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`) ) ;
Let’s configure MySQL
nano /etc/mysql/my.cnf
bind-address = www.notesfromchechu.com
general_log_file = /var/log/mysql/mysql.log
general_log = 1
/etc/init.d/mysql restart
POP/IMAP
nano /etc/courier/authdaemonrc
authmodulelist=”authmysql”
logging.DEBUG_LOGIN=2
nano /etc/courier/authmysqlrc
MYSQL_USERNAME mail
MYSQL_PASSWORD PASSWORD
MYSQL_DATABASE maildb
MYSQL_USER_TABLE users
MYSQL_CRYPT_PWFIELD crypt
# MYSQL_CLEAR_PWFIELD clear
MYSQL_MAILDIR_FIELD concat(home,’/’,maildir)
MYSQL_WHERE_CLAUSE enabled=1
Basic settings are done…let’s going to test it:
reboot server
telnet localhost 25
EHLO name_of_our_server
MAIL FROM:
RCPT TO:
data
we’ll write somethig and will finish with and enter and ‘.’
we can see logs here /var/log/mail.log
Let’s go for more
Amavis check mails for viruses and spam, Amavis’s conf files are in:
cd /etc/amavis/conf.d
nano 15-content_filter_mode
Comment out both virus and spam scans. (Default).
# #@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);
nano 50-user
In the middle insert:
@local_domains_acl = qw(.);
$log_level = 2;
$syslog_priority = ‘debug’;
# $sa_tag_level_deflt = 2.0; # add spam info headers if at, or above that level
# $sa_tag2_level_deflt = 6.31;# add ‘spam detected’ headers at that level
$sa_kill_level_deflt = 8.0; # triggers spam evasive actions
# $sa_dsn_cutoff_level = 10; # spam level beyond which a DSN is not sent
$final_spam_destiny = D_PASS;
# $final_spam_destiny = D_REJECT;# default
# $final_spam_destiny = D_BOUNCE; # debian default
# $final_spam_destiny = D_DISCARD; # ubuntu default, recommended as sender is usually faked
We have now setup amavis to scan and pass along incomming email. Next we will setup postfix to talk to amavis.
vi /etc/postfix/master.cf
Append these lines to the end of the file (make sure they are not already present). (Note the -o lines have spaces in front of them).
amavis unix – – – – 2 smtp
-o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes
-o disable_dns_lookups=yes
-o max_use=20
www.notesfromchechu.com: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
Also add the following two lines immediately below the “pickup” transport service:
-o content_filter=
-o receive_override_options=no_header_body_checks
and then added to main.cf
nano /etc/postfix/main.cf
content_filter = amavis:[www.notesfromchechu.com]:10024
Add user to group:
adduser clamav amavis
This should be it to get amavis working. If emails are picked up by amavis and passed back to postfix then it looks okay. Only when finished testing do you proced to uncomment the anti virus and anti spam lines insudo
nano 15-content_filter_mode
@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);
nano /etc/amavis/conf.d/50-user
@local_domains_acl = qw(.);
$log_level = 1;
$syslog_priority = ‘info’;
# $sa_tag_level_deflt = 2.0;# add spam info headers if at, or above that level
# $sa_tag2_level_deflt = 6.31; # add ‘spam detected’ headers at that level
$sa_kill_level_deflt = 8.0; # triggers spam evasive actions # $sa_dsn_cutoff_level = 10; # spam level beyond which a DSN is not sent
# $final_spam_destiny = D_PASS; # $final_spam_destiny = D_REJECT; # default
# $final_spam_destiny = D_BOUNCE; # debian default $final_spam_destiny = D_DISCARD; # ubuntu default, recommended as sender is usually faked
Activate SpamAssasin
nano /etc/default/spamassassin
ENABLED=1
nano /etc/spamassassin/local.cf
use_bayes 1bayes_auto_learn 1
By default freshclam, the daemon that updates the virus definition database, is run 24 times a day. That seems a little excessive, so I tend to set that to once a day.
Choose daemon and which server is closest to you.
dpkg-reconfigure clamav-freshclam
The Postgrey conf is ok, but we need to tell postfix to use it:
nano /etc/postfix/main.cf
smtpd_recipient_restrictions = reject_unauth_pipelining, permit_mynetworks, permit_sasl_authenticated, reject_non_fqdn_recipient, reject_unknown_recipient_domain, reject_unauth_destination, check_policy_service inet:www.notesfromchechu.com:10023, permit
nano /etc/default/postgrey
POSTGREY_OPTS=”–inet=10023 –max-age=365″
Now we’ll insert some data to test the system…
We enter into phpmysql, and execute the next sql commands:
INSERT INTO domains (domain) VALUES (‘domain.com’);
Some alias:
INSERT INTO aliases (mail,destination) VALUES (‘prueba1@domain.com’,’prueba@domain.com’), (‘prueba2@domain.com’,’prueba@domain.com’);
And the user:
INSERT INTO users (id,name,maildir,crypt) VALUES (‘prueba@domain.com’,’prueba’,’prueba/’, encrypt(‘prueba’) );
SECURITY
SASL
aptitude install sasl2-bin libpam-mysql libsasl2-modules libsasl2-modules-sql
adduser postfix sasl
mkdir -p /var/spool/postfix/var/run/saslauthd
nano /etc/postfix/main.cf
# SASL
smtpd_sasl_auth_enable = yes # If your potential clients use Outlook Express or other older clients
# this needs to be set to yes
broken_sasl_auth_clients = no
smtpd_sasl_security_options = noanonymous smtpd_sasl_local_domain =
Modify these existing configurations:
# Add permit_sasl_authenticated to you existing smtpd_sender_restrictions
smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks,
warn_if_reject reject_non_fqdn_sender, reject_unknown_sender_domain,
reject_unauth_pipelining, permit
# Add permit_sasl_authenticated to you existing smtpd_recipient_restrictions
smtpd_recipient_restrictions = reject_unauth_pipelining, permit_mynetworks,
permit_sasl_authenticated, reject_non_fqdn_recipient, reject_unknown_recipient_domain,
reject_unauth_destination, check_policy_service inet:www.notesfromchechu.com:10023, permit
We change the way Sasl is running:
nano /etc/default/saslauthd
START=yes
OPTIONS=”-r -c -m /var/spool/postfix/var/run/saslauthd”
Tell postfix how to interact with SASL:
nano /etc/postfix/sasl/smtpd.conf
pwcheck_method: saslauthd
mech_list: plain login cram-md5 digest-md5
log_level: 7
allow_plaintext: true
auxprop_plugin: mysql
sql_engine: mysql
sql_hostnames: www.notesfromchechu.com
sql_user: mail
sql_passw: PASSWORD
sql_database: maildb
sql_select: select crypt from users where id=’%u@%r’ and enabled = 1
nano /etc/pam.d/smtp
auth required pam_mysql.so user=mail passwd=PASSWORD host=www.notesfromchechu.com db=maildb table=users usercolumn=id passwdcolumn=crypt crypt=1
account sufficient pam_mysql.so user=mail passwd=PASSWORD host=www.notesfromchechu.com db=maildb table=users usercolumn=id passwdcolumn=crypt crypt=1
/etc/init.d/saslauthd restart
/etc/init.d/postfix restart
Now we’ll set the encryption
First we need to create the certificate:
cd /etc/postfix
openssl req -new -outform PEM -out postfix.cert -newkey rsa:2048 -nodes -keyout postfix.key -keyform PEM -days 999 -x509
nano /etc/postfix/main.cf
# TLS parameters
# smtp_use_tls = no
smtp_tls_security_level = may
# smtpd_use_tls=yes
smtpd_tls_security_level = may
# smtpd_tls_auth_only = no
smtp_tls_note_starttls_offer = yes
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom
smtpd_tls_cert_file = /etc/postfix/postfix.cert
smtpd_tls_key_file = /etc/postfix/postfix.key
# smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
# smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
nano /etc/postfix/master.cf
submission inet n – n – – smtpd
-o smtpd_sasl_auth_enable=yes
# if you do not want to restrict it encryption only, comment out next line
-o smtpd_tls_auth_only=yes
# -o smtpd_tls_security_level=encrypt
# -o header_checks=
# -o body_checks=< -o smtpd_client_restrictions=permit_sasl_authenticated,reject_unauth_destination,reject -o smtpd_sasl_security_options=noanonymous,noplaintext -o smtpd_sasl_tls_security_options=noanonymous # -o milter_macro_daemon_name=ORIGINATING< smtps inet n - - - - smtpd -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes -o smtpd_tls_auth_only=yes -o smtpd_client_restrictions=permit_sasl_authenticated,reject -o smtpd_sasl_security_options=noanonymous,noplaintext -o smtpd_sasl_tls_security_options=noanonymous # -o milter_macro_daemon_name=ORIGINATING cd /etc/courier openssl req -x509 -newkey rsa:1024 -keyout imapd.pem -out imapd.pem -nodes -days 999 nano /etc/courier/imapd-ssl Ok the mail server conf its done...now we are going to enable the webmail... WEBMAIL aptitude install roundcube roundcube-mysql This will create a symblink in /etc/apache2/conf.d/ to /etc/roundcube/apache.conf. Edit this file. nano /etc/roundcube/apache.conf Depending on your setup you may want to move those Alias commands at the top to your virtual hosts configuration, or for this example enable them here for all hosts. # Uncomment them to use it or adapt them to your configuration Alias /roundcube/program/js/tiny_mce/ /usr/share/tinymce/www/ Alias /roundcube /var/lib/roundcube Next edit the configuration file nano /etc/roundcube/main.inc.php $rcmail_config['default_host'] = 'ssl://localhost:993'; $rcmail_config['smtp_server'] = 'ssl://localhost'; $rcmail_config['smtp_port'] = 465; $rcmail_config['smtp_helo_host'] = 'mailserver.domain.com''; $rcmail_config['create_default_folders'] = TRUE; $rcmail_config['sendmail_delay'] = 1; Reload Apache /etc/init.d/apache2 reload
Cloud Computing LinuxMay 16th, 20130 comments
-
Categories
-
Latest Posts