Archivi categoria: Networking

Websockets e Squid Proxy

Ultimamente ho deciso di approfondire una tecnologia Web abbastanza recente, ovvero i Websockets. In particolare, essa consente di instaurare un tunnel di comunicazione client/server attraverso il protocollo HTTP, riducendo notevolmente, rispetto al classico longpolling tipico del linguaggio AJAX, la mole di traffico richiesta e soprattutto l’overhead del server. Mediante i Websockets sarà possibile inviare “gli aggiornamenti” al client “in tempo reale”, ovvero senza che l’utente debba effettuare i classici “refresh” della pagina Web.

In ambito open source esistono diverse implementazioni dei Websockets. Quella che preferisco in assoluto si basa sulla libreria socket.io, integrata ad un applicativo nodejs (quest’ultimo rappresenta una vera e propria rivoluzione poichè ha consentito di utilizzare un linguaggio di programmazione nato per i client, ovvero Javascript, come un vero e proprio linguaggio server-side).

Ora, effettuando alcuni test su un proxy Web (Squid per la precisione), ho notato che i tentativi di connessione verso il server nodejs (sfruttando quindi i Websockets), venivano sistematicamente bloccati.

squid

La spiegazione è molto semplice. Infatti, andando a visualizzare la configurazione di default del suddetto proxy, è possibile notare la presenza di tale parametro:

http_access deny CONNECT !SSL_ports

Tale direttiva impone a Squid di negare l’uso del metodo HTTP CONNECT da parte dei client nel caso in cui non si stia utilizzando il protocollo HTTPS (HTTP + SSL/TLS). Infatti, di per se, il protocollo HTTPS prevede l’instaurazione di un “tunnel” di comunicazione “sicuro” tra client e server, utilizzando, per l’appunto, il metodo CONNECT. Ora, tale metodo viene utilizzato anche dai Websocket per creare il “canale” di comunicazione HTTP con i client, ergo basta commentare la suddetta entry per consentire l’accesso ai client:

#http_access deny CONNECT !SSL_ports

Effettuiamo reload della configurazione di Squid mediante il comando

[root@webProxy ~]# squid -k reconfigure

ed il gioco è fatto.

Alla prossima.

Cisco 877W: configurare una porta ethernet come WAN

Alcuni provider esteri prevedono l’accesso ad Internet tramite connessione diretta (via cavo UTP) tra il router del cliente (CPE – Customer Premise Equipment) ed un loro router di zona. Ciò permette di evitare completamente la vecchia linea POTS (detta anche PSTN), garantendo un servizio sicuramente migliore.

Per quanto riguarda il router Cisco 877W, occorre precisare che con l’IOS fornita di default (ovvero la 870-advsecurityk9-mz.124-24.T4.bin), l’unico modo per connettersi al service provider è mediante l’interfaccia ATM, utilizzando quindi il doppino telefonico. Per questa ragione, affinchè si possa configurare una porta ethernet WAN dedicata, è necessario, in primo luogo, aggiornare l’IOS del dispositivo in oggetto, sostituendo la  870-advsecurityk9-mz.124-24.T4.bin con la c870-advipservicesk9-mz.124-24.T6.bin.

cisco 877

Preparazione del router

Per prima cosa è necessario assegnare al router un indirizzo IP che possa contattare il server SCP (su cui copiare la vecchia IOS come backup e da cui scaricare quella nuova).

Router>
Router#
Router(config)# int vlan 1
Router(config-if)# ip address 192.168.1.9 255.255.255.0
Router(config-if)# end
Router# copy run start

Facciamo un ping al server SCP (per sincerarci che sia effettivamente raggiungibile):

Router# ping 192.168.1.8

Upgrade dell’IOS 

Poichè l’IOS (ovvero il sistema operativo del router) viene salvata all’interno della memoria flash (che comunque è piuttosto limitata in termini di spazio), occorre dapprima cancellare quella di default, rimuovendo anche tutti i file con estensione *.tar ed il file home.shtml (che concorrono a formare l’SDM).

Per prima cosa facciamo un backup della vecchia IOS (nel caso in cui l’operazione di upgrade dovesse non riuscire):

Router# copy flash: scp://user@192.168.1.8:870-advsecurityk9-mz.124-24.T4.bin

cancelliamo i file precedentemente elencati:

Router# delete flash:c870-advsecurityk9-mz.124-24.T4.bin
Router# delete flash:home.tar
Router# delete flash:common.tar
Router# delete flash:sdm.tar
Router# delete flash:home.shtml

e salviamo la nuova immagine nella memoria flash:

Router# copy scp://user@192.168.1.8:c870-advipservicesk9-mz.124-24.T6.bin flash:

A questo punto dobbiamo definire la nuova immagine da caricare al boot:

Router# conf t
Router(config)# boot system flash:c870-advipservicesk9-mz.124-24.T6.bin
Router(config)# end
Router# copy run start
Router# reload

