domenica 23 gennaio 2011

Come controllare che la VPN non sia down

Un'esigenza che sento ultimamente è quella di controllare che la mia connessione VPN non cada, o meglio... visto che è sicuro che prima o poi vada down, vorrei che torni up in automatico.

Come sempre per Windows esiste una soluzione: VPNetmon. Questo è un software che, una volta installato, tiene d'occhio la propria connessione Vpn, e se quest'ultima venisse a mancare, si prodiga nel chiudere altri software che non devono funzionare se non tramite VPN

Sotto Linux ho trovato una soluzione migliore, casereccia ma altrettanto funzionale. Purtroppo non ho ritrovato il link degli autori dello script, ma va a loro il merito.


La soluzione consiste in uno script Python (lanciato da uno script bash) che si preoccupa di controllare ogni 20 secondi che la nostra VPN sia up. Se così non fosse... la ritira su!




Per mettere in opera questo sistema è necessario creare in primis uno script bash dal nome (ad esempio) check-vpn.sh  con il seguente contenuto


   1:  #!/bin/bash
   2:  while [ 1 ]; do
   3:     echo -n $(date) "##  "
   4:     python /home/tuonome/vpn-restart.py #wherever you have installed the script
   5:     sleep 20
   6:  done

Anche chi fosse a digiuno di Bash Shell saprà leggere che questo file si limita a rilanciare lo script Python ogni 20 secondi.

A questo punto, metteremo codesto script in esecuzione automatica del nostro sistema Linux. Nella mia Mint sotto Preferenze delle applicazioni d'avvio. Il comando da inserire sarà qualcosa tipo
sh /home/vostro_user/check-vpn.sh


Si può usare anche crontab ovviamente.


Bene, ora manca il nostro script Python che fisicamente controlla la nostra connessione. Ecco di seguito il sorgente.



#!/usr/bin/python
 
import sys
import os
import dbus
import gobject
from  dbus.mainloop.glib import DBusGMainLoop
 
# The uuid of the VPN connection to activate
VPN_CONNECTION_UUID = "QUI VA UUID VPN"
 
# The uuid of the connection that needs to be active to start the VPN connection
ACTIVE_CONNECTION_UUID = "QUI VA UUID RETE ETH0 o WLAN"
 
# some service, path and interface constants
NM_DBUS_SERVICE                   = "org.freedesktop.NetworkManager"
NM_DBUS_PATH                      = "/org/freedesktop/NetworkManager"
NM_DBUS_INTERFACE                 = "org.freedesktop.NetworkManager"
NM_DBUS_IFACE_CONNECTION_ACTIVE   = "org.freedesktop.NetworkManager.Connection.Active"
NM_DBUS_SERVICE_SYSTEM_SETTINGS   = "org.freedesktop.NetworkManagerSystemSettings"
NM_DBUS_SERVICE_USER_SETTINGS     = "org.freedesktop.NetworkManagerUserSettings"
NM_DBUS_IFACE_SETTINGS            = "org.freedesktop.NetworkManagerSettings"
NM_DBUS_PATH_SETTINGS             = "/org/freedesktop/NetworkManagerSettings"
NM_DBUS_IFACE_SETTINGS_CONNECTION = "org.freedesktop.NetworkManagerSettings.Connection"
 
DBusGMainLoop(set_as_default=True)
 
nm_dbus_settings_services = (NM_DBUS_SERVICE_SYSTEM_SETTINGS, NM_DBUS_SERVICE_USER_SETTINGS)
 
def get_connections(bus, service):
proxy = bus.get_object(service, NM_DBUS_PATH_SETTINGS)
iface = dbus.Interface(proxy, dbus_interface=NM_DBUS_IFACE_SETTINGS)
return iface.ListConnections()
 
def get_connection_by_uuid(bus, uuid):
for service in nm_dbus_settings_services:
for c in get_connections(bus, service):
proxy = bus.get_object(service, c)
iface = dbus.Interface(proxy, dbus_interface = NM_DBUS_IFACE_SETTINGS_CONNECTION)
settings = iface.GetSettings()
if settings['connection']['uuid'] == uuid:
return (c, service)
return None
 
