Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have configured the VPN connection in OS X 10.7.3, but since the network I'm connecting to uses a corporate proxy, has custom Maven repository servers, and other network-specific settings (remote drives, for instance), I want to run a script on logon/logoff of a VPN to:

  • change the Maven ~/.m2/settings.xml to point to their maven repo
  • map a few smb:// shares,
  • alias some commands to use their servers

I don't know how to accomplish this, though.

  1. How do you execute a script or set of commands automatically on logon?
  2. How do you execute a script or set of commands automatically on logoff?
share|improve this question

2 Answers 2

up vote 4 down vote accepted

If you already have the VPN configured, you can connect to it via commandline. As I explained in this answer, you can create two shell functions for login and logout, respectively, by adding them to your ~/.bash_profile – see the linked answer for the vpn-disconnect function.

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
}

Just include the custom commands you need after the EOF marker.


If you want a GUI way to do it, open up Automator.app and create a new Application. Then, drag the actions to run an AppleScript and Shell script from the left pane, and insert the commands as shown below.

You can then just put this pseudo-application into your Dock to quickly launch it.

share|improve this answer
    
this work OK, but if you need to so something with the vpn network interface (like adding IPs to the route table for the VPN) this approach does not work completely as the shell script executes long before the VPN is connected –  Felipe Sabino Aug 12 '14 at 16:49
    
just found this discussions.apple.com/thread/2255494?start=0&tstart=0 the guys does a delay and waits for the VPN to connect before continuing :) –  Felipe Sabino Aug 12 '14 at 17:08
    
You mean the shell script "exits" before it is connected rather than "executes"? Yeah, a simple delay would do the trick – not aware of any other method. –  slhck Aug 12 '14 at 17:15

Another solution is to use a LaunchDaemon to monitor a specific directory and launch an external script whenever that directory has modifications. The Mac Developer Library gives an outline of such a script (their example monitors /etc/hostconfig and runs syslog -s -l notice "somebody touched /etc/hostconfig" whenever that files' modification time changes.)

For our purpose, we note that every time you login to your VPN the directory /Library/Preferences/SystemConfiguration gets modified. So if you save the following plist file inside /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>

Note that this LaunchDaemon will be called for more than just your VPN connecting (e.g., every time you connect to wifi). So your script /opt/local/bin/vpn_some_script.sh should have a check that the tunnel is actually connected and the script should not create issues if its run multiple times in a row. (So if you mount shares, you may want to check that they aren't already mounted).

For example, my script /opt/local/bin/vpn_some_script.sh is simply:

#!/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

which only adds the route to 10.0.0.0/8 through the tunnel if I am connected to the VPN tunnel (and change the default to go to the 192.168.1.1 router).

When you save the plist file, it will automatically be loaded on next reboot. However, you can also manually load it with:

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

Note, if your bash script needs root permissions (e.g., my script which changes the routing table), you need to store it in /Library/LaunchDaemons/ (or /System/Library/LaunchDaemons). If your script should be run as a normal user you should store it in ~/Library/LaunchAgents/.

If your script runs as root and do not want to suffer privilege escalation attacks, the bash script that is being called should be in a directory like /opt/local/bin/ that can only be modified by root. If you stored in say ~/bin a regular user could alter the script (or rename the file/directory and replace it with a file they wrote) and gain full access to your system.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.