Dopo il riavvio del router dobbiamo appurare che la nuova IOS sia stata effettivamente caricata. Per fare ciò è sufficiente lanciare il comando:

Router# sh ver

Bene, ora che il dispositivo in questione è stato aggiornato correttamente, possiamo procedere con la configurazione dello stesso.

Configurazione

Per prima cosa cancelliamo la nvram (dove è stata salvata la configurazione precedente):

Router# erase nvram:

e successivamente passiamo alla configurazione vera e propria:

no service pad
service timestamps debug datetime msec
service timestamps log datetime msec
service password-encryption
!
hostname RouterADSL
!
boot-start-marker
boot-end-marker
!
logging exception 100000
logging count
logging message-counter syslog
logging queue-limit 10000
logging buffered 150000 notifications
logging console informational
enable secret <secret>
enable password <password>
!
no aaa new-model
clock timezone UTC 2
!
!
dot11 syslog
ip source-route
!
!
ip dhcp excluded-address 192.168.1.1 192.168.1.127
!
ip dhcp pool LAN
   network 192.168.1.0 255.255.255.0
   default-router 192.168.1.1
   dns-server 8.8.8.8 8.8.4.4
   domain-name uniqro.local
!
!
ip cef
ip name-server 8.8.8.8
ip name-server 8.8.4.4
!
multilink bundle-name authenticated
!
vpdn enable
!
vpdn-group 1
 accept-dialin
  protocol pptp
  virtual-template 1

!
!
!
no spanning-tree vlan 2
username admin password <password>
!
!
!
archive
 log config
  hidekeys
!
!
!
!
interface ATM0
 no ip address
 shutdown
 no atm ilmi-keepalive
!
interface FastEthernet0
 switchport access vlan 2
 no cdp enable
!
interface FastEthernet1
!
interface FastEthernet2
!
interface FastEthernet3
!
interface Virtual-Template1
 ip unnumbered Vlan1
 ip nat inside
 ip virtual-reassembly
 peer default ip address pool PPTP-Pool
 no keepalive
 ppp encrypt mppe 128
 ppp authentication ms-chap ms-chap-v2
!
interface Dot11Radio0
 no ip address
 shutdown
 speed basic-1.0 basic-2.0 basic-5.5 6.0 9.0 basic-11.0 12.0 18.0 24.0 36.0 48.0 54.0
 station-role root
!
interface Vlan1
 ip address 192.168.1.1 255.255.255.0
 ip nat inside
 ip tcp adjust-mss 1452
!
interface Vlan2
 no ip address
 pppoe enable group global
 pppoe-client dial-pool-number 1
!
interface Dialer1
 ip address negotiated
 ip mtu 1492
 ip virtual-reassembly
 ip nat outside
 encapsulation ppp
 ip tcp adjust-mss 1452
 dialer pool 1
 dialer-group 1
 no cdp enable
 ppp authentication chap pap callin
 ppp chap hostname <username>
 ppp chap password <password>
 ppp pap sent-username <username> password <password>
 ppp ipcp dns request accept
 ppp ipcp route default
 ppp ipcp address accept
!
ip local pool PPTP-Pool 192.168.1.244 192.168.1.254
ip forward-protocol nd
no ip http server
no ip http secure-server
ip route 0.0.0.0 0.0.0.0 Dia1
!
!
!
!
!
ip nat inside source list 1 interface Dialer1 overload
!
access-list 1 permit 192.168.1.0 0.0.0.255
dialer-list 1 protocol ip permit
!
control-plane
!
!
line con 0
 password <vostrapass>
 login
 no modem enable
line aux 0
line vty 0 4
 access-class 1 in
 password <vostrapass>
 login
!
scheduler max-task-time 5000
sntp server 193.204.114.232
!

Da notare che la suddetta configurazione comprende la timezone (clock timezone UTC 2), un server SNTP tramite il quale aggiornare la data e l’ora del router (sntp server 193.204.114.232), i parametri per il logging, la configurazione del server DHCP embedded e la configurazione della VPN PPTP (vedi questo post per approfondire).

Occorre soffermarsi, inoltre, sulla configurazione della VLAN 2. Infatti, essa ci permette di fare in modo che una delle porte ethernet del router possa essere configurata come WAN (ed è il reale motivo per cui abbiamo aggiornato l’IOS, poichè quella di default non consentiva di configurare VLAN multipe). Il protocollo utilizzato per la connessione all’ISP è il PPPoE ed i parametri associati alla VLAN 2 sono i seguenti:

interface Vlan2
 no ip address
 pppoe enable group global
 pppoe-client dial-pool-number 1

Nella fattispecie, la suddetta VLAN viene messa in binding con l’interfaccia virtuale (spoofed) Dialer 1, nella quale bisogna configurare i seguenti parametri:

