BSoft&Co Humeurs et Rumeurs

20Jan/100

(re)connexion automatique à un VPN sous Ubuntu

En ces temps peu glorieux d'Hadopi et tous ses dérivés... un bon moyen de pouvoir surfer sans être espionné, est d'utiliser un VPN.

Pour ma part, j'ai été confronté à des problèmes de déconnexions intempestives, sans reconnexion automatique. Ce qui peut être parfois gênant...

Voilà donc un (bon) moyen de palier ce problème. Ce n'est surement pas la meilleure solution, et je ne suis pas un fou de linux.. mais au moins, elle me satisfait!

Cette solution se compose de 2 fichiers. Un "check_vpn" qui se charge de lancer le script principal à intervalles définis. Et "vpn_restart.py", script en python qui relance la connexion si celle ci déconnectée.

check_vpn

#!/bin/bash
  1.  
  2. while [ 1 ]; do
  3.     echo -n $(date) "##  "
  4.     sudo /home/bsoft/Bureau/vpn_restart.py #où le script est installé
  5.     sleep 60  #en secondes, temps de boucle du script
  6. done

vpn_restart.py

#!/usr/bin/python
  1. #http://ubuntuforums.org/showthread.php?t=1316314
  2. import sys
  3. import os
  4. import dbus
  5. import gobject
  6. from  dbus.mainloop.glib import DBusGMainLoop
  7.  
  8. # The uuid of the VPN connection to activate
  9. VPN_CONNECTION_UUID = "20d3d577-51b4-435c-b408-2a3f3c8a5463"
  10.  
  11. # The uuid of the connection that needs to be active to start the VPN connection
  12. ACTIVE_CONNECTION_UUID = "recupere via get_active_conn(bus)"
  13.  
  14. # Mon conn ID
  15. CONN_ID = "Auto eth0"
  16. # Mon conn['type']
  17. CONN_TYPE = "802-3-ethernet"
  18.  
  19. # some service, path and interface constants
  20. NM_DBUS_SERVICE                   = "org.freedesktop.NetworkManager"
  21. NM_DBUS_PATH                      = "/org/freedesktop/NetworkManager"
  22. NM_DBUS_INTERFACE                 = "org.freedesktop.NetworkManager"
  23. NM_DBUS_IFACE_CONNECTION_ACTIVE   = "org.freedesktop.NetworkManager.Connection.Active"
  24. NM_DBUS_SERVICE_SYSTEM_SETTINGS   = "org.freedesktop.NetworkManagerSystemSettings"
  25. NM_DBUS_SERVICE_USER_SETTINGS     = "org.freedesktop.NetworkManagerUserSettings"
  26. NM_DBUS_IFACE_SETTINGS            = "org.freedesktop.NetworkManagerSettings"
  27. NM_DBUS_PATH_SETTINGS             = "/org/freedesktop/NetworkManagerSettings"
  28. NM_DBUS_IFACE_SETTINGS_CONNECTION = "org.freedesktop.NetworkManagerSettings.Connection"
  29.  
  30. DBusGMainLoop(set_as_default=True)
  31.  
  32. nm_dbus_settings_services = (NM_DBUS_SERVICE_SYSTEM_SETTINGS, NM_DBUS_SERVICE_USER_SETTINGS)
  33.  
  34. def get_connections(bus, service):
  35.     proxy = bus.get_object(service, NM_DBUS_PATH_SETTINGS)
  36.     iface = dbus.Interface(proxy, dbus_interface=NM_DBUS_IFACE_SETTINGS)
  37.     return iface.ListConnections()
  38.  
  39. def get_connection_by_uuid(bus, uuid):
  40.     for service in nm_dbus_settings_services:
  41.         for c in get_connections(bus, service):
  42.             proxy = bus.get_object(service, c)
  43.             iface = dbus.Interface(proxy, dbus_interface = NM_DBUS_IFACE_SETTINGS_CONNECTION)
  44.             settings = iface.GetSettings()
  45.             if settings['connection']['uuid'] == uuid:
  46.                 return (c, service)
  47.     return None
  48.  
  49. def list_uuids(bus):
  50.     for service in nm_dbus_settings_services:
  51.         for c in get_connections(bus, service):
  52.             proxy = bus.get_object(service, c)
  53.             iface = dbus.Interface(proxy, dbus_interface=NM_DBUS_IFACE_SETTINGS_CONNECTION)
  54.             settings = iface.GetSettings()
  55.             conn = settings['connection']
  56.             print "%s: %s - %s (%s)" % (service, conn['uuid'], conn['id'], conn['type'])
  57.  
  58. # recupere l'uuid de la connexion active via CONN_ID et CONN_TYPE
  59. def get_active_conn(bus):
  60.     for service in nm_dbus_settings_services:
  61.         for c in get_connections(bus, service):
  62.             proxy = bus.get_object(service, c)
  63.             iface = dbus.Interface(proxy, dbus_interface=NM_DBUS_IFACE_SETTINGS_CONNECTION)
  64.             settings = iface.GetSettings()
  65.             conn = settings['connection']
  66.             if conn['id'] == CONN_ID and conn['type'] == CONN_TYPE:
  67.     return conn['uuid']
  68.  
  69. def get_active_connection_path(bus, uuid):
  70.     proxy = bus.get_object(NM_DBUS_SERVICE, NM_DBUS_PATH)
  71.     iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.DBus.Properties')
  72.     active_connections = iface.Get(NM_DBUS_INTERFACE, 'ActiveConnections')
  73.     connection_and_service = get_connection_by_uuid(bus, uuid)
  74.     if connection_and_service == None:
  75.         return None
  76.     for a in active_connections:
  77.         proxy = bus.get_object(NM_DBUS_SERVICE, a)
  78.         iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.DBus.Properties')
  79.         path = iface.Get(NM_DBUS_IFACE_CONNECTION_ACTIVE, 'Connection')
  80.         service = iface.Get(NM_DBUS_IFACE_CONNECTION_ACTIVE, 'ServiceName')
  81.         if service != connection_and_service[1]:
  82.             continue
  83.         proxy = bus.get_object(connection_and_service[1], path)
  84.         iface = dbus.Interface(proxy, dbus_interface=NM_DBUS_IFACE_SETTINGS_CONNECTION)
  85.         settings = iface.GetSettings()
  86.         if settings['connection']['uuid'] == uuid:
  87.             return a
  88.     return None
  89.  
  90. def activate_connection(bus, vpn_connection, active_connection):
  91.     def reply_handler(opath):
  92.         print "<<SUCCESS>>"
  93.         sys.exit(0)
  94.     def error_handler(*args):
  95.         print "<<FAILURE>>"
  96.         sys.exit(1)
  97.     proxy = bus.get_object(NM_DBUS_SERVICE, NM_DBUS_PATH)
  98.     iface = dbus.Interface(proxy, dbus_interface=NM_DBUS_INTERFACE)
  99.     iface.ActivateConnection(NM_DBUS_SERVICE_USER_SETTINGS,
  100.         vpn_connection[0],
  101.         dbus.ObjectPath("/"),
  102.         active_connection,
  103.         reply_handler=reply_handler,
  104.         error_handler=error_handler)
  105.  
  106. bus = dbus.SystemBus()
  107.  
  108. print "connections:"
  109. list_uuids(bus)
  110.  
  111. ACTIVE_CONNECTION_UUID = get_active_conn(bus)
  112.  
  113. if len(VPN_CONNECTION_UUID) < 1 or len(ACTIVE_CONNECTION_UUID) < 1:
  114.     print "you need to set the uuids"
  115.     sys.exit(0)
  116.  
  117. vpn_connection = get_connection_by_uuid(bus, VPN_CONNECTION_UUID)
  118. if not vpn_connection:
  119.     print "Configured VPN connection is not known to NM, check VPN_CONNECTION_UUID."
  120.     sys.exit(1)
  121.  
  122. active_connection = get_connection_by_uuid(bus, ACTIVE_CONNECTION_UUID)
  123. if not active_connection:
  124.     print "Configured active connection is not known to NM, check ACTIVE_CONNECTION_UUID."
  125.     sys.exit(1)
  126.  
  127. if get_active_connection_path(bus, VPN_CONNECTION_UUID) != None:
  128.     print "VPN connection already activated"
  129.     sys.exit(0)
  130.  
  131. active_connection_path = get_active_connection_path(bus, ACTIVE_CONNECTION_UUID)
  132. if not active_connection_path:
  133.     print "The required connection isn't active at the moment"
  134.     sys.exit(0)
  135.  
  136. print "connecting to:\n  '%s'\nwith active connection:\n  '%s'" % (vpn_connection, active_connection)
  137.  
  138. activate_connection(bus, vpn_connection, active_connection_path)
  139.  
  140. loop = gobject.MainLoop()
  141. loop.run()

