9

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?

3 Answers 3

10

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.

4
  • 1
    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 Aug 12, 2014 at 16:49
  • 1
    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 :) Aug 12, 2014 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, 2014 at 17:15
  • 1
    This won't work with IKEv2 VPNs. Here's how you can do that: matt.coneybeare.me/… -service-on-your-mac/
    – coneybeare
    Sep 30, 2017 at 21:38
10

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 file's 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, it will watch that directory:

<?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.

0
5

/etc/ppp/ip-up for pre-connection script, and /etc/ppp/ip-down for post-connection script. Do not forget to add execution permission bit. I use them for changing and restoring the route table before and after PPTP and L2TP VPN connections.

After you've written the two script named ip-up and ip-down, you run the following commands in the Terminal.app:

chmod +x ip-up ip-down
sudo cp ip-up ip-down /etc/ppp
3
  • Need more elaboration here, please...
    – lobi
    Jun 3, 2016 at 21:06
  • 1
    @lobi, I've added the commands. Hope they help you. Jun 4, 2016 at 8:28
  • 1
    Is there something like this for IPSec VPN connections, too?
    – not2savvy
    Jan 10, 2021 at 21:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .