Blog di Bernardino (Dino) Ciuffetti

29 Lug 21 Don’t use SORBS DNSBL

Sorbs is a infamous DNS blacklist born to try to fight spam. They have a too much restrictive policy that won’t block spam at all but they just create some pain to your MTA.

They can delist your IP a couple of times but if one of your clients get hacked your good quality MTA will be listed for months, even years!

What they don’t understand is that we work with our IP reputation, so just change the IP is not a valid solution. When a valid MTA got abused to send spam the problem is generally solved in hours, or even minutes. A one month list will generate a great problem to the hacked MTA’s clients.

The only solution is: DON’T USE SORBS AT ALL. The list is not business oriented and so is only valid for lamers, bofh sysadmins and nerds…. ok I’m a bofh, nerd sysadmin but I don’t use Sorbs anymore. Sorry.

NOTA: Tell your sysadmins to NOT USE SORBS.

06 Lug 18 How to setup xtables GeoIP for iptables on OpenWRT

I’m not racist, but sometimes you may need to keep some people out of your network based on its geographical region… in reality I’m referring to its public source IP address.

Requests are coming from the big internet, so you can check if the source IP of the peers that are trying to connect to your powerful OpenWRT Linux router are coming from a particular region and you may want to stop all those requests accordingly.

If you are using iptables and ip6tables (if you are on linux this is the standard) you can setup GeoIP based packet filtering with iptables: it’s an iptables extension that make use of the glorious and free MaxMind GeoLite Legacy Downloadable Database (that is now dying…).

On OpenWRT this is supported automatically, but generally your router does not have all the disk space to host the entire GeoLite GeoIP database. So, you need to prepare all the records of the geographical regions that you want to block on your firewall.

Take a linux workstation or server (your notebook, a raspberry pi you own always on, one of your client’s server… better not IMHO…) and run those commands:

root@firegate2:~# mkdir /tmp/temp
root@firegate2:~# cd /tmp/temp
root@firegate2:/tmp/temp# /usr/share/xt_geoip/xt_geoip_dl
–2018-07-05 23:54:40–
Risoluzione di (…,, 2400:cb00:2048:1::6810:262f, …
Connessione a (||:80… connesso.
Richiesta HTTP inviata, in attesa di risposta… 200 OK
Lunghezza: 1715246 (1,6M) [application/octet-stream]
Salvataggio in: “GeoIPv6.csv.gz”

GeoIPv6.csv.gz 100%[================================================================>] 1,64M –.-KB/s in 0,1s

2018-07-05 23:54:40 (10,9 MB/s) – “GeoIPv6.csv.gz” salvato [1715246/1715246]

–2018-07-05 23:54:40–
Riutilizzo della connessione esistente a
Richiesta HTTP inviata, in attesa di risposta… 200 OK
Lunghezza: 2540312 (2,4M) [application/zip]
Salvataggio in: “” 100%[================================================================>] 2,42M 11,3MB/s in 0,2s

2018-07-05 23:54:40 (11,3 MB/s) – “” salvato [2540312/2540312]

TERMINATO –2018-07-05 23:54:40–
Tempo totale: 0,4s
Scaricati: 2 file, 4,1M in 0,4s (11,1 MB/s)
inflating: GeoIPCountryWhois.csv
root@firegate2:/tmp/temp# /usr/share/xt_geoip/xt_geoip_build -D . *.csv
209370 entries total
0 IPv6 ranges for A1 Anonymous Proxy
32 IPv4 ranges for A1 Anonymous Proxy
0 IPv6 ranges for A2 Satellite Provider
36 IPv4 ranges for A2 Satellite Provider
3 IPv6 ranges for AD Andorra
26 IPv4 ranges for AD Andorra
51 IPv6 ranges for AE United Arab Emirates
302 IPv4 ranges for AE United Arab Emirates
… and continues …
11 IPv6 ranges for ZM Zambia
64 IPv4 ranges for ZM Zambia
14 IPv6 ranges for ZW Zimbabwe
59 IPv4 ranges for ZW Zimbabwe

The script /usr/share/xt_geoip/xt_geoip_build it’s part of xtables-addons package that you may or may not find on your distribution. Search on google for that.

This will create LE and BE directories. Now you want to extract only the geo regions that you need (ex: CN,UA,TW,VN,VG,KP,VI,KR), like that:

root@firegate2:/tmp/temp# du -csh BE/CN.iv? BE/UA.iv? BE/TW.iv? BE/VN.iv? BE/VG.iv? BE/KP.iv? BE/VI.iv? BE/KR.iv? LE/CN.iv? LE/UA.iv? LE/TW.iv? LE/VN.iv? LE/VG.iv? LE/KP.iv? LE/VI.iv? LE/KR.iv?
36K BE/CN.iv4
48K BE/CN.iv6
24K BE/UA.iv4
16K BE/UA.iv6
8,0K BE/TW.iv4
4,0K BE/TW.iv6
4,0K BE/VN.iv4
4,0K BE/VN.iv6
4,0K BE/VG.iv4
4,0K BE/VG.iv6
4,0K BE/KP.iv4
0 BE/KP.iv6
4,0K BE/VI.iv4
4,0K BE/VI.iv6
8,0K BE/KR.iv4
4,0K BE/KR.iv6
36K LE/CN.iv4
48K LE/CN.iv6
24K LE/UA.iv4
16K LE/UA.iv6
8,0K LE/TW.iv4
4,0K LE/TW.iv6
4,0K LE/VN.iv4
4,0K LE/VN.iv6
4,0K LE/VG.iv4
4,0K LE/VG.iv6
4,0K LE/KP.iv4
0 LE/KP.iv6
4,0K LE/VI.iv4
4,0K LE/VI.iv6
8,0K LE/KR.iv4
4,0K LE/KR.iv6
352K totale

So, in this case we will need 352 Kb of router disk space. After we created the /usr/share/xt_geoip/BE/ and /usr/share/xt_geoip/LE/ directories on our router’s filesystem:

root@dam2ktplinkrouter:~# mkdir -p /usr/share/xt_geoip/BE /usr/share/xt_geoip/LE

We are going to copy those files on our OpenWRT router:

root@firegate2:/tmp/temp# scp LE/CN.iv? LE/UA.iv? LE/TW.iv? LE/VN.iv? LE/VG.iv? LE/KP.iv? LE/VI.iv? LE/KR.iv? root@
root@’s password:
CN.iv4 100% 35KB 109.8KB/s 00:00
CN.iv6 100% 47KB 76.0KB/s 00:00
UA.iv4 100% 23KB 108.4KB/s 00:00
UA.iv6 100% 15KB 87.9KB/s 00:00
TW.iv4 100% 4704 47.5KB/s 00:00
TW.iv6 100% 3104 77.8KB/s 00:00
VN.iv4 100% 3888 98.9KB/s 00:00
VN.iv6 100% 3584 87.9KB/s 00:00
VG.iv4 100% 536 40.1KB/s 00:00
VG.iv6 100% 224 20.0KB/s 00:00
KP.iv4 100% 40 3.9KB/s 00:00
KP.iv6 100% 0 0.0KB/s 00:00
VI.iv4 100% 392 30.6KB/s 00:00
VI.iv6 100% 160 14.4KB/s 00:00
KR.iv4 100% 8128 105.8KB/s 00:00
KR.iv6 100% 3616 87.0KB/s 00:00
root@firegate2:/tmp/temp# scp BE/CN.iv? BE/UA.iv? BE/TW.iv? BE/VN.iv? BE/VG.iv? BE/KP.iv? BE/VI.iv? BE/KR.iv? root@
root@’s password:
CN.iv4 100% 35KB 114.4KB/s 00:00
CN.iv6 100% 47KB 66.0KB/s 00:00
UA.iv4 100% 23KB 115.2KB/s 00:00
UA.iv6 100% 15KB 74.9KB/s 00:00
TW.iv4 100% 4704 93.8KB/s 00:00
TW.iv6 100% 3104 75.7KB/s 00:00
VN.iv4 100% 3888 108.8KB/s 00:00
VN.iv6 100% 3584 76.2KB/s 00:00
VG.iv4 100% 536 40.3KB/s 00:00
VG.iv6 100% 224 20.0KB/s 00:00
KP.iv4 100% 40 4.1KB/s 00:00
KP.iv6 100% 0 0.0KB/s 00:00
VI.iv4 100% 392 33.1KB/s 00:00
VI.iv6 100% 160 15.4KB/s 00:00
KR.iv4 100% 8128 111.1KB/s 00:00
KR.iv6 100% 3616 71.8KB/s 00:00

OK, now we have our pieces of geo ip informations. We now need to install the iptables-mod-geoip from the LuCI web interface (or by hand if you like).
Now you can create your Firewall Traffic Rules. Go to Network -> Firewall -> Traffic Rules on the router’s LuCI web interface and add a custom traffic rule. In my case I created 2 that I called “CinamerdaMuoriUDPeTCP” and “CinamerdaMuoriICMP”, the first to block TCP and UDP and the second to block ICMP traffic.

After that you can setup your custom rule setting your protocol and address families, set “source zone” to WAN, “destination zone” to “Any zone (forward)”, action to DROP, and the “Extra arguments” field like this:

-m geoip –source-country CN,UA,TW,VN,VG,KP,VI,KR

You can check the image below.

OpenWRT Firewall geoip example

Now you can say hello to most chinaspammers and something like that, but don’t abuse, this is not ethic if you set up this on a server that offers some sort of public service.

21 Feb 12 Mitigare attacchi di tipo Distributed Denial Of Service su apache con mod_evasive

C’e’ un modulo molto carino non official per apache che permette di bloccare o comunque mitigare facilmente attacchi di tipo DDOS.

Si scarica il modulo mod_evasive dal sito, si decomprime il tar.gz e si compila con la seguente stringa:

<directory_di_installazione_apache>/bin/apxs -i -c mod_evasive20.c

Ora bisogna inserire due cosette in httpd.conf e successivamente riavviare gli apache:

1) LoadModule evasive20_module modules/
2) La sua configurazione

