Cheap VPS & Xen Server

Residential Proxy Network - Hourly & Monthly Packages

Setting Up A Spam-Proof Home Email Server (The Somewhat Alternate Way) (Debian Squeeze)


Introduction

Email spam is a huge problem. I have found for myself quite a simple solution, however it’ll take some time to “migrate” completely over to it.

The solution is to create a unique email address everytime I have to give an email address to someone else or to some website to sign up. If I want an account at twitter, I’d use “www.twitter.com@MYDOMAIN.COM”. For webbased services, I use the full domain name incl. subdomain (www) on the left of the @ (some poorly designed websites do not recognizes the www. as valid email address, for those I just leave it away).

For people I use a format like that: “email.john.doe@MYDOMAIN.COM”. You could also use like “from.john.doe@MYDOMAIN.COM”. The good thing is, the left side of the @ for email addresses is almost “unlimited”.

Because I generate unique email addresses for every contact, I can easily find out where my email address got leaked and then I can easily remove it.

This howto will set up a full functioning email server with according scripts to make easy email management. It includes also the DNS setup part – even if you are on a dynamic address – e.g. if you want to run your own little mailserver from home.

 

Summary

In this howto I use Debian Squeeze as server. For other Linux distros you’ll have to make according changes yourself.

A short summary of what is being done in this howto is like this:

  • Obtaining a domain name
  • Taking care of a dynamic ip – if necessary
  • Taking care of the dns and routing
  • Setting up postfix
  • Setting up procmail
  • Setting up dovecot
  • Setting up webserver for email address management
  • Setting up Thunderbird with addon

 

Credits

In this howto I also relay on a few other howtos here – especially regarding the setup of the bind and email server. For those, I copied more or less from Falko’s Perfect Debian Server howtos. Also the email relay section was borrowed from a howto here by sjau. Without those, I probably would not have been able to set this up.

 

Obtaining a Domain Name

Before you can start running your own mailserver you need a domain name for which you can also set MX records. I don’t want to make any suggestion as there are tons and tons of domain registrars out there. One of the cheapest I know of is GoDaddy.

I don’t use GoDaddy myself but as far as I’ve heard they provide a solid service.

 

Handle Dynamic IPs

Another challenge to be facing is how to handle things on a dynamic ip address. If you don’t have a dedicated box rented somewhere but use your home internet connection, then very likely you have not a static ip.

In the web it’s essential to have a static ip so that others always know where to reach you. However there are services that help you with that.

One of the services I use is EveryDNS. They let me host the DNS for the domain name.

As of now they still offer the service for free. Although they got bought up in 2010, the promise was, that then-customers who have donated money, can also in future use the system for free. On their webpage, they don’t mention anything yet that new customers need to pay – but I don’t know for sure.

The reason for EveryDNS is, that they offer also a little perl script that can be used to update the DNS. This is essential as your IP changes over time if you don’t have a static IP address. You can get the perl script from here.

When you have a domain name then first go to What Is My IP. It will show you your current public ip address. Then create an account at EveryDNS and make at least the following entries where MYDOMAIN.COM would be your domain name:

(1) Make an “A” record type, set as fully qualified domain name “MYDOMAIN.COM” and set as value your public ip address

(2) Make a “CNAME” record type, set as fully qualified domain name “*.MYDOMAIN.COM” and set as “MYDOMAIN.COM”

(3) Make a “MX” record type, set as fully qualified domain name “MYDOMAIN.COM”, set as value “MYDOMAIN.COM” and set as “MX Value” “10”

What we just did is setup the DNS for the domain. The main domain is found at your IP address (a-record), all other domains are also found there (the * in the cname record pointing to the main domain) and we also operate a mail server there (mx record).

 

root user

The following things are being done as root user – unless told otherwise.

 

Dyn. IP Update

As said before, if you don’t have a static IP address you will need to regurarly update the DNS info.

 

(1) Get the perlscript and make it executable

cd /root
wget http://www.everydns.net/eDNS.pl
chmod 0755 eDNS.pl

 

