mercredi 14 avril 2010

Reconnection automatique du VPN en cas de coupure de connection sous Ubuntu

Il arrive parfois qu'une connexion réseau est interrompue lors de l'utilisation d'un VPN.
La connexion réseau est rapidement rétablie sans problème, mais le VPN reste déconnecté.

Il s'agit d'une question de sécurité très gênante pour les utilisateurs.

Une première solution proposée par votre serviteur a été de couper les échanges si la connection au VPN était coupée: voir http://papillon-butineur.blogspot.com/2009/09/deconnexion-du-vpn-un-script-pour.html
L'inconvénient était qu'il fallait relancer à la main le VPN

Une deuxième solution proposée par CoreDump sur le forum d'Ubuntu-fr était de relancer automatiquement une connection VPN en cas de coupure : voir http://papillon-butineur.blogspot.com/2010/01/reconnection-automatique-du-vpn-en-cas.html
L'inconvénient de la solution était qu'une fois les scripts lancés, plus moyen d'arrêter le VPN , à moins de modifier à la main les scripts.

Désormais, une troisième solution proposée par Spiritism sur le Blog du VPN a été de réaliser un mixte des deux solutions précédentes: voir ICI

La dernière version de spiritism est téléchargeable : ICI


Descriptif:


Premier script : connection-service
Ce script rédigé par Coredump va permettre de connecter le VPN


Deuxième Script : watch_vpn.sh
Ce script va lancer le troisième script testvpn.sh à intervalle régulier


Le troisième script : testvpn.sh
Ce script teste l'état de la connection VPN et l'état de la connection tout court et lance le premier script connection-service si nécessaire.

Télechargements des scripts légèrement modifiés : ICI

les  scripts détaillés :

watch_vpn.sh

#!/bin/bash
#Surveille le VPN et le reconnecte si besoin
#nécessite droit d'accès root




if [ -f /var/tmp/connexion.txt ]
then rm /var/tmp/connexion.txt
fi
if [ -f /var/tmp/fai.txt ]
then rm /var/tmp/fai.txt
fi
verif=$(nm-tool | grep -E "VPN" | cut -d" " -f4)
if [ "$verif" == "" ]
then
echo "Le Vpn n'est pas activé ...... Arrêt"
echo "Appuyez sur Entrée pour terminer l'application"
read mot
exit
fi
#Inscription de la connection vpn dans le fichier connexion.txt
nm-tool | grep -E "VPN" | cut -d" " -f4 | cut -d'[' -f2 | cut -d']' -f1 >> /var/tmp/connexion.txt
# Inscription du nom du fai dans le fichier fai.txt
wget http://www.mon-ip.com/ -O - -o /dev/null | grep -e 'FAI' | cut -d'<' -f 3 | cut -d '>' -f 2 >> /var/tmp/fai.txt
# lancement du script de test toutes les n secondes
sudo sh -c 'watch -n 2 testvpn.sh'
sudo -k
exit 0




testvpn.sh

#!/bin/bash
#nécessite nm-tool (inclu avec Network Manager)
#initialisation des variables
test1="VPN:"
name=$(cat /var/tmp/connexion.txt)
fai=$(cat /var/tmp/fai.txt)
#test de la connection en mode VPN :cherche le terme VPN: dans la sortie de nm-tool
test0=$(nm-tool | grep -E "VPN" | cut -d" " -f2)
#test de la connection
connect=$(host 8.8.8.8 | grep -E "8.8.8.8" | cut -d'(' -f2 | cut -d')' -f1)
#conditions
if [ "$test0" != "$test1" -o "$connect" == "SERVFAIL" ]
then
connection-service $name start
sudo rm /var/tmp/fai.txt
sudo wget http://www.mon-ip.com/ -O - -o /dev/null | grep -e 'FAI' | cut -d'<' -f 3 | cut -d '>' -f 2 >> /var/tmp/fai.txt
else
text="VPN "$name" ACTIF --> "$fai
echo $text
echo "Test connection Ok"
fi
exit



Connection-service

#!/bin/bash


    ############
    # SETTINGS #
    ############

