Comment créer une connexion VPN via un terminal?

9

J'ai un macbook pro avec des non-conformistes en cours d'exécution. Je cherche un moyen de me connecter à un réseau VPN dans le terminal.

La raison pour laquelle je veux le faire est que je veux écrire un petit programme en Python qui détecte automatiquement le serveur VPN le plus rapide parmi 30 serveurs. Il s'agit d'un projet de pratique motivé, donc je pense que je m'en tiendrai au langage Python. Je décompose donc la tâche et pense que le programme peut avoir besoin de se connecter d'abord à l'un des serveurs et ensuite, d'exécuter un test de vitesse.

Je suis donc maintenant bloqué dans cette première étape parce que j'ai réalisé que l'établissement d'une connexion VPN semble être au niveau du système car je ne trouve pas de module VPN pré-écrit en python. Je suppose donc que ce sera comme si je dis à Python de dire au shell du système de se connecter à un serveur VPN.

En fouillant, j'ai trouvé une commande en tapant apropos vpn. Ça s'appelle vpnagent. Mais man vpnagentne fournit pas d'informations utiles et ne which vpnagentme dit pas que l'utilitaire n'est pas installé sur mon Mac. Une autre chose intéressante que j'ai trouvée était, pppdmais la configuration du fichier de configuration était très frustrante. Je n'ai pas réussi à faire ça.

Existe-t-il un moyen de se connecter au VPN à l'aide d'un terminal? De plus, comme je suis nouveau dans la programmation, tout commentaire sur mon projet est également le bienvenu. Merci d'avance.

Choushishi
la source

Réponses:

6

Vous pouvez utiliser ces merveilleuses fonctions bash de @slhck sur Super User :

Pour vous connecter à différents VPN, disposez de plusieurs VPN dans Network.prefpane.

function vpn-connect {
/usr/bin/env osascript <<-EOF
tell application "System Events"
        tell current location of network preferences
                set VPN to service "UniVPN" -- your VPN name here
                if exists VPN then connect VPN
                repeat while (current configuration of VPN is not connected)
                    delay 1
                end repeat
        end tell
end tell
EOF
}
function vpn-disconnect {
/usr/bin/env osascript <<-EOF
tell application "System Events"
        tell current location of network preferences
                set VPN to service "UniVPN" -- your VPN name here
                if exists VPN then disconnect VPN
        end tell
end tell
return
EOF
}

N'oubliez pas de changer le nom du VPN.

grg
la source
Merci ça marche. Mais il devient difficile de devoir changer le nom du VPN à ~/.bash-profilechaque fois que je dois me connecter à un autre VPN . Existe-t-il un moyen d'ajouter un argument dans la fonction, donc je peux appeler comme vpn-connect UniVPN?
Choushishi
@Choushishi Vous pouvez simplement créer plusieurs fonctions avec différents noms et différents VPN. Dupliquez la fonction et modifiez le nom de la fonction sur la première ligne et le nom du VPN.
grg
Merci, c'est une bonne solution. Je pense que j'essaierai toujours de trouver un moyen d'ajouter des arguments pour le rendre plus élégant
Choushishi
1
@Choushishi, vous pouvez lui faire prendre un argument simplement en le remplaçant UniVPNpar $1. (tout en gardant les guillemets doubles)
Timothée Boucher
6

scutil devrait être tout ce dont vous avez besoin.

scutil --nc start <service name>

Ainsi, votre script Python pour vous connecter à chacun à son tour peut inclure quelque chose comme ceci:

import re
from subprocess import call, check_output

vpns_string = check_output(["scutil", "--nc", "list"]) # lists all VPN services

vpns = re.findall('"(.+)"', vpns_string) # service names are double-quoted

for vpn in vpns:
  call(["scutil", "--nc", "start", vpn])
  #...do stuff with your connection, test speed etc.
  call(["scutil", "--nc", "stop", vpn])

Vous pouvez éventuellement spécifier un nom d'utilisateur, un mot de passe et un secret pour vous connecter - voir scutil --nc helppour l'utilisation.

MatzFan
la source
2
#!/bin/sh
# Random UUID for this config
vpnUuid=``
# Address of VPN server
serverName=""
# The group of usernames that is allowed in
groupName=""
# The name of connection type displayed in GUI
labelName=""
# The Shared Secret
sharedSecret=""
# The user this VPN config is for
userName=""

