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 two VPN configurations on my mac and I would like to be able to start them from the console when I ssh into my machine.

I have found the command networksetup which allows me to configure connections, but as far as I can tell not actually start one.

Using Lion.

share|improve this question

4 Answers 4

up vote 19 down vote accepted

You can use AppleScript to connect to the VPN services of your choice. We'll use shell functions, which are available from the command line, once they are loaded.

Add the functions below to your ~/.bash_profile or ~/.profile (whatever you use).

You just need to change the name of the VPN connection itself, as it appears under the Network preferences. I used my university VPN here.

enter image description here

You can change the names of the functions as well, if you want to do it for different ones. It might be possible to shorten this using arguments, but it works just fine this way. I tested it on Snow Leopard (but Leopard and Lion should work too).

Once you've added the functions, reload the terminal and call them with vpn-connect and vpn-disconnect, respectively.


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
}
share|improve this answer
    
I got this sort of working by putting in backticks like in boulder_ruby's code. However ideally it would wait for a callback before returning. My goal is to run vpn-connect && git fetch && vpn-disconnect. Do you think there's a way to do this? –  Michael Forrest Jan 24 '13 at 17:13
    
Good idea. I updated my script… just tested it and it seems to work. –  slhck Jan 24 '13 at 17:51
    
Awesome, thank you! –  Michael Forrest Jan 25 '13 at 10:02
    
This may be obvious but just for the record: It seems you actually need a GUI session open for this to work. When I login via SSH while there is a GUI session of the same user active on that machine and call vpn-connect it does throw a syntax error: Expected end of line but found identifier. (-2741) but after having converted it to an Application with the AppleScript editor and calling open vpn-connect.app it works. However if there is no active GUI session of that user a LSOpenURLsWithRole() failed with error -10810 is thrown when calling it via SSH. –  Stefan Schmidt Dec 16 '13 at 21:05

Haven't tested this under Lion but but I'm using following command under Mountain Lion without any problem:

networksetup -connectpppoeservice UniVPN
share|improve this answer
    
This should work this utility was added back in '02. –  El Developer Jul 6 '13 at 20:53
1  
Yes, surprisingly this approach does work even though the switch is not for VPN services but for PPPoE services, but disconnecting doesn't work this way. –  Stefan Schmidt Dec 16 '13 at 21:11

You can also, as of at least Lion1, use the scutil command.

For example, if I have a VPN service named "Foo", I could connect via:

$ scutil --nc start Foo

I can optionally specify a username, password, and secret using flags of the same names:

$ scutil --nc start Foo --username bar --password baz --secret quux

The service can be disconnected via:

$ scutil --nc stop Foo

For more detailed help, you can see the man page, or run:

$ scutil --nc help

Update

Adding a quick script to poll until the connection is established (in response to the comment from Eric B.

#!/bin/bash

# Call with <script> "<VPN Connection Name>"

set -e
#set -x

vpn="$1"

function isnt_connected () {
    scutil --nc status "$vpn" | sed -n 1p | grep -qv Connected
}

function poll_until_connected () {
    let loops=0 || true
    let max_loops=200 # 200 * 0.1 is 20 seconds. Bash doesn't support floats

    while isnt_connected "$vpn"; do
        sleep 0.1 # can't use a variable here, bash doesn't have floats
        let loops=$loops+1
        [ $loops -gt $max_loops ] && break
    done

    [ $loops -le $max_loops ]
}

scutil --nc start "$vpn"

if poll_until_connected "$vpn"; then
    echo "Connected to $vpn!"
    exit 0
else
    echo "I'm too impatient!"
    scutil --nc stop "$vpn"
    exit 1
fi

Footnotes:

  1. It's not clear when this command was added to OSX, I have it in Mavericks, and user Eric B. reports that it works in Lion (10.7.5).
share|improve this answer
    
Just tried this in Lion (10.7.5) and it works great. Just not documented in the man pages. Thanks! –  Eric B. Apr 2 at 18:59
    
Any wait to get scutil to wait until the connection is complete before returning? I need to run a script once the connection is established, but scutil returns too quickly and the following command is executed before the connection is established. –  Eric B. Apr 2 at 19:12
    
@EricB. See my updates for a quick script. –  encoded Apr 3 at 4:22

I just used the above script by slhck (who is clearly a golden god) to create this nifty ruby script that could be used for all sorts of things

class SwitchIp

def go
  turn_off
  sleep 3
  turn_on
end

def turn_on
  `/usr/bin/env osascript <<-EOF
      tell application "System Events"
        tell current location of network preferences
            set VPN to service "StrongVPN" -- your VPN name here
            if exists VPN then connect VPN
      end tell
    end tell
  EOF` 
end

def turn_off
  `/usr/bin/env osascript <<-EOF
    tell application "System Events"
      tell current location of network preferences
            set VPN to service "StrongVPN" -- your VPN name here
            if exists VPN then disconnect VPN
      end tell
  end tell
 EOF`
end

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