get_connections_paths()
{
    dbus-send --system --print-reply --dest="$1" "/org/freedesktop/NetworkManagerSettings" "org.freedesktop.NetworkManagerSettings.ListConnections" \
    | grep "object path" | cut -d '"' -f2
}

get_connection_settings()
{
    dbus-send --system --print-reply --dest="$1" "$2" org.freedesktop.NetworkManagerSettings.Connection.GetSettings
}

get_connection_string_setting()
{
    echo "$1" | grep -A 1 \""$2"\" | grep variant | cut -d '"' -f2
}

get_connection_id()
{
    get_connection_string_setting "$1" "id"
}

get_connection_type()
{
    get_connection_string_setting "$1" "type"
}

get_device_type_by_connection_type()
{
    echo "$1" | grep -q "ethernet" && echo 1 && return
    echo "$1" | grep -q "wireless" && echo 2 && return
    echo 0
}

find_connection_path()
{
    for connection_path in `get_connections_paths "$1"`
    do
        connection_settings=`get_connection_settings "$1" "$connection_path"`
        connection_settings_id=`get_connection_id "$connection_settings"`
        [ "$connection_settings_id" = "$2" ] && echo "$1" "$connection_path"
    done
}

find_connection_path_everywhere()
{
    find_connection_path "org.freedesktop.NetworkManagerSystemSettings" "$1"
    find_connection_path "org.freedesktop.NetworkManagerUserSettings" "$1"
}

print_connections_ids()
{
    for connection_path in `get_connections_paths "$1"`
    do
        connection_settings=`get_connection_settings "$1" "$connection_path"`
        connection_settings_id=`get_connection_id "$connection_settings"`
        echo "$connection_settings_id"
    done
}

print_connections_ids_everywhere()
{
    print_connections_ids "org.freedesktop.NetworkManagerSystemSettings"
    print_connections_ids "org.freedesktop.NetworkManagerUserSettings"
}


    ###########
    # DEVICES #
    ###########

get_devices_paths()
{
    dbus-send --system --print-reply --dest="org.freedesktop.NetworkManager" "/org/freedesktop/NetworkManager" "org.freedesktop.NetworkManager.GetDevices" \
    | grep "object path" | cut -d '"' -f2
}

get_device_property()
{
    dbus-send --system --print-reply --dest="org.freedesktop.NetworkManager" "$1" "org.freedesktop.DBus.Properties.Get" string:"org.freedesktop.NetworkManager.Device" string:"$2" \
    | grep variant | awk '{print $3}'
}

get_device_type()
{
    get_device_property "$1" "DeviceType"
}

get_device_path_by_device_type()
{
    device_path_by_device_type="/"
    for device_path in `get_devices_paths`
    do
        device_type=`get_device_type "$device_path"`
        [ "$device_type" = "$1" ] && device_path_by_device_type="$device_path"
    done
    echo "$device_path_by_device_type"
}


    #######################
    # ACTIVES CONNECTIONS #
    #######################

get_actives_connections_paths()
{
    dbus-send --system --print-reply --dest="org.freedesktop.NetworkManager" "/org/freedesktop/NetworkManager" "org.freedesktop.DBus.Properties.Get" string:"org.freedesktop.NetworkManager" string:"ActiveConnections" \
    | grep "object path" | cut -d '"' -f2
}

get_last_active_connection_path()
{
    get_actives_connections_paths | tail -n 1
}

get_parent_connection_path_by_device_type()
{
    parent_connection_path="/"
    [ "$1" = 0 ] && parent_connection_path=`get_last_active_connection_path`
    echo "$parent_connection_path"
}

get_active_connection_property()
{
    dbus-send --system --print-reply --dest="org.freedesktop.NetworkManager" "$1" "org.freedesktop.DBus.Properties.Get" string:"org.freedesktop.NetworkManager.Connection.Active" string:"$2" \
    | grep variant | awk -F '"' '{print $2}'
}

get_active_connection_service()
{
    get_active_connection_property "$1" "ServiceName"
}

get_active_connection_path()
{
    get_active_connection_property "$1" "Connection"
}

get_active_connection_path_by_connection_path()
{
    for active_connection_path in `get_actives_connections_paths`
    do
        service=`get_active_connection_service $active_connection_path`
        path=`get_active_connection_path $active_connection_path`
        [ "$service" = "$1" ] && [ "$path" = "$2" ] && echo "$active_connection_path"
    done
}

