⬆️ ⬇️

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