DEV Community

Andreas Siegel
Andreas Siegel

Posted on

Connect to a VPN from the Command Line on Mac OS

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

Top comments (15)

Collapse
 
patakijv profile image
John Pataki • Edited

Thanks for this. It is a great script and teaching tool for using macos command line tools.

Short: Does this need to be updated for Monterey (macos 12) or for Apple Silicon chipsets?

Longer: I've been using this script successfully on my 2019 Macbook Pro that is running Big Sur (macos 11) (with the modification referred to in the comments for Big Sur). I briefly had a test machine for the 2021 Macbook Pro M1 that was running Monterey (macos12) and it seems like some things change so the script didn't work correctly. I already returned the machine (getting the M1 Pro as a replacement) and can't recall exactly but I think the format of the output that checks the connected state was different which was throwing the script off. Has anyone modified the script so it works on Monterey (and possibly also is backward compatible?)

Collapse
 
josephfisher profile image
Joseph Fisher • Edited

I appreciate your detailed explanation of different ways to connect to a VPN from the command line. It's great to have alternatives to the graphical interface for more efficient workflow. Additionally, I wanted to mention that if you're looking for a reliable VPN solution, Hotspot Shield VPN is worth considering. It offers secure and private browsing, protects your online activities, and provides access to blocked content. With its user-friendly interface and strong encryption, Hotspot Shield VPN ensures a safe and seamless VPN experience.

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
 
laureano_galarraga_9f4cdb profile image
Laureano Galarraga

Hi!
Thanks, worked perfectly, but I had to make a small modification.
In my case, when the script tried to input the password, it'll put it in the username filed, then hit return and fail.
I had to add:
osascript -e "tell application \"System Events\" to keystroke (ASCII character 9)"
before
osascript -e "tell application \"System Events\" to keystroke \"${1}\""
osascript -e "tell application \"System Events\" to keystroke return"

to send the tab key and input the password in the correct field.
Hope that helps!

Collapse
 
pchavanc profile image
pchavanc

Hi,
thank you for this post.
I have EdgeMax as my VPN/firewall & I was always able to connect through my mac VPN GUI client. I recently upgraded to Big Sur & my client no longer connect the way it used to. One of the other websites suggested connecting through the scripts & was trying your way to VPN connect.
I get the following error . Any suggestion on how this could be resolved?

L2TP: incorrect user shared secret found.

The script does not mention of a shared key.

Regards,
Prakash

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
 
teaglebuilt profile image
dillan teagle

what vpn clients do you use?

Collapse
 
andreassiegel profile image
Andreas Siegel

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.

Collapse
 
redhat57 profile image
FireHawk

Hi, I'm unable to run that script in cronjob. It cannot fetch password from keychain. Please help me.

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
 
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!