interface Dialer1
 ip address negotiated
 ip mtu 1492
 ip virtual-reassembly
 ip nat outside
 encapsulation ppp
 ip tcp adjust-mss 1452
 dialer pool 1
 dialer-group 1
 no cdp enable
 ppp authentication chap pap callin
 ppp chap hostname <username>
 ppp chap password <password>
 ppp pap sent-username <username> password <password>
 ppp ipcp dns request accept
 ppp ipcp route default
 ppp ipcp address accept

Infine, nella configurazione completa che ho illustrato precedentemente, potete notare che il protocollo spanning-tree è stato disabilitato per la VLAN 2:

no spanning-tree vlan 2

Ciò è preferibile in quanto, non conoscendo la configurazione del router di zona del provider, potrebbe venir fuori un port type mismatch con il successivo shutdown dell’interfaccia fa0 del nostro router (mi è già successo).

Infine, salviamo la nostra configurazione mediante il comando:

RouterADSL# copy run start

ed abbiamo finito.

Alla prossima.

DHCP e lease time: alcune considerazioni

Dopo la recente migrazione di un server DHCP da un dispositivo di tipo embedded ad un server dedicato (nella fattispecie un domain controller), mi sono soffermato sulla corretta configurazione del lease time.

dhcplease

Premesso che non esiste una configurazione “corretta” a prescindere, ma che essa dipende strettamente dal tipo di network su cui il servizio DHCP è in ascolto, occorre trovare la giusta quadra tra un tempo di lease ragionevole e l’utilizzo delle risorse locali del server (tenendo in cosiderazione, ovviamente, anche l’eventuale traffico previsto sulla rete).

Infatti, di per sè, il servizio DHCP (soprattutto quello messo a disposizione da Microsoft, almeno fino alla versione Windows Server 2008, secondo quanto riportato qui), prevede un uso “intensivo” del disco (leggasi I/O rate), in quanto il database con le associazioni IP/MAC viene consultato ogni volta che un nuovo dispositivo si “presenta” in rete oppure intende rinnovare il proprio tempo di lease. Ciascun client DHCP tenterà un rinnovo del tempo di lease allo scadere del 50% dello stesso (passando dallo status BOUND a quello RENEWING). Se tale attività non andrà a buon fine, verrà tentato un rinnovo allo scadere dell’87.5% del lease time (passando dallo status RENEWING a quello REBINDING). Se anche in questo caso non si otterrà l’estensione del suddetto tempo di lease, il client entrerà in status INIT per richiedere un nuovo indirizzo IP. E’ palese che tali tentativi sono tanto più frequenti quanto il tempo di lease è ridotto.

Ora, un tempo di lease “basso” è comunque una scelta corretta quando si ha a che fare con una rete che prevede la connessione di un numero abbastanza elevato di dispositivi (Wi-Fi), pur essendoci a disposizione un pool DHCP (leggasi scope) non molto esteso (ad esempio una classe /25). In questo caso un lease time di 360 minuti (6 ore) sembra abbastanza ragionevole. Invece, se si ha a che fare con network in cui il numero di dispositivi è piuttosto ridotto, va bene mantenere il lease time di default (pari a 8 giorni per il DHCP server di casa Microsoft).

Una volta impostato il lease time conviene sempre e comunque tenere sotto controllo lo stato del servizio DHCP, poichè un’errata configurazione dello stesso potrebbe portare all’impossibilità, da parte dei client, di connettersi alla rete (DHCPNAK ad ogni nuova richiesta per via dello scope ormai saturo).

Qui trovate un link in cui sono presenti le varie icone (con relativo significato) che possono comparire sullo “status” del server DHCP Microsoft.

E’ tutto. Alla prossima.

Nagios troubleshooting

In questo post ho illustrato il comando da lanciare per appurare molto velocemente l’eventuale presenza di errori all’interno della configurazione di Nagios . Qui, invece, ho discusso di un valido tool in grado di debuggare i plugin utilizzati dall’NMS in questione.

nagiosEntrambi i suddetti metodi non rappresentano le uniche alternative in fase di troubleshooting. Infatti, Nagios mette a disposizione nativamente una modalità debug, la quale è in grado di “mostrare” come i vari comandi (configurati all’interno del file commands.cfg e valorizzati in nomehost.cfg) vengono interpretati ed eseguiti di volta in volta.

Per attivare tale modalità occorre operare all’interno del file /etc/nagios/nagios.cfg, impostando il debug level a 2048 (macros):

debug_level=2048

Il file da consultare sarà questo:

/var/log/nagios/nagios.debug

Inoltre, quando si ha a che fare con alcuni plugin sviluppati soprattutto in perl che lanciati da linea di comando come utente nagios funzionano correttamente mentre da pagina Web restituiscono un risultato di tipo Critical con output null, si può aggiungere, all’interno del file /etc/nagios/commands.cfg (in corrispondenza del comando che fa uso del suddetto plugin), la seguente entry:

2>&1

