Start configured VPN from command line (OSX)

50

19

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.

Ketema

Posted 2011-11-17T15:00:58.400

Reputation: 683

Related: How to create a VPN connection via terminal?

– kenorb – 2018-02-18T20:14:31.053

Answers

46

For newer macOS versions, a very simple command can be used, as shown in the below answers, e.g. this one (give it a +1!).

All you need is:

 networksetup -connectpppoeservice "UniVPN"

The only problem is that you cannot disconnect using this command.


You can also 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
}

slhck

Posted 2011-11-17T15:00:58.400

Reputation: 182 472

You can disconnect. networksetup -disconnectpppoeservice "New VPN" – Shchvova – 2020-02-04T08:35:22.093

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 – 2013-01-24T17:13:00.257

Good idea. I updated my script… just tested it and it seems to work. – slhck – 2013-01-24T17:51:33.527

1This 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 – 2013-12-16T21:05:33.937

58

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 user, password, and secret using flags of the same names:

$ scutil --nc start Foo --user 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).

encoded

Posted 2011-11-17T15:00:58.400

Reputation: 796

The username option should be --user, not --username – Rockallite – 2015-01-05T09:14:25.683

2Any ideas why scutil --nc stop Foo does not work (on Yosemite)? – fdot – 2015-01-13T18:37:35.313

@fdot No, but I've noticed the same behavior. It's somewhere on my todo list to check the open bug reports at Apple. – encoded – 2015-01-16T16:20:40.937

scutil --nc start doesn't work for me under Mavericks. I get an error The IPSec Shared Secret is missing. Verify your settings and try reconnecting.. However, networksetup -connectpppoeservice does work. Unfortunately, network setup -disconnectpppoeservice does nothing. At least scutil -nc stop will work in that case. – Norman – 2015-02-03T17:04:19.690

@fdot and others. For what it's worth, I didn't find any open bugs with apple. I asked a question on their site, but haven't received any responses. https://discussions.apple.com/message/27696050#27696050

– encoded – 2015-03-12T16:30:04.437

Any way to get around a Cisco VPN connection REQUIRING you to enter a password in the dialog every time you want to connect? scutil -ns start will simply bring the password dialog up even with the --password argument specified. – dbainbridge – 2016-02-23T15:29:45.127

@dbainbridge Maybe you could do something with AppleScript? I'm wondering the same thing. – bonh – 2016-06-09T13:30:18.720

I've tried scutil, but at least on Yosemite, the "L2TP/Cisco" doesn't start in my environment as it complains about "can't connect to server". The oascript to tell System Event to start VPN, worked like a charm for me. – Hvisage – 2017-08-25T09:36:24.080

Just tried this in Lion (10.7.5) and it works great. Just not documented in the man pages. Thanks! – Eric B. – 2014-04-02T18:59:51.060

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. – 2014-04-02T19:12:33.283

@EricB. See my updates for a quick script. – encoded – 2014-04-03T04:22:18.840

26

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

networksetup -connectpppoeservice UniVPN

pierre-o

Posted 2011-11-17T15:00:58.400

Reputation: 261

This works with L2TP stored shared secret, while scutil does not! – Konstantin Suvorov – 2016-11-01T16:25:50.780

This works perfectly, as the scutil doesn't take any of the saved data, which is a pain. – Matt Fletcher – 2017-06-12T08:44:22.880

Worked for me on OS X 10.13.5 !! – User7391 – 2018-06-23T16:17:43.687

This should work this utility was added back in '02. – El Developer – 2013-07-06T20:53:05.023

2Yes, 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 – 2013-12-16T21:11:03.573

0

You can use networksetup -connectpppoeservice "myvpn" to connect to a vpn named myvpn, and use networksetup -disconnectpppoeservice "myvpn" to disconnect from the vpn named myvpn

Before use these command lines, you need to manually config a connection in System Preferences > Network

Feng Liu

Posted 2011-11-17T15:00:58.400

Reputation: 101

0

Works on MacOS 10.14.5 Mojave:

Connect VPN: Use @slhck's answer -> networksetup -connectpppoeservice "VPN Name"

Disconnect VPN: From @encoded's answer -> scutil --nc stop "VPN Name"

This worked for my L2TP over IPSEC VPN. I did not test Cisco IPSEC or IKEv2 VPNs

Eric Nelson

Posted 2011-11-17T15:00:58.400

Reputation: 101

0

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

boulder_ruby

Posted 2011-11-17T15:00:58.400

Reputation: 368