(2) Create a bash script that calls the perl script (there’s other ways but I found that the simplest):

touch eDNS.sh
echo “#!/bin/bash” > eDNS.sh
echo “perl /root/eDNS.pl -u USERNAME -p PASSWORD -d MYDOMAIN.COM” >> eDNS.sh

Replace USERNAME and PASSWORD with your everydns login credentials.

 

(3) Setup a cron to run it regurarly

I love to work with a cron.txt file that contains all crons. I think it’s a lot simpler to maintain it like that.

First you have to check out if there is already a cron entry:

crontab -l

If there is no cron entry yet, then just run the following commands

touch cron.txt
chmod 0700 cron.txt
echo “*/5 * * * * /root/eDNS.sh >/dev/null 2>&1” > cron.txt

If there are already cron entries, copy them, create a cron.txt file and insert them and add the following command also:

*/5 * * * * /root/eDNS.sh >/dev/null 2>&1

Now we load the cron.txt as cron:

crontab cron.txt

And we check if it was added properly:

crontab -l

 

LAN/Routing/Bind

The next problem we’re facing then is how to resolve the domain in your lan. If your mail server is behind a router then I will probably have a local ip like 192.168.0.x or 10.0.0.x.

If you are behind a router, you will need to forward the following ports to your server: 25, 80, 143, 443, 991. There could be more ports required like 587.

Also we face the problem on how to resolve the domain name from inside the lan. From outside the lan you have the DNS entry that should point to your current IP address. However when you are inside the lan and make a dns query it will only return your public ip and usuall it will fail then.

There are several solutions for that problem – if the problem even exists at all.

One way would be the use of dnsmasq in routers (e.g. dd-wrt or tomato-wrt). However as I can’t guarantee for it to work, the only other option I see is to setup a full fledged DNS server on your mailserver.

In this tutorial I’ll use a chrooted Bind9 as I am the most familiar with it. For other DNS servers you’ll find plenty of documentation online.

 

(1) Install the software and stop it

apt-get install bind9
/etc/init.d/bind9 stop

 

(2) Change the /etc/default/bind9 config so that the options line is like this:

OPTIONS="-u bind  -t /var/lib/named"

 

(3) Create the necessary directories under /var/lib:

mkdir -p /var/lib/named/etc
mkdir /var/lib/named/dev
mkdir -p /var/lib/named/var/cache/bind
mkdir -p /var/lib/named/var/run/bind/run

 

(4) Then move the config directory from /etc to /var/lib/named/etc:

mv /etc/bind /var/lib/named/etc

 

ln -s /var/lib/named/etc/bind /etc/bind

 

(6) Make null and random devices, and fix permissions of the directories:

mknod /var/lib/named/dev/null c 1 3
mknod /var/lib/named/dev/random c 1 8
chmod 666 /var/lib/named/dev/null /var/lib/named/dev/random
chown -R bind:bind /var/lib/named/var/*
chown -R bind:bind /var/lib/named/etc/bind

 

(7) Edit the /etc/rsyslog.d/bind-chroot.conf file and add

$AddUnixListenSocket /var/lib/named/dev/log

 

(8) Restart services

/etc/init.d/rsyslog restart
/etc/init.d/bind9 start

and check /var/log/syslog for errors.

Now we have setup Bind9 in a chrooted environment. The next thing to do is to acutally add a zonefile for your domain.

 

(9) Edit /etc/bind/named.conf.local and add

zone "MYDOMAIN.COM" IN {
        type master;
        file "/etc/bind/zones/MYDOMAIN.COM.db";
        allow-update { none; };
};

 

(10) Create the zone folder and zonefile

mkdir /etc/bind/zones
touch /etc/bind/zones/MYDOMAIN.COM.db
chown -R bind:bind /etc/bind/zones/MYDOMAIN.COM.db

 

(11) Add your zonefile info to MYDOMAIN.COM.db

$TTL    86400
@               IN SOA  @ MYDOMAIN.COM. (
                                        1              ; serial
                                        2600              ; refresh
                                        15M             ; retry
                                        3600              ; expiry
                                        360 )            ; minimum
@               IN NS           ns.MYDOMAIN.COM.
ns              IN A            LOCALIP
www             IN A            LOCALIP
MYDOMAIN.COM.             IN A            LOCALIP
MYDOMAIN.COM.     IN MX   10      LOCALIP

Of course replace MYDOMAIN.COM with your actual domain name and LOCALIP with your static LAN IP address. Bascially we tell here that the nameserver for that domain is hosted on “ns.MYDOMAIN.COM” and “ns.MYDOMAIN.COM” is to be found at the static local ip address.

 

(12) Restart Bind9

/etc/init.d/bind9 restart

 

(13) Change router NS resolution

While Bind9 is setup now, there’s one last thing to do. On your router you have to change the nameserver resolution order. The first nameserer must now be your “mail server” with the according static local ip. Otherwise the whole bind9 setup was for nothing. As the second nameserver enter the value of what was aleady in there as first one. Depending on your router it can be a bit trickier.

Set Up Postfix

We made sure to this point, that we have a domain name, that the domain can be hosted on a dynamic ip address and that the resolution of the domain name works from inside the lan as well as outside. Now we can put our focus on how to actually setup the mail server. The mail server usually consists of two parts. For me this was in the beginning a bit confusing and I try to explain it quickly.

One part that makes up the mail server is the MTA. The MTA in this case is postfix. It’s job is to actually send emails between different servers. What MTAs (usually) don’t provide is “end user access”. So if you want with thunderbird to connect to your email account and check your mail or send mail, you will also need a pop3 or imap server. Their job is just the transfer of emails between you as enduser and the mailserver.

In this part we’ll first setup postfix and make it ready to be used in a secured way (STARTTLS).

 

(1) Install the required packages

apt-get install postfix libsasl2-2 sasl2-bin libsasl2-modules procmail

During this you’ll be asked two questions:

General type of mail configuration: <– Select “Internet Site”

System mail name: <– Enter: “MYDOMAIN.COM”

 

(2) Reconfigure postfix

dpkg-reconfigure postfix

Again, you’ll be asked some questions:

General type of mail configuration: <– Select “Internet Site”

System mail name: <– Enter: “MYDOMAIN.COM”

Root and postmaster mail recipient: <– Leave blank

Other destinations to accept mail for (blank for none): <– Enter: “MYDOMAIN.COM, localhost.MYDOMAIN.COM, localhost.localdomain, localhost”

Force synchronous updates on mail queue? <– Select “No”

Local networks: <– Leave as default

Use procmail for local delivery? <– Select “Yes”

Mailbox size limit (bytes): <– Enter “0”

Local address extension character: <– Enter “+”

Internet protocols to use: <– Select “all”

 

(3) Enhance the postfix configuration

Make sure to replace MYDOMAIN.COM with your domain name

postconf -e ‘smtpd_sasl_local_domain =’
postconf -e ‘smtpd_sasl_auth_enable = yes’
postconf -e ‘smtpd_sasl_security_options = noanonymous’
postconf -e ‘broken_sasl_auth_clients = yes’
postconf -e ‘smtpd_sasl_authenticated_header = yes’
postconf -e ‘smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination’
postconf -e ‘inet_interfaces = all’
postconf -e ‘myhostname = MYDOMAIN.COM’
postconf -e ‘smtpd_tls_auth_only = no’
postconf -e ‘smtp_use_tls = yes’
postconf -e ‘smtpd_use_tls = yes’
postconf -e ‘smtp_tls_note_starttls_offer = yes’
postconf -e ‘smtpd_tls_key_file = /etc/postfix/ssl/smtpd.key’
postconf -e ‘smtpd_tls_cert_file = /etc/postfix/ssl/smtpd.crt’
postconf -e ‘smtpd_tls_CAfile = /etc/postfix/ssl/cacert.pem’
postconf -e ‘smtpd_tls_loglevel = 1’
postconf -e ‘smtpd_tls_received_header = yes’
postconf -e ‘smtpd_tls_session_cache_timeout = 3600s’
postconf -e ‘tls_random_source = dev:/dev/urandom’
postconf -e ‘home_mailbox = Maildir/’
postconf -e ‘virtual_maps = hash:/etc/postfix/virtual’
postconf -e ‘mailbox_command = /usr/bin/procmail -a “$EXTENSION” DEFAULT=$HOME/Maildir/ MAILDIR=$HOME/Maildir’
echo ‘pwcheck_method: saslauthd’ >> /etc/postfix/sasl/smtpd.conf
echo ‘mech_list: plain login’ >> /etc/postfix/sasl/smtpd.conf

 

(4) Generate certificates for TLS

mkdir /etc/postfix/ssl
cd /etc/postfix/ssl/
openssl genrsa -des3 -rand /etc/hosts -out smtpd.key 1024
chmod 600 smtpd.key
openssl req -new -key smtpd.key -out smtpd.csr
openssl x509 -req -days 3650 -in smtpd.csr -signkey smtpd.key -out smtpd.crt
openssl rsa -in smtpd.key -out smtpd.key.unencrypted
mv -f smtpd.key.unencrypted smtpd.key
openssl req -new -x509 -extensions v3_ca -keyout cakey.pem -out cacert.pem -days 3650

A problem I’ve encountered on Debian Squeeze is that from the second OpenSSL generation with the previously created certificate always an error comes. It will prompt you for the password for the smtpd.key and if you enter it, you’ll get an error. What I ended up doing was first to not enter passwords when asked for the one for smtpd key -> it’ll just continue demainding one. Then press ctrl-c to abort and rerun it but this time I enter the password. That seems to have worked for me just fine.

 

(5) Adjust SASL

mkdir -p /var/spool/postfix/var/run/saslauthd

Edit /etc/default/saslauthd.

In order to activate saslauthd and set START to yes and alter options to this:

OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd -r"

 

(6) Add postfix user to SASL group

adduser postfix sasl

 

(7) Creating virtual.db

touch /etc/postfix/virtual
postmap /etc/postfix/virtual

Before restarting postfix, the virtual.db must exist. For more info about it, skip ahead to the Setup Email Address Management section.

 

(8) Restart daemons

/etc/init.d/postfix restart
/etc/init.d/saslauthd restart

 

(9) Check if it works correctly

telnet localhost 25

And enter:

ehlo localhost

You should get an output that contain STARTTLS and two times AUTH LOGIN PLAIN (one time with a “=”). Exit by typing

quit

 

(10) Add port 587

Edit the file /etc/postfix/master.cf and copy this line

smtp      inet  n       -       -       -       -       smtpd

to

587      inet  n       -       -       -       -       smtpd

You have now the smtp and the 587 line there.

 

Set Up Outgoing SMTP

While the postfix MTA would work now just fine, there is still a problem with dynamic ip addresses. Most mailservers will not accept incoming email from a mailserver on a dynamic ip address. If you have a static ip address, you can simply skip this part.

In order to successfully send email, you can use your ISPs email server for relaying. That means postfix won’t contact the recipient email server directly, but it will authenticate against your IPSs email server and send (better: relay) the email through it. It’s unlikely that your ISP is blocked.

Instead of using your ISPs email server you could also relay through google and maybe even other free providers.

(1) Enhance postfix config

postconf -e ‘smtp_sasl_auth_enable = yes’
postconf -e ‘smtp_sasl_security_options = noanonymous’
postconf -e ‘smtp_sasl_password_maps = hash:/etc/postfix/saslpasswd’
postconf -e ‘smtp_always_send_ehlo = yes’
postconf -e ‘relayhost = SMTP.YOURISP.COM’

Of course replace SMTP.YOURISP.COM with your ISPs actual smtp server.

In some cases ISPs allow to being submitted emails from their customers only on a given port. Very often the “submission” port 587 is being used.

In that case use as relayhost the following:

relayhost = [SMTP.YOURISP.COM]:PORT

The edgy brackets around SMTP.YOURISP.COM are required. Replace port with the one given by your ISP and necessarly adjust your routers portforwarding.

 

(2) Edit /etc/postfix/saslpasswd

And add

SMTP.YOURISP.COM     USERLOGIN:PASSWORD

You usually can get an email account with your ISP. When doing so you should get also a username and password to login. The username can be the full email address or something else. Just set according login info there.

 

(3) Hash the saslpasswd file

postmap /etc/postfix/saslpasswd

 

(4) Restart postfix

/etc/init.d/postfix restart

Now all outgoing email is being sent through your ISP.

 

Set Up Inital Maildir

(1) Change to USER

su USER cd ~

 

(2) Create the Maildir folder

maildirmake.dovecot Maildir

 

(3) Create Maildir subfolders

maildirmake.dovecot Maildir/.Drafts
maildirmake.dovecot Maildir/.Sent
maildirmake.dovecot Maildir/.Trash
maildirmake.dovecot Maildir/.Templates

You can create more subfolders. The leading “.” for the subfolder is required.

If you plan not to be the only email user on the system, then it’s wise to create the structure in the /etc/skel folder also. This enables for all future generated users that they have the Maildir directly available.

 

(4) Change back to root and create the maildirs

exit
maildirmake.dovecot /etc/skel/Maildir
maildirmake.dovecot /etc/skel/Maildir/.Drafts
maildirmake.dovecot /etc/skel/Maildir/.Sent
maildirmake.dovecot /etc/skel/Maildir/.Trash
maildirmake.dovecot /etc/skel/Maildir/.Templates

 

(5) If you already have more existing users on the system, just repeate step 1-3 for them.

 

Procmail

Procmail is a local delivery agent. Simply said procmail can filter email based on rules. It can pre-sort them into different folders or even discard email. In the postfix setup section the groundwork for procmail filtering is already laid out. If you want to make use of serverside filtering with procmail, then do the following as actual USER and not as root.

 

(1) Change to USER

su USER cd ~

 

(2) Edit ~/.procmailrc and add

PATH=/bin:/usr/bin:/usr/local/bin:/usr/sbin
DROPPRIVS=yes
MAILDIR=$HOME/Maildir/
DEFAULT=$HOME/Maildir/
:0
* ^From:.*SOMEONE@SOMEDOMAIN\.COM
$MAILDIR/.SOMEONE/
:0
* ^From:.*MAILLIST@MAILLIST\.COM
$MAILDIR/.MAILLIST/

The first four lines just are some variables, don’t worry about them. The next three lines indicate that all incoming email matching “*SOMONE@SOMEDOMAIN.COM” should be put into the SOMEONE folder. Then you have another rule for the sender MAILLIST.

Those are just two simple rules. The web is full with more examples.

Procmail seems meanwhile unmaintained and Dovecot has an own local delivery agent which also updates the according dovecot index files. I have no experience yet with it or how to set it up, hence I skip this part here. If someone is willing to enhance this howto with Dovecote LDA, please do so.

Set Up Dovecot

(1) Install the packages

apt-get install dovecot-imapd

The Dovecot config file is located at /etc/dovecot/dovecot.conf. Edit it and make following changes:

 

(2) Add Maildir

Search for

#mail_location =

and add below

mail_location = maildir:~/Maildir

 

(3) Add authentication

Search for

auth default {

rename it to

auth default2 {

and add above

auth default {
	mechanisms = plain login
	passdb pam {
	}
	userdb passwd {
	}
	socket listen {
		client {
			path = /var/spool/postfix/private/auth
			mode = 0660
			user = postfix
			group = postfix
		}
	}
}

(3) Restart Dovecot

/etc/init.d/dovecot restart

By default only IMAP and IMAPs is enabled on dovecot. I don’t see any point nowadays in POP3 hence the according daemon is not being installed and activated.

 

Set Up Email Address Management

Now we actually have a fully functioning mail server. The only problem is, the mailserver does not yet know what to do with incoming email.

When we added this “virtual_maps = hash:/etc/postfix/virtual” to the postfix config we told the server, that the incoming email address and their destination is to be found in this file. This file has a very simple structure:

USER@MYDOMAIN.COM		SYSUSER

In that case incoming email to the “USER@MYDOMAIN.COM” email address will be put into the Maildir of the system user “SYSUSER”.

Assuming my username on the system is “testuser” and I setup a recipient address for my buddy John Doe like “from.john.doe@testuser.com” then I would have an entry like this:

from.john.doe@testuser.com		testuser

If only that would be in the virtual table and an email with recipient address “really.from.john.doe@testuser.com” would arrive, then Postfix can’t find a match and it will reject it. The sender will get an according notice, that this email address does not exist.

This means we can easily just add hundreds and thousands of email addresses there and tell they should all go to the “testuser” account. When I then notice, I get spam to specific incoming email address, I can simply remove that one.

HOWEVER, just creating that file doesn’t do the job. There are two more steps required after each edit:

postmap /etc/postfix/virtual
/etc/init.d/postfix reload

The first one converts the virtual file into a hashed virtual.db file which makes it faster for postfix to process and the second command reloads the file.

Always editing this by hand is cumbersome. Hence I created myself a little PHP script which makes it simple. It only has two options:

– adding new incoming email addresses

– remove existing entries

In order to prevent any abuse, a few precautions have to be taken. Namely:

– According access to the script is only possible with HTTPS

– Username and password are required to login

– virtual file is not directly altered but updated with cron

 

(1) Install packages

apt-get install libapache2-mod-php5

This will install Apache, PHP5, PHP5 Module and PHP5 Cli.

 

(2) Create SSL certificate for Apache

openssl req $@ -new -x509 -days 3650 -nodes -out /etc/apache2/apache.pem -keyout /etc/apache2/apache.pem

 

(3) Create the email webfolder

mkdir -p /var/www/email

 

(4) Edit /var/www/email/.htaccess and add

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

 

(5) Edit /var/www/email/index.php and add

<?php
$sysuser = 'USERNAME';
$domain = 'MYDOMAIN.COM';
#######################################################################################################
#                                                                                                     #
#                                                                                                     #
#                        DO NOT EDIT BELOW                                                            #
#                                                                                                     #
#                                                                                                     #
#######################################################################################################

$email = $_POST['email'];
$pg = $_POST['submit'];
if($pg == '') {  $pg = $_GET['pg']; }

switch ($pg) {
    case 'Add':
        $output = add_email($email, $domain, $sysuser);
        break;
    case 'Remove':
        $output = remove_email($email);
        break;
    case 'RemoveForm':
        $output = remove_form();
        break;
    default:
        $output = add_form();
}
$output = f_header() . $output . f_footer();
echo $output;

function f_header() {
	$output = "<html>\n<head>\n<title>Email Management</title>\n</head>\n
			<body>\n
			<a href='?pg=AddForm'>Add Email</a> | <a href='?pg=RemoveForm'>Remove Email</a><br><br>
			<form name='input' action='" . $PHP_SELF . "' method='POST'>\n
	";	
	return($output);
}
function f_footer() {
	$output = "</form>\n</body>\n</html>";
	return($output);
}

function add_form($added) {
	$output = "$added<br>
			<br>Domain '@$domain' will be automatically added.<br>
			<input type='text' name='email' value='' size='30'>\n
			<input type='submit' name='submit' value='Add'>\n
	";
	return($output);
}
function remove_form($added) {
	$output = "$added<br>
			<br>Only enter the 'left' part of the '@'<br>
			<input type='text' name='email' value='' size='30'>\n
			<input type='submit' name='submit' value='Remove'>\n
	";
	return($output);
}

function add_email($email, $domain, $sysuser) {
        $myFile = "add.txt";
		$write_block = $email . '@' . $domain ."\t\t\t" .$sysuser . "\n";
        $fh = fopen($myFile, 'a') or die("can't open file");
        fwrite($fh, $write_block);
        fclose($fh);
        $added = $email . "@" . $domain . " - marked for addition";
        $output = add_form($added);
        return($output);	
}
function remove_email($email) {
        $myFile = "remove.txt";
		$write_block = $email . "\n";
        $fh = fopen($myFile, 'a') or die("can't open file");
        fwrite($fh, $write_block);
        fclose($fh);
        $added = $email . " - marked for removal";
        $output = remove_form($added);
        return($output);
}
?>

Replace at the beginning the USERNAME with your system user name and MYDOMAIN.COM with your actual domain name.

 

(6) Chown /var/www/email

chown -R www-data:www-data /var/www/email

 

(7) Enable apache modules

a2enmod ssl auth_digest rewrite

 

(8) Extend apach2 config

echo “servername localhost” >> /etc/apache2/apache2.conf

(9) Edit /etc/apache2/sites-enabled/000-default

Insert after

        <Directory /var/www/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
        </Directory>

this

        <Directory /var/www/email/>
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>

 

(10) Still editing the /etc/apache2/sites-enabled/000-default add at the end of the file the following

<VirtualHost *:443>
        ServerAdmin webmaster@localhost
        SSLEngine on
        SSLCertificateFile /etc/apache2/apache.pem
        DocumentRoot /var/www/
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
        </Directory>
        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>
        ErrorLog /var/log/apache2/error.log
        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn
        CustomLog /var/log/apache2/access.log combined
    Alias /doc/ "/usr/share/doc/"
    <Directory "/usr/share/doc/">
        Options Indexes MultiViews FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.0/255.0.0.0 ::1/128
    </Directory>
    <Location /email>
        AuthType Digest
        AuthName "email"
        AuthDigestDomain /var/www/email/ http://MYDOMAIN.COM/email
        AuthDigestProvider file
        AuthUserFile /etc/apache2/passwords
        Require valid-user
        SetEnv R_ENV "/var/www/email"
     </Location>
</VirtualHost>

 

(11) Add yourself to authdigest

htdigest -c /etc/apache2/passwords email USERLOGIN

Enter a desired username for USERLOGIN and enter twice the desired password.

 

(12) Restart Apache

/etc/init.d/apache2 restart

What we have now is an auto-redirect to SSL version of the email management script. When successfully logged in, the script will create an “add.txt” and “remove.txt” file when email addresses should be added/removed.

The missing piece now is to communicate those changes with postfix. For this, we just add another small shell script and add that one to cron.

 

(13) Edit /root/email_virtual.sh and add:

#!/bin/bash
ADD="/var/www/email/add.txt"
REMOVE="/var/www/email/remove.txt"
DEST="/etc/postfix/virtual"
if [ -f $ADD ] 
then 
        while read CURLINE; do
#               echo $CURLINE
                echo $CURLINE >> $DEST
        done < $ADD
        rm $ADD
fi 
if [ -f $REMOVE ]
then
        while read CURLINE; do
#               echo $CURLINE
                sed -i "/$CURLINE/ d" $DEST
        done < $REMOVE
        rm $REMOVE
fi
postmap /etc/postfix/virtual 
/etc/init.d/postfix reload 

 

(14) Make it executable

cd /root
chmod 0700 email_virtual.sh

 

(15) Add the script to the cron.txt

echo “*/2 * * * * virtual_email.sh >/dev/null 2>&1” >> cron.txt

 