Ad esempio, per il plugin check_squid.pl ho definito il seguente comando:

'check_squid' command definition
define command{
        command_name    check_squid
        command_line    $USER1$/check_squid -u $ARG1$ -p $HOSTADDRESS$ -l $ARG2$ -e $ARG3$ 2>&1
        }

in modo tale da pololare il risultato del check presente nella pagina Web reindirizzando lo standard err (2>) nello standard out (&1).

Entrambi i metodi illustrati in questo post prevedono un reload della configurazione di Nagios per entrare in funzione:

[root@NMS ~]# service nagios reload

Per ora è tutto.

Alla prossima.

check_arptables: script Nagios per verificare lo stato di arptables_jf

In questo post ho discusso della configurazione di LVS in modalità Direct Routing. Tale configurazione richiedeva l’installazione e la corretta configurazione di arptables_jf per la gestione delle richieste ARP dirette ai frontend. Adesso vedremo come verificare l’effettivo funzionamento del suddetto applicativo attraverso l’NMS open source per eccellenza, Nagios.

nagiosCreazione dell’eseguibile e configurazione dell’NMS

Il codice bash che ho creato per effettuare i controlli sullo status di arptables_jf è il seguente:

#!/bin/bash

host=$1
warning=$2
critical=$3

usage="check_arptables <host> <warning> <critical>"

if [ -n "$host" ]; then

        if [ -n "$warning" ];then

                if [ -n "critical" ];then

                        if [ "$warning" -lt "$critical" ];then

                                echo "UNKNOWN: warning has to be greater than critical"
                                exit 3;

                        else

                                output=`sudo arptables -L | grep -v Chain | grep -v target | wc -l`

                                if [ "$output" -le "$critical" ];then

                                        echo "CRITICAL: total number of rules is $output";
                                        exit 2;

                                elif [ "$output" -gt "$critical"  -a  "$output" -le "$warning" ];then

                                        echo "WARNING: total number of rules is $output";
                                        exit 1;

                                else

                                        echo "OK: total number of rules is $output";
                                        exit 0;

                                fi
                        fi
                else

                        echo "$usage"
                        exit 3;

                fi
        else

                echo "$usage"
                exit 3;

        fi
else

        echo "$usage"
        exit 3;

fi

Il suddetto codice è abbastanza esplicativo: dopo aver verificato la presenza di tutti i parametri richiesti e la loro consistenza (ovvero la soglia di warning deve essere strettamente maggiore di quella di critical), viene effettuato il conteggio delle regole arptables attive sul frontend monitorato. Il comando principale è il seguente:

sudo arptables -L | grep -v Chain | grep -v target | wc -l

Da notare che è presente la direttiva sudo poichè l’applicativo arptables richiede i privilegi di root per essere eseguito. Rendiamo il suddetto codice eseguibile:

[root@NMS ~]# chmod +x check_arptables

e copiamolo nella directory /usr/lib64/nagios/plugins del frontend:

[root@NMS ~]# scp check_arptables root@frontend.dominio.com:/usr/lib64/nagios/plugins

Ora è possibile, all’interno della configurazione di Nagios, definire il comando da lanciare per monitorare arptables sul frontend (all’interno del file /etc/nagios/commands.cfg):

# 'check_remote_arptables' command definition
define command{
        command_name    check_remote_arptables
        command_line    $USER1$/check_by_ssh -H $HOSTADDRESS$ -C "/usr/lib64/nagios/plugins/check_arptables $ARG1$ $ARG2$ $ARG3$"
        }

Tale comando non fa altro che connettersi al frontend via SSH (senza password, mediante un semplice scambio di chiavi RSA) e lanciare l’eseguibile precedentemente creato.

Nella configurazione di Nagios relativa allo specifico frontend, invece, occorre creare un servizio simile al seguente:

define service{
        use                             local-service         ; Name of service template to use
        host_name                       frontend.dominio.com
        service_description             Arptables Rules Status
        check_command                   check_remote_arptables!localhost!3!2
        notifications_enabled           0
        }

Configurazione del frontend

Sul frontend è sufficiente editare il file /etc/sudoers per consentire all’utente nagios di lanciare il comando arptables senza sessione TTY e senza richiesta di inserimento della password. Nella fattispecie, nel primo caso è sufficiente commentare la direttiva:

#Defaults requiretty

mentre nel secondo caso occorre inserire la seguente stringa:

nagios  ALL=(root)      NOPASSWD: /sbin/arptables

A configurazione del frontend terminata possiamo lanciare sull’NMS il comando:

[root@NMS ~]# service nagios reload

ed abbiamo finito.

Ora arptables è correttamente monitorato.

Alla prossima.

Cisco RV016 e firmware 4.2.3.03-tm: problemi con il server DHCP integrato

Premesso che il router Cisco RV016 sembrava uno dei migliori oggetti presenti sul mercato dedicato agli abienti SOHO, ho riscontrato, durante il suo normale utilizzo, tutta una serie di bug che ne inficiano il funzionamento e che mi hanno fatto ricredere sulla sua effettiva qualità.

