Monday, April 22, 2013

Lupta cu spam(bot)-uri (partea 2)

Am scris despre o metodă anti-spam folosing postfix/postscreen. Iată o altă metodă pe care în urmă cu câteva săptămâni am descoperit.
Clientul (spambot-ul) este respins pe baza numelui de domeniu invers (reverse DNS). Faptul că o mare parte a spambot-urilor "lucrează" pe calculatoare infectate a căror adrese de IP sunt alocate dinamic de către diverse ISP, aceste adrese de IP au reverse-ul de exemplu: 77.88.44.55.adsl.dynamic.isp.net. Pe baza acestor rDNS s-a creat un set de reguli, care se poate descărca de aici: http://www.hardwarefreak.com/fqrdns.pcre. Conform autorului, o actualizare la 2-3 săptămâni este suficient pentru ca nu sunt modificari majore și zilnice.

Eu în felul următor îl utilizez (main.cf):

smtpd_recipient_restrictions =  permit_mynetworks,
                                check_client_access mysql:/etc/postfix/mysql-virtual_client.cf,
                                check_sender_access mysql:/etc/postfix/mysql-virtual_sender.cf,
                                check_recipient_access mysql:/etc/postfix/mysql-virtual_recipient.cf,
                                reject_unknown_reverse_client_hostname,
                                reject_non_fqdn_sender,
                                reject_non_fqdn_recipient,
                                reject_unknown_sender_domain,
                                reject_unknown_recipient_domain,
                                reject_unauth_destination,
                                reject_unauth_pipelining,
                                reject_unlisted_sender,
                                check_reverse_client_hostname_access pcre:/etc/postfix/fqrdns.pcre


Evident, setul de reguli nu este perfect, iar dacă blochează un expeditor legitim, cel mai simplu este să fie pus pe whitelist. În exemplul de mai sus la check_client_access.
În cazul în care postfix-ul folosit nu suporta tabele PCRE (Perl Compatible Regular Expressions), functionează și cu REGEXP, doar ca va fi puțin mai încet și la servere nu foarte solicitate este neglijabil.



Thursday, March 28, 2013

Lupta cu spam(bot)-uri (partea 1)

Folosesc aproape de un an caracteristica postscreen a serverului de mail postfix. Postscreen are rolul de a apăra serverul de conexiunile venite de la așa numitele zombie-uri si spambot-uri, pentru a păstra resursele serverului pentru conexiunile și, implicit, mailurile legitime.
Se spune că 90% din spam-uri sunt generate de astfel de zombie-uri si spambot-uri ... părerea mea este că acest procent este chiar mai mare.
Cu postscreen și încă câteva trucuri simple se pot opri peste 95% din spam-uri. Și asta încă în stadiul de conexiune, fără să intre în șirul de așteptare (reject before queue) a serverului postfix, fără verificari consumatoare de resurse (spamassassin, etc.).

Imaginile de mai jos sunt pe un interval de 24 de ore, generate în diferite momente și arată volumul mesajelor bounced(negru), infectate cu virus(galben), spam(gri), respinse de postscreen(verde) și respinse de smtpd_(client, helo, sender, relay, recipient, data, end_of_data)_restrictions(roșu).


Graficul a fost generat anul trecut în mai, când am pornit prima oara funcția postscreen pe un server cu postfix, atunci, servind un singur domeniu. Se vede raportul dintre postscreen/spam că este destul de mare: 188 repsinse conexiuni de postscreen și 48 spam-uri, care, cel puțin mie, înseamna un câștig enorm de mare.

Ce este de fapt această conexiune respinsă de postscreen? Probabil o conexiune venită de la un calculator infectat cu un progrămel (malware), care trimite spam-urile în lume. Dar o mare parte dintre aceste programe nu respectă standardele prin care se trimit mesajele și exact acest lucru este de care se foloseste funcția postscreen: respinge toate conexiunile non-standard. Pe langă asta poate face și test DNS black/whitelist interogând liste ca spamhaus.org, barracudacentral.org sau altele date de către utilizator.
Fiecare conexiune respinsă de către postscreen reprezintă cel puțin un spam ... și dacă are mai multe adrese la destinatar? Ușor s-ar poate dubla/tripla numarul spam-urilor.

Între timp am mai mutat câteva domenii pe același server, având 8 în momentul de față.
Pe următorul grafic se vede că serverul este chiar în mijlocul unui atac de spam, iar acest lucru evidențiază și mai bine cât de eficient poate fi funcția postscreen.


Dacă înainte raportul postscreen/spam a fost 188/48=3,92, aici este 59308/420=141,21. Ouch! F... you all spammers!

