Category Archives: Networking

Configurazione di un bonding tra due schede di rete

In questo articolo vedremo come configurare il link aggregation (Bonding) di due schede di rete in Debian, utile per creare connessioni ridondate ed aumentare il throughput del nostro server.

Il software di cui abbiamo bisogno è “ifenslave”, che serve per attivare o disattivare il bonding tra le due schede.

Un bonding device si comporterà come una normale interfaccia ethernet, ma invierà i pacchetti attraverso le interfacce secondarie (slaves) attraverso uno scheduler round-robin. Questo permette un load-balancing, del tutto simile alle tecniche Channel Bonding o Trunking usati negli switch.

Nel nostro esempio abbiamo due interfacce di rete:

202.54.1.1 (eth0)
192.168.1.254 (eth1)

Installiamo ifenslave:

apt-get install ifenslave-2.6

Creiamo ora un file chiamato /etc/modprobe.d/bonding.conf:

vim /etc/modprobe.d/bonding.conf

e vi inseriamo:

alias bond0 bonding
options bonding mode=0 arp_interval=100 arp_ip_target=192.168.1.254, 192.168.1.12

Salviamo e chiudiamo il file. Questa configurazione è molto importante in quanto sarà usata dal driver del Kernel di Linux chiamato “bonding”. Le opzioni sopra inserite sono:

  • mode=0: Dice al driver di usare lo scheduler balance-rr, che sarebbe il round robin. Questo è la modalità di default.
  • arp_interval=100: è l’intervallo (in millisecondi) per il controllo l’arp monitoring. Senza questo parametro all’avvio riceverete molti warning.
  • arp_ip_target=192.168.1.254, 192.168.1.12: usa l’interfaccia collegata al router (192.168.1.254) e l’IP 192.168.1.2 per effettuare l’arp monitoring quando l’arp_interval > 0. Questo è usato per determinare la salute dei nostri link. Possiamo inserire più indirizzi IP, delimitati da una virgola. Dobbiamo inserire chiaramente almeno un indirizzo IP.

A questo momento carichiamo il driver:

modprobe bonding

Controlliamo che l’interfaccia virtuale sia stata creata:

ifconfig bond0

Ora fermiamo le due interfacce preconfigurate:

/etc/init.d/networking stop

Mofifichiamo il file di configurazione della rete di debian:

cp /etc/network/interfaces /etc/network/interfaces.bak
vim /etc/network/interfaces

Eliminiamo le entry eth0 ed eth1 che al momento non servono più ed inseriamo la entry relativa al bonding:

# The primary network interface
auto bond0
iface bond0 inet static
address 192.168.1.10
netmask 255.255.255.0
network 192.168.1.0
gateway 192.168.1.254
slaves eth0 eth1
# jumbo frame support
mtu 9000
# Load balancing and fault tolerance
bond-mode balance-rr
bond-miimon 100
bond-downdelay 200
bond-updelay 200

Salviamo e chiudiamo.

Un po’ di spiegazione su quest’ultima entry:

  • address 192.168.1.10: indirizzo IP di bond0
  • netmask 255.255.255.0: netmask di bond0
  • network 192.168.1.0: network di bond0
  • gateway 192.168.1.254: default gateway di bond0
  • slaves eth0 eth1: specifichiamo le interfacce reali dove fare il bonding
  • mtu 9000: settiamo l’MTU a 9000
  • bond-mode balance-rr: settiamo il bonding come “Load balancing and fault tolerance”
  • bond-miimon 100: settiamo il link monitoring a 100 millisecondi
  • bond-downdelay 200: ritardo massimo di un link prima di essere dichiarato “failed”
  • bond-updelay 200: ritardo massimo di un link prima di essere dichiarato “up”

A questo punto effettuiamo un restart della rete:

/etc/init.d/networking restart

Controlliamo che tutto sia andato bene:

ifconfig

Dovremmo avere qualcosa simile a:

bond0 Link encap:Ethernet HWaddr 00:xx:yy:zz:tt:31
inet addr:192.168.1.10 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::208:9bff:fec4:3031/64 Scope:Link
UP BROADCAST RUNNING MASTER MULTICAST MTU:9000 Metric:1
RX packets:2414 errors:0 dropped:0 overruns:0 frame:0
TX packets:1559 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:206515 (201.6 KiB) TX bytes:480259 (469.0 KiB)
eth0 Link encap:Ethernet HWaddr 00:xx:yy:zz:tt:31
UP BROADCAST RUNNING SLAVE MULTICAST MTU:9000 Metric:1
RX packets:1214 errors:0 dropped:0 overruns:0 frame:0
TX packets:782 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:103318 (100.8 KiB) TX bytes:251419 (245.5 KiB)
Memory:fe9e0000-fea00000
eth1 Link encap:Ethernet HWaddr 00:xx:yy:zz:tt:31
UP BROADCAST RUNNING SLAVE MULTICAST MTU:9000 Metric:1
RX packets:1200 errors:0 dropped:0 overruns:0 frame:0
TX packets:777 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:103197 (100.7 KiB) TX bytes:228840 (223.4 KiB)
Memory:feae0000-feb00000
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:560 (560.0 B) TX bytes:560 (560.0 B)

Per controllare lo status del bonding possiamo digitare:

cat /proc/net/bonding/bond0

Dovremmo avere qualcosa simile a:

Ethernet Channel Bonding Driver: v3.5.0 (November 4, 2008)
Bonding Mode: load balancing (round-robin)
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 200
Down Delay (ms): 200
Slave Interface: eth0
MII Status: up
Link Failure Count: 0
Permanent HW addr: 00:xx:yy:zz:tt:31
Slave Interface: eth1
MII Status: up
Link Failure Count: 0
Permanent HW addr: 00:xx:yy:zz:tt:30

Se un link aggregation non è andato a buon fine avremo:

cat /proc/net/bonding/bond0

 

Ethernet Channel Bonding Driver: v3.5.0 (November 4, 2008)
Bonding Mode: load balancing (round-robin)
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 200
Down Delay (ms): 200
Slave Interface: eth0
MII Status: up
Link Failure Count: 0
Permanent HW addr: 00:xx:yy:zz:tt:31
Slave Interface: eth1
MII Status: down
Link Failure Count: 1
Permanent HW addr: 00:xx:yy:zz:tt:30

Vi ricordo che anche il file /var/log/messages contiene importanti informazioni sullo stato del bonding:

Sep 5 04:20:21 nas01 kernel: [ 6517.492974] e1000e: eth1 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX/TX
Sep 5 04:20:21 nas01 kernel: [ 6517.548029] bonding: bond0: link status up for interface eth1, enabling it in 200 ms.
Sep 5 04:20:21 nas01 kernel: [ 6517.748016] bonding: bond0: link status definitely up for interface eth1.

Sep 5 04:16:15 nas01 kernel: [ 6271.468218] e1000e: eth1 NIC Link is Down
Sep 5 04:16:15 nas01 kernel: [ 6271.548027] bonding: bond0: link status down for interface eth1, disabling it in 200 ms.
Sep 5 04:16:15 nas01 kernel: [ 6271.748018] bonding: bond0: link status definitely down for interface eth1, disabling it

Politiche di link aggregation del bonding di Linux

  • balance-rr or 0: Politica di round robin. I pacchetti sono inviati in sequenza dal primo slave disponibile fino all’ultimo. Questa modalità supporta il load balancing ed il fault tollerance.
  • active-backup or 1: Politica di backup attivo. Solo uno slave nel bond è attivo, Un altro slave diventa attivo soltanto se il primo fallisce. Questa modalità supporta il fault tollerance.
  • balance-xor or 2: secondo altre fonti la policy di default è [(source MAC address XOR’d with destination MAC address) modulo slave count]. Fornisce load balancing e fault tollerance
  • broadcast or 3: Trasmette tutto il traffico a tutti gli slave
  • 802.3ad or 4: Crea gruppi di aggregazione che condividono la stessa velocità e duplex. Utilizza gli slave attivi secondo lo standard 802.3ad. Molti switch avranno bisogno di configurazioni avanzate per utilizzare 802.3ad.
  • balance-tlb or 5: Il traffico in uscita è instradato secondo il carico sulle singole interfacce di rete. Il traffico in entrata è ricevuto dallo slave corrente. Se lo slave ricevente fallisce, un altro slave diventerà automaticamente ricevente prendendo il suo mac address.
  • balance-alb or 6: include il balance-tlb ed in più effettua il load balancing in entrata tramite l’arp negotiation.

Come prevenire i bruteforce con Iptabes

Ci sono vari modi per bannare un ip che sta effettuando un attacco di bruteforce al server SSH sul nostro server. Vediamo come fare con Iptables.

Il modo è molto semplice, anche se non è utilizzato da molti, in quanto anche il software fail2ban offre questa feature insieme alle altre. Le regole da inserire sono tre ed utilizzeremo un modulo di Iptables chiamato RECENT, che offre la possibilità di marcare i pacchetti a seconda della frequenza con il quale vengono mandati.

Vediamo l’esempio, e consideriamo che l’interfaccia utilizzata sia eth0

Inizialmente dico ad Iptables di creare un database chiamato SSH degli IP che tentano di connettersi alla porta 22 (server SSH):

iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH

Dopodiché loggo tutti gli IP che effettuano 3 nuove connessioni in meno di 300 secondi:

iptables -A INPUT -m recent --update --seconds 300 --hitcount 3 --name SSH -j LOG --log-level info --log-prefix "SSH SCAN blocked: "

Infine blocco gli IP

iptables  -A INPUT -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP

Una volta che saranno passati i 300 secondi dovrò rimuovere il ban dagli IP:

iptables -A INPUT   -m recent --name SSH --remove

Quello che ho ottenuto è un ban automatico di 300 secondi di un IP che sbaglia 2 volte la password. Se si utilizzano le chiavi SSH è perfetto. Per vedere gli IP che vengono bloccati, essi saranno loggati in /var/log/syslog. Il database degli ip creato da Iptables si trova in /proc/net/ipt_recent/.

Ecco il mio in questo momento:

maradona:/home/luca# cat /proc/net/ipt_recent/SSH
src=66.96.207.19 ttl: 53 last_seen: 1574688771 oldest_pkt: 17 1574675627, 1574676051, 1574676051, 1574676070, 1574676070, 1574676070, 1574676899, 1574676899, 1574677663, 1574677663, 1574677663, 1574678595, 1574678595, 1574681987, 1574681987, 1574688771, 1574688771, 1574675452, 1574675452, 1574675627
src=121.184.33.56 ttl: 45 last_seen: 1523900419 oldest_pkt: 1 1523900419
src=59.30.218.148 ttl: 46 last_seen: 1550603547 oldest_pkt: 1 1550603547
src=122.70.150.106 ttl: 112 last_seen: 1561734410 oldest_pkt: 1 1561734410
src=218.108.0.91 ttl: 112 last_seen: 1580437381 oldest_pkt: 1 1580437381
src=61.236.182.11 ttl: 52 last_seen: 1584381984 oldest_pkt: 4 1584379536, 1584379536, 1584381984, 1584381984, 1584377172, 1584377172, 1584377242, 1584377242, 1584377394, 1584377394, 1584377700, 1584377700, 1584377922, 1584377922, 1584377922, 1584378312, 1584378312, 1584379421, 1584379421, 1584379421
src=195.228.135.138 ttl: 112 last_seen: 1525774504 oldest_pkt: 1 1525774504
src=64.120.26.34 ttl: 52 last_seen: 1548030041 oldest_pkt: 10 1548007267, 1548007267, 1548007583, 1548007583, 1548014434, 1548014434, 1548015069, 1548015069, 1548030041, 1548030041, 1548001891, 1548001968, 1548001968, 1548002398, 1548002398, 1548002398, 1548003683, 1548003683, 1548003840, 1548003840
src=38.108.125.101 ttl: 55 last_seen: 1551424865 oldest_pkt: 1 1551424865
src=85.114.140.73 ttl: 118 last_seen: 1594716674 oldest_pkt: 1 1594716674
src=59.1.90.140 ttl: 46 last_seen: 1550619212 oldest_pkt: 1 1550619212
src=174.36.85.36 ttl: 119 last_seen: 1551527977 oldest_pkt: 1 1551527977
src=211.202.2.107 ttl: 49 last_seen: 1552508574 oldest_pkt: 10 1552476845, 1552476845, 1552478775, 1552478775, 1552483035, 1552483035, 1552491546, 1552491546, 1552508574, 1552508574, 1552475052, 1552475052, 1552475346, 1552475346, 1552475346, 1552475586, 1552475586, 1552476649, 1552476649, 1552476845
src=64.120.26.58 ttl: 52 last_seen: 1589438178 oldest_pkt: 10 1589425634, 1589426141, 1589426141, 1589426141, 1589427426, 1589427426, 1589431010, 1589431010, 1589438178, 1589438178, 1589424066, 1589424066, 1589424290, 1589424290, 1589424641, 1589424641, 1589424641, 1589424738, 1589424738, 1589425634
src=93.93.129.125 ttl: 54 last_seen: 1601942176 oldest_pkt: 19 1601925043, 1601925313, 1601925313, 1601925572, 1601925572, 1601925572, 1601925857, 1601925857, 1601926945, 1601926945, 1601927078, 1601927078, 1601927078, 1601929122, 1601929122, 1601933473, 1601933473, 1601942176, 1601942176, 1601925043
src=112.161.94.145 ttl: 46 last_seen: 1577293804 oldest_pkt: 1 1577293804
src=62.128.149.44 ttl: 50 last_seen: 1562069800 oldest_pkt: 2 1562069208, 1562069800
src=125.138.59.232 ttl: 46 last_seen: 1586717876 oldest_pkt: 1 1586717876
src=14.37.84.210 ttl: 46 last_seen: 1549261247 oldest_pkt: 1 1549261247
src=178.162.239.192 ttl: 54 last_seen: 1593634277 oldest_pkt: 10 1593616610, 1593616610, 1593616805, 1593616805, 1593619302, 1593619302, 1593624293, 1593624293, 1593634277, 1593634277, 1593614621, 1593614621, 1593614934, 1593614934, 1593615110, 1593615110, 1593615110, 1593615557, 1593615557, 1593616610
src=60.190.216.90 ttl: 50 last_seen: 1549489599 oldest_pkt: 0 1549486840, 1549486840, 1549487023, 1549487023, 1549487392, 1549487392, 1549487510, 1549487510, 1549487510, 1549488127, 1549488127, 1549489010, 1549489010, 1549489010, 1549489599, 1549489599, 1549492543, 1549492543, 1549498431, 1549498431
src=112.220.100.226 ttl: 43 last_seen: 1563702466 oldest_pkt: 10 1563673299, 1563673299, 1563674914, 1563674914, 1563678850, 1563678850, 1563686722, 1563686722, 1563702466, 1563702466, 1563671471, 1563671471, 1563671799, 1563671799, 1563671799, 1563671963, 1563671963, 1563672946, 1563672946, 1563673299
src=109.168.123.134 ttl: 120 last_seen: 1571008152 oldest_pkt: 1 1571008152
src=31.210.72.73 ttl: 50 last_seen: 1590914007 oldest_pkt: 9 1590893785, 1590894295, 1590894295, 1590897111, 1590897111, 1590902743, 1590902743, 1590914007, 1590914007, 1590891831, 1590891831, 1590892183, 1590892183, 1590892285, 1590892285, 1590892285, 1590892887, 1590892887, 1590893785, 1590893785
src=109.230.232.145 ttl: 55 last_seen: 1592528351 oldest_pkt: 1 1592528351
src=58.68.174.76 ttl: 54 last_seen: 1520319496 oldest_pkt: 10 1520303368, 1520303369, 1520303369, 1520303369, 1520305672, 1520305672, 1520310280, 1520310280, 1520319496, 1520319496, 1520301352, 1520301352, 1520301640, 1520301640, 1520301869, 1520301869, 1520301869, 1520302216, 1520302216, 1520303368
src=218.108.85.240 ttl: 112 last_seen: 1578974064 oldest_pkt: 1 1578974064
src=95.250.59.247 ttl: 49 last_seen: 1515911697 oldest_pkt: 1 1515911697
src=81.56.117.225 ttl: 47 last_seen: 1562139443 oldest_pkt: 15 1562137225, 1562137303, 1562137303, 1562137303, 1562137911, 1562137911, 1562137955, 1562137955, 1562138784, 1562138784, 1562138784, 1562139351, 1562139351, 1562139443, 1562139443, 1562136857, 1562136857, 1562137199, 1562137199, 1562137225
src=41.139.66.52 ttl: 50 last_seen: 1573686109 oldest_pkt: 1 1573686109
src=109.70.149.42 ttl: 55 last_seen: 1558340790 oldest_pkt: 10 1558325333, 1558325425, 1558325425, 1558325425, 1558327542, 1558327542, 1558331958, 1558331958, 1558340790, 1558340790, 1558323402, 1558323402, 1558323678, 1558323678, 1558323926, 1558323926, 1558323926, 1558324230, 1558324230, 1558325333
src=61.232.11.146 ttl: 115 last_seen: 1590588858 oldest_pkt: 1 1590588858