Uno di questi bug riguarda il server DHCP integrato, il quale, di punto in bianco, ha smesso di rilasciare gli indirizzi IP (compresa subnet mask, gateway e nameserver) ai client connessi in rete.

Ho deciso di andare a fondo alla questione e, armato di sniffer (tcpdump), ho salvato le relative tracce, che si possono riassumere in quanto segue (nell’immagine seguente sono riportate le 4 fasi principali relative al “normale” funzionamento del protocollo DHCP) :

dhcp1) Il client invia in broadcast un messaggio del tipo DHCPDISCOVER, alla ricerca dei server DHCP in ascolto sulla porta UDP 67:

15:03:00.463759 IP (tos 0x0, ttl 128, id 29956, offset 0, flags [none], proto UDP (17), length 328)
    0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 74:e6:e2:0e:3d:a0 (oui Unknown), length 300, xid 0x24dc5170, Flags [none]
          Client-Ethernet-Address 74:e6:e2:0e:3d:a0 (oui Unknown)
          Vendor-rfc1048 Extensions
            Magic Cookie 0x63825363
            DHCP-Message Option 53, length 1: Discover
            Client-ID Option 61, length 7: ether 74:e6:e2:0e:3d:a0
            Hostname Option 12, length 10: "ClientPC"
            Vendor-Class Option 60, length 8: "MSFT 5.0"
            Parameter-Request Option 55, length 13:
              Subnet-Mask, Domain-Name, Default-Gateway, Domain-Name-Server

2) Al suddetto messaggio fa seguito un DHCPOFFER, inviato dal server al client (unicast), il quale contiene tutta una serie di informazioni, come l’indirizzo IP che intende assegnare al dispositivo che lo ha appena contattato:

15:03:00.470460 IP (tos 0x0, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 332)
    dhcpserver.domain.local.bootps > 192.168.18.203.bootpc: BOOTP/DHCP, Reply, length 304, xid 0x24dc5170, Flags [none]
          Your-IP 192.168.18.203
          Client-Ethernet-Address 74:e6:e2:0e:3d:a0 (oui Unknown)
          Vendor-rfc1048 Extensions
            Magic Cookie 0x63825363
            DHCP-Message Option 53, length 1: Offer
            Server-ID Option 54, length 4: dhcpserver.domain.local

3) Il client risponde al server accettando l’Indirizzo IP e gli altri parametri di rete che gli sono stati proposti, utilizzando un apposito messaggio denominato DHCPREQUEST (in broadcast):

15:03:00.473016 IP (tos 0x0, ttl 128, id 29957, offset 0, flags [none], proto UDP (17), length 345)
 0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 74:e6:e2:0e:3d:a0 (oui Unknown), length 317, xid 0x24dc5170, Flags [none]
 Client-Ethernet-Address 74:e6:e2:0e:3d:a0 (oui Unknown)
 Vendor-rfc1048 Extensions
 Magic Cookie 0x63825363
 DHCP-Message Option 53, length 1: Request
 Client-ID Option 61, length 7: ether 74:e6:e2:0e:3d:a0
 Requested-IP Option 50, length 4: 192.168.18.203
 Server-ID Option 54, length 4: dhcpserver.domain.local
 Hostname Option 12, length 10: "ClientPC"
 FQDN Option 81, length 13: "ClientPC"

4) Infine, il server, mediante un DHCPNAK (in broadcast), declina la suddetta richiesta inoltratagli dal client:

15:03:00.477422 IP (tos 0x0, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 278)    dhcpserver.domain.local.bootps > 255.255.255.255.bootpc: BOOTP/DHCP, Reply, length 250, xid 0x24dc5170, Flags [none]
          Client-Ethernet-Address 74:e6:e2:0e:3d:a0 (oui Unknown)
          Vendor-rfc1048 Extensions
            Magic Cookie 0x63825363
            DHCP-Message Option 53, length 1: NACK
            Server-ID Option 54, length 4: dhcpserver.domain.local

Il malfunzionamento è proprio questo, ovvero il server continuerà a rispondere con dei DHCPNAK (anzichè i DHCPACK), inibendo l’ottenimento dei parametri di rete a tutti i client.

Ho risolto “migrando” il server DHCP dal router al Domain Controller.

Per ulteriori info sui messaggi DHCP potete consultare questa pagina.

Alla prossima.

PS: tale bug sembra essere strettamente correlato alla versione del firmware (4.2.3.03-tm), infatti con la versione immediatamente precedente (4.2.2.08) non ho mai riscontrato malfunzionamenti in tal senso.

Swatch e Asterisk: monitorare la chiamate in ingresso ed in uscita

