59

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.

Ƭᴇcʜιᴇ007
  • 111,883
  • 19
  • 201
  • 268
Ketema
  • 793
  • 1
  • 5
  • 8
  • Related: [How to create a VPN connection via terminal?](https://apple.stackexchange.com/q/128297/22781) – kenorb Feb 18 '18 at 20:14

6 Answers6

63

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
  • 866
  • 7
  • 6
  • Just tried this in Lion (10.7.5) and it works great. Just not documented in the man pages. Thanks! – Eric B. Apr 02 '14 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 02 '14 at 19:12
  • @EricB. See my updates for a quick script. – encoded Apr 03 '14 at 04:22
  • The username option should be ```--user```, not ```--username``` – Rockallite Jan 05 '15 at 09:14
  • 2
    Any ideas why `scutil --nc stop Foo` does not work (on Yosemite)? – fdot Jan 13 '15 at 18:37
  • @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 Jan 16 '15 at 16:20
  • `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 Feb 03 '15 at 17:04
  • @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 Mar 12 '15 at 16:30
  • 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 Feb 23 '16 at 15:29
  • @dbainbridge Maybe you could do something with AppleScript? I'm wondering the same thing. – bonh Jun 09 '16 at 13:30
  • 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 Aug 25 '17 at 09:36
  • How can one confirm automatically a message by the VPN server that pops up after the connection has been established? – Fábio Feb 17 '21 at 11:37
58

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
  • 223,558
  • 70
  • 607
  • 592
  • 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
  • 1
    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
  • You can disconnect. `networksetup -disconnectpppoeservice "New VPN"` – Shchvova Feb 04 '20 at 08:35
30

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

networksetup -connectpppoeservice UniVPN
Seth
  • 393
  • 8
  • 26
pierre-o
  • 301
  • 3
  • 2
2

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
  • 121
  • 3
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
  • 101
  • 1
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
  • 378
  • 2
  • 4
  • 16