Tutorial: Limitare il traffico dei proxy con TC ed Iptables

Opensource LogoQualche giorno fa ho dovuto far fronte ad un problema di sovraccarico di rete di alcuni server per un provider americano che eroga servizi di anonimato. Nello specifico, proxy e VPN. Ho dovuto quindi stendere un piccolo script per poter fare un po’ di traffic shaping. Ecco come l’ho creato.

Ambiente e servizi

Prima di tutto ho dato un’occhiata al traffico e al modo in cui la macchina eroga i servizi.

Il carico di rete alto proveniva essenzialmente dai proxy, che vengono usati per fare spidering dei siti internet. Si parla quindi di una grande mole di connessioni simultanee da parte dello stesso IP.

I proxy venivano anche usati per effettuare il download di files o lo streaming di flussi video. Ho provato poi a configurare un account nella mia macchina per controllare il numero medio di connessioni simultanee per un utilizzo standard del servizio ed ho visto che tocca punte di 40 connessioni (posta, browsing, ed altre piccole cose), mentre alcuni IP arrivavano anche a 500-600 connessioni.
Il proxy è in ascolto in porta 80.
Per una maggiore usabilità ho chiaramente dovuto escludere dei servizi dal sistema di shaping, come SSH, lasciandoli “liberi di correre”.

Ho deciso quindi di utilizzare un semplice traffic shaping avvalendomi di 2 tools molto potenti: TC e Iptables, che mi hanno consentito di creare una catena dinamica delle connessioni e dei rispettivi limiti di banda.

Ecco come funziona:

  • La banda viene limitata secondo le possibilità fisiche: se il provider ti offre un limite 10mbit di banda, pena un sovrapprezzo per megabyte, dovremo accuratamente settare la quantità di banda consentita
  • Le prime 50 connessioni simultanee vengono accodate a priorità 1 a massima velocità
  • Dalla connessione 51, le connessioni vengono accodate in una catena a banda limitata
  • I files vengono scaricati a piena velocità da 0 a 9.99Mbyte, da 10Mbyte a 49.99 Mbyte vengono accodati in una coda limitata, e da 50Mbyte in poi, in una coda ancor più limitata.
  • Possibilità di utilizzare solo una parte della banda totale, utilizzando i parametri “DESIRED” e “DEFAULT”

Vediamo un po’ come implementare questa soluzione:

Prima di tutto creo una sezione per la configurazione delle variabili che utilizzerà lo script:

# Configuration part:
# $IPT binary
IPT=/sbin/iptables
# Tc binary
TC=/sbin/tc
# Physical interface - no virtual interfaces allowed ($ETH:0, $ETH:1 etc)
ETH=eth0
# SSH server port - we accept all connections in order to bypass the shaper
SSH_PORT=131
# Total bw rate
TOTAL_BW=10mbit
# Bandwidth peak - Please set it a little lower than your real preference
PEAK_BW=10mbit
# Desired Bandwidth Rate - Useful if you want to use less bw of your real capacity
DESIRED_BW=9mbit
# Desired peak - Same as above
DESIRED_PEAK=10mbit
# Jail rate - Set it quite lower if you want real results
JAIL_BW=512mbit
# Jail peak - Same as above
JAIL_PEAK=1mbit
# Default Bandwidth
# Set: 1 for Total values
#      2 for Desired values
DEFAULT_BW=2
# Connection Limit - Note that we talk about symultaneous connections. A good value is 10
CONNLIMIT=30
# Set first size limit
FIRST_SIZE=10485760
# Set the total available bandwidth for the first size limit
FIRST_SIZE_BW=1mbit
# Set the total available peak for the first size limit
FIRST_SIZE_PEAK=1mbit
# Set second size limit
SECOND_SIZE=52428800
# Set the total available bandwidth for the second size limit
SECOND_SIZE_BW=512kbit
# Set the total available peak for the second size limit
FIRST_SIZE_BW_PEAK=512kbit
# End of configuration file