N-am vorbit încă despre linia roșie, care reprezintă volumul mesajelor respinse, care au trecut de postscreen, dar n-au trecut verificarile smtpd_(client, helo, sender, relay, recipient, data, end_of_data)_restrictions. Urmează un alt articol, în care descriu o metoda foarte simpla și eficientă cu care se pot respinge mesajele venite de pe IP-uri dinamice.

Wednesday, July 11, 2012

yum HISTORY: info|list|summary|redo|undo|new

Deși folosesc din august 2011 CentOS 6, de abia acuma am descoperit ce (mai) știe YUM. Funcția yum history este un lucru pe care eu de mult îmi doream de la 'câinele galben'.
Versiunea nouă care vine cu CentOS 6 (cu RHEL 6, cu Fedora 12, etc...), pe lângă altele, are funcția de a reveni la o stare de înainte a sistemului de operare.
Ceva asemănător am folosit înainte cu CentOS 5 cu așa numitul transaction flags: tsflags=repackage în yum.conf. Pe lângă asta, trebuia setat și %_repackage_all_erasures 1 în /etc/rpm/macros, apoi cu comanda rpm -Uhv --rollback 'dată'  se putea pune sistemul într-o stare anterioară. Bineînțeles într-o stare, în care setările de mai sus erau făcute deja.
Vestea bună este că CentOS 6 vine nativ cu versiunea mai nouă a programului yum și implicit cu funcții noi.
Toate instalările, update-urile, dezinstalările se pot vizualiza:
# yum history

Loaded plugins: fastestmirror, priorities

ID     | Login user               | Date and time    | Action(s)      | Altered

-------------------------------------------------------------------------------

    82 | System <unset>           | 2012-07-11 09:25 | I, U           |  136 EE

    81 | System <unset>           | 2012-07-03 12:01 | Update         |    1

    80 | System <unset>           | 2012-07-03 12:00 | Update         |    1 EE

    79 | System <unset>           | 2012-07-02 09:10 | Update         |    1

    78 | System <unset>           | 2012-06-27 12:07 | I, U           |   13

    77 | System <unset>           | 2012-06-27 09:17 | Update         |   10

    76 | System <unset>           | 2012-06-14 09:28 | Update         |    2

    75 | System <unset>           | 2012-06-13 09:12 | Update         |    6

    74 | System <unset>           | 2012-06-11 17:56 | Install        |    2

    73 | System <unset>           | 2012-06-08 09:38 | Update         |    3

    72 | System <unset>           | 2012-06-05 15:51 | Update         |    1 EE

    71 | System <unset>           | 2012-05-30 18:36 | Update         |    2

    70 | System <unset>           | 2012-05-29 08:49 | I, U           |    3

    69 | System <unset>           | 2012-05-25 17:41 | Update         |    1 EE

    68 | System <unset>           | 2012-05-25 16:53 | Install        |    9

    67 | System <unset>           | 2012-05-24 10:08 | Update         |    2

    66 | System <unset>           | 2012-05-22 12:32 | Update         |    1 EE

    65 | System <unset>           | 2012-05-22 12:12 | Update         |    1 EE

    64 | System <unset>           | 2012-05-22 12:05 | Update         |    1

    63 | System <unset>           | 2012-05-17 11:42 | Update         |    1

history list

Informații suplimentare pentru careva modificare cu opțiunea info:
# yum history info 81

Loaded plugins: fastestmirror, priorities

Transaction ID : 81

Begin time     : Tue Jul  3 12:01:57 2012

Begin rpmdb    : 523:ff17c8b87bea4edf9e8d878dcb46b463d865c80e

End time       :            12:02:04 2012 (7 seconds)

End rpmdb      : 523:6de95ce5d3deb90f31ede91c2aded43b1095eb54

User           : System <unset>

Return-Code    : Success

Command Line   : update ./dovecot-2.1.8-1.el6.i686.rpm --nogpgcheck

Transaction performed with:

    Updated       rpm-4.8.0-19.el6_2.1.i686                     @updates

    Updated       yum-3.2.29-22.el6.centos.2.noarch             @updates

    Installed     yum-metadata-parser-1.1.2-16.el6.i686         @base

Loading mirror speeds from cached hostfile

 * base: mirrors.ch-center.com

 * epel: ftp.astral.ro

 * extras: ftp.ines.lug.ro

 * rpmforge: ftp.lug.ro

 * rpmforge-extras: ftp.lug.ro

 * updates: ftp.ines.lug.ro

329 packages excluded due to repository priority protections

    Updated       yum-plugin-fastestmirror-1.1.30-10.el6.noarch ?

Packages Altered:

    Updated dovecot-1:2.1.7-2_132.el6.i686 @/dovecot-2.1.7-2_132.el6.i686

    Update          1:2.1.8-1.el6.i686     @/dovecot-2.1.8-1.el6.i686

history info

Cu opțiunea summary 'packagename', primim informații despre tranzacțiile în care acel pachet a fost implicat:
# yum history summary kernel-headers

