DEV Community

loading...

Connect to a VPN from the Command Line on Mac OS

andreassiegel profile image Andreas Siegel ・4 min read

During Corona time, I have to connect to a VPN most of the time in order to work.
I use two different VPNs depending on what I'm working on.
I can select the network to connect to from the status bar at the top of the screen
but there seems to be a bug: Sometimes there isn't anything to select,
so I have to go to the network preferences and connect from there.

This works, but it also bothers me. Most of what I do frequently can be done from the command line.
There must be a way to also connect to a VPN from there!

It turned out there are multiple ways, actually.
Prerequisite is that the VPN has been configured in the network preferences.

Use networksetup

The networksetup command provides access to network settings that are usually configured in the System Preferences application.

Use this command to connect the VPN configured with the name "myVPN":

$ networksetup -connectpppoeservice "myVPN"

The following command will disconnect again:

$ networksetup -disconnectpppoeservice "myVPN"

If you want to check the connection status, use:

$ networksetup -showpppoestatus "myVPN"

Use scutil

The "system configuration utility" or scutil command provides access to network configuration, too.

To connect to your VPN, use this command:

$ scutil --nc start "myVPN"

Execute the following command to disconnect from the VPN:

$ scutil --nc stop "myVPN"

If you want to check the connection status, use:

$ scutil --nc status "myVPN"

Connect with Password from Keychain

Both mentioned commands work with the built-in VPN client.
Unfortunately, it is required to enter the password every time I connect because the account password is not stored in the keychain.
People are discussing for years now whether this is actually a bug or a feature of the built-in VPN client in Mac OS.

Installing another VPN client might solve that problem but you can also use a script as a workaround.

A script or at least an alias is a good idea anyway because I'd like to have something as short as vpn connect "myVPN".
It would be a great plus if that wouldn't even ask me to enter a password but retrieves it from the keychain instead.

Looking at the keychains in the Keychain Access application, I see only entries of kind IPSec Shared Secret in the system keychain and nothing in the login keychain or local items.
Thus, as of now, there isn't anything to retrieve the password from.

Add the VPN Account Password to the Keychain

To fix that, we first of all add the account password to the login keychain:

$ security add-generic-password \
  -D "VPN account password" \
  -s "myVPN" \
  -a "myUserAccount@myVPN" \
  -w "mySuperStrongPassword" \
  -T "/usr/bin/security"
  • -a specifies your VPN account name (required)
  • -D specifies the kind of the keychain entry (optional, default is "application password")
  • -s specifies the service name (the name of the keychain entry, required)
  • -T specifies an application which may access the keychain entry (multiple -T options are possible)
  • -w specified your VPN account password

The -s option should match the name of your configured VPN because we will use it to retrieve the account password from the keychain.

Create a Utility Script

Next, we will create a utility script that uses the keychain entry we just created:

$ echo '#!/bin/bash' > ~/vpnConnection.sh && chmod +x ~/vpnConnection.sh

This creates the vpnConnection.sh bash script in the home directory and makes it executable.

Open the script in an editor, and add this code:

With that script, you can now use these commands:

Command Description
~/vpnConnection.sh list show all VPN connections
~/vpnConnection.sh connect "myVPN" connect to the VPN "myVPN" and automatically enter the password
~/vpnConnection.sh disconnect "myVPN" disconnect to the VPN "myVPN"
~/vpnConnection.sh status "myVPN" show the connection status for VPN "myVPN"

Configure Privacy

If you run the script now, you might get an error like this:

execution error: System Events got an error: osascript is not allowed to send keystrokes. (1002)

In this case, you will have to configure your Privacy settings:

  1. Go to System Preferences > Security & Privacy
  2. Select the Privacy tab
  3. Select Accessibility
  4. Unlock the configuration if necessary
  5. Click the + button
  6. Press Cmd+Shift+G in the Finder window that opens
  7. Enter /usr/bin/osascript and click Go
  8. Click Open

This will allow osascript to control your computer, i.e.,
to automatically interact with the Mac OS user interface.

You might also have to add your terminal application (e.g., iTerm) to that list.

Set an Alias

With that, it is already pretty convenient to manage VPN connections.
To make it even more convenient, we will also set an alias so that we can type vpn instead of ~/vpnConnection.sh.

Add the following line to the configuration of your shell, e.g., ~/.zshrc or ~/.bashrc:

alias vpn="~/vpnConnection.sh"

Now, using VPN connections is as easy as this:

$ vpn list
$ vpn connect "myVPN"
$ vpn status "myVPN"
$ vpn disconnect "myVPN"

This post has initially been published on 4ndrs.xyz

Discussion (9)

pic
Editor guide
Collapse
gamergun profile image
GamerGun

Since Big Sur, it inserts the password into the "Account Name" field (probably because the focus is on that field by default). Any idea how to resolve that?

Collapse
tuksaur profile image
tuksaur

you can add tab to the enterPassword function after sleep 1, should resolve from printing password in username field.

osascript -e "tell application \"System Events\" to keystroke tab"

Collapse
gamergun profile image
GamerGun

Thank you, works like a charm!

Collapse
marcoslhc profile image
Marcos Hernández

This assumes your VPN server is supported by Mac Native Client. If you use OpenVPN you are out of luck :(

Collapse
marcoslhc profile image
Marcos Hernández

The scripts are awesome though. Great work!

Collapse
jamesmorr profile image
Jamesmorr

I'm looking for a VPN at the moment. There are a lot of reviews vpnwelt.com/vpn-mac/ such as this but they didn't count a user experience. Gonna try a native client. Thanks.

Collapse
grafst profile image
grafst

That is a great Idea

However, when running the script I get:

security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.
Unable to find VPN password in keychain

Collapse
teaglebuilt profile image
dillan teagle

what vpn clients do you use?

Collapse
andreassiegel profile image
Andreas Siegel Author

I use the native client in Mac OS which is available by default. In the past, I used Cisco AnyConnect but I don't see a need for it as the default is working just fine.