Monitoritzar els clients amb iptables

De Jose Castillo Aliaga
Ir a la navegación Ir a la búsqueda

Anem a suposar que utilitzem un ordinador o contenidor amb Ubuntu per a fer de porta d'enllaç per a clients d'una LAN. Aquesta porta d'enllaç té configurat els IPtables per fer forward amb nat.

Preparació de l'entorn

Primer de tot, vaig a enumerar els comandaments auxiliars que necessitem per anar comprovant que tot va bé:

# iptables -L -n -v -x

Per veure totes les regles i els comptadors

# iptables -L -t nat

Per a veure totes les regles del nat

# iptables -N CADENA 

Per crear una nova cadena

El que cal fer és crear dos chain o cadenes noves per a les connexions entrats i les d'eixida, connectar-les amb la cadena de FORWARD per a que tot el tràfic que passe a través de la màquina, passe també per les cadenes d'entrada i d'eixida. Després, cal especificar tots els clients i fer una regla per a cadascun.

Amb aquestes premisses creem un script:

#!/bin/bash

iptables -N TRAFFIC_ACCT_IN
iptables -N TRAFFIC_ACCT_OUT
iptables -I FORWARD -i eth0 -j TRAFFIC_ACCT_IN
iptables -I FORWARD -o eth0 -j TRAFFIC_ACCT_OUT
iptables -I FORWARD -i eth2 -j TRAFFIC_ACCT_IN
iptables -I FORWARD -o eth2 -j TRAFFIC_ACCT_OUT
for i in {1..200}; do 
iptables -A TRAFFIC_ACCT_IN --dst 192.168.9.$i; 
iptables -A TRAFFIC_ACCT_OUT --src 192.168.9.$i; 
done
iptables -L -n -v -x

Aquest script prepara el sistema per comptabilitzar el tràfic de cada client.

Aquestes dades són un comptador i és complicat detectar amb un valor immediat el consum instantani o històric dels clients. Cal fer un cron que guarde periòricament les dades en una base de dades rotatòria.

Per fer això, confiarem en RRDTool, que proporciona també una manera de fer gràfics molt eficient i potent.

Aquest comandament prepara l'entorn, crean la base de dades:

$ rrdtool create clients.rrd --start $(date +%s) --step 60 DS:client102in:COUNTER:600:U:U \
DS:client102out:COUNTER:600:U:U RRA:AVERAGE:0.5:1:600 RRA:AVERAGE:0.5:6:700

I cada cert temps:

$ rrdtool update clients.rrd $(date +%s):$(iptables -L TRAFFIC_ACCT_IN -x -v -n | grep '192.168.9.104 ' | \ 
tr -s " " | cut -d" " -f3):$(iptables -L TRAFFIC_ACCT_OUT -x -v -n | grep '192.168.9.104 ' | tr -s " " | \
cut -d" " -f3)

Aquest exemple és sols per un client. Amb aquest script se crea per a tots:

#!/bin/bash
mkdir /var/lib/control_aules
for i in {1..199}; do 
rrdtool create /var/lib/control_aules/client$i.rrd --start $(date +%s) --step 60 \
DS:in:COUNTER:600:U:U DS:out:COUNTER:600:U:U RRA:AVERAGE:0.5:1:360 RRA:AVERAGE:0.5:10:1008; 
done
#cp actualitzar.sh /var/lib/control_aules/
echo "Crea un crontab -e para ejecutar cada minuto actualitzar.sh"

I amb aquest, anomenat actualitzar.sh, anem clavant dades (ha d'estar cada minut en un cron)

#!/bin/bash

ipin=$(/sbin/iptables -L TRAFFIC_ACCT_IN -x -n -v | grep '192.168.' | awk '{ print $8" "$2}')
ipout=$(/sbin/iptables -L TRAFFIC_ACCT_OUT -x -n -v | grep '192.168.' | awk '{ print $2}')

ips=$(paste -d " " <(echo "$ipin") <(echo "$ipout"))

#echo "$ips"
echo "$ips" | while read line
do
read cip cin cout <<< $line
#echo $line $cip $cin $cout
cip=$(echo $cip | cut -d"." -f4)

rrdtool update /var/lib/control_aules/client$cip.rrd $(date +%s):$cin:$cout

rrdtool graph /var/lib/control_aules/spd$cip.png --start -6h --end $(date +%s) \ 
DEF:sin=/var /lib/control_aules/client$cip.rrd:in:AVERAGE LINE2:sin\#FF0000:"in" \ 
DEF:sout=/var/lib/control_aules/client$cip.rrd:out:AVERAGE LINE2:sout\#00FF00:"out"

done

args=""
while read ip
do
ip=$(echo $ip | cut -d"." -f4)
color=$(($ip*80000))
color=$(printf "%06X\n" $color)
[[ $ip -lt 200 ]] && args=$args" DEF:sin$ip=/var/lib/control_aules/client$ip.rrd:in:AVERAGE \
LINE1:sin$ip#$color:\"192.168.x.$ip\""
done < /tmp/ips
rrdtool graph /var/lib/control_aules/total.png --start -6h --end $(date +%s) $args

Amb ixò tenim una imatge per a cada client, sols cal fer una web que les mostre.

Resultat en la terminal de les IPtables:

root@gw:~ # iptables -L -x -v -n
Chain INPUT (policy ACCEPT 2518 packets, 3506441 bytes)
    pkts      bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 1763 packets, 148429 bytes)
    pkts      bytes target     prot opt in     out     source               destination   
