Setting Up A Spam-Proof Home Email Server (The Somewhat Alternate Way) (Debian Squeeze) - Page 3
Set Up Dovecot(1) Install the packagesapt-get install dovecot-imapd The Dovecot config file is located at /etc/dovecot/dovecot.conf. Edit it and make following changes:
(2) Add MaildirSearch for #mail_location = and add below mail_location = maildir:~/Maildir
(3) Add authenticationSearch 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 ManagementNow 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 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 packagesapt-get install libapache2-mod-php5 This will install Apache, PHP5, PHP5 Module and PHP5 Cli.
(2) Create SSL certificate for Apacheopenssl req $@ -new -x509 -days 3650 -nodes -out /etc/apache2/apache.pem -keyout /etc/apache2/apache.pem
(3) Create the email webfoldermkdir -p /var/www/email
(4) Edit /var/www/email/.htaccess and addRewriteEngine 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/emailchown -R www-data:www-data /var/www/email
(7) Enable apache modulesa2enmod ssl auth_digest rewrite
(8) Extend apach2 configecho "servername localhost" >> /etc/apache2/apache2.conf
(9) Edit /etc/apache2/sites-enabled/000-defaultInsert 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 authdigesthtdigest -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
(15) Add the script to the cron.txtecho "*/2 * * * * virtual_email.sh >/dev/null 2>&1" >> cron.txt
(16) Load the new cron.txtcrontab cron.txt
(17) Display current cronscrontab -l
|

![Creative Commons Attribution-NonCommercial-ShareAlike 2.0 License [Creative Commons Attribution-NonCommercial-ShareAlike 2.0 License]](http://creativecommons.org/images/public/somerights20.gif)


Recent comments
1 day 4 hours ago
1 day 9 hours ago
1 day 10 hours ago
1 day 11 hours ago
1 day 13 hours ago
1 day 17 hours ago
1 day 18 hours ago
1 day 20 hours ago
2 days 9 hours ago
2 days 11 hours ago