Archivi tag: iptables

Cisco 2811: utilizzare le route-map per creare delle regole di destination NAT basate su IP sorgente

Scenario

Supponiamo che si abbia a che fare con un ufficio centrale (main office) a cui sono collegati N uffici periferici (branch office) tramite dei tunnel VPN IPsec Site-to-Site dedicati (che concorrono a formare la classica topologia a stella). Supponiamo, inoltre, che i suddetti uffici periferici, per questioni di failover, debbano essere in grado di raggiungere i servizi presenti nell’ufficio centrale anche nel caso in cui i tunnel VPN non siano disponibili (passando quindi  direttamente per Internet).

vpn-ipsec1Utilizzando delle regole di destination NAT classiche, del tipo:

ip nat inside source static tcp 192.168.2.4 80 interface fastethernet0/0 80

(dove 192.168.4.2 è l’IP locale del server Web esposto su Internet), i branch office non saranno in grado di raggiungere il server in questione tramite il tunnel VPN (utilizzando il protocollo HTTP).

Ergo, il fatto che un determinato servizio sia pubblicato su Internet, implica automaticamente l’impossibilità di raggiungerlo anche tramite il tunnel VPN.

Per ovviare a tale problematica esistono 2 soluzioni: la prima, meno impegnativa (ma che richiede la modifica della URL lato client in caso di failover), consiste nel modificare la configurazione del server in modo tale che rimanga in ascolto su 2 porte distinte, ad esempio la TCP 80 per Internet e la TCP 81 per la VPN;  la seconda, più impegnativa (ma anche molto più scalabile), consiste nel creare sul nostro router Cisco 2811 (main office) delle route-map (che si avvalgono di opportune ACL) in grado di filtrare gli indirizzi IP sorgenti dei client che vogliono collegarsi al server Web. In questo modo, se la richiesta di connessione proviene da un determinato IP privato tipico di una VPN Site-to-Site (ad esempio 192.168.3.1), per essa non viene applicato il destination NAT; viceversa, nel caso in cui la richiesta di connessione provenga da Internet, verrà applicato il destination NAT come di consueto.

Ho definito la seconda soluzione come la più scalabile delle 2 per un semplice motivo: impostando la route-map sul router del main office e modificando sul nameserver locale il record di tipo A che punta all’IP del server Web, si può fare in modo che quest’ultimo possa essere contattato tramite tunnel VPN o tramite Internet a seconda dei casi senza dover modificare la URL lato browser (passando, ad esempio, da http://www.vostrodominio.com a http://www.vostrodominio.com:81).

Vediamo adesso come mettere in pratica la soluzione #2.

Configurazione del router Cisco 2811 (main office)

Per prima cosa occorre creare l’ACL in grado di “riconoscere” gli IP locali e di negare il destination NAT:

Router(config)# access-list 150 deny ip host 192.168.2.4 192.168.3.0 0.0.0.255
Router(config)# access-list 150 deny ip host 192.168.2.4 192.168.4.0 0.0.0.255
Router(config)# access-list 150 deny ip host 192.168.2.4 192.168.5.0 0.0.0.255
Router(config)# access-list 150 deny ip host 192.168.2.4 192.168.6.0 0.0.0.255
Router(config)# access-list 150 permit ip host 192.168.2.4 any

Successivamente creiamo la route-map vera e propria:

Router(config)# route-map nonat
Router(config-route-map)# match ip address 150

dove 150 è il numero dell’ACL estesa precedentemente definita.

Infine, associamo la route-map appena creata alla regola di destination NAT:

Router(config)# ip nat inside source static tcp 192.168.2.4 <IP Pubblico> 80 route-map nonat extendable

Ovviamente, affinchè la suddetta soluzione sia realmente scalabile, è necessario che il vostro collegamento ad Internet sia dotato di indirizzo IP pubblico statico.

Salviamo adesso la configurazione del nostro router:

Router# copy run start

e passiamo al vaglio alcune soluzioni alternative alle route-map.

1) Utilizzo dei record DNS di tipo SRV (vedi qui per ulteriori dettagli). Essi ci consentono non solo di specificare il protocollo di comunicazione ma anche la porta su cui è in ascolto il server, definendo una priorità per ciascuna entry che li compone:

_http._tcp.vostrodominio.com. 86400 IN SRV 0 5 81 www.vostrodominio.com.
_http._tcp.vostrodominio.com. 86400 IN SRV 1 5 80 www1.vostrodominio.com.

dove 0 e 1 sono le priorità, 81 e 80 le porte su cui è in ascolto il server. In caso di timeout sulla porta 81 e l’IP di www (raggiungibile via VPN) il browser “dovrebbe” switchtare automaticamente sulla 80 e l’IP di www1. Ho utilizzato il condizionale poichè non tutti i broswer supportano tale meccanismo ed un workaround (applicato però solo da alcuni di essi), consiste nel definire record A con il medesimo hostname ma indirizzi IP differenti: nel caso in cui la connessione al primo IP della lista vada in timeout, il broswer tenterà automaticamente di connettersi al secondo IP (e così via).

2) Utilizzo di un firewall interno per filtrare le connessioni in uscita (outbound). ln questo caso, grazie ad esso, potremmo creare delle regole ad hoc (source NAT) per il mapping delle porte di destinazione, ad esempio (utilizzando iptables):

[root@firewall ~]# iptables -t nat -A OUTPUT -p tcp -d www.vostrodominio.com --dport 80 -j DNAT --to-destination www.vostrodominio.com:81

Anche in questo caso, prima di applicare la suddetta regola di firewalling, sarà necessario modificare sul nameserver il record A per l’hostname www.

E’ tutto. Alla prossima.

CentOS 6 ed rsyslog: creare un sistema di log centralizzato per i dispositivi di rete

Scenario

Diversi uffici periferici (in gergo branch office), connessi all’ufficio centrale (main office) mediante dei tunnel IPSec site-to-site dedicati (classici link VPN utilizzati per creare una intranet con topologia a stella).

Problema

Creare un sistema di log centralizzato per tutti i dispositivi di rete, compresi i router degli uffici periferici.

Soluzione