# CHECK TO SEE IF A VALUE WAS PASSED IN PARAMETER 4 AND, IF SO, ASSIGN TO "serverName"
if [ "$4" != "" ] && [ "$ranAtImaging" == "" ]; then
    ranAtImaging=$4
fi

# CHECK TO SEE IF A VALUE WAS PASSED IN PARAMETER 5 AND, IF SO, ASSIGN TO "serverName"
if [ "$5" != "" ] && [ "$serverName" == "" ]; then
    serverName=$5
fi

# CHECK TO SEE IF A VALUE WAS PASSED IN PARAMETER 6 AND, IF SO, ASSIGN TO "groupName"
if [ "$6" != "" ] && [ "$groupName" == "" ]; then
    groupName=$6
fi

# CHECK TO SEE IF A VALUE WAS PASSED IN PARAMETER 7 AND, IF SO, ASSIGN TO "labelName"
if [ "$7" != "" ] && [ "$labelName" == "" ]; then
    labelName=$7
fi

# CHECK TO SEE IF A VALUE WAS PASSED IN PARAMETER 8 AND, IF SO, ASSIGN TO "sharedSecret"
if [ "$8" != "" ] && [ "$sharedSecret" == "" ]; then
    sharedSecret=$8
fi

# CHECK TO SEE IF A VALUE WAS PASSED IN PARAMETER 9 AND, IF SO, ASSIGN TO "userName"
if [ "$9" != "" ] && [ "$userName" == "" ]; then
    userName=$9
fi

loggedInUser=`/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }'`
macModel=`system_profiler SPHardwareDataType | grep "Model Name:" | awk '{ print $3 }'`

# Check that we are running this on a MacBook
if [ "$macModel" == "MacBook" ]; then

    # Setup Keychain shared secret granting appropriate access for the OS apps
    /usr/bin/security add-generic-password -a "$groupName" -l "$labelName" -D "IPSec Shared Secret" -w "$sharedSecret" -s "$vpnUuid".SS -T /System/Library/Frameworks/SystemConfiguration.framework/Resources/SCHelper -T /Applications/System\ Preferences.app -T /System/Library/CoreServices/SystemUIServer.app -T /usr/sbin/pppd -T /usr/sbin/racoon /Library/Keychains/System.keychain

    # Write a Network Config containing this keychain item directly to System Config
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:DNS dict" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:IPv4 dict" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:IPv4:ConfigMethod string Automatic" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:IPv6 dict" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:Proxies dict" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:Proxies:ExceptionList array" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:Proxies:ExceptionList:0 string \*\.local" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:Proxies:ExceptionList:1 string 169\.254\/16" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:Proxies:FTPPassive integer 1" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:SMB dict" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:UserDefinedName string $labelName" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:Interface dict" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:Interface:Type string IPSec" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:IPSec dict" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:IPSec:AuthenticationMethod string SharedSecret" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:IPSec:LocalIdentifier string $groupName" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:IPSec:LocalIdentifierType string KeyID" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:IPSec:RemoteAddress string $serverName" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:IPSec:SharedSecret string $vpnUuid\.SS" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:IPSec:SharedSecretEncryption string Keychain" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:IPSec:XAuthName string $userName" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :NetworkServices:$vpnUuid:IPSec:XAuthPasswordEncryption string Prompt" /Library/Preferences/SystemConfiguration/preferences.plist

    # At this point, we should have only one Network Set (Automatic) so we find out its UUID — errr, messy
    autoUuid=`/usr/libexec/Plistbuddy -c "Print :Sets" /Library/Preferences/SystemConfiguration/preferences.plist | grep -B1 -m1 Automatic | grep Dict | awk '{ print $1 }'`

    # and we add our newly created config to the default set
    /usr/libexec/PlistBuddy -c "Add :Sets:$autoUuid:Network:Service:$vpnUuid dict" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :Sets:$autoUuid:Network:Service:$vpnUuid:__LINK__ string \/NetworkServices\/$vpnUuid" /Library/Preferences/SystemConfiguration/preferences.plist
    /usr/libexec/PlistBuddy -c "Add :Sets:$autoUuid:Network:Global:IPv4:ServiceOrder: string $vpnUuid" /Library/Preferences/SystemConfiguration/preferences.plist

else
    echo "This mac is not a MacBook… so skipping…"
fi
davidcondrey
la source