print_actives_connections_ids()
{
    for active_connection_path in `get_actives_connections_paths`
    do
        service=`get_active_connection_service $active_connection_path`
        path=`get_active_connection_path $active_connection_path`
        connection_settings=`get_connection_settings "$service" "$path"`
        connection_settings_id=`get_connection_id "$connection_settings"`
        echo "$connection_settings_id"
    done
}


    ##############
    # START/STOP #
    ##############

start_connection()
{
    my_connection_complete_path=`find_connection_path_everywhere "$1"`
    my_connection_settings=`get_connection_settings $my_connection_complete_path`
    my_connection_type=`get_connection_type "$my_connection_settings"`
    my_connection_device_type=`get_device_type_by_connection_type "$my_connection_type"`
  
    my_connection_service=`echo $my_connection_complete_path | awk '{print $1}'`
    my_connection_path=`echo $my_connection_complete_path | awk '{print $2}'`
    my_connection_device_path=`get_device_path_by_device_type "$my_connection_device_type"`
    my_parent_connection_path=`get_parent_connection_path_by_device_type "$my_connection_device_type"`
  
#    echo "connection_service=$my_connection_service"
#    echo "connection_path=$my_connection_path"
#    echo "connection_device_path=$my_connection_device_path"
#    echo "parent_connection_path=$my_parent_connection_path"
  
    dbus-send --system --print-reply --dest="org.freedesktop.NetworkManager" /org/freedesktop/NetworkManager "org.freedesktop.NetworkManager.ActivateConnection" string:"$my_connection_service" objpath:"$my_connection_path" objpath:"$my_connection_device_path" objpath:"$my_parent_connection_path"
}

stop_connection()
{
    my_connection_complete_path=`find_connection_path_everywhere "$1"`
    my_active_connection_path=`get_active_connection_path_by_connection_path $my_connection_complete_path`
  
    echo "active_connection_path=$my_active_connection_path"
  
    dbus-send --system --print-reply --dest="org.freedesktop.NetworkManager" /org/freedesktop/NetworkManager "org.freedesktop.NetworkManager.DeactivateConnection" objpath:"$my_active_connection_path"
}


    ########
    # MAIN #
    ########

invalid_arguments()
{
    echo "Usage: `basename "$0"` connexion_name start|stop"
    echo "Connexion disponibles:"
    print_connections_ids_everywhere
    echo "Connexion actives:"
    print_actives_connections_ids
    exit 0
}

[ "$#" != 2 ] && invalid_arguments

case "$2" in
    "start")
        start_connection "$1"
            ;;
    "stop")
        stop_connection "$1"
        ;;
    "restart")
        stop_connection "$1"
        start_connection "$1"
        ;;
    "status")
        if print_actives_connections_ids | grep -q -x "$1"
        then
            echo "Connexion \"$1\" active"
            exit 0
        else
            echo "Connexion \"$1\" inactive"
            exit 1
        fi
        ;;
    *)
        invalid_arguments
        ;;
esac

3 commentaires:

  1. Rendons à césar ce qui est à césar. Ce n'est pas mon blog. C'est un blog créé par un fan de vpn et une bande de doux-dingues (en tout cas c'est mon cas) passioné et ravi d'explorer ce nouveau terrain de jeu ou beaucoup de choses reste à faire pour le démocratiser et le populariser.

    Mon site, celui dont je suis le webmestre, n'est pas franchement dans le même sujet.

    Si tu pouvais corriger ça serait sympa.

    Merci

    RépondreSupprimer
  2. @spiritism
    César va être content, c'est corrigé !

    RépondreSupprimer
  3. @papillon

    il vous en remercie :D

    Au passage j'ai une nouvelle version qui corrige un bug (celui de la reconnection en cas de chute de bp ... Désolé pour ta fierté de programmeur mais la commande ne marchait pas ... bon l'honneur est sauf le principe était le bon ... c'est ce qui compte)

    Voici le lien http://www.toofiles.com/fr/oip/documents/tar.gz/7465_vpn-auto-reconnection.html

    Stay tuned ;)

    RépondreSupprimer