Skip to content
🔧 Create macOS VPNs programmatically
Swift Ruby Objective-C
Branch: master
Clone or download

README.md

Version Homebrew License Build Status Codebeat Gitter

Create Mac OS VPNs programmatically

This is a command-line tool written in Objective-C (transitioning to Swift) that can create VPN network configurations on your Mac.

It supports both L2TP over IPSec and Cisco IPSec. Integration tests are run on Travis to ensure it's working properly.

Screenshot

Requirements

  • macOS High Sierra 10.13, Sierra 10.12, El Capitan 10.11, Yosemite 10.10, or Mavericks 10.9
  • Administrator privileges (i.e. you've got to run it with sudo)

Why sudo?

The passwords of VPN services are stored in the System Keychain. Only sudo or a HelperTool can write to the System Keychain. I don't want you to have to deal with the complexity a HelperTool can entail (GUI authorization and upgrading), so we simply use sudo.

Installation

If you have Homebrew installed, you can simply start a Terminal and run:

# See https://github.com/Homebrew/homebrew-core/search?q=macosvpn&type=Issues
brew install macosvpn

If not, you can run this curl command to get the compiled executable from Github:

# Make sure first that the directory /usr/local/bin exists
sudo bash -c "curl -L https://github.com/halo/macosvpn/releases/download/0.3.1/macosvpn > /usr/local/bin/macosvpn"
sudo chmod +x /usr/local/bin/macosvpn

If that freaks you out (it should), you can compile it yourself if you have Xcode installed:

git clone https://github.com/halo/macosvpn.git
cd macosvpn
xcodebuild -configuration Debug
build/Debug/macosvpn

You can always run macosvpn --version to see the version currently installed on your system and compare it to the latest available version on Github.

Usage

Creating a single L2TP over IPSec VPN Service:

sudo macosvpn create --l2tp Atlantic --endpoint atlantic.example.com --username Alice --password p4ssw0rd --shared-secret s3same
  • Replace --l2tp with --cisco to create a Cisco IPSec instead.
  • Groupnames can be specified with --groupname.
  • Add --force to overwrite an existing VPN with the same name.

By default, L2TP is created with the "Send all traffic over VPN connection" option, also known as wildcard routing. You can add the --split flag to not force all traffic over VPN.

Shortcuts

The same command but shorter:

sudo macosvpn create l2tp Atlantic endpoint atlantic.example.com username Alice password p4ssw0rd shared-secret s3same

The same command even shorter:

sudo macosvpn create -l Atlantic -e atlantic.example.com -u Alice -p p4ssw0rd -s s3same

The same command as short as possible:

sudo macosvpn create -leups Atlantic atlantic.example.com Alice p4ssw0rd s3same

Creating multiple VPNs at once

Repeat the arguments for creating multiple Services at once (no matter which short version you use :)

sudo macosvpn create -leups Atlantic atlantic.example.com Alice p4ssw0rd s3same \\
                     -leups Northpole northpole.example.com Bob s3cret pr1v4te

Deleting VPN services by name

These commands will prompt you for your password to allow changes to your Network configuration:

macosvpn delete --name MyVPN --name AnotherOne
macosvpn delete -n ThisOneToo

Run it with sudo to avoid the prompt:

sudo macosvpn delete --name MyVPN

Troubleshooting

  • If you're stuck, try to add the --debug flag and see if it says something useful.

Limitations

  • It is not possible to add so called "configurations" for L2TP. See this issue.

Development

The master branch is always edge and may not be ready for production.

Integration tests are run using ruby. Simply look at the before_script and script sections in the .travis.yml file to see how to run the tests on your Mac.

When using Xcode it's important to remember that you need to compile this app in the Debug configuration and not the Release configuration. Otherwise you will end up with unexplainable random crashes.

Useful commands for debugging:

# Show all current VPN service configurations
open /Library/Preferences/SystemConfiguration/preferences.plist
# Show all Keychain Items and their access policies
security dump-keychain -a /Library/Keychains/System.keychain

History and credits

Feel free to browse through the code of this application. It's pretty small and straight-forward.

It all began with finding this page you probably already found. But it was not before this practical example that I actually dared to try to implement this. Then, google led me to this page where I learned how to set the Shared Secret. The last hurdle was to get the "Send all traffic over VPN" flag, which I finally found the answer to here. Finally, I learned from over here how to add things to the System Keychain.

Special thanks

Thank you for reporting bugs. And thanks to all keen contributors.

These are the 3rd party libraries I was allowed to use:

License

MIT 2016 halo. See MIT-LICENSE.

You can’t perform that action at this time.