Dopodiché creo lo script vero e proprio:

Prima di tutto faccio un flush della tavola di mangle (che serve per il mark dei pacchetti) e della catena di OUTPUT – che è l’unica che utilizzerò -:

# Flush all queues
$TC qdisc del dev $ETH root
# Flush mangle chains
$IPT -t mangle -F
$IPT -t mangle -Z
$IPT -t mangle -X
$IPT -F OUTPUT

A questo punto posso creare la qdisc, con le relative classi:

# Creating New TC queue
$TC qdisc add dev $ETH root handle 1: htb default $DEFAULT_BW
$TC class add dev $ETH parent 1: classid 1:1 htb rate $TOTAL_BW ceil $PEAK_BW
$TC class add dev $ETH parent 1:1 classid 1:2 htb rate $DESIRED_BW ceil $DESIRED_PEAK
$TC class add dev $ETH parent 1:1 classid 1:3 htb rate $JAIL_BW ceil $JAIL_PEAK
$TC class add dev $ETH parent 1:1 classid 1:4 htb rate $FIRST_SIZE_BW ceil $FIRST_SIZE_PEAK
$TC class add dev $ETH parent 1:1 classid 1:5 htb rate $SECOND_SIZE_BW ceil $FIRST_SIZE_BW_PEAK

Poi aggancio le classi al device principale:
# Adding the queue lists to the main device
$TC qdisc add dev $ETH parent 1:2 sfq
$TC qdisc add dev $ETH parent 1:3 sfq
$TC qdisc add dev $ETH parent 1:4 sfq
$TC qdisc add dev $ETH parent 1:5 sfq

Dico a TC di effettuare il traffic shaping secondo il mark dei pacchetti di Iptables:

# Adding filter by packet mark
$TC filter add dev $ETH parent 1:0 protocol ip prio 1 handle 7 fw flowid 1:3
$TC filter add dev $ETH parent 1:0 protocol ip prio 1 handle 20 fw flowid 1:4
$TC filter add dev $ETH parent 1:0 protocol ip prio 1 handle 21 fw flowid 1:5

Ed infine creo le regole di MARK su Iptables e il canale preferenziale per SSH:

# Setting packet connmarks:
$IPT -A PREROUTING -t mangle -j CONNMARK --restore-mark
$IPT -A POSTROUTING -t mangle -m mark ! --mark 0 -j ACCEPT
$IPT -A POSTROUTING -t mangle -p tcp  -m connlimit --connlimit-above $CONNLIMIT -j MARK --set-mark 7
$IPT -A POSTROUTING -t mangle -j CONNMARK --save-mark
# Setting file size mark
$IPT -A OUTPUT -p tcp --sport $SSH_PORT -j ACCEPT
$IPT -A OUTPUT -p tcp -o $ETH -m connbytes --connbytes $SECOND_SIZE: --connbytes-dir both  --connbytes-mode bytes -j MARK --set-mark 21
$IPT -A OUTPUT -p tcp -o $ETH -m connbytes --connbytes $FIRST_SIZE:$SECOND_SIZE --connbytes-dir both  --connbytes-mode bytes -j MARK --set-mark 20
$IPT -A OUTPUT -p tcp  -m connlimit --connlimit-above $CONNLIMIT -j MARK --set-mark 7

Conclusione

Non sono sicuro al 100% che questo script sia stato steso in maniera perfetta, certo è che funziona abbastanza bene. I carichi sui suddetti server sono spariti e la navigazione con i proxy è fluida e veloce, nonostante ora venga utilizzato solamente circa un terzo della banda.

Come limitare il tempo o il volume dati con freeradius: Rlm_sqlcounter

Eccovi semplice un how-to che vi consentirà di abilitare le limitazione di traffico e di tempo su freeradius in pochi passi utilizzando Rlm_sqlcounter.

In un vecchio post ho parlato di come installare e configurare Coovachilli su Ubuntu, e utilizzarlo con un’autenticazione Radius basata su Mysql. Oggi vi mostrerò come  limitare gli account in base al volume di traffico e al tempo.

Lo strumento che andremo ad utilzzare è Rlm_sqlcounter.

Rlm_sqlcounter è un plugin per Freeradius che, tramite una query sql, restituisce il volume di tempo o di traffico rimanente nell’autenticazione mediante l’utilizzo di attributi radius specifici. In caso il tempo o il traffico siano terminati, l’autenticazione non andrà a buon fine.

Vi ricordo che l’autenticazione dovrà essere fatta tassativamente tramite mysql.

Gli attributi che verranno utilizzati sono:

Max-All-Session - Per quanto riguarda il volume di tempo (in secondi)
Max-All-MB - Per quanto riguarda il volume di traffico (in bytes)

L’implementazione è semplice. Le più moderne distribuzioni pacchettizzate (Debian, Ubuntu, Centos) già prevedono la possibilità di attivare il plugin. Pertanto quello che dovrete fare è:

Attivare il plugin nel file di configurazione principale di freeradius:

vim /etc/freeradius/radiusd.conf
oppure
vim /etc/raddb/radiusd.conf

e decommentare la seguente riga:

$INCLUDE ${confdir}/sqlcounter.conf

Dopodiché aprite – o create in caso non esistesse – il file sqlcounter.conf e aggiungete queste righe:

vim /etc/freeradius/sqlcounter.conf
oppure
vim /etc/raddb/sqlcounter.conf

e aggiungete queste righe:

sqlcounter noresetcounter {
counter-name = Max-All-Session-Time
check-name = Max-All-Session
sqlmod-inst = sql
key = User-Name
reset = never
query = "SELECT SUM(AcctSessionTime) FROM radacct WHERE UserName='%{%k}'"

}

sqlcounter octetslimit {
counter-name = Max-All-MB
check-name = Max-All-MB
reply-name = Chillispot-Max-Total-Octets
key = User-Name
reset = never
query = "SELECT SUM(acctinputoctets+acctoutputoctets) from radacct WHERE UserName='%{%k}'"
sqlmod-inst = sql
}

Infine andate ad attivare il count del traffico e del tempo:

vim /etc/freeradius/sites-available/default
oppure
vim /etc/raddb/sites-available/default

e in fondo alla sezione authorize aggiungete:

authorize {
...
...
...

noresetcounter
octetslimit
}

riavviate freeradius

/etc/init.d/freeradius restart
oppure
/etc/init.d/radiusd restart

A questo punto il vostro server dovrebbe essere apposto. Quello che resta da fare è provare a limitare un utente. Eccovi qualche esempio di utilizzo:

– L’utente test0001 ha un volume complessivo di tempo di 15 MegaBytes (l’utente può effettuare il login quante volte lo ritiene necessario, ma può essere online per una quantitaà totale di traffico di 15 MegaBytes, ovvero 165675008 bytes). La query da inserire sarà:

INSERT into radcheck VALUES ('','test0001','Max-All-MB','165675008',':=');

Fintanto che l’utente avrà a disposizione del tempo, l’autenticazione andrà a buon fine utilizzando la propria password:

[root@kingston raddb]#  radtest test0001 test 10.100.0.1 0 passwordradius
Sending Access-Request of id 228 to 10.100.0.1 port 1812
User-Name = "test0001"
User-Password = "test"
NAS-IP-Address = 173.255.219.122
NAS-Port = 0
rad_recv: Access-Accept packet from host 10.100.0.1 port 1812, id=132, length=20
ChilliSpot-Max-Total-Octets = 165675008
[root@kingston raddb]#

Una volta che il tempo si sarà esaurito, il radius non autenticherà l’utente:

[root@kingston raddb]#  radtest test0001 test 10.100.0.1 0 passwordradius
Sending Access-Request of id 228 to 10.100.0.1 port 1812
User-Name = "test0001"
User-Password = "test"
NAS-IP-Address = 173.255.219.122
NAS-Port = 0
rad_recv: Access-Reject packet from host 10.100.0.1 port 1812, id=228, length=68
Reply-Message = "Your maximum never usage time has been reached"
[root@kingston raddb]#

Lo stesso comportamento succede per quanto riguarda l’attributo Max-All-Session.

Se avete problemi con con il funzionamento vi ricordo che si può attivare il debug in foreground arrestando il demone:

/etc/init.d/freeradius stop

oppure

/etc/init.d/radiusd stop

ed avviando la modalità debug:

freeradius -XXX

oppure

radiusd -XXX

oppure potete consultare i log che si trovano in:

/var/log/freeradius

oppure

/var/log/radius/

Happy Hacking!

Creazione di Un Hotspot Wifi con Coova-chilli e scheda Atheros

Avete a disposizione un PC con una scheda Wifi Atheros e volete installare un hotspot con autenticazione username/password? Fatelo con Ubuntu Linux!

Sono stato contattato per un progetto dedicato all’installazione di un sistema di hotspot Wifi scalabile basato su autenticazione username/password, con sistema di registrazione online.

Per iniziare a sviluppare la rete, ho dovuto crearmi una situazione simile a casa. Ho utilizzato il mio hardware a disposizione, e la mia connessione casalinga. Vale a dire, un Netbook Samsung N130 – con scheda Wifi Atheros AR9285 – e la mia ADSL. Per quanto riguarda il software, invece, mi sono servito dei seguenti programmi e tools:

  • Ubuntu come distribuzione Linux
  • Hostapd come programma di gestione dell’access point
  • Coova-chilli come sistema di accesso alla rete
  • Freeradius come sistema di autenticazione
  • MySQL come sistema di account
  • Apache come web server

Eccovi qui un how-to su come configuare correttamente i seguenti programmi per avere un sistema di hotspot funzionante.

Software necessario
Per prima cosa, naturalmente, dobbiamo avere un server Linux funzionante e connesso ad Internet. ho optato per Ubuntu (e non per la abituale Debian) perché Coova-Chilli ha già il pacchetto precompilato per Ubuntu 10.10. Non dovendo utilizzare una Linux Box come sistema finale (ma degli Open-WRT su router Linksys), ho optato per la comodità.