In questo post ho discusso della configurazione di Asterisk per il sip provider cheapvoip (cheapnet.it). Ora vedremo come monitorare le chiamate in ingresso ed in uscita dal nostro PBX utilizzando un apposito tool, ovvero swatch.

asteriskPer prima cosa è necessario creare il file di configurazione di swatch (che chiameremo swatchvoip.conf) all’interno della directory /etc:

[root@PBX ~]# nano /etc/swatchvoip.conf

il contenuto del suddetto file dovrà essere il seguente:

#Inbound call
watchfor  /cheapvoip-inbound/
     echo
     mail addresses=vostro.indirizzo\@email.it,subject=SWATCH HOME: Inbound call received

#Outbound call
watchfor  /cheapvoip-outbound/
     echo
     mail addresses=vostro.indirizzo\@email.it,subject=SWATCH HOME: Outbound call performed

Mediante la direttiva watchfor indichiamo la stringa da monitorare (che identifica univocamente le chiamate in ingresso e quelle in uscita, nella fattispecie cheapvoip-inbound e cheapvoip-outbound).

Con echo imponiamo a swatch di reindirizzare l’output su terminale (tty) e mediante mail facciamo in modo che le chiamate vegano notificate al nostro indirizzo di posta elettronica.

Infine editiamo il file /etc/rc.local, in modo da eseguire automaticamente swatch dopo un eventuale riavvio della macchina:

swatch -c /etc/swatchvoip.conf -t /var/log/asterisk/cdr-csv/Master.csv &

A questo punto non ci resta che lanciare il comando:

swatch -c /etc/swatchvoip.conf -t /var/log/asterisk/cdr-csv/Master.csv &

da console ed abbiamo finito.

A presto.

Configurarazione di Asterisk per cheapvoip Italia (cheapnet.it)

Premessa

Dopo aver avuto a che fare con Asterisk durante le mie ultime attività lavorative, ho deciso di creare un piccolo testbed casalingo, in modo da approfondire bene il funzionamento di tale applicativo, al netto di alcune customizzazioni e configurazioni ad hoc ereditate dal campo. Infatti, secondo la mia opinione, il modo più rapido per riuscire a padroneggiare una determinata tecnologia consiste nella realizzazione ex novo dell’infrastruttura che ne fa uso (ovviamente su scala ridotta), configurando manualmente i vari software coinvolti (in questo caso Asterisk ed i telefoni VOIP utilizzati come client).

asteriskScelta del sip provider

Tra i diversi sip provider che ho passato al vaglio la scelta è ricaduta su cheapvoip Italia, sicuramente uno dei migliori in termini di costi/benefici.  E’ sufficiente registrarsi, scegliere il numero geografico per la nostra linea e pagare i 6 € di credito telefonico iniziale (il quale potrà essere ulteriormente incrementato in un secondo momento). I 6 € si riferiscono al piano tariffario Standard.

Una volta attivato l’account ed il numero geografico possiamo procedere con la configurazione del nostro PBX open source.

Configurazione di Asterisk

Per configurare Asterisk occorre operare dapprima sul file /etc/asterisk/sip.conf, inserendo le informazioni relative alla registrazione verso il provider. Occorre notare, inoltre, che tale registrazione è mandatoria per le chiamate in ingresso (inbound), mentre per quelle in uscita (outbound) non è richiesta. In particolare, sarà necessario aggiungere la seguente direttiva:

register => 6554XXXXXX:password@sip.cheapnet.it/6554XXXXXX

all’interno della sezione [general] del suddetto file di configurazione. Tale direttiva ha il seguente formato:

voipusername:voippassword@sipproxy/extension

dove voipusername ed extension coincidono (corrispondono semplicemente al numero VOIP fornitoci dal sip provider).

A questo punto possiamo definire gli interni da utilizzare, ad esempio il 7001 ed il 7002:

[7001]
type=friend
host=dynamic
context=from-sip
callerid=Test1 <7001>
secret=passaccount
context=internal

[7002]
type=friend
host=dynamic
context=from-sip
callerid=Test1 <7002>
secret=passaccount
context=internal

Bene, ora non ci resta che definire i parametri per le chiamate in ingresso ed in uscita:

[cheapvoip-inbound]
type=peer
username=6554XXXXXX@sip.cheapnet.it
secret=<vostra voippassword>
fromuser=6554XXXXXX
fromdomain=sip.cheapnet.it
host=sip.cheapnet.it
outboundproxy=sip.cheapnet.it
context=cheapvoip-in
insecure=port,invite
realm=sip.cheapnet.it
nat=yes
qualify=yes
regseconds=60
disallow=all
allow=alaw
allow=ulaw
allow=g729
[cheapvoip-outbound]
type=peer
callerid="Vostro identificativo testuale" <vostro numero geografico>
username=6554XXXXXX@sip.cheapnet.it
secret=pass
fromuser=6554XXXXXX
fromdomain=sip.cheapnet.it
host=sip.cheapnet.it
outboundproxy=sip.cheapnet.it
context=cheapvoip-in
insecure=port,invite
realm=sip.cheapnet.it
nat=yes
qualify=yes
regseconds=60
disallow=all
allow=alaw
allow=ulaw
allow=g72