Loaded plugins: fastestmirror, priorities

Login user                 | Time                | Action(s)        | Altered

-------------------------------------------------------------------------------

System <unset>             | Last day            | I, U             |      136

System <unset>             | Last 3 months       | Update           |       14

System <unset>             | Last 6 months       | I, O, U          |       39

history summary

package-list 'packagename' informații despre ce s-a întâmplat cu respectivul pachet:
# yum history package-list kernel-headers

Loaded plugins: fastestmirror, priorities

ID     | Action(s)      | Package

-------------------------------------------------------------------------------

    82 | Updated        | kernel-headers-2.6.32-220.23.1.el6.i686            EE

    82 | Update         |                2.6.32-279.el6.i686                 EE

    77 | Updated        | kernel-headers-2.6.32-220.17.1.el6.i686

    77 | Update         |                2.6.32-220.23.1.el6.i686

    63 | Updated        | kernel-headers-2.6.32-220.13.1.el6.i686

    63 | Update         |                2.6.32-220.17.1.el6.i686

    45 | Updated        | kernel-headers-2.6.32-220.7.1.el6.i686

    45 | Update         |                2.6.32-220.13.1.el6.i686

    42 | Updated        | kernel-headers-2.6.32-220.4.1.el6.i686

    42 | Update         |                2.6.32-220.7.1.el6.i686

     2 | Dep-Install    | kernel-headers-2.6.32-220.4.1.el6.i686

history package-list

undo anulează tranzacția dată. Aici, conform documentației, se poate întâmpla că pachetul de versiune mai veche nu mai există nicăieri și atunci operația va eșua. Acest lucru nu se putea întâmpla cu CentOS 5: cum spuneam mai sus tsflags=repackage, adică orice pachet dezinstalat este arhivat local, și dacă este suficient spațiu se poate reveni la orice mai veche stare a sistemului de operare fără bătaie de cap, fără teama că acea versiune oare mai există undeva pe careva mirror.

redo execută din nou exact aceeași tranzacție specificată. Nu este vorba de reinstalare, pur și simplu se execută din nou operațiile din acea tranzacție.

new creează o nouă bază de date cu istoria tranzacțiilor.

Monday, May 7, 2012

mailgraph with postfix/postscreen

With mailgraph you can make really cool graphs to visualize daily, weekly, monthly and yearly statistics about postfix received/sent and bounced/rejected/spam/virus mails.

Some days ago I started to use postfix's postscreen feature. I didn't thought how cool and useful is. The spam volume is reduced with more than 50% on my server.

But I like very much graphs with mail statistics, I need postscreen stats too. Google it, but found nothing with separated stats, only cumulated with reject or spam.

So I made a patch based on NetworkMonkey IT Blog and if you use postfix with long queue id, you need to apply another patch to mailgraph from here: http://pub.birkosan.com/mailgraph/long_queue_ids.patch.




You need to patch mailgraph.pl and mailgraph.cgi too!

Patches:


Enjoy...

Thursday, March 8, 2012

Hardurile din IBM eServer x206

Am desfacut serverul IBM... la vremea lui (2006-2009) rula postgres ... de aproximativ 3 ani și jumătate este server de mail.
Hardurile sunt UltraSCSI320, la 10k în raid1



#smartctl --all /dev/sdb

smartctl version 5.38 [i686-redhat-linux-gnu] Copyright (C) 2002-8 Bruce Allen
Home page is http://smartmontools.sourceforge.net/


Device: IBM-ESXS PYH073C3-ETS10FN Version: RXQE

Serial number:         V3V4K3KA

Device type: disk

Transport protocol: Parallel SCSI (SPI-4)

Local Time is: Thu Mar  8 16:15:37 2012 EET

Device supports SMART and is Enabled

Temperature Warning Enabled

SMART Health Status: OK


Current Drive Temperature:     40 C

Drive Trip Temperature:        65 C

Manufactured in week 13 of year 2005

Recommended maximum start stop count:  10000 times

Current start stop count:      138 times

Elements in grown defect list: 0

Vendor (Seagate/Hitachi) factory information

number of hours powered up = 56325.08 -------------> / 24 / 365 = 6.429 

number of minutes until next internal SMART test = 56

Deci, 56325.08 ore în funcțiune egal cu 2346 zile sau 6.429 ani.

Cool, hm?

Friday, February 17, 2012

Rapoarte PostgreSQL log cu pgFouine

pgFouine este un program de analiză a log-urilor serverului PostgreSQL. In rapoarte poți vedea pe o anumită perioadă, câte interogări au fost, care dintre ele sunt cele mai lente (cu exemple), cele mai frecvente interogari, erorile, grafice cu numarul/durata interogărilor pe tipuri de interogări(exemple).