Aggiorniamo il sistema con:

apt-get update
apt-get upgrade

Installiamo il software:

apt-get install apache2 mysql-server php5 libapache2-mod-php5 freeradius freeradius-mysql dhcp3-server hostapd hostapd-utils libapache2-mod-auth-mysql ssl-cert

cd /tmp
wget http://ap.coova.org/chilli/coova-chilli_1.2.6_i386.deb
dpkg -i coova-chilli_1.2.6_i386.deb

Oltre a questo, abbiamo bisogno di un pacchetto chiamato haserl. Lo possiamo trovare qui. Una volta scaricato dobbiamo installare il compilatore GCC – se ancora non lo abbiamo nella macchina – e compilare il programma:

apt-get install gcc
tar xvf haserl-*.tar.gz
cd haserl-*/
./configure
make
make install

Configurazioni Preliminari
Una volta installato tutto il software necessario, passiamo alla configurazione dei servizi. La prima cosa da fare è la configurazione della rete e dell’access point. Assumiamo che l’accesso ad Internet sia fornito su interfaccia eth0 e l’IP dal DHCP. Andiamo quindi a modificare il file /etc/network/interfaces come segue:

vim /etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

auto wlan0

Abilitiamo il port-forwarding:

echo 1 > /proc/sys/net/ipv4/ip_forward
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf

Configurazione di Hostapd e Dhcp-server
Configuriamo hostapd:

vim /etc/hostapd/hostapd.conf
interface=wlan0
driver=nl80211
ssid=HotSpot
channel=6
ieee8021x=0

Dopodiché configuriamo il server dhcpd:

vim /etc/dhcp3/dhcpd.conf

e aggiungiamo:

subnet 10.0.1.0 netmask 255.255.255.0
{
range 10.0.1.100 10.0.1.200;
option subnet-mask 255.255.255.0;
option broadcast-address 10.0.1.255;
option domain-name-servers 8.8.8.8,8.8.4.4;
option routers 10.0.1.1;
}

infine abilitiamo il server dhcpd per l’interfaccia virtuale tun0, che è quella che Coova-Chilli abiliterà e utilizzerà automaticamente.

vim /etc/default/dhcp3-server
INTERFACES="tun0"

Riavviamo il server dhcp:

/etc/init.d/dhcp-server restart

e testiamo la configurazione avviando il demone in foreground:

hostapd /etc/hostapd/hostapd.conf

Se siamo in grado di collegarci correttamente punto di accesso appena creato e riceviamo l’IP dal dhcp, chioudiamo il programma con Ctrl+C e avviamolo in background con:

/etc/init.d/hostapd start

Configurazione del server radius
Configuriamo ora il server radius per essere usato con un database mysql.
Creiamo il database:

mysql -u root
CREATE DATABASE radius;
quit

Lo popoliamo:

mysql -u root -p radius < /etc/freeradius/sql/mysql/schema.sql
mysql -u root -p radius < /etc/freeradius/sql/mysql/schema.sql
mysql -u root
GRANT ALL PRIVILEGES ON radius.* TO 'radius'@'localhost' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;
quit

Diciamo a freeradius come utilizzare il database:

vim /etc/freeradius/sql.conf
server = "localhost"
login  = "radius"
password = "password"

Settiamo la password per il client di freeradius:

vim /etc/freeradius/clients.conf
client localhost {
ipaddr = 127.0.0.1
secret = radiuspassword
}

Testiamo adesso la corretta configurazione dell’ACL appena creata:

vim /etc/freeradius/users

decommentare le seguenti righe:

"John Doe"     Auth-Type := Local, User-Password == "hello"
Reply-Message = "Hello, %u"

A questo punto comproviamo la corretta inclusione dei file di configurazione avviando freeradius in foregrund:

/etc/init.d/freeradius stop
freeradius -XXX

Se tutto è andato bene, l’ultima linea stampata dovrà terminare con:

Debug: Ready to process requests.

Usciamo di nuovo da freeradius con Ctrl+C e lo avviamo di nuovo in background:

/etc/init.d/freeradius start

Eseguiamo allora una chiamata al radius per l’utente di test “John Doe”

radtest "John Doe" hello 127.0.0.1 0 radiuspassword

Se tutto è andato bene come risposta dovremmo ricevere:

Sending Access-Request of id 136 to 127.0.0.1 port 1812
User-Name = "John Doe"
User-Password = "hello"
NAS-IP-Address = 255.255.255.255
NAS-Port = 0
rad_recv: Access-Accept packet from host 127.0.0.1:1812, id=136, length=37
Reply-Message = "Hello, John Doe"

Se il test sopra ha funzionato, possiamo cambiare il backend di autorizzazione, da “files” a “sql”

vim /etc/freeradius/sites-available/default

e Cambiamo:

files con #files
#sql con sql

Aggiungiamo ora un utente di test al nostro database mysql:

echo "INSERT INTO radcheck (UserName, Attribute, Value) VALUES ('mysqltest', 'Password', 'test');" | mysql -u radius radius

Coova-chilli di default utilizza l’username ‘chillispot’ con password ‘chillispot’ per loggarsi al server radius. Dobbiamo quindi aggiungere anche questo utente nel database mysql:

echo "INSERT INTO radcheck (UserName, Attribute, Value) VALUES ('chillispot', 'Password', 'chillispot');" | mysql -u radius radius

Questa impostazione di trova nel file /etc/chilli/config

HS_ADMUSR=chillispot
HS_ADMPWD=chillispot

Riavviamo freeradius:

/etc/init.d/freeradius restart

Testiamo infine il corretto funzionamento di freeradius con backend mysql:

radtest mysqltest testsecret 127.0.0.1 0 radiuspassword
radtest chillispot chillispot 127.0.0.1 0 radiuspassword

Se tutto è andato bene, dovresti ricevere un output del genere:

Sending Access-Request of id 180 to 127.0.0.1 port 1812
User-Name = "mysqltest"
User-Password = "test"
NAS-IP-Address = 255.255.255.255
NAS-Port = 0
rad_recv: Access-Accept packet from host 127.0.0.1:1812, id=180, length=20

Configurazione di Coova-Chilli
Prima di tutto copiamo la configurazione di default di Coova-Chilli e Apache2:

cp /etc/chilli/defaults /etc/chilli/config
mkdir /var/www/hotspot
cd /var/www/hotspot
cp /etc/chilli/www/* /var/www/hotspot
mkdir /var/www/hotspot/images
cp /var/www/hotspot/coova.jpg /var/www/hotspot/images/
mkdir /var/www/hotspot/uam
cd /var/www/hotspot/uam
wget http://ap.coova.org/uam/
wget http://ap.coova.org/js/chilli.js

Modifichiamo il file index.html per dirgli di utilizzare chilli.js localmente (Coova-Chilli utilizza 10.1.0.1 come IP di esempio, e noi pure):

sed -i 's/ap.coova.org\/js\/chilli.js/10.1.0.1\/uam\/chilli.js/g' /var/www/hotspot/uam/index.html

Modifichiamo il file ChilliLibrary.js per dirgli di utilizzare l’IP corretto:

sed -i 's/192.168.182.1/10.1.0.1/g' /etc/chilli/www/ChilliLibrary.js
sed -i 's/192.168.182.1/10.1.0.1/g' /var/www/hotspot/ChilliLibrary.js

Abilitiamo Coova-Chilli all’avvio del sistema, che è disabilitato di default:

vim /etc/default/chilli
START_CHILLI=1
CONFFILE="/etc/chilli.conf"

e avviamo Coova-Chilli:

/etc/init.d/chilli start

A questo punto, se non si sono presentati errori, dobbiamo modificare la configurazione di Coova-Chilli. Il file di configurazione è /etc/chilli/config. per una configurazione basica basterà cambiare poche variabili:

vim /etc/chilli/config

e modifichiamo:

HS_WANIF=eth0
HS_LANIF=wlan0
HS_UAMSERVER=10.1.0.1

Dobbiamo anche modificare il file /etc/chilli/up.sh, in quanto è presente un bug che non configura correttamente iptables:

vim /etc/chilli/up.sh

E aggiungiamo alla fine del file:

[ -e "/var/run/chilli.iptables" ] && sh /var/run/chilli.iptables 2>/dev/null
iptables -I POSTROUTING -t nat -o $HS_WANIF -j MASQUERADE

Infine, riavviamo Coova-Chilli:

/etc/init.d/chilli restart

Configurazione di Apache2 e SSL
Dobbiamo ora creare una pagina di login. Coova-Chilli ne ha una di default che possiamo utilizzare:

mkdir -p /var/www/hotspot/cgi-bin
zcat -c /usr/share/doc/coova-chilli/hotspotlogin.cgi.gz | sudo tee /var/www/hotspot/cgi-bin/hotspotlogin.cgi
sudo chmod a+x /var/www/hotspot/cgi-bin/hotspotlogin.cgi

Modifichiamo ora lo script di login:

/var/www/hotspot/cgi-bin/hotspotlogin.cgi

e decommentiamo:

$uamsecret = "uamsecret";
$userpassword=1;

Passiamo ora alla configurazione di SSL:
Creiamo i certificati:

mkdir /etc/apache2/ssl
make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/apache2/ssl/apache.pem

Attiviamo SSL:

a2enmod ssl
/etc/init.d/apache2 restart

Creiamo ora un VirtualHost per il nostro hotspot:

vim /etc/apache2/sites-available/hotspot
NameVirtualHost 10.1.0.1:443

ServerAdmin [email protected]
DocumentRoot "/var/www/hotspot"
ServerName "10.1.0.1"

Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all

Alias "/dialupadmin/" "/usr/share/freeradius-dialupadmin/htdocs/"

Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all

ScriptAlias /cgi-bin/ /var/www/hotspot/cgi-bin/

AllowOverride None
Options ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all

ErrorLog /var/log/apache2/hotspot-error.log

LogLevel warn

CustomLog /var/log/apache2/hotspot-access.log combined

ServerSignature On
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/apache.pem

Abilitiamo il nuovo virtualhost:

a2ensite hotspot
/etc/init.d/apache2 reload

A questo punto il vostro hotspot dovrebbe essere funzionante!
Provate ad agganciarvi alla vostra rete Wifi ed aprire qualunque pagina. Dovrebbe apparirvi la pagina di accesso di Coova-Chilli e poi la pagina di login.

Riferimenti