def list_uuids(bus):
for service in nm_dbus_settings_services:
for c in get_connections(bus, service):
proxy = bus.get_object(service, c)
iface = dbus.Interface(proxy, dbus_interface=NM_DBUS_IFACE_SETTINGS_CONNECTION)
settings = iface.GetSettings()
conn = settings['connection']
print " %s: %s - %s (%s)" % (service, conn['uuid'], conn['id'], conn['type'])
 
def get_active_connection_path(bus, uuid):
proxy = bus.get_object(NM_DBUS_SERVICE, NM_DBUS_PATH)
iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.DBus.Properties')
active_connections = iface.Get(NM_DBUS_INTERFACE, 'ActiveConnections')
connection_and_service = get_connection_by_uuid(bus, uuid)
if connection_and_service == None:
return None
for a in active_connections:
proxy = bus.get_object(NM_DBUS_SERVICE, a)
iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.DBus.Properties')
path = iface.Get(NM_DBUS_IFACE_CONNECTION_ACTIVE, 'Connection')
service = iface.Get(NM_DBUS_IFACE_CONNECTION_ACTIVE, 'ServiceName')
if service != connection_and_service[1]:
continue
proxy = bus.get_object(connection_and_service[1], path)
iface = dbus.Interface(proxy, dbus_interface=NM_DBUS_IFACE_SETTINGS_CONNECTION)
settings = iface.GetSettings()
if settings['connection']['uuid'] == uuid:
return a
return None
 
def activate_connection(bus, vpn_connection, active_connection):
def reply_handler(opath):
print "<<SUCCESS>>"
sys.exit(0)
def error_handler(*args):
print "<<FAILURE>>"
sys.exit(1)
proxy = bus.get_object(NM_DBUS_SERVICE, NM_DBUS_PATH)
iface = dbus.Interface(proxy, dbus_interface=NM_DBUS_INTERFACE)
iface.ActivateConnection(NM_DBUS_SERVICE_USER_SETTINGS,
vpn_connection[0],
dbus.ObjectPath("/"), 
active_connection,
reply_handler=reply_handler,
error_handler=error_handler)
 
bus = dbus.SystemBus()
 
print "connections:"
list_uuids(bus)
 
if len(VPN_CONNECTION_UUID) < 1 or len(ACTIVE_CONNECTION_UUID) < 1:
print "you need to set the uuids"
sys.exit(0)
 
vpn_connection = get_connection_by_uuid(bus, VPN_CONNECTION_UUID)
if not vpn_connection:
print "Configured VPN connection is not known to NM, check VPN_CONNECTION_UUID."
sys.exit(1)
 
active_connection = get_connection_by_uuid(bus, ACTIVE_CONNECTION_UUID)
if not active_connection:
print "Configured active connection is not known to NM, check ACTIVE_CONNECTION_UUID."
sys.exit(1)
 
if get_active_connection_path(bus, VPN_CONNECTION_UUID) != None:
print "VPN connection already activated"
sys.exit(0)
 
active_connection_path = get_active_connection_path(bus, ACTIVE_CONNECTION_UUID)
if not active_connection_path:
print "The required connection isn't active at the moment"
sys.exit(0)
 
print "connecting to:\n  '%s'\nwith active connection:\n  '%s'" % (vpn_connection, active_connection)
 
activate_connection(bus, vpn_connection, active_connection_path)
 
loop = gobject.MainLoop()
loop.run()

E' necessario modificare la testa di questo script, inserendo il codice UUID della vostra VPN. Non vi preoccupate, vi basta lanciare lo script così com'è la prima volta: esso vi mostrerà l'elenco delle vostre VPN e schede di rete con accanto il codice UUID.

Salvate questo script Python con il nome vpn-restart.py e a questo punto il gioco è fatto.

Anche se la vostra VPN cadrà, in 20 secondi tornerete on line.

Per riassumere, si può dire che questa soluzione sia il Vpnetmon per Linux.



Nessun commento:

Posta un commento