Utilizzare una Linux box (CentOS 6) con a bordo il demone che funge da syslog server, ovvero rsyslog.

syslog

Configurazione della Linux box e del syslog server

Per prima cosa occorre fare in modo che la nostra Linux box sia in grado di ricevere correttamente (sulla porta UDP 514) i log inoltrati dai dispositivi di rete. Per fare ciò è sufficiente creare la seguente regola di netfilter (ultilizzando iptables):

-A INPUT -m state --state NEW -m udp -p udp -s 192.168.0.0/16 --dport 514 -j ACCEPT

ed aggiungerla all’interno del file /etc/sysconfig/iptables, per poi lanciare un:

[root@linuxbox ~]# service iptables restart

in modo da rendere la suddetta regola operativa (da notare che 192.168.0.0/16 è la subnet classe B che raggruppa tutte le /24 utilizzate dai branch office).

Una volta fatto ciò è necessario aggiungere la seguente direttiva all’interno del file di configurazione rsyslog, ovvero /etc/rsyslog.conf:

$template CiscoVPN,"/var/log/cisco/system-%HOSTNAME%.log"

*.* -?CiscoVPN

e creare la dir di target in cui verranno salvati i log, ovvero /var/log/cisco:

[root@linuxbox ~]# mkdir -p /var/log/cisco

A questo punto possiamo riavviare rsyslog in modo da rendere effettive le suddette modifiche:

[root@linuxbox ~]# service rsyslog restart

Configurazione dei dispositivi di rete

Per semplicità mi soffermerò solo ed esclusivamente nella configurazione dei router (Cisco) dei branch office. Tale operazione consiste in 2 fasi: la definizione di una sorgente SNTP affidabile ed identica per tutti i network device (in modo da poter effettuare un’eventuale correlazione tra gli eventi) e la configurazione del syslog server target.

Per configurare la sorgente SNTP è sufficiente lanciare il comando:

Router(config)# sntp server <IP del server SNTP>

Ad esempio, se volessimo utilizzare come server SNTP ntp1.inrim.it, dovremmo digitare:

Router(config)# sntp server 193.204.114.232

Per quanto riguarda la configurazione del target dei log, è sufficiente lanciare i seguenti comandi:

Router(config)# service timestamps log
Router(config)# logging source-interface Vlan1
Router(config)# logging <IP del syslog server>

Il primo comando serve a fare in modo che il timestamp dell’evento venga aggiunto automaticamente alla entry del log; il secondo comando specifica l’interfaccia dalla quale i log devono essere inviati (essendo in VPN, l’interfaccia di riferimento è quella della LAN, in questo caso la Vlan 1);  l’ultimo comando specifica molto banalmente l’indirizzo IP del syslog server.

Infine, controlliamo che i log vengano popolati in real time, lanciando il comando:

[root@linuxbox ~] #tail -f /var/log/system-<hostname>.log

dove <hostname> è l’hostname del dispositivo di rete di cui volete consultare il file di log.

Se tutto funziona a dovere possiamo dire di aver finalmente realizzato il nostro sistema di log centralizzato.

A presto.

CentOS 6 e contromisure agli attacchi DDoS: regole di firewalling basate sui netblock dei provider italiani

Scenario

Server Web Linux (basato su Apache) con CentOS 6 a bordo, dotato di 16 GB di RAM e 2 CPU con 4 core ciascuna. Totale assenza di firewall di frontend, ergo il filtraggio del traffico viene demandato direttamente al server in questione.

Problema

Da N giorni la suddetta macchina è vittima di attacchi di tipo DDoS, provenienti per lo più da IP stranieri (macchine zombie facenti parte di una botnet).

Soluzione

Creare delle regole netfilter ad hoc (mediante iptables), consentendo solo ed esclusivamente i netblock degli ISP italiani. Inoltre, per evitare che l’attaccante possa avvalersi di qualche proxy “aperto” made in Italy, sono stati bloccati ulteriori IP pubblici recuperati da un sito specifico. Infine, sono stati consentiti gli IP pubblici degli spider (aka crawler) utilizzati dai più importanti motori di ricerca (Google, Bing, Yahoo!), in modo tale da impedire che il sito Web hostato sul server venga penalizzato in termini di ranking.

Step 1: consentire gli IP italiani

Lo scrip bash (permit_ita.sh) che esegue tale operazione è il seguente:

#!/bin/bash

iptables -A INPUT -p tcp --dport 80 -j DROP
iptables -A INPUT -p tcp --dport 443 -j DROP

wget http://www.ipdeny.com/ipblocks/data/countries/it.zone -O ip_italiani.txt

while read line
do
    iptables -I INPUT -s $line -p tcp --dport 80 -j ACCEPT
    iptables -I INPUT -s $line -p tcp --dport 443 -j ACCEPT
done < ip_italiani.txt

iptables-save

Il suo funzionamento è banale: per prima cosa vengono create 2 regole netfilter per droppare tutto il traffico HTTP/HTTPS diretto al sito Web. Successivamente viene scaricato (mediante wget) il contenuto del sito http://www.ip-deny.com/ipblocks/data/countries/it.zone, in cui è presente l’elenco dei netblock italiani. Infine, vegnono consentiti i netblock in questione.

Step 2: bloccare i proxy made in Italy

A questo punto possiamo procedere con il blocco dei proxy “open” italiani. Per fare ciò possiamo utilizzare il seguente scrip bash (block_proxy.sh):

#!/bin/bash

wget --user-agent="Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.3) Gecko/2008092416 Firefox/3.0.3"  http://spys.ru/free-proxy-list/IT/ -O lista_proxy.txt

grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}" lista_proxy.txt | uniq > ip_proxy.txt

while read line
do
    iptables -I INPUT -s $line -p tcp --dport 80 -j DROP
    iptables -I INPUT -s $line -p tcp --dport 443 -j DROP
done < ip_proxy.txt

iptables-save

Il sito target (ovvero quello che contiene la lista dei proxy da bloccare) è http://spys.ru/free-proxy-list/IT/, il quale effettua un filtraggio dei client che possono accedervi utilizzando lo User Agent come discriminante (quindi non è possibile scaricarne il contenuto se non si effettua uno spoofing di tale parametro tramite wget e l’opzione –user-agent).

