¿Cómo crear una conexión VPN a través de la terminal?

9

Tengo un macbook pro con mavericks en ejecución. Estoy buscando una manera de conectarme a una red VPN en la terminal.

La razón por la que quiero hacer esto es que quiero escribir un pequeño programa en Python que detecte automáticamente el servidor VPN más rápido entre 30 servidores. Este es un proyecto de práctica motivado, así que creo que me quedaré con el lenguaje Python. Así que desgloso la tarea y creo que el programa puede necesitar conectarse a uno de los servidores primero y luego ejecutar una prueba de velocidad.

Así que ahora estoy atrapado en este primer paso porque me di cuenta de que establecer una conexión VPN parece estar por debajo del nivel del sistema porque no puedo encontrar el módulo VPN preescrito en Python. Entonces supongo que será como decirle a Python que le diga al shell del sistema que se conecte a un servidor VPN.

Mientras hurgaba y encontré un comando escribiendo apropos vpn. Se llama vpnagent. Pero man vpnagentno proporciona información útil ni which vpnagentme dice que la utilidad no está instalada en mi Mac. Otra cosa interesante que encontré fue que pppdconfigurar el archivo de configuración fue muy frustrante. No pude hacer eso.

Entonces, ¿hay alguna manera de conectarse a VPN usando la terminal? Además, como soy nuevo en programación, cualquier comentario sobre mi proyecto también es bienvenido. Gracias de antemano.

Choushishi
fuente

Respuestas:

6

Puede utilizar estas maravillosas funciones de bash de @slhck en Super User :

Para conectarse a diferentes VPN, tenga varias VPN en 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
}

No olvides cambiar el nombre de la VPN.

grg
fuente
Gracias funciona. Pero se vuelve desagradable que necesito cambiar el nombre de la VPN ~/.bash-profilecada vez que necesito conectarme a otra VPN . ¿Hay alguna forma de agregar argumentos a la función, para que pueda llamar como vpn-connect UniVPN?
Choushishi
@Choushishi Puede crear múltiples funciones con diferentes nombres y diferentes VPN. Duplique la función y cambie el nombre de la función en la primera línea y el nombre de VPN.
grg
Gracias, esta es una buena solución. Creo que todavía intentaré encontrar una manera de agregar argumentos para hacerlo más elegante
Choushishi
1
@Choushishi puedes hacer que tome una discusión simplemente reemplazando UniVPNpor $1. (manteniendo las comillas dobles)
Timothée Boucher
6

scutil debe ser todo lo que necesitas.

scutil --nc start <service name>

Por lo tanto, su script de Python para conectarse a cada uno puede incluir algo como esto:

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])

Opcionalmente, puede especificar el nombre de usuario, la contraseña y el secreto para conectarse; consulte el scutil --nc helpuso.

MatzFan
fuente
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
fuente