(16) Load the new cron.txt

crontab cron.txt

 

(17) Display current crons

crontab -l

Backup MX Server

Another problem that can occur on a dynamic IP address is, that your IP address changes and that it takes some time to propagate throughout the internet. If people want to send you email, they shouldn’t get an error message.

For that reason you can add a backup MX server.

Someone I know as error404 told me a while back about Roller Network. From what I can see is that they offer cusotmizable email, dns and stuff and also backup mx capabilities.

I didn’t sign up there as I have a couple of dedicated serves which I give other people to use as backup mx server, so I can’t tell you how to proceed on Roller.

However the only thing you have to do, once you setup backup mx server on Roller Network, is to go to EveryDNS again, log into your account, select your domain and create another mx entry.

Make a “MX” record type, set as fully qualified domain name “MYDOMAIN.COM”, set as value “ROLLERNETWORK” and set as “MX Value” “20”

The FQDN stays your domain name. Because it is for your domain name where a backup shall be created. The backup will be on the Roller Network, so you have to enter there whatever they tell you. The next important thing is, that the MX value is higher than the one you set for your own server. The higher the MX value, the less priority it gets – because even on a dynamic IP address you should be reachable most of the time.

 

Thunderbird

Now we have all together. Setup a nice little server, run Postfix, Dovecot, Procmail, Apache on it. We have a script that allows easy add/remove of incoming email addresses and we have also a backup mx server in case of downtime or ip address change.