Inoltre, poichè il contenuto del sito non è una “lista piatta” di IP pubblici, è stato necessario filtrare il tutto utilizzando un’espressione regolare in grado di individuare i 4 ottetti tipici dell’IPv4.

Step 3: consentire gli spider dei motori di ricerca

Come ultima fase, occorre consentire gli IP degli spider, utilizzando tale scrip (permit_spider.sh):

#!/bin/bash

while read line
do
    iptables -I INPUT -s $line -p tcp --dport 80 -j ACCEPT -m comment --comment "crawler"
done < ip_spider.txt

iptables-save

Il contenuto del file ip_spider.txt potete ricavarlo da qui (Google), qui (Yahoo!) e qui (Bing ed altri).

A configurazione completata, possiamo saggiare il carico sul server (intento a droppare il traffico proveniente dalla botnet) utilizzando htop.

Se la macchina regge e le risorse hardware locali non sono allo stremo potremo finalmente dire di aver vinto.

Alla prossima.

FTP in modalità passiva e netfilter su CentOS 6

In questo post ho spiegato qual è la differenza tra la modalità attiva e quella passiva (PASV) del servizio FTP.

Per fare in modo che la modalità passiva possa funzionare correttamente su Centos 6 è necessario configurare il firewall (netfilter) in modo appropriato, garantendo il supporto dello stateful inspection.

 

iptables,ipchains,conntrack,ftp,modalità attiva,modalità passiva,pasv

Per fare ciò occorre inserire questa regola all’interno del file di configurazione di netfilter, ovvero /etc/sysconfig/iptables (dove iptables non è altro che la CLI di netfilter):

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

A questo punto si dovrà abilitare un particolare modulo di netfilter (affinchè possa tenere correttamente traccia delle sessioni FTP attive) ovvero ip_conntrack_ftp, editando il file /etc/sysconfig/iptables-save:

IPTABLES_MODULES="ip_conntrack_ftp"

Restartiamo il servizio di firewalling mediante il comando:

[root@sever ~]# service iptables restart

ed abbiamo finito.

A presto.

Apache virtual host su IP pubblico dedicato

Scenario

Un virtual host di Apache che deve essere accessibile solo da determinati indirizzi IP pubblici.

Problema

Sulla macchina sono presenti anche altri virtual host “pubblici”.

Soluzione

Mettere in bind il virtual host in oggetto su un indirizzo IP pubblico dedicato e successivamente creare delle regole ad hoc mediante Iptables.

 

apache,virtual host,httpd,bind,virtual interface,dedicated public ip,private access,logging,syslogd,iptables,rc.local

Per prima cosa occorre creare un’interfaccia virtuale da associare all’indirizzo IP pubblico dedicato. Su CentOS tale operazione è piuttosto banale e consta dei seguenti passi:

1) Creo il file contenente i parametri dell’interfaccia all’interno della directory /etc/sysconfig/network-scrips/:

[root@server network-scrips]# sudo nano ifcfg-eth0:0

il cui contenuto dovrà essere simile al seguente:

 DEVICE=eth0:0
 ONBOOT=yes
 HWADDR=
 IPADDR=<indirizzo IP pubblico>
 NETMASK=<netmask>
 BROADCAST=<indirizzo di broadcast>
 GATEWAY=<indirizzo del default gw>
 NETWORK=
 TYPE=Ethernet

2) Attivo l’interfaccia virtuale e mi sincero che sia effettivamente operativa:

[root@server network-scrips]# ifup eth0:0

[root@server network-scrips]# ifconfig

il cui output dovrebbe essere simile al seguente:

eth0:0    Link encap:Ethernet  HWaddr <mac address>
           inet addr:<indirizzo IP>  Bcast:<indirizzo di broadcast>  Mask:<netmask>
           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
           Interrupt:169 Memory:fb5e0000-fb600000

Successivamente creo la configurazione del virtual host all’interno della directory /etc/httpd/vhosts.d/:

[root@server vhosts.d]# nano privatevhost.conf

il cui contenuto dovrà essere:

Listen <ip pubblico assegnato all'interfaccia virtuale>:80
NameVirtualHost <ip pubblico assegnato all'interfaccia virtuale>:80

<VirtualHost <ip pubblico assegnato all'interfaccia virtuale:80>
  ServerName privatevhost.dominio.com
  ServerAlias privatevhost.dominio.com

  DocumentRoot /var/www/virtual/privatevhost.dominio.com/htdocs

  ErrorLog /var/www/virtual/privatevhost.dominio.com/logs/error.log
  CustomLog /var/www/virtual/privatevhost.dominio.com/logs/access.log combined
  #ServerSignature Off

  Redirect 404 /favicon.ico

  <Location /favicon.ico>
   ErrorDocument 404 "No favicon"
  </Location>

</VirtualHost>

Lancio un reload della configurazione di Apache per rendere effettive le suddette modifiche:

[root@server vhosts.d]# service httpd reload

A questo punto posso procedere con la creazione dei filtri di accesso mediante iptables:

iptables -F
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

iptables -A INPUT -s <IP sorgente consentito>/32 -d <IP pubblico assegnato all'interfaccia virtuale>/32 -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -s <IP sorgente consentito>/32 -d <IP pubblico assegnato all'interfaccia virtuale>/32 -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -s <IP sorgente consentito>/32 -d <IP pubblico assegnato all'interfaccia virtuale>/32 -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -s <IP sorgente consentito>/32 -d <IP pubblico assegnato all'interfaccia virtuale>/32 -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -d <IP pubblico assegnato all'interfaccia virtuale>/32 -j LOG  --log-prefix "Private Area Access Attempt:" --log-level 4
iptables -A INPUT -d <IP pubblico assegnato all'interfaccia virtuale>/32 -p ICMP -j ACCEPT
iptables -A INPUT -d <IP pubblico assegnato all'interfaccia virtuale>/32 -j DROP

exit 0

