У меня есть MacBook Pro с работающими Mavericks. Я ищу способ подключения к сети VPN в терминале.
Причина, по которой я хочу это сделать, заключается в том, что я хочу написать небольшую программу на Python, которая автоматически определяет самый быстрый VPN-сервер среди 30 серверов. Это самостоятельный практический проект, поэтому я думаю, что буду придерживаться языка Python. Поэтому я разбиваю задачу и думаю, что программе может потребоваться сначала подключиться к одному из серверов, а затем запустить тест скорости.
Итак, я сейчас застрял на этом первом шаге, потому что понял, что установка VPN-соединения находится на системном уровне, потому что я не могу найти предварительно написанный модуль VPN в python. Так что я предполагаю, что это будет похоже на то, как если бы я сказал Python указать системной оболочке подключиться к VPN-серверу.
Когда я ковырялся, я нашел команду, набрав apropos vpn
. Это называется vpnagent
. Но man vpnagent
не предоставляет полезную информацию и не which vpnagent
говорит мне, что утилита не установлена на моем Mac. Еще одна интересная вещь, которую я обнаружил, заключалась pppd
в том, что настройка файла конфигурации была очень сложной. Мне это не удалось.
Так есть ли способ подключиться к VPN через терминал? Кроме того, поскольку я новичок в программировании, любые комментарии по моему проекту также приветствуются. Заранее спасибо.
Вы можете использовать эти замечательные функции bash от @slhck в Super User :
Чтобы подключиться к разным VPN, создайте несколько VPN в 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 }
Не забудьте изменить имя VPN.
scutil должен быть всем, что вам нужно.
scutil --nc start <service name>
Таким образом, ваш скрипт Python для подключения к каждому по очереди может включать что-то вроде этого:
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])
При желании вы можете указать имя пользователя, пароль и секрет для подключения - см scutil --nc help
. Использование.
#!/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
Чушиши
~/.bash-profile
каждый раз, когда мне нужно подключиться к другому VPN. Есть ли способ добавить аргумент в функцию, чтобы я мог вызывать какvpn-connect UniVPN
?грг
Чушиши
Тимоти Буше
UniVPN
на$1
. (при сохранении двойных кавычек)