root@gw:~ # ./scriptiptables.sh
Chain INPUT (policy DROP 12379 packets, 1997510 bytes)
    pkts      bytes target     prot opt in     out     source               destination         
   46059  5331656 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
       6      360 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22
       0        0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8000
       0        0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:3000
      14      840 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80
    1414    84720 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:443

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination         
   31377  3960158 TRAFFIC_ACCT_OUT  all  --  *      eth2    0.0.0.0/0            0.0.0.0/0           
   22324 23647451 TRAFFIC_ACCT_IN  all  --  eth2   *       0.0.0.0/0            0.0.0.0/0           
 9140306 911473308 TRAFFIC_ACCT_OUT  all  --  *      eth0    0.0.0.0/0            0.0.0.0/0           
10015277 18261036886 TRAFFIC_ACCT_IN  all  --  eth0   *       0.0.0.0/0            0.0.0.0/0           
10051316 18329598636 ACCEPT     all  --  eth0   eth1    0.0.0.0/0            0.0.0.0/0           
 9175803 914415878 ACCEPT     all  --  eth1   eth0    0.0.0.0/0            0.0.0.0/0           
   22324 23647451 ACCEPT     all  --  eth2   eth1    0.0.0.0/0            0.0.0.0/0           
   31377  3960158 ACCEPT     all  --  eth1   eth2    0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT 30953 packets, 7171093 bytes)
    pkts      bytes target     prot opt in     out     source               destination         

Chain TRAFFIC_ACCT_IN (2 references)
    pkts      bytes target     prot opt in     out     source               destination         
       0        0            all  --  *      *       0.0.0.0/0            192.168.9.1         
       0        0            all  --  *      *       0.0.0.0/0            192.168.9.2         
       0        0            all  --  *      *       0.0.0.0/0            192.168.9.3         
       0        0            all  --  *      *       0.0.0.0/0            192.168.9.4         
       0        0            all  --  *      *       0.0.0.0/0            192.168.9.5         
       0        0            all  --  *      *       0.0.0.0/0            192.168.9.6         
       0        0            all  --  *      *       0.0.0.0/0            192.168.9.7         
       0        0            all  --  *      *       0.0.0.0/0            192.168.9.8         
       0        0            all  --  *      *       0.0.0.0/0            192.168.9.9         
     782   540552            all  --  *      *       0.0.0.0/0            192.168.9.10        
   70995 111303403            all  --  *      *       0.0.0.0/0            192.168.9.11        
   58504 135692413            all  --  *      *       0.0.0.0/0            192.168.9.12        
       0        0            all  --  *      *       0.0.0.0/0            192.168.9.13        
[...]

Chain TRAFFIC_ACCT_OUT (2 references)
    pkts      bytes target     prot opt in     out     source               destination         
       0        0            all  --  *      *       192.168.9.1          0.0.0.0/0           
       0        0            all  --  *      *       192.168.9.2          0.0.0.0/0           
       0        0            all  --  *      *       192.168.9.3          0.0.0.0/0           
       0        0            all  --  *      *       192.168.9.4          0.0.0.0/0           
       0        0            all  --  *      *       192.168.9.5          0.0.0.0/0           
       0        0            all  --  *      *       192.168.9.6          0.0.0.0/0           
       0        0            all  --  *      *       192.168.9.7          0.0.0.0/0           
       0        0            all  --  *      *       192.168.9.8          0.0.0.0/0           
       0        0            all  --  *      *       192.168.9.9          0.0.0.0/0           
     899   108097            all  --  *      *       192.168.9.10         0.0.0.0/0           
   53371  3267207            all  --  *      *       192.168.9.11         0.0.0.0/0           
   57092  4362316            all  --  *      *       192.168.9.12         0.0.0.0/0           
       0        0            all  --  *      *       192.168.9.13         0.0.0.0/0           
     240    20312            all  --  *      *       192.168.9.14         0.0.0.0/0           
     240    11217            all  --  *      *       192.168.9.15         0.0.0.0/0           
       0        0            all  --  *      *       192.168.9.16         0.0.0.0/0           
    2416   181280            all  --  *      *       192.168.9.17         0.0.0.0/0          
[...]


Amb això ja tenim un mètode per a comptabilitzar tots els paquets i bytes que entren o eixen per tots els clients de la xarxa.

Enllaços

http://blog.osusnet.com/2009/11/10/monitorizando-aplicaciones-web-con-rrdtool/

https://userlinux.net/437_rrdtool.html

http://oss.oetiker.ch/rrdtool/tut/rrdtutorial.en.html

Control Aula