I’m building mail server
November 3, 2009 | linux, other, toolsauthor: Karol Zielinski | comments: 0 | views: 1428
Tags: administration, email, mail, mysql, postfix, server
I want to build mail server on my VPS (ubuntu). What I want to have is: multiple domains and users; users’ accounts in MySQL database; Courier package to control my pop and imap access to the emails. So.. let’s do it.
Check your hostname:
hostname -f
If it’s ok – skip this step. If it’s not:
sudo vim /etc/hostname
Replace the hostname with your mail server hostname.
sudo vim /etc/hosts
replace your current hostname to new one.
Now
sudo reboot
and check hostname again. It should be ok right now.
It’s some kind of unique. Each VPS has its own procedure for setting RDNS.
First… check your actual RDNS:
dig -x YOUR_IP
There should be your hostname. If it’s not – you need to set it. More about Reverse DNS you can find here.
Now, we will create user ‘vmail’. Using this name is a common way of identifying the system user where the mail is physically located.
sudo groupadd -g 5000 vmail sudo useradd -s /usr/sbin/nologin -g vmail -u 5000 vmail -d /home/vmail -m
The second command creates the ‘vmail’ user, ensures they can’t login (it is not a normal account), adds them to the ‘vmail’ group and creates the home directory.
sudo apt-get install postfix postfix-mysql mysql-server postfix-tls libsasl2-2 libsasl2-modules libsasl2-modules-sql sasl2-bin libpam-mysql openssl telnet mailx
For MySQL: you will need to set new password for root.
For Postfix: Choose ‘Internet Site’ for type of mail condfiguration and set your new hostname as a system mail name.
mysql -u root -p
use your MySQL’s root password to log in.
CREATE DATABASE mail; CREATE USER 'mailadmin'@'localhost' IDENTIFIED BY 'newpassword'; FLUSH PRIVILEGES; GRANT SELECT, INSERT, UPDATE, DELETE ON `mail` . * TO 'mailadmin'@'localhost'; FLUSH PRIVILEGES;
Do replace ‘newpassword’ with a password of your choosing.
Now we have new database (mail) and new user (mailadmin) with privileges (GRANT SELECT, INSERT, UPDATE, DELETE).
Next…
USE mail;
and create some tables in our database…
for domains:
CREATE TABLE domains ( domain varchar(50) NOT NULL, PRIMARY KEY (domain) ) TYPE=MyISAM;
for users:
CREATE TABLE users ( email varchar(80) NOT NULL, password varchar(20) NOT NULL, PRIMARY KEY (email) ) TYPE=MyISAM;
for forwards:
CREATE TABLE forwards ( source varchar(80) NOT NULL, destination TEXT NOT NULL, PRIMARY KEY (source) ) TYPE=MyISAM;
Leave your MySQL console.
To enable Postfix to use the MySQL database we need to create some text files.
sudo vim /etc/postfix/mysql-domains.cf
and add there:
user = mailadmin password = newpassword dbname = mail query = SELECT domain AS virtual FROM domains WHERE domain='%s' hosts = 127.0.0.1
sudo vim /etc/postfix/mysql-forwards.cf
and add there:
user = mailadmin password = newpassword dbname = mail query = SELECT destination FROM forwards WHERE source='%s' hosts = 127.0.0.1
sudo vim /etc/postfix/mysql-mailboxes.cf
and add there:
user = mailadmin password = newpassword dbname = mail query = SELECT CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/') FROM users WHERE email='%s' hosts = 127.0.0.1
sudo vim /etc/postfix/mysql-email.cf
and add there:
user = mailadmin password = newpassword dbname = mail query = SELECT email FROM users WHERE email='%s' hosts = 127.0.0.1
Set the permissions on the files…
sudo chmod o= /etc/postfix/mysql-* sudo chgrp postfix /etc/postfix/mysql-*
Now… the hardest part: configure main.cf.
sudo vim /etc/postfix/main.cf
My file looks like this:
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu) biff = no append_dot_mydomain = no readme_directory = no smtpd_sasl_auth_enable = yes broken_sasl_auth_clients = yes smtpd_sasl_authenticated_header = yes smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination smtpd_use_tls = yes smtpd_tls_cert_file = /etc/ssl/certs/mailcert.pem smtpd_tls_key_file = $smtpd_tls_cert_file myhostname = HERE_IS_MY_HOSTNAME alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases myorigin = /etc/mailname mydestination = relayhost = mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 mailbox_size_limit = 0 recipient_delimiter = + inet_interfaces = all virtual_alias_domains = virtual_alias_maps = proxy:mysql:/etc/postfix/mysql-forwards.cf, mysql:/etc/postfix/mysql-email.cf virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql-domains.cf virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-mailboxes.cf virtual_mailbox_base = /home/vmail virtual_uid_maps = static:5000 virtual_gid_maps = static:5000 proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $virtual_mailbox_limit_maps
Replace HERE_IS_MY_HOSTNAME by your hostname.
I won’t describe each option… for me – it works good enough. All the informations about these parameters you can find here.
Saslauth is “a daemon process that handles plaintext authentication requests on behalf of the SASL library.”
sudo vim /etc/default/saslauthd
Change START variable to ‘yes’:
# Should saslauthd run automatically on startup? (default: no) START=yes
and OPTIONS variable to:
# Example for postfix users: "-c -m /var/spool/postfix/var/run/saslauthd" OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd -r"
Now we need to create missing directory:
sudo mkdir -p /var/spool/postfix/var/run/saslauthd
and two other files to allow the authorisation process access to the db holding the relevant data:
sudo vim /etc/pam.d/smtp
add there:
auth required pam_mysql.so user=mailadmin passwd=newpassword host=127.0.0.1 db=mail table=users usercolumn=email passwdcolumn=password crypt=1 account sufficient pam_mysql.so user=mailadmin passwd=newpassword host=127.0.0.1 db=mail table=users usercolumn=email passwdcolumn=password crypt=1
and the second file…
sudo vim /etc/postfix/sasl/smtpd.conf
add there:
pwcheck_method: saslauthd mech_list: plain login allow_plaintext: true auxprop_plugin: mysql sql_hostnames: 127.0.0.1 sql_user: mailadmin sql_passwd: newpassword sql_database: mail sql_select: select password from users where email = '%u'
Now we need to add postfix to the sasl group so it can access the saslauthd process we just setup.
sudo adduser postfix sasl
restart postfix and saslauthd
sudo /etc/init.d/postfix restart sudo /etc/init.d/saslauthd restart
We will need to create a self signed certificate.
It will produce a warning from your mail client, but for your own usage… that’s ok.
Remember that you will need to purchase a valid certificate if other people or clients will use this mail server.
However now we will create self signed certificate…
sudo make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/ssl/certs/mailcert.pem
You will be asked a series of questions regarding the details for the certificate. Don’t be scared… just answer them.
Note is is important the Hostname matches the mail server hostname.
Now we have our certificate in ‘/etc/ssl/certs/mailcert.pem’ (just like we have above in our main.cf).
First… install it:
sudo aptitude install courier-authdaemon courier-authlib-mysql courier-pop courier-pop-ssl courier-imap courier-imap-ssl
During the installation you will be asked if you wish to create directories for web based administration – select ‘No’.
Now we need to configure Courier to access the MySQL ‘mail’ database for authorisation.
sudo vim /etc/courier/authdaemonrc
and change value of authmodulelist variable to ‘authmysql’, so it should looks like:
authmodulelist="authmysql"
Set the details of the MySQL database:
sudo vim /etc/courier/authmysqlrc
this file should looks like:
MYSQL_SERVER localhost MYSQL_USERNAME mailadmin MYSQL_PASSWORD newpassword MYSQL_PORT 0 MYSQL_DATABASE mail MYSQL_USER_TABLE users MYSQL_CRYPT_PWFIELD password MYSQL_UID_FIELD 5000 MYSQL_GID_FIELD 5000 MYSQL_LOGIN_FIELD email MYSQL_HOME_FIELD "/home/vmail" MYSQL_MAILDIR_FIELD CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/')
Restart courier:
sudo /etc/init.d/courier-authdaemon restart sudo /etc/init.d/courier-imap restart sudo /etc/init.d/courier-imap-ssl restart sudo /etc/init.d/courier-pop restart sudo /etc/init.d/courier-pop-ssl restart
Log in to your MySQL console:
mysql -u root -p
Next…
USE mail;
INSERT INTO domains (domain) VALUES ('mydomain.com');
INSERT INTO users (email, password) VALUES ('karol@mydomain.com', ENCRYPT('my_super_secret_password'));
quit;
Reload Postfix:
sudo postfix reload
THE END.
Everything should works fine right now.
First test
ls /home/vmail
It’s empty, right?
That’s because the correct folders are only created on receipt of the first email.
So… send some mail to your new e-mail address (in my example it’s karol@mydomain.com).
and look again:
ls /home/vmail
there is a new folder named ‘domain.com’, right? Sure, yeah. It works!
Second test
Configure some of your mail program… such as Outlook, Thunderbird or even gmail and check it via ‘standard way’! Receive some mails, send some mails.
Remember that your username is your full e-mail address (in my example it’s karol@domain.com).
Hello, I'm Karol Zielinski, internet evangelist, an entrepreneur, project manager and a web developer from Gdynia, Poland. I like creative design, good advertisement, social media and all kind of stuff around the web.