Ho deciso di separare le chiamate in ingresso da quelle in uscita poichè, in quest’ultimo caso, voglio sovrascrivere il caller id di default creando una stringa ad hoc da usare come identificativo.

Salviamo le modifiche apportate al suddetto file e passiamo alla configurazione di /etc/asterisk/extensions.conf, che dovrà essere simile alla seguente:

[internal]

include => cheapvoip-in
include => cheapvoip-out

exten => 7001,1,Answer()
exten => 7001,2,Dial(SIP/7001,60)
exten => 7001,3,Hangup()

exten => 7002,1,Answer()
exten => 7002,2,Dial(SIP/7002,60)
exten => 7002,3,Hangup()

[cheapvoip-in]

exten =>  6554XXXXXX,1,Dial(SIP/7001&SIP/7002)

[cheapvoip-out]

exten => _X.,1,Dial(SIP/${EXTEN}@cheapvoip-outbound)

Nel contesto [internal] ho incluso le regole definite in [cheapvoip-out] e [cheapvoip-in]. Ho inoltre definito le actions per ciascun interno ed ho imposto la chiamata simultanea su entrambi in caso di telefonata proveniente dall’esterno:

Dial(SIP/7001&SIP/7002)

Infine, in caso di chiamata verso l’esterno, si dovrà procedere con l’inoltro della stessa verso il sip provider, sfruttando la configurazione definita in [cheapvoip-outbound] del file /etc/asterisk/sip.conf. Da notare che il pattern _X. rappresenta semplicemente una dialplan, dove _ indica il carattere che demarca l’inizio della stessa, X rappresenta tutti i digit da 0 a 9 e . indica una o più occorrenze di tali digit.

A configurazione ultimata sarà sufficiente ricaricare la configurazione di Asterisk mediante il comando:

[root@PBX ~]# service asterisk reload

Port forwarding

Per le chiamate in ingresso è necessario che il sip provider sia in grado di comunicare con il nostro PBX attraverso la porta 5060, protocollo UDP. Per fare ciò occorre consentire in ingresso tale tipologia di traffico sul nostro router (definendo anche le opportune regole di port forwarding). E’ bene restringere il filtro al solo IP sorgente  87.238.30.10 (sip.cheapnet.it).

 Client

Il client che ho utilizzato è un softphone scaricabile gratuitamente da Internet, ovvero Zoiper.

Fine del post, alla prossima.

Nagios e gli event handlers

Come già affermato in più occasioni, Nagios è sicuramente uno dei migliori NMS open source in circolazione.  Esso mette a disposizione del sysadmin tutta una serie di funzioni utilissime per verificare lo stato di salute relativo agli host monitorati e consente, in alcune circostanze, di gestire i downtime in modo automatico (ad esempio riavviando il servizio che ha generato lo status di tipo CRITICAL).

Nagios_logo_blackTale gestione automatica dei downtime viene realizzata attraverso i cosiddetti event handlers. Vediamo come configurarli.

Per prima cosa è necessario creare un comando simile al seguente, editando il file /etc/nagios/object/commands.cfg

define command {
command_name      flushcache
command_line      /usr/lib/nagios/plugins/eventhandlers/flushcache $HOSTADDRESS$ $SERVICESTATE$ $SERVICESTATETYPE$ $SERVICEATTEMPT$
}

Nella fattispecie, il suddetto comando utulizza l’eseguibile flushcache, il cui compito è quello connettersi alla macchina target e di cancellare la cache del sistema operativo in caso di memory leak.

Occorre ora configurare l’event handler all’interno del servizio che si occupa del monitoraggio della RAM:

define service{        
use                            local-service              host_name                       vostrohost.vostrodominio.it        service_description             FREE RAM        check_command                   check_remote_ram!10!5        event_handler                   flushcache        notifications_enabled           0        
}

A questo punto la configurazione di Nagios può ritenersi ultimata. Non ci rimane che creare l’eseguibile flushcache all’interno della directory /usr/lib/nagios/plugins/eventhandlers/:

[root@NMS eventhandlers]# nano flushcache

il cui contenuto dovrà essere il seguente:

#!/bin/bash
if [ -n "$1" ];then
        case "$2" in
        OK)
                ;;
        WARNING)
                ;;
        UNKNOWN)
                ;;
        CRITICAL)
                case "$3" in
                SOFT)
                        case "$4" in
                        3)
                                echo -n "Flushing cache memory (3rd soft critical state)..."
                                /usr/lib/nagios/plugins/eventhandlers/connect_server.sh $1
                                ;;
                                esac
                        ;;
                HARD)
                        echo -n "Flushing cache memory..."
                        /usr/lib/nagios/plugins/eventhandlers/connect_server.sh $1
                        ;;
                esac
                ;;
        esac
