📜 ⬆️ ⬇️

Spam protection with captcha

After a brief research on how to combat spam, I decided to make my own.

The thing is that the methods found do not satisfy one simple condition - protection must save traffic, i.e. preferably, the text of the letter is not uploaded to the server, and the decision whether or not to accept the letter is based solely on the analysis of the headers.
Since we have a web server that is located on the same computer as the mail server, the following algorithm was implemented:
- Create a white list of senders from which letters are accepted without restriction
- If the sender is not in the white list - an error is sent to him indicating how to add his address to the white list
- On the web server we make a page with captcha to add the address to the white list

And so, in order (we use ubuntu, so the instructions are given for this type of distribution):
1. To store the whitelist, we will use postgresql:
sudo apt-get install apache2 postgresql-8.3 postfix php

insert the line into the /etc/postgresql/8.3/main/pg_hba.conf file
local whitelist whitelist password

Next, create a whitelist database with a single whitelist table.
')
sudo su - postgres
psql -c "create user whitelist password '1'" ( )
psql -c "create database whitelist owner whitelist"
psql -d whitelist -c "create table whitelist(email varchar, primary key(email))"


2. The database is ready, create a page to add an email address. mail to the white list.
Download kcaptcha http://www.captcha.ru/kcaptcha/
create whitelist.php:
 <? session_start(); ?> <html><head><title></title> </head> <body> <div align="center"> <table width="80%"><tr><td> <h1>    </h1>       , ,    . </td></tr> <tr><td align="center" class="formbg"> <form action="/whitelist_add.php" method="post"> <table><tr> <td>  e-mail :</td> <td><input type="text" name="email" class="inp"/></td></tr> <tr><td> </td></tr> <tr> <td valign="bottom">  :</td> <td><img src="/kcaptcha/index.php?<?=session_name()?>=<?=session_id()?>"><br/><input type="text" name="keystring" class="inp"></td></tr> <tr><td> </td></tr> <tr><td colspan="2" align="center"><input type="submit" value="     "></td> </tr></table> </form> </td></tr> </table> </body> </html> 
<? session_start(); ?> <html><head><title></title> </head> <body> <div align="center"> <table width="80%"><tr><td> <h1> </h1> , , . </td></tr> <tr><td align="center" class="formbg"> <form action="/whitelist_add.php" method="post"> <table><tr> <td> e-mail :</td> <td><input type="text" name="email" class="inp"/></td></tr> <tr><td> </td></tr> <tr> <td valign="bottom"> :</td> <td><img src="/kcaptcha/index.php?<?=session_name()?>=<?=session_id()?>"><br/><input type="text" name="keystring" class="inp"></td></tr> <tr><td> </td></tr> <tr><td colspan="2" align="center"><input type="submit" value=" "></td> </tr></table> </form> </td></tr> </table> </body> </html>


and the whitelist_add.php file
 <? session_start(); $correct = false; if(count($_POST)>0){ if(isset($_SESSION['captcha_keystring']) && $_SESSION['captcha_keystring'] == $_POST['keystring']){ $correct = true; } } unset($_SESSION['captcha_keystring']); ?> <html><head><title> </title> </head> <body> <div align="center"> <table width="80%"><tr><td> <h1><? if($correct) { $dbconn = pg_connect("host=localhost dbname=whitelist user=whielist password=1") //    ,    .1 or die('Could not connect: ' . pg_last_error()); // Performing SQL query $result = pg_prepare($dbconn, "check_query", 'select email from white_list where email = $1'); $result = pg_execute($dbconn, "check_query", array($_POST['email'])); if(pg_fetch_array($result)) { ?>      <? } else { $result = pg_prepare($dbconn, "insert_query", 'insert into white_list(email) values($1)'); $result = pg_execute($dbconn, "insert_query", array($_POST['email'])); ?>    !<? } if($result) { pg_free_result($result); } pg_close($dbconn); } else { ?>   <? }?> </h1><? if($correct) { ?>        <? } else { ?>  <a href="whitelist.php"> </a> <? } ?> </td></tr> <tr><td><br/><br/><a href="/whitelist.php">   </a></td></tr> </table> </body> </html> 


3. now we configure postfix to filter the headers

in / etc / postfix create a block file
/.*/ REJECT \n\n******** your e-mail should be in our whitelist ******** \n Visit http://[ ]/whitelist.php \n\n *******************************************\n\n

in the same directory create the file pg_whitelist.cf
hosts = localhost
user = whitelist
password = 1 # . 1
dbname = whitelist
query = select 'permit' from white_list where email = '%s'


in the /etc/postfix/main.conf file we add
smtpd_sender_restrictions = check_sender_access pgsql:/etc/postfix/pg_whitelist.cf, check_sender_access regexp:/etc/postfix/block

4. we overload postfix:
sudo /etc/init.d/postfix reload

We use such a mechanism for about a year. From the first day of using spam as cut off. Of course, from time to time you have to enter the addresses of clients on your own, but they mostly understand it on their own. Spam can be broken, for 2 reasons: the return address is either not filled, or coincides with the recipient - since all recipients are on the white list, the filter passes them. Unfortunately, I didn’t find a quick way to check that From = To did not exist for a long time.

Source: https://habr.com/ru/post/57078/


All Articles