Face față la log-uri mari cu impact redus asupra resurselor. Eu, pe serverul administrat, am zilnic 350k-400k de interogări cu log-ul de 130-150MB (nu că aș considera asta foarte mare) și 3 rapoarte combinate sunt gata in nici 2 minute (pentru cei care au server solicitat tot timpul; în cazul meu face noaptea, când nimeni nu lucrează).

Despre instalare nu prea am ce sa vorbesc: este simplu si este descris de la A-Z pe site-ul lor.

În 2 ani de utilizare întotdeauna m-au deranjat graficele: e o chestie subiectivă, dar mi se par foarte mici. Nu că vezi mult mai mult daca sunt mai mari, dar de când lucrez la un monitor de 23" la 1920x1080, trebuie sa-mi bag nasul in el ca să văd ceva.
Apropo. Folosesc, la momentul de față, PostgreSQL 9.1.2 pe CentOS 6.2, toate instalate de pe http://yum.pgrpms.org/ din repo corespunzător. Tot de aici se poate instala și pgFouine (yum rules) din pachetul contrib.

Am zis să încerc, poate-poate ... nefiind un php guru n-am pus mari speranțe să pot modifica programul, dar iată că am reușit ... și încă ce repede ...

Fișierul în care am facut modificări HourlyStatsReport.class.php și în cazul meu se găsește by default în /usr/share/pgfouine/include/reporting/reports.

Iată:

--- ./HourlyStatsReport.class.php 2008-05-13 23:45:42.000000000 +0300
+++ ./new.class.php 2012-01-06 14:19:49.000000000 +0200
@@ -125,16 +125,16 @@
   $html = $this->getHtml();
   
   if(in_array('hourly_queries_per_second', $graphsGenerated)) {
-   $html .= '<p><img src="'.$this->reportAggregator->getImageBaseName('hourly_queries_per_second').'" alt="Queries per second" /></p>';
+   $html .= '<p align="center"><img src="'.$this->reportAggregator->getImageBaseName('hourly_queries_per_second').'" alt="Queries per second" /></p>';
   }
   if(in_array('hourly_all_queries', $graphsGenerated)) {
-   $html .= '<p><img src="'.$this->reportAggregator->getImageBaseName('hourly_all_queries').'" alt="Hourly queries" /></p>';
+   $html .= '<p align="center"><img src="'.$this->reportAggregator->getImageBaseName('hourly_all_queries').'" alt="Hourly queries" /></p>';
   }
   if(in_array('hourly_select_queries', $graphsGenerated)) {
-   $html .= '<p><img src="'.$this->reportAggregator->getImageBaseName('hourly_select_queries').'" alt="Hourly SELECT queries" /></p>';
+   $html .= '<p align="center"><img src="'.$this->reportAggregator->getImageBaseName('hourly_select_queries').'" alt="Hourly SELECT queries" /></p>';
   }
   if(in_array('hourly_write_queries', $graphsGenerated)) {
-   $html .= '<p><img src="'.$this->reportAggregator->getImageBaseName('hourly_write_queries').'" alt="Hourly write queries" /></p>';
+   $html .= '<p align="center"><img src="'.$this->reportAggregator->getImageBaseName('hourly_write_queries').'" alt="Hourly write queries" /></p>';
   }
 
   return $html;
@@ -252,7 +252,7 @@
 
   // Queries per second
   if($this->countValidValues($max) > 2) {
-   $graph = new Graph(840, 250);
+   $graph = new Graph(1000, 550);
    $graph->setAntiAliasing(true);
    $graph->setBackgroundColor(new Color(0xFF, 0xFF, 0xFF));
    
@@ -313,7 +313,7 @@
   
   // All queries
   if($this->countValidValues($queryCountValues) > 2) {
-   $graph = new Graph(840, 250);
+   $graph = new Graph(1000, 550);
    $graph->setAntiAliasing(true);
    $graph->setBackgroundColor(new Color(0xFF, 0xFF, 0xFF));
    
@@ -391,7 +391,7 @@
   
   // SELECT queries
   if($this->countValidValues($selectCountValues) > 2) {
-   $graph = new Graph(840, 250);
+   $graph = new Graph(1000, 550);
    $graph->setAntiAliasing(true);
    $graph->setBackgroundColor(new Color(0xFF, 0xFF, 0xFF));
    
@@ -468,7 +468,7 @@
   
   // write queries
   if($this->countValidValues($updateCountValues) > 2 || $this->countValidValues($insertCountValues) > 2 || $this->countValidValues($deleteCountValues) > 2) {
-   $graph = new Graph(840, 250);
+   $graph = new Graph(1000, 550);
    $graph->setAntiAliasing(true);
    $graph->setBackgroundColor(new Color(0xFF, 0xFF, 0xFF));