else
        echo "Usage: flushcache <hostname>"
fi

exit 0

Dove $1 è la variabile $HOSTADDRESS$, $2 è il $SERVICESTATE$, $3 è il $SERVICESTATETYPE$ e $4 è il $SERVICEATTEMPT$ (sono semplicemente le variabili utilizzate nella definizione del comando flushcache in command.cfg).

Premesso che per il tipo di servizio local-service il max_check_attempts è impostato a 4 (nel file template.cfg), il suddetto codice bash non fa altro che interrogare la macchina target ($HOSTADDRESS), ricavando il $SERVICESTATE$ (OK, WARNING, UNKNOWN o CRITICAL), il $SERVICESTATETYPE$ (SOFT oppure HARD) ed il $SERVICEATTEMPT$ (ovvero il numero di check già eseguiti da Nagios nel caso in cui il $SERVICESTATE$ sia diverso da OK).

Il suddetto eseguibile prevede delle operazioni solo se il $SERVICESTATE$ è di tipo CRITICAL: in tal caso, al terzo check consecutivo (siamo ancora in SOFT state – parliamo di HARD state solo se il $SERVICESTATE$ è ancora CRITICAL dopo il quarto check), verrà lanciato l’eseguibile connect_server.sh (expect) che si occuperà di svuotare la cache della macchina monitorata. La suddetta operazione verrà eseguita nuovamente appena il $SERVICESTATETYPE$ passerà da SOFT a HARD.

Inoltre, tale eseguibile prevede come unico parametro in ingresso l’IP dell’host, ovvero $HOSTADDRESS$ (connect_server.sh $1).

Di seguito il sorgente relativo a connect_server.sh:

#!/usr/bin/expect

set hostname [lindex $argv 0]
set password "vostrapass"

spawn ssh -l root $hostname
expect "*assword:"
send "$password\n"
expect "#"
send "sync && echo 3 > /proc/sys/vm/drop_caches\n"
expect "#"
send "exit\n"
expect eof

Nella fattispecie, il comando vero e proprio che si occupa dello svuotamento della cache sulla macchina target è:

sync && echo 3 > /proc/sys/vm/drop_caches

A questo punto possiamo ricaricare la configurazione di Nagios per rendere effettive le suddette modifiche:

[root@NMS eventhandlers]# service nagios reload

ed abbiamo finito.

A presto.

OpenVPN e client multipli

In questo post ho discusso della configurazione di OpenVPN (sia client che server). Tale configurazione si basa su una rete privata punto-punto, consentendo quindi la connessione in VPN ad un solo client per volta (solitamente quello dell’amministratore di rete per eventuali attività da remoto).

openvpn

Nel caso in cui, invece, si voglia consentire a più utenti di connettersi contemporaneamente al nostro VPN concentrator, è necessario apportare delle modifiche alla configurazione del server.

Di seguito gli step da seguire.

Configurazione del server

Per prima cosa, è necessario sostituire la direttiva:

ifconfig 192.168.110.1 192.168.110.2

con

server 192.168.110.0 255.255.255.0

Inoltre, mediante l’opzione:

 ifconfig-pool-persist ipp.txt

imporremo ad OpenVPN di mantenere una lista persistente di IP associati ai client, affinchè ad ogni nuova connessione venga loro assegnato sempre il medesimo indirizzo.

Per ragioni di sicurezza è meglio non far comunicare tra loro i client connessi in VPN ma, nel caso in cui si voglia consentire tale tipologia di traffico, è sufficiente aggiuntere questa opzione al file di configurazione del server:

client-to-client

Infine, se volessimo fare in modo che i client vegano nattati su Internet utilizzando l’IP pubblico del server VPN, è sufficiente aggiungere tali direttive al file di configurazione del demone in oggetto:

push "redirect-gateway def1"

impostando il nostro VPN concentrator come default gateway e:

push "dhcp-option DNS 8.8.8.8"

per forzare il nameserver da utilizzare durante la risoluzione degli FQDN in indirizzi IP.

E’ bene notare che, qualora fosse necessario, si dovrà operare anche sulla configurazione di netfilter del server VPN, impostando una regola di NAT simile alla seguente:

iptables -t nat -A POSTROUTING -s 192.168.110.0/24 -o eth1 -j MASQUERADE

e, nel caso in cui fosse abilitato lo steteful inspection, sarà necessario creare una regola del tipo:

iptables -A FORWARD -i eth1 -o tun0 -m state --state ESTABLISHED,RELATED -j ACCEPT

dove eth1 è l’interfaccia esposta su Internet e tun0 è l’interfaccia associata alla VPN.

Configurazione del client

Per il client, occorre semplicemente rimuovere la direttiva:

ifconfig 192.168.110.2 192.168.110.1

ed abbiamo finito.

Il post termina qui, alla prossima.