如何在 OS X 上连接到 VPN 后自动运行脚本?

如何在 OS X 上连接到 VPN 后自动运行脚本?

我已经在 OS X 10.7.3 中配置了 VPN 连接,但由于我连接的网络使用公司代理,具有自定义 Maven 存储库服务器和其他特定于网络的设置(例如远程驱动器),所以我想在登录/注销 VPN 时运行脚本来:

  • 更改 Maven~/.m2/settings.xml以指向他们的 maven repo
  • 绘制一些smb://共享图,
  • 为某些命令设置别名以使用它们的服务器

但我不知道如何实现这一点。

  1. 如何执行脚本或命令集自动地登录
  2. 如何执行脚本或命令集自动地注销

答案1

如果您已经配置了 VPN,则可以通过命令行连接到它。正如我所解释的那样在这个答案中,您可以分别创建两个用于登录和注销的 shell 函数,方法是将它们添加到您的~/.bash_profile– 请参阅该函数的链接答案vpn-disconnect

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
        end tell
end tell
EOF 
# insert your commands here
}

只需在标记后包含您需要的自定义命令EOF


如果你想用 GUI 方式来做,请打开Automator.app并创建一个新的应用。然后,从左侧窗格拖动操作以运行 AppleScript 和 Shell 脚本,并插入命令,如下所示。

然后,您只需将该伪应用程序放入 Dock 即可快速启动它。

答案2

另一个解决方案是使用LaunchDaemon监视特定目录,并在该目录发生修改时启动外部脚本。Mac 开发人员库提供了一个此类脚本的概要(每当该文件的修改时间发生变化时,它们的示例就会监视/etc/hostconfig并运行。)syslog -s -l notice "somebody touched /etc/hostconfig"

为了达到我们的目的,我们注意到每次您登录 VPN 时,目录/Library/Preferences/SystemConfiguration都会被修改。因此,如果您将以下 plist 文件保存在里面/Library/LaunchDaemons/vpn.connectscript.plist,它将监视该目录:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
      "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>vpn.connectscript</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>/opt/local/bin/vpn_some_script.sh</string>
    </array>
    <key>WatchPaths</key>
    <array>
        <string>/Library/Preferences/SystemConfiguration</string>
    </array>
</dict>
</plist>

请注意,此 LaunchDaemon 不仅会在 VPN 连接时调用(例如,每次连接到 wifi 时)。因此,您的脚本/opt/local/bin/vpn_some_script.sh应该检查隧道是否确实已连接,并且如果脚本连续运行多次,则不应产生问题。(因此,如果您安装共享,您可能需要检查它们是否尚未安装)。

例如,我的脚本/opt/local/bin/vpn_some_script.sh很简单:

#!/bin/bash                                                                                                             

# This only changes the routes table if utun0 exists.                                                                   
# -n checks that `ifconfig utun0` returns something other than "" on STDOUT                                             
# The 2> /dev/null redirects STDERR to null, to silence errors                                                          
if [[ -n `ifconfig utun0 2> /dev/null` ]] ; then
   route -n add -net 10.0.0.0/8 -interface utun0

   # Find the old default gateway                                                                                       
   GATEWAY=`route -n get default -ifscope en0 | grep gateway | awk '{ print $2 }'`
   # make everything (except blocks described above) go through old default gateway rather than VPN                     
   route -n change default $GATEWAY
fi

如果我连接到 VPN 隧道(并将默认值更改为转到 192.168.1.1 路由器),它只会通过隧道添加到 10.0.0.0/8 的路由。

保存 plist 文件后,下次重启时会自动加载。不过,您也可以使用以下命令手动加载它:

sudo launchctl load -w /Library/LaunchDaemons/vpn.connectscript.plist

注意,如果您的 bash 脚本需要 root 权限(例如,我的脚本会更改路由表),则需要将其存储在/Library/LaunchDaemons/(或/System/Library/LaunchDaemons)中。如果您的脚本需要以普通用户身份运行,则应将其存储在 中 ~/Library/LaunchAgents/

如果您的脚本以 root 身份运行,并且不想遭受特权升级攻击,则被调用的 bash 脚本应位于/opt/local/bin/只有 root 才能修改的目录中。如果您存储在~/bin普通用户可以更改脚本(或重命名文件/目录并将其替换为他们编写的文件)并获得对系统的完全访问权限。

答案3

/etc/ppp/ip-up用于连接前脚本,以及/etc/ppp/ip-down连接后脚本。不要忘记添加执行权限位。我使用它们来在 PPTP 和 L2TP VPN 连接之前和之后更改和恢复路由表。

编写名为ip-up和 的两个脚本后ip-down,在 Terminal.app 中运行以下命令:

chmod +x ip-up ip-down
sudo cp ip-up ip-down /etc/ppp

相关内容