In soldoni, ho prima consentito l’accesso via Web al suddetto virtual host solo a determinati indirizzi IP pubblici. Successivamente ho impostato una regola per il logging dei tentativi di accesso non autorizzati, consentendo solo il traffico ICMP (aka ping) proveniente da qualunque indirizzo sorgente (per questione di praticità durante le eventuali operazioni di diagnostica).

Infine ho droppato tutto il traffico diretto all’interfaccia virtuale che non rispetta nessuna delle regole definite in precedenza.

Copio le suddette regole all’interno del file /etc/rc.local per renderle attive anche dopo eventuali reboot della macchina e facciamo alcuni test per verificare che tutto funzioni correttamente (tentativo di accesso via Browser al virtual host, prima da indirizzo IP consentito e successivamente da indirizzo IP non consentito).

Inoltre, per loggare i tentativi di accesso non autorizzati, occorre modificare la configurazione del file syslog.conf, aggiungendo la seguente entry all’inizio del file in questione:

kern.warning                                    /var/log/iptables.log

Infine, lancio un restart del demone di logging:

[root@server vhosts.d]# service syslog restart

E’ tutto, alla prossima.

Redirect del traffico in uscita mediante iptables

Iptables, ovvero l’interfaccia a linea di comando del celeberrimo firewall Netfilter, consente di fare dei veri e propri giochi di prestigio.

Ad esempio, potrebbe succedere che, per ragioni di sicurezza, un dato server Web non sia in ascolto sulla classica porta TCP 80, ma su una porta non standard (ad esempio la 9876). Supponiamo, inoltre, che a tale sito debbano accedere gli sviluppatori, che, di volta in volta dovranno forgiare opportune URL con l’estensione :9876.

netfilter.jpg

Per semplicifare loro la vita si può agire direttamente sul firewall/router, facendo un semplice redirect del traffico in uscita diretto alla porta 80 del server Web. Ecco la regola:

iptables -t nat -A OUTPUT -p tcp -d ipserverweb –dport 80 -j DNAT –to-destination ipserverweb:9876
Ovviamente potete lavorare anche di file hosts, aggiungendo dei record A statici che vi possano aiutare a creare le regole più facilmente, senza doversi obbligatoriamente ricordare gli indirizzi IP coinvolti a memoria.
In quest’ultimo caso la suddetta regola diverrebbe:
iptables -t nat -A OUTPUT -p tcp -d miodominio.com --dport 80 -j DNAT --to-destination miodominio.com:9876
Semplice, vero?
A presto.

WI-FI IP camera (made in China) ed il traffico di rete “anomalo”

Che io sia paranoico è risaputo, soprattutto se mi ritrovo ad aver a che fare con hardware made in China. Diciamo anche che nella mia rete tendo a tenere sotto controllo tutto il traffico, sia in entrata che in uscita.

Per farla breve, ho installato questa IP camera WI-FI ed ho iniziato a monitorare, mediante Iptables, tutto il traffico in uscita. Ecco uno stralcio del file di log:

Dec 10 14:04:25 nightbox kernel: [3094903.376462] HTTP direct traffic: IN=eth1 OUT=eth0 SRC=10.1.x.x DST=58.61.155.158 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=41186 DF PROTO=TCP SPT=3755 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0
Dec 10 14:10:39 nightbox kernel: [3095278.163044] HTTP direct traffic: IN=eth1 OUT=eth0 SRC=10.1.x.x DST=58.61.155.158 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=20423 DF PROTO=TCP SPT=4005 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0
Dec 10 14:10:42 nightbox kernel: [3095281.160190] HTTP direct traffic: IN=eth1 OUT=eth0 SRC=10.1.x.x DST=58.61.155.158 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=20424 DF PROTO=TCP SPT=4005 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0
Dec 10 14:16:40 nightbox kernel: [3095639.086794] HTTP direct traffic: IN=eth1 OUT=eth0 SRC=10.1.x.x DST=58.61.155.158 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=26618 DF PROTO=TCP SPT=4724 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0
Dec 10 14:16:43 nightbox kernel: [3095642.083772] HTTP direct traffic: IN=eth1 OUT=eth0 SRC=10.1.x.x DST=58.61.155.158 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=26619 DF PROTO=TCP SPT=4724 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0

In soldoni, ogni 6 minuti (per un certo lasso di tempo), il giocattolino in questione provava a contattare l’IP 58.61.155.158 sulla porta 80. Per far cosa, poi?

Per capirci qualcosa in più ho deciso di effettuare una query DNS inversa mediante il comando host:

nightfly@nightbox:~$ host 58.61.155.158
Host 158.155.61.58.in-addr.arpa. not found: 3(NXDOMAIN)

Uhm, not found, brutto segno. Quindi ho eseguito un whois:

nightfly@nightbox:~$ whois 58.61.155.158
% [whois.apnic.net node-4]
% Whois data copyright terms    http://www.apnic.net/db/dbcopyright.html

inetnum:        58.61.155.152 - 58.61.155.167
netname:        shenzhenshirongdaxinxijishuyoux
descr:          shenzhenshilonggangqubujizhenbaolinglonggangdianxinfenjuIDCjifang¡£
country:        CN
admin-c:        SZ-AP
tech-c:         IC83-AP
mnt-by:         MAINT-CHINANET-GD
changed:        gdtel_ipreg@163.com 20100108
status:         Allocated non-portable
source:         APNIC

person:         SHENZHEN WANJIAN
address:        Communication Bldg, No.48 Yi Tian Rd., Futian Shenzhen, China
country:        CN
phone:          +86-755-28812000
e-mail:         ipadm@gddc.com.cn
remarks:        IPMASTER is not for spam complaint,please send spam complaint to abuse@gddc.com.cn
nic-hdl:        SZ-AP
mnt-by:         MAINT-CHINANET-GD
changed:        CHENYIQ@GSTA.COM 20080328
source:         APNIC

person:         IPMASTER CHINANET-GD
nic-hdl:        IC83-AP
e-mail:         ipadm@189.cn
address:        NO.1,RO.DONGYUANHENG,YUEXIUNAN,GUANGZHOU
phone:          +86-20-83877223
fax-no:         +86-20-83877223
country:        CN
changed:        ipadm@189.cn 20110418
mnt-by:         MAINT-CHINANET-GD
remarks:        IPMASTER is not for spam complaint,please send spam complaint to abuse_gdnoc@189.cn
abuse-mailbox:  abuse_gdnoc@189.cn
source:         APNIC

Ok, in realtà stava contattando un server cinese. Un portscan stealth mi ha restituito questo output:

nightfly@nightbox:/etc/apache2$ sudo nmap -sS 58.61.155.158

Starting Nmap 5.00 ( http://nmap.org ) at 2012-12-09 20:48 CET
Interesting ports on 58.61.155.158:
Not shown: 992 filtered ports
PORT     STATE  SERVICE
21/tcp   closed ftp
25/tcp   closed smtp
53/tcp   open   domain
80/tcp   open   http
110/tcp  closed pop3
1433/tcp closed ms-sql-s
5631/tcp open   pcanywheredata
8888/tcp open   sun-answerbook

Check veloce sulla porta 80, su cui gira una pagina in ASP (ecco lo screenshot):

ipcamera.png

Quale account non esiste? La pagina di configurazione dell’aggeggio non ha nessun form di registrazione, quindi di cosa stiamo parlando?

Altro check, stavolta sulla 8888:

ipcamera2.png

Porta differente, ma identico risultato.

I fantastici costruttori cinesi hanno pensato bene di mettere in ascolto quel server su due differenti porte, poichè spesso e volentieri la porta 80 in uscita è filtrata (proxy?).

Per andare ancora più a fondo alla questione ho deciso di usare uno sniffer, ovvero tcpdump:

22:30:16.159916 IP google-public-dns-a.google.com.domain > guest1.mialan.org.3076: 797 1/0/0 A 58.61.155.158 (47)
E..K; ../.5m....
....5...7Z..............www.nwsvr.com..............'..:=..
22:30:16.161941 IP 10.1.x.x.3718 > 58.61.155.158.www: Flags [S], seq 1520784463, win 5840, options [mss 1460,sackOK,TS val 464$
E..<..@.@...
...:=.....PZ.TO...................
.F..........

Non sembrava che venissero inviate informazioni sensibili (aka password di account email ed FTP), ma piuttosto sembrava del semplice polling.

Qualcosa di utile tcpdump però l’ha fatto, ovvero mi ha rilevato l’hostname dell’IP 58.61.155.158, ovvero www.nwsvr.com, il cui whois è il seguente:

Registrant:
  Organization   : shenzhenshi hui yan shi xun dian zi you xian gong si
  Name           : LuoYingchun
  Address        : 6 northern zone,shangxuekejicheng, shenzhen ,china
  City           : shenshi
  Province/State : guangdongsheng
  Country        : china
  Postal Code    : 518000

Administrative Contact:
  Name           : LuoYingchun
  Organization   : Luo yingchun
  Address        : 6 northern zone,shangxuekejicheng, shenzhen ,china
  City           : shenzhen
  Province/State : Guangdong
  Country        : CN
  Postal Code    : 518000
  Phone Number   : 86-755-26988288
  Fax            : 86-755-26988233
  Email          : robbi_luo@163.com

Technical Contact:
  Name           : LuoYingchun
  Organization   : Luo yingchun
  Address        : 6 northern zone,shangxuekejicheng, shenzhen ,china
  City           : shenzhen
  Province/State : Guangdong
  Country        : CN
  Postal Code    : 518000
  Phone Number   : 86--83333333
  Fax            : 86--83333333
  Email          : robbi_luo@163.com

Billing Contact:
  Name           : LuoYingchun
  Organization   : Luo yingchun
  Address        : 6 northern zone,shangxuekejicheng, shenzhen ,china
  City           : shenzhen
  Province/State : Guangdong
  Country        : CN
  Postal Code    : 518000
  Phone Number   : 86--83333333
  Fax            : 86--83333333
  Email          : robbi_luo@163.com

Alla fine ho scoperto che si trattava di un servizio di DDNS. Ho spulciato le configurazioni dell’IP camera e mi sono ritrovato questo settaggio abilitato (di default):

 

ipcamera3.png

Ovvero, l’aggeggino non faceva altro che tentare di comunicare al server (cinese) l’indirizzo IP pubblico della mia WAN. E con la privacy come la mettiamo?

Ho tolto la spunta ed il traffico “anomalo” ha cessato di esistere.

Alla prossima.

100 sfumature di NAT

Si, avete ragione, il titolo è “leggermente” riciclato, ma se l’ho scelto avrò i miei buoni motivi. Uno su tutti è il fatto che qualunque dispositivo di rete in grado di operare con il NAT implementa una propria logica e lo usa come meglio crede. Vi sembro esagerato? Provate a leggere la continuazione di questo post ed alla fine non potrete che essere d’accordo con me.

 

nat.gif

Cos’è il NAT e perchè viene usato?

L’acronimo NAT sta per Network Address Translation e consente di tradurre un determinato indirizzo IP in un’altro. Tale tecnologia è stata introdotta poichè i classici indirizzi IP pubblici a 32 bit (leggasi IPv4) iniziavano a scarseggiare, ragion per cui si è deciso di fare in modo che i PC di una LAN (con spazio di indirizzamento privato, ovvero 10.0.0.0/8, 172.16.0.0/12 e 192.168.0.0/16) potessero “presentarsi” su Internet utilizzando uno o più indirizzi IP pubblici.

Il NAT è sufficiente?

Bhè, forse il NAT puro è stato sufficiente per i primi tempi, ma dopo un po’ ha cominciato a presentare qualche punto debole, soprattutto quando viene usato per tradurre indirizzi IP privati in pubblici. Infatti, se nella LAN sono presenti N PC con N indirizzi IP privati, sono necessari altrettanti indirizzi IP pubblici (NAT pool) per consentire loro di navigare su Internet contemporaneamente. Che fregatura, vero? Bene, per sopperire a tale limitazione si è scelto di implementare una tecnologia simile al NAT (poichè anche questa effettua una traduzione da privato in pubblico), ma, per certi versi, più performante, ovvero il PAT. Il PAT viene detto anche IP Maquerading (poichè consente di nascodenre l’IP privato dietro l’IP pubblico), NAT Overloading o IP overloading e vi assicuro che ciascun produttore di network device potrebbe utilizzare a piacere uno qualunque di questi appellativi, dunque tenete bene a mente tali sinonimi.

Cos’è il PAT?

Il termine PAT sta per Port Address Translation. A differenza del NAT non effettua una traduzione uno a uno (static NAT) o uno a molti (dynamic NAT, ovvero un indirizzo IP privato può essere mappato su uno degli N indirizzi IP pubblici del pool, a seconda della loro disponibilità) ma è in grado di tradurre più indirizzi IP privati in un unico indirizzo IP pubblico. La logica che segue è molto semplice: per ogni richiesta proveniente da un PC della LAN memorizza non solo l’IP sorgente, ma anche la porta sorgente. Ad esempio:

192.168.3.1:1025

viene tradotto in:

98.53.21.3:1025

dove 98.53.21.3 è l’IP pubblico utilizzato dai PC della LAN per uscire su Internet, mentre 1025 è la porta usata per inizializzare la connessione verso l’esterno.

Queste informazioni vengono inserite e mantenute (per un lasso di tempo variabile ma comunque limitato), all’interno di un’apposita tabella, detta appunto NAT table.

Nell’ambito dei sistemi *nix che fungono da firewall/router è possibile implementare il PAT mediante un semplice comando, ovvero:

#PAT

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Il MASQUERADE finale indica che stiamo utilizzando il PAT (aka IP Masquerading).

Inoltre, stiamo appendendo una regola (-A) alla chain POSTROUTING che fa riferimento alla tabella nat (-t nat).

Il PAT è supportato (ovviamente) anche dai router casalinghi di casa Cisco (in particolare la serie 800).

Per implementarlo è neccessario utilizzare le seguenti direttive:

Router# conf t
Router(config)# int dia0
Router(config-if)# ip nat outside
Router(config-if)# exit
Router(config)# int e0
Router(config-if)# ip nat outside
Router(config)# ip nat inside source list 1 interface Dialer0 overload

Stiamo semplicemente dicendo al router che l’interfaccia e0 è quella “affacciata” alla nostra LAN, mentre l’interfaccia Dia0 (virtuale), è quella a cui è associato il nostro IP pubblico. Con l’ultimo comando, infine, stiamo imponendo la traduzione degli IP della LAN nell’indirizzo pubblico (la keyword overload cosa vi ricorda? IP o NAT overloading, ovvero il PAT).

Quanti tipi di NAT esistono?

La risposta è un po’ lapidaria: molteplici. Infatti, il NAT generalmente viene suddiviso in due macro tipologie: source NAT e destination NAT. Nel primo caso è l’IP privato ad essere tradotto in IP pubblico, nel secondo caso accade il contrario. Il destination NAT viene utilizzato quando volete mettere in ascolto su Internet un PC della vostra LAN (alcuni router casalinghi chiamano tale operazione port forwarding o port mapping, altri ancora la chiamano virtual server).

Vediamo quali sono i comandi per implementare il destination NAT mediante iptables:

iptables -t nat -A PREROUTING -p tcp --dport 4711 -i eth0 -j DNAT --to 10.0.0.4

Come si implementa il destination NAT sui router Cisco serie 800? Semplice, basta usare il seguente comando:

Router(config)#ip nat inside source static tcp <indirizzo locale PC> 22 interface Dialer0 22

In particolare, stiamo nattando l’indirizzo locale del PC su cui è in ascolto un demone SSH sulla porta 22 dell’IP pubblico assegnato alla Dialer0. In soldoni, ciò significa che tutti i tentativi di connessioni provenienti da Internet e diretti al nostro indirizzo IP pubblico sulla porta 22, verranno “inoltrati” al PC della LAN su cui è in ascolto il demone SSH.

Per ragioni di sicurezza, potremmo modificare la porta pubblica su cui metterci in ascolto, utilizzando ad esempio la 2244 (non standard):

Router(config)# ip nat inside source static tcp <indirizzo locale PC> 22 interface Dialer0 2244

Quindi, chiunque si volesse connettere sulla porta 2244 del nostro IP pubblico, verrà “girato” sulla porta 22 del PC locale.

In questo caso parliamo di NAPT (Network And Port Translation).

Infine, è bene notare che abbiamo a che fare con lo static NAT, in quanto all’indirizzo IP pubblico viene associato staticamente l’IP locale del PC che funge da server SSH.

Oltre al source ed al destination NAT esiste anche il cosiddetto double NAT. Esso viene utilizzato nell’ambito delle VPN site-to-site, in grado cioè di interconnettere in modo sicuro due LAN dislocate in punti geografici differenti. Inoltre, affinchè si renda necessario l’uso del double NAT è indispensabile che entrambe le LAN utilizzino lo stesso spazio di indirizzamento privato. Infatti, non è possibile ruotare i pacchetti tra due LAN che usano la medesima classe di indirizzi IP privati, quindi per evitare che si effettui una rimappatura di tali indirizzi si utilizza il double NAT.

Ma il NAT/PAT serve solo per la traduzione di IP privati in pubblici?

No. Il NAT può tornare utile anche quando si vuole consetire ad un PC della LAN di accedere ad un server che sta in DMZ. Infatti, per default, le security appliance rendono impossibile la comunicazione tra la zona Interna e la DMZ, quindi, l’unico modo per riuscire a fare ciò è creare una entry NAT con relativa regola di firewalling.

E’ possibile visualizzare il contenuto delle tabelle NAT?

Certo che si. Per i sistemi *nix occorre installare un pacchetto apposito, ovvero netstat-nat:

nightfly@nightbox:~$ sudo apt-get install netstat-nat

e poi lanciare il comando sudo netstat-nat il cui output sarà simile al seguente:

Proto NATed Address                  Destination Address            State

tcp   nightflyvaio.*.*:8373   mil01s16-in-f23.1e100.ne:https ESTABLISHED
tcp   nightflyvaio.*.*:8440   mil01s17-in-f9.1e100.net:https ESTABLISHED
tcp   nightflyvaio.*.*:6033   78.141.*.*:12350            ESTABLISHED
tcp   nightflyvaio.*.*:8370   muc03s02-in-f17.1e100.ne:https ESTABLISHED
tcp   nightflyvaio.*.*:6349   pop.tiscali.it:imaps           ESTABLISHED
tcp   nightflyvaio.*.*:8372   muc03s02-in-f24.1e100.ne:https ESTABLISHED

Per i router Cisco serie 800, invece, è sufficiente utilizzare il comando:

Router# sh ip nat translations

il cui output sarà simile a:

Pro Inside global         Inside local          Outside local         Outside global

tcp 79.55.117.*:6881    192.168.*.*:6881      ---                   ---
tcp 79.55.117.*:6882    192.168.*.*:6882      ---                   ---
udp 79.55.117.*:52121   192.168.*.*:52121     208.67.222.222:53     208.67.222.222:53
udp 79.55.117.*:30171   192.168.*.*:30171     208.67.220.220:53     208.67.220.220:53
udp 79.55.117.*:58847   192.168.*.*:58847     208.67.220.220:53     208.67.220.220:53
tcp 79.55.117.*:6882    192.168.*.*:6882      151.62.35.107:54700   151.62.35.107:54700

Nei prossimi post (tempo permettendo) parlerò delle tecniche di NAT traversal.

A presto.

Controllare lo stato di iptables mediante Nagios

Recentemente su uno dei miei server ho lanciato il comando:

nightfly@nightbox:~$ sudo iptables -L

e con mio enorme disappunto mi sono accorto che le regole di firewalling che il server avrebbe dovuto caricare all’avvio erano praticamente assenti (eccezion fatta per fail2ban), indi per cui ho deciso di monitorare lo stato di iptables mediante Nagios.

iptables.jpg

Lo scrip che ho utilizzato per i check potete scaricarlo da qui. Inoltre, poichè tale scrip è piuttosto bacato, ho deciso di apportare qualche piccola correzione. Di seguito la versione originale dello scrip:

#!/bin/bash

PARAM1=$1
TABLE=$2
MINRULES=$3
PARAM4=$4
LOG=/var/log/iptables/iptables.log
CHKIPTBLS=`/sbin/iptables -n -t filter -L |wc -l`

#
# Parameter Validation
##

if [ "$PARAM1" != "-T" -o "$TABLE" == "" -o "$MINRULES" != "-r" -o "$PARAM4" == "" ]; then
        echo "Usage: $0 -T <table> -r <min rules>"
        echo ""
        exit 3
                # Nagios exit code 3 = status UNKNOWN = orange

if [ "$PARAM1" == "-h" ]; then
        echo ""
        echo "         -h = Display's this Help"
        echo "         -T = Table to check"
        echo "                 Available Tables:"
        echo "                    nat"
        echo "                    mangle"
        echo "                    filter"       
        echo "         -r = Minimun quantity of rules"
        echo ""
        # Nagios exit code 3 = status UNKNOWN = orange
                exit 3
   fi
fi

##
#    DO NOT MODIFY ANYTHING BELOW THIS
##

$CHKIPTBLS >/dev/null 2>/dev/null

if [ "$CHKIPTBLS" == 0 ]; then
    TOTRULES=$CHKIPTBLS
else
    TOTRULES=$[$CHKIPTBLS-8]
fi

if [ "$TOTRULES" -gt "$PARAM4" ]; then
                    echo "OK - Iptables are OK the table $TABLE has $TOTRULES rules configured"
                    # Nagios exit code 0 = status OK = green
                    exit 0
else
                    echo " CRITICAL - Iptables are CRITICAL the table $TABLE has $TOTRULES rules configured"
                    for i in `w  -h | cut -f1 -d" " | sort | uniq`
                    do

                        echo "`date '+%d/%m/%Y - %H:%M:%S'` - CRITICAL - $i is logged in and there are only $TOTRULES loaded" >> $LOG
                    done
                    # Nagios exit code 2 = status CRITICAL = red
                    exit 2               
fi

Punto primo: la seconda condizione dell’if non ha praticamente senso, in quanto la prima è sempre verificata.
E’ bastato invertire le due condizioni e trattarle separatamente:

#
# Parameter Validation
##

if [ "$PARAM1" == "-h" ]; then
        echo ""
        echo "          -h = Display's this Help"
        echo "          -T = Table to check"
        echo "          Available Tables:"
        echo "          nat"
        echo "          mangle"
        echo "          filter"
        echo "          -r = Minimun quantity of rules"
        echo ""
        # Nagios exit code 3 = status UNKNOWN = orange
        exit 3
fi

if [ "$PARAM1" != "-T" -o "$TABLE" == "" -o "$MINRULES" != "-r" -o "$PARAM4" ==                                                                                         "" ]; then
        echo "Usage: $0 -T <table> -r <min rules>"
        echo ""
        exit 3
        # Nagios exit code 3 = status UNKNOWN = orange
fi

Punto secondo: la variabile CHKIPTBLS utilizza sempre e comunque la tabella filter, dunque il parametro -T non ha senso di esistere. Possiamo però ovviare a tale mancanza, permettendo all’utente di scegliere su quale tabella (tra filter, mangle e nat) effettuare i controlli, modificando la variabile citata in precedenza nel seguente modo:

CHKIPTBLS=`sudo /sbin/iptables -n -t "$TABLE" -L |wc -l`

Punto terzo: la condizione

if [ "$TOTRULES" -gt "$PARAM4" ]; then

controlla che il numero di regole caricate sia strettamente maggiore di quello definito mediante il parametro -r. Questo però cozza con quanto dichiarato dall’autore dello scrip, ovvero:

OK - The number of Iprules equal o more than the minimun that we setup on the -r variable

Per ovviare a tale errore, occorre sostituire la condizione riportata in precedenza con questa:

if [ "$TOTRULES" -ge "$PARAM4" ]; then

Punto quarto: nagios non ha i permessi per lanciare iptables, ergo dobbiamo effettuare delle modifiche al file /etc/sudoers, inserendo la entry:

nagios   ALL = NOPASSWD: /sbin/iptables

alla fine del file. 

In definitiva, lo scrip per controllare lo stato di iptables dovrà essere il seguente:

#!/bin/bash

PARAM1=$1
TABLE=$2
MINRULES=$3
PARAM4=$4
LOG=/var/log/check_iptables.log
CHKIPTBLS=`sudo /sbin/iptables -n -t "$TABLE" -L |wc -l`

#
# Parameter Validation
##

if [ "$PARAM1" == "-h" ]; then
        echo ""
        echo "          -h = Display's this Help"
        echo "          -T = Table to check"
        echo "          Available Tables:"
        echo "          nat"
        echo "          mangle"
        echo "          filter"
        echo "          -r = Minimun quantity of rules"
        echo ""
        # Nagios exit code 3 = status UNKNOWN = orange
        exit 3
fi

if [ "$PARAM1" != "-T" -o "$TABLE" == "" -o "$MINRULES" != "-r" -o "$PARAM4" == "" ]; then
        echo "Usage: $0 -T <table> -r <min rules>"
        echo ""
        exit 3
        # Nagios exit code 3 = status UNKNOWN = orange
fi

##
#       DO NOT MODIFY ANYTHING BELOW THIS
##

$CHKIPTBLS >/dev/null 2>/dev/null

if [ "$CHKIPTBLS" == 0 ]; then
        TOTRULES=$CHKIPTBLS
else
        TOTRULES=$[$CHKIPTBLS-8]
fi

if [ "$TOTRULES" -ge "$PARAM4" ]; then
                    echo "OK - Iptables is OK The Table $TABLE has $TOTRULES rules configured"
                    # Nagios exit code 0 = status OK = green
                    exit 0
else
                    echo " CRITICAL - Iptables is CRITICAL The Table $TABLE has $TOTRULES rules configured"
                                        for i in `w  -h | cut -f1 -d" " | sort | uniq`
                                        do
                                                echo "`date '+%d/%m/%Y - %H:%M:%S'` - CRITICAL - $i is logged in and there are only $TOTRULES loaded" >> $LOG
                                        done
                    # Nagios exit code 2 = status CRITICAL = red
                    exit 2
fi

Se il file /var/log/check_iptables.log non esiste, dovrete crearlo mediante il comando:

nightfly@nightbox:~$ sudo touch /var/log/check_iptables.log

A questo punto possiamo rinominare lo scrip:

nightfly@nightbox:~$ mv check_iptables_status.sh check_iptables_status

rendondolo successivamente eseguibile:

nightfly@nightbox:~$ chmod +x check_iptables_status

Spostiamolo nella directory /usr/lib/nagios/plugins:

nightfly@nightbox:~$ sudo mv check_iptables_status /usr/lib/nagios/plugins

Creiamo il file iptables.cfg nella directory /etc/nagios-plugins/config:

nightfly@nightbox:/etc/nagios-plugins/config$ sudo nano iptables.cfg

il cui contenuto dovrà essere il seguente:

# 'check_iptables_status' command definition
define command{
        command_name    check_iptables_status
        command_line    /usr/lib/nagios/plugins/check_iptables_status -T '$ARG1$' -r '$ARG2$'
        }

infine aggiungiamo la seguente direttiva al file dell’host su cui vogliamo monitorare lo stato di iptables (tale file è presente nella directory /etc/nagios3/conf.d):

define service{
        use                             generic-service         ; Name of service template to use
        host_name                       localhost
        service_description             iptables
                check_command                   check_iptables_status!filter!84
}

Dove 84 è il numero minimo di regole di firewalling attive.

Infine, riavviamo nagios:

nightfly@nightbox:~$ sudo service nagios3 restart

ed abbiamo finito.

Alla prossima.

PSAD: individuare i port scan diretti ai nostri server

PSAD (Port Scan Attack Detector), è un software utile ed abbastanza robusto, in grado di individuare l’indirizzo IP sorgente di un eventuale attacco port scan lanciato verso i nostri server. Nella fattispecie, in questo post illustrerò come installarlo e configurarlo.

 

psad,nmap,portscan attack,iptables,logging

 

Procediamo dunque con l’installazione del pacchetto citato in precedenza, digitando:

nightfly@nightbox:~$ sudo apt-get install psad

Poichè tale software si basa sui log generati da iptables, è necessario che sul nostro server siano attive le seguenti regole di firewalling:

iptables -A INPUT -j LOG
iptables -A FORWARD -j LOG

Personalmente ho deciso di abilitare tali regole direttamente all’avvio del server, in modo da rendere psad subito operativo. Modifichiamo dunque il file /etc/rc.local:

nightfly@nightbox:~$ sudo nano /etc/rc.local

aggiungendo le entry:

#psad

iptables -A INPUT -j LOG
iptables -A FORWARD -j LOG

Ovviamente, dopo aver installato psad è necessario configurarlo. Per fare ciò dobbiamo aprire in scrittura il file psad.conf, presente nella directory /etc/psad:

nightfly@nightbox:~$ sudo nano /etc/psad/psad.conf

Inseriamo l’indirizzo email a cui verranno inviati gli alert generati da psad:

EMAIL_ADDRESSES             vostro.indirizzo@email.it;

impostiamo correttamente la soglia che fa scattare gli alert (ovvero il numero minimo di porte vittima del port scan):

PORT_RANGE_SCAN_THRESHOLD   3;

e successivamente facciamo in modo che vengano ignorati alcuni indirizzi IP inoffensivi. Per fare ciò occorre modificare il file /etc/psad/auto_dl, inserendo ad esempio queste direttive:

127.0.0.1       0;
193.204.114.232 0;
193.204.114.233 0;
10.0.3.0/24        0;
224.0.0.251     0;

Lo 0 indica il grado più basso di pericolosità associato all’IP, dove per pericolosità si intende un valore intero compreso nell’intervallo [0; 5].

Infine, riavviamo psad:

nightfly@nightbox:~$ sudo service psad restart

ed abbiamo finito.

Da notare che la configurazione trattata in questo post è piuttosto minimale e di tipo passivo, ovvero si limita ad individuare gli attacchi senza bloccarli. Potete però fare in modo che, appena psad riconosce un eventuale attacco, proceda automaticamente con la creazione di una regola iptables per bloccarlo (in questo caso parliamo di configurazione attiva).

A presto.