Ens trobem que l’ADSL d’un client no dóna a coll i tota l’empresa es queixa de la lentitud de la connexió.
La sortida és a través de dues línies ADSL i el tallafocs reparteix el trànsit segons tipus: consultes DNS, HTTP i HTTPS per una, la resta per l’altre. A la LAN hi ha varis servidors (web, correu, vpn, terminal server…) als quals s’accedeix des de fora.
Com que mesurem el rendiment del tallafocs amb Munin, a les gràfiques de xarxa es veu clarament que es satura la pujada de la primera ADSL (DNS, HTTP, HTTPS), però quina aplicació l’està saturant? Ens cal una gràfica més detallada. Per sort el Shorewall i el Munin ens ho posen fàcil.

Configurant Shorewall

Primer dividirem el trànsit en les categories que volem que apareixin a la gràfica. Per començar, volem tenir visibilitat de l’ample de banda de navegació web dels usuaris, i del consumit per el servidor1 (www) i el servidor2 (correu), que són els que s’hi accedeix per aquesta ADSL.
Al Shorewall farem ús del “Traffic Accounting” que permet definir unes regles i comptar tot el trànsit que hi coincideixi.

Editem /etc/shorewall/accounting i afegim les regles (eth1 és la tarja de la ADSL)

# trànsit de navegació (HTTP i HTTPS)
http_up:COUNT       -       -           eth1         tcp    80
http_down:COUNT     -       eth1        -            tcp    -           80
http_up:COUNT       -       -           eth1         tcp    443
http_down:COUNT     -       eth1        -            tcp    -          443

# trànsit cap al server1
server1_down:COUNT    -   eth1          192.168.1.19 tcp    80
server1_info_up:COUNT -   192.168.1.19  eth1         tcp    -           80

# trànsit cap al server2
server2_down:COUNT  -     eth1          192.168.1.18 tcp    -
server2_up:COUNT    -     192.168.1.18  eth1         tcp    -

comprovem la configuració

[root@fw1 ~]# shorewall check

i l’apliquem

[root@fw1 ~]# shorewall restart

ara podem consultar el volum de dades de cada regla

[root@fw1 ~]# shorewall -x show accounting
Chain accounting (3 references)
    pkts      bytes target     prot opt in     out     source               destination        
    3451   141931 http_up    tcp  --  *      eth1    0.0.0.0/0            0.0.0.0/0           multiport dports 80
 4284168 5869787661 http_down  tcp  --  eth1   *       0.0.0.0/0            0.0.0.0/0           multiport sports 80
  955172 387608054 http_up    tcp  --  *      eth1    0.0.0.0/0            0.0.0.0/0           multiport dports 443
  963938 547990542 http_down  tcp  --  eth1   *       0.0.0.0/0            0.0.0.0/0           multiport sports 443
(...)

Configurant Munin

Ja tenim les dades. Ara cal un plugin de Munin que les reculli per fer-ne una gràfica. Nosaltres hem descarregat aquest plugin i hem fet una petita modificació per a que el trànsit de pujada (tot el que el nom acabi en “_up”) apareixi en negatiu, sota l’eix X de la gràfica.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#!/usr/bin/python
# shorewall_accounting
# A munin plugin for tracking traffic as recorded by shorewall accounting rules
# Written by Chris AtLee <chris@atlee.ca>
# Released under the GPL v2
import sys, commands, re
accountingLineExp = re.compile(r"^\s*\d+\s+(\d+)\s+(\w+).*$")
negativeValueExp = re.compile(r".*_up$")

def getBytesByChain():
    status, output = commands.getstatusoutput("shorewall -x show accounting")
    if status != 0:
        raise OSError("Error running command (%s)[%i]: %s" % (trafficCmd, status, output))
    chains = {}
    for line in output.split("\n"):
        m = accountingLineExp.match(line)
        if m is not None:
            target = m.group(2)
            bytes = int(m.group(1))
            if target in chains:
                chains[target] += bytes
            else:
                chains[target] = bytes
    retval = []
    chainNames = chains.keys()
    chainNames.sort()
    for name in chainNames:
        mm = negativeValueExp.match(name)
        if mm is not None:
            value = chains[name] * -1
        else:
            value = chains[name]
        retval.append((name, value))
    return retval

if len(sys.argv) > 1:
    if sys.argv[1] == "autoconf":
        print "yes"
        sys.exit(0)
    elif sys.argv[1] == "config":
        print "graph_title Shorewall accounting"
        print "graph_category network"
        print "graph_vlabel bits per ${graph_period}"
        for chain,bytes in getBytesByChain():
            neg_val = negativeValueExp.match(chain)
            if neg_val is not None:
                print "%s.max 0" % chain
            else:
                print "%s.min 0" % chain
            print "%s.type DERIVE" % chain
            print "%s.label %s" % (chain, chain)
            print "%s.cdef %s,8,*" % (chain, chain)
        sys.exit(0)

for chain, bytes in getBytesByChain():
    print "%s.value %i" % (chain, bytes)

Ho posem al directori de plugins del Munin (/usr/share/munin/plugins/shorewall_accounting) i l’activem

[root@fw1 ~]# ln -s /usr/share/munin/plugins/shorewall_accounting /etc/munin/plugins/shorewall_accounting

Per a accedir a l’iptables calen permisos de root, configurem el plugin a /etc/munin/plugin-conf.d/shorewall_accounting

[shorewall_accounting]
user root

reiniciem el munin-node i comprovem que tot funcioni

[root@fw1 ~]# /etc/init.d/munin-node restart
[root@fw1 ~]# munin-run shorewall_accounting

Finalment amb la gràfica que se’ns genera podem veure el consum d’ample de banda de cada categoria:
shorewall accounting