Le script python peut très facilement être amélioré. On peut imaginer par exemple de fermer certaines applications lorsque la connexion VPN est morte..

Pour faire fonctionner le tout, il suffit de copier le script python où vous voulez.
Puis, de copier en admin (sudo) le script check_vpn dans /etc/init.d
Il faut le rendre exécutable (chmod u+x nom_du_fichier)
Puis il faut créer un lien symbolique du script dans /etc/rc2.d afin que celui ci démarre automatique avec le système.
ln -s /etc/init.d/check_vpn /etc/rc2.d/S88check_vpn

Et voilà!
Chez moi, sous Ubuntu 9.04, ca fonctionne très bien. Il faut bien entendu au préalable avoir une connexion VPN de configurée dans le network manager.

Comments (0) Trackbacks (1)

Leave a comment

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Anti-spam image

Click to Insert Smiley

SmileBig SmileGrinLaughFrownBig FrownCryNeutralWinkKissRazzChicCoolAngryReally AngryConfusedQuestionThinkingPainShockYesNoLOLSillyBeautyLashesCuteShyBlushKissedIn LoveDroolGiggleSnickerHeh!SmirkWiltWeepIDKStruggleSide FrownDazedHypnotizedSweatEek!Roll EyesSarcasmDisdainSmugMoney MouthFoot in MouthShut MouthQuietShameBeat UpMeanEvil GrinGrit TeethShoutPissed OffReally PissedMad RazzDrunken RazzSickYawnSleepyDanceClapJumpHandshakeHigh FiveHug LeftHug RightKiss BlowKissingByeGo AwayCall MeOn the PhoneSecretMeetingWavingStopTime OutTalk to the HandLoserLyingDOH!Fingers CrossedWaitingSuspenseTremblePrayWorshipStarvingEatVictoryCurseAlienAngelClownCowboyCyclopsDevilDoctorFemale FighterMale FighterMohawkMusicNerdPartyPirateSkywalkerSnowmanSoldierVampireZombie KillerGhostSkeletonBunnyCatCat 2ChickChickenChicken 2CowCow 2DogDog 2DuckGoatHippoKoalaLionMonkeyMonkey 2MousePandaPigPig 2SheepSheep 2ReindeerSnailTigerTurtleBeerDrinkLiquorCoffeeCakePizzaWatermelonBowlPlateCanFemaleMaleHeartBroken HeartRoseDead RosePeaceYin YangUS FlagMoonStarSunCloudyRainThunderUmbrellaRainbowMusic NoteAirplaneCarIslandAnnouncebrbMailCellPhoneCameraFilmTVClockLampSearchCoinsComputerConsolePresentSoccerCloverPumpkinBombHammerKnifeHandcuffsPillPoopCigarette