Per quanto riguarda la numero 2 bisogna fare una considerazione importante, ovvero che il tuning del presente modulo con parametri errati o maldimensionati puo’ provocare dei falsi positivi che creano gravi disservizi per un periodo anche prolungato di tempo.

La configurazione e’ simile a questa (effettuo già un pre tuning che comunque dovrete ricontrollare e confermare voi che conoscete il vostro sistema):

<IfModule mod_evasive20.c>
DOSHashTableSize   196613
DOSLogDir “/tmp”

DOSPageCount         20
DOSPageInterval      10

DOSSiteCount        350
DOSSiteInterval      5

DOSBlockingPeriod   10

Di seguito una breve spiegazione dei parametri:

DOSHashTableSize: e’ la dimensione della tabella di lookup interna usata dal modulo. Su server carichi il numero non deve essere troppo basso. Non andrebbe messo un numero casuale ma un numero primo presente nella struct dei numeri primi dentro mod_evasive20.c.

DOSLogDir: e’ una directory dove evasive appoggia dei dati che vengono utilizzati internamente per motivi di locking tra i processi child di apache

DOSPageCount: e’ la soglia per il numero di richieste effettuate verso una stessa url da uno stesso IP entro un determinato intervallo di tempo specificato dalla direttiva DOSPageInterval. Se il numero di richieste verso una stessa pagina/oggetto/uri viene superato nell’intervallo di tempo specificato apache blocchera’ l’IP del client per un determinato numero di secondi specificati dalla variabile DOSBlockingPeriod. Consiglio vivamente di non impostare questo parametro troppo basso per evitare falsi positivi all’interno di ambienti nattati o dietro proxy server (ad esempio clienti fastweb, utenti all’interno di grosse organizzazioni che usano un proxy server, ecc.)

DOSPageInterval: e’ l’intervallo di tempo espresso in secondi che attiva la soglia relativa al parametro precedente (DOSPageCount)

DOSSiteCount: e’ la soglia per il numero di richieste complessive verso tutto il sito effettuate da uno stesso IP entro un determinato intervallo di tempo specificato dalla direttiva DOSSiteInterval. Se il numero complessivo di richieste verso apache viene superato nell’intervallo di tempo specificato, apache blocchera’ l’IP del client per un determinato numero di secondi specificati dalla variabile DOSBlockingPeriod. Anche qui consiglio vivamente di non impostare questo parametro troppo basso per evitare falsi positivi all’interno di ambienti nattati o dietro proxy server (ad esempio clienti fastweb, utenti all’interno di grosse organizzazioni che usano un proxy server, ecc.)

DOSSiteInterval: e’ l’intervallo di tempo espresso in secondi che attiva la soglia relativa al parametro precedente (DOSSiteCount)

DOSBlockingPeriod: e’ l’intervallo di tempo espresso in secondi durante i quali tutti i client finiti in blacklist avendo superato i limiti imposti dai parametri specificati sopra non potranno collegarsi ad apache e navigare sul sito ottenendo invece un codice di errore HTTP/403 (Forbidden). Se i clients bloccati continuano ad effettuare nuove richieste durante il periodo di blocco, ogni richiesta resetta il timer percui il conteggio ricomincia. Consiglio quindi VIVAMENTE di non impostare questo parametro troppo alto, in genere non vanno mai superati i 20 secondi. Il motivo principale e’ la mitigazione di eventuali disservizi causati da falsi positivi. Il discorso e’ inoltre valido perche’ durante un attacco DDOS il timer viene continuamente resettato e l’attacco viene comunque mitigato anche impostando il parametro ad un valore molto basso.