Basically we’re now good to go.

Now we just need to setup our email client. My preference here is Thunderbird – although it still has one major drawback in my opinion (but that’s not for discussion here now). The reason for Thunderbird is a great addon:

Virtual Identity – this addon tries to figure out what your incoming email address is and will then set it as outgoing email address. The reason why this addon makes TB great is, because in other email clients you usually define your email address and it will be by default set as your outgoing email address. Normally you can manually alter it but that’s a hassle.

Just imagine you set your email address to “testuser@testuser.com” but you create all those individual email addresses on websites and friends. If you don’t alter it, then people will reply to “testuser@testuser.com” which then defeates the purpose of having a unique email address for everyone out there.

So this addon will take away a great deal of “manual setting of sender email address”. The newest version can be found here (the one on Mozilla is quite outdated): Current Virtual Identity

Thunderbird also tries to figure out what capabilities your server supports. In case auto-detection isn’t work properly, I’ll give you the details right here:

Email Address: This can be just about anything you want. I recommend however that you do setup this email address also in the virtual file – just to be sure!

Username: This is your actual system user name

Password: This is your actual system password

Incoming Mailserver: This is just MYDOMAIN.COM, use IMAP and as Port 143 and set to STARTTLS

Outgoing Mailserver: This is just MYDOMAIN.COM, set Port to what is required and set to STARTTLS

If the autodection doesn’t automatically work, you can press the “Stop” button (several) times and then fill in things manually and have it rechecked.

By default the Username will be set to the “left” part of the supplied email address. That’s a common reason for auto-detection not working properly.

Once you have setup the account, you will be prompted to accept the certificate. I recommend to make accept the certificate permanently. It’s you who created it. Also first sending of email will probably fail because of the certificate that also first needs to be accepted.

 

Slow sending of emails

As TLS negotiation requires random numbers for the session, on a little used box it can be the case that it takes a long time to send even small emails. The reason is that entropy might not be sufficient. You can boost entropy but it will be at a cost of security.

 

(1) Install rng-tools

apt-get install rng-tools

 

(2) Edit /etc/default/rng-tools

Add below

#HRNGDEVICE=/dev/null

this

HRNGDEVICE=/dev/urandom

 

(3) Restart rng-tools

/etc/init.d/rng-tools restart

 

Port 25/587/… blocked

At my university port 25 was totally blocked. So I couldn’t send emails at all while I was connected to the univesity network – except using their email client. This is different from being blocked by your ISP for submission of email because you want to send email from your device to your home server and your home server will then submit the email to the actual recipient.

Because of that I did add a couple more ports to the master.cf file.

As we already added port 587 to the master.cf (check above), you can easily add more ports there. Currently I do add port 2525 and 2500 (they are also easy to remember).

In your Thunderbird account settings for the SMTP servers, just change the port accordingly to 2525 or 2500 if neither 25 or 587 are working.

Of course you can add even more ports onto which Postfix shall listen.


Comments

comments