Riavviate apache e buon divertimento.

Dino Ciuffetti.

07 Set 11 How to map DNS responses based to user’s geo location

In this short abstract I’ll show you how did I make my work on trying to create a highly scalable, geo localized and distributed system using the DNS.

What we are going to create is a simple but powerful DNS system that can handle queries for a domain returning records based on the user’s geo location.

To accomplish this task we have to choose a good opensource DNS server. My choice was powerdns (
Powerdns is a great piece of software. It’s a powerful DNS server daemon that can be configured to fit in different DNS environments.
You can save domain zones into different backends (MySQL, Oracle, bind zone file, ldap, etc), and you can have primary and secondary DNS servers with automatic zone replication. This is all what you need to create a full featured DNS system.

One of the powerdns backends do accomplish the geo lookup task, and it’s called “geobackend” (

Our test environment will consist in a primary DNS server (powerdns as a master), a secondary DNS server (powerdns as a slave) and a geo lookup DNS server (powerdns as master with geobackend enabled). We will enable automatic zone transfer between the primary and the slave server, so that if you add a new record on the master it will be automatically created on the slave.

So, we need 3 servers with powerdns installed. The installation process may be different in each case, but if you are using debian, the task can be as simple as running by root the following command:
apt-get install pdns-server

Now you need the backend where you will save the zone data. May be you want to choose “MySQL” for the master and “bind format file” for the slave DNS. The geo dns server will not need a zone backend because its single task is to retrieve the caller’s IP address and fetch its geographic location from a particular location file, then lookup this location from a map file and return back to the calling user the associated CNAME record that’s into the map file.
A quick brain guideline is given below.

My system ( is composed like this: (primary DNS server with mysql backend) (secondary DNS server with auto zone replication on bind zone file) (geo lookup DNS server with geobackend)

I executed the steps below:

On you have to:
1) install powerdns with the gmysql backend
2) install MySQL server, create a database and grant a user on that DB
3) configure powerdns as master, with gmysql backend connecting to MySQL
4) please note that this server is authoritative to the “” zone
5) delegate the “geo” zone with a NS record to the geo dns server: “geo IN NS”
6) create the glue record for the geodns with the record: “ns1.geo IN A ip_geo_dns_server”

On you have to:
1) install powerdns with the bind backend
2) configure powerdns to be a slave with bind backend and enable as a supermaster
3) please note that this server is authoritative to the “” zone

On you have to:
1) install powerdns with the geo backend
2) configure powerdns as master with geobackend
3) please note that this server is authoritative to the “” zone
4) create a map file to handle the association between your country location (eg: uk) and the CNAME that the server will reply
5) download the location database zone, for example I use: (

If you need how to do that in details please do not hesitate to write me a email. You will find it into my contact page.
Ciao, Dino.

24 Ago 10 Why do not host sites from your own home

I would not recommend you to host sites that way, you have to be sure that your ISP give you public IP(s) and setup your router to port forward ports 80, 443, 53, and so on.
There are other problems too:
1) if you want to host more than one site with SSL you must have one public IP for each SSL site or use different SSL ports for each site, because name virtualhosting with SSL is not possible;
2) dsl lines are not designed to be stable. The connection can go down and make your site not visible. This is a major problem if you make the mistake to have your own DNS server on it!! The ISP assigned public IP address can change more than one time a day and you have to sync the DNS zone each time.
3) dsl ips are putted into DNS based blacklists zones. You may not be reached from various HTTP proxy servers around the world. For the same reason you cannot send mails, for example originated from your sites.
4) adsl lines are asymmetric (unbalanced for download). You have few kbytes per second in upload, that is just what you need to publish web sites, so this can be a problem when you have just more than 3 users.
5) you probably have problems with High-Availability and Load-Balancing on domestic hardware and you may have blackouts.
6) DNS subsystem may need primary and secondary DNS servers.

The best way (imho) is to use services like slicehost where you have a HA virtual server slice running linux, public IP addresses, free primary and secondary DNS hosting service, large public bandwidth, disk space… and not last your own root password that you can use to have maintenance on your own server for your own.

13 Mar 10 DynaBlast, and your access_log give you something

If you want an apache httpd server access_log scanner written in C that check for you every IP address that exceed a given number of hits in the last given time period, then DynaBlast is a tool that make sense for you.

This tool, released as usual in GPLv2, can be spawned every minute in crontab without the risk of having two instances running: we make use of a lock mechanism.
It has a fast mode that can skip already parsed line from a consecutive scan, so each time it runs, it play very fast.

In stdout you’ll get the scanning result. Ex:


You can download DynaBlast from here:

Ciao, Dino.

21 Feb 10 Scandalo, the fast and Simple clamdscan mail frontend

Hi people.
I’m now talking about a simple GPLv2, C written, small program that work as a very fast clamdscan antivirus frontend.

Scandalo can take a mail on standard input and parse it from viruses, piping it to clamdscan.
It then get the virus status from clamdscan and put a mail header called “X-Virus-Ret” returning the virus scanner status.
It also put a mail header called “X-Virus-stream” returning the first virus name found (if any).

You can then setup a rule on your (say, maildrop) mail filter to pipe the incoming mail to scandalo, and another rule to check the return scanned mail header for viruses.
If a virus was found, you can drop the mail, or put it into a .Virus maildir.

If you have any question, I’m the developer of scandalo.
Scandalo –

Write me a note at

Ciao, Dino.

29 Gen 10 Per un buon mailserver

Chiunque ha, o abbia provato ad avere un proprio mailserver per spedire mail in uscita ha potuto costatare personalmente che moltissimi mailserver dall’altra parte del filo hanno dei sistemi di blacklist per cercare di combattere lo spam, e che presto o tardi finiscono con il bloccare temporaneamente il nostro IP, o peggio mandare le nostre mail nella cartella Spam del destinatario.

Sebbene non esista un capitolato standard, dopo qualche anno di combattimento con le mail ho potuto stilare una serie di buone regole per cercare di attenuare la problematica.

Io utilizzo da anni Courier MTA ( e mi trovo veramente bene, ad ogni modo le seguenti regole valgono per qualsiasi mailserver.

Attenendosi alle seguenti regole, sara’ possibile inviare tante mail senza troppi problemi.

1) utilizza NECESSARIAMENTE un IP statico per inviare le mail
2) crea un Reverse PTR record sul DNS per il tuo IP e chiamalo
3) crea un A record chiamato sul DNS che punta all’IP
4) crea un MX record per accettare le mail in ingresso/ritorno e fallo puntare a
5) crea sul DNS il TXT record per il Sender Policy Framework e crea regole che abilitano a spedire posta dal tuo dominio solo dall’IP del mailserver
6) fai utilizzare al tuo MTA una connessione di rete stabile, e soprattutto un DNS stabile e veloce!!
7) crea sul server SMTP un account
8) disabilita il relaying per il tuo mailserver. Se lo devi abilitare, crea degli utenti abilitati al relaying con password robuste e abilita SSL sul server SMTP
9) fai uscire dall’IP del tuo MTA solo le mail originate dal tuo mailserver. Se ad esempio c’e’ un Firewall che fa source NAT in uscita, fai in modo di aprire la porta di destinazione 25 sul firewall verso internet solo ai pacchetti provenienti dal mailserver. Se hai nella tua rete altri client SMTP che creano mail in uscita spegnili, o falli passare necessariamente in relaying per il tuo MTA
10) utilizza se possibile accorgimenti atti a sopprimere i Delivery Status Notification per le mail in ingresso, come ad esempio ritornare errore subito durante la ricezione della mail se un utente non siste o la mail viene bloccata
11) utilizza un sistema antispam come spamassassin e abilita le blacklist IP basate su DNS per tutte le mail in ingresso
12) imposta il tuo “Helo” message sul mailserver affinche’ si esponga sempre come “”
13) se possibile, per le mail in relaying, configura il tuo mailserver per strippare i “Delivered to” headers. In questo modo gli altri mailserver crederanno che la mail in relaying e’ stata generata dal tuo mailserver.
14) se possibile, quando spedisci le mail, utilizza sempre come mittente un account esistente che corrisponda ad un dominio gestito dal tuo mailserver
15) evita se possibile account non esistenti del tipo “”. Nel caso ti servisse, crea l’account e scarta tutte le mail in ingresso buttandole in “/dev/null”

Queste regole sono secondo me un buon modo per evitare di finire velocemente nelle miliardi di blacklist in giro per il mondo.

Mi raccomando, scrivetemi a e fatemi sapere se funziona, o mandatemi i vostri suggerimenti con altre regole e io le integrero’.

Ciao, Dino.