Skip to content

Cisco on macOS / Linux ​

Don't launch the GUI client. Everything here drives the command-line interface so the login can be scripted.

On a standard desktop install, the CLI lives at:

/opt/cisco/secureclient/bin/vpn

macOS users can alternatively install the iOS-style AnyConnect client, which also supports split tunneling, but features and stability vary by version.

Prerequisites ​

bash
# Debian/Ubuntu
sudo apt install oathtool

# macOS
brew install oath-toolkit

You also need Cisco AnyConnect / Secure Client already installed, so that /opt/cisco/secureclient/bin/vpn exists.

Quick install ​

bash
curl -fsSL https://sh.mawenqian.com/cisco-unix-install.sh | bash

What it does:

  • Drops cisco-vpn.sh and a config.sh template into /opt/cisco-vpn. Override with INSTALL_DIR=.... Creating the directory needs sudo, same as the OpenConnect installers.
  • Makes cisco-vpn.sh executable and symlinks it to ~/.local/bin/ciscovpn.
  • If ~/.local/bin isn't on your PATH yet, appends an export PATH=... line to .bashrc / .zshrc / .profile (whichever matches $SHELL), so ciscovpn actually works after you restart your shell. It checks for that exact line first, so re-running never duplicates it.

Re-running it later refreshes cisco-vpn.sh without touching your config.sh, so it doubles as an update mechanism.

Manual install ​

  1. Copy Cisco/unix/cisco-vpn.sh and Cisco/unix/config.sh wherever you like.
  2. Edit config.sh with your real VPN_HOST, VPN_USER, VPN_PASSWORD and VPN_SECRET.
  3. Make the script executable: chmod +x cisco-vpn.sh

Usage ​

bash
ciscovpn connect      # disconnect any existing session, then log in
ciscovpn disconnect   # disconnect

# or, if you installed manually / skipped the symlink:
./cisco-vpn.sh connect
./cisco-vpn.sh disconnect

Under the hood ​

cisco-vpn.sh generates a fresh TOTP code with oathtool and pipes a scripted command sequence into the CLI's -s (stdin-scripted) mode. The CLI doesn't accept connect <host> as a plain command-line argument on either platform; it only reacts to that sequence typed at its own interactive VPN> prompt. The Windows side uses the same mechanism via vpncli.exe -s.

bash
printf 'connect %s\n%s\n%s\n%s\n' "$VPN_HOST" "$VPN_USER" "$VPN_PASSWORD" "$OTP" \
    | /opt/cisco/secureclient/bin/vpn -s

Nothing touches disk. The credentials only exist in the pipe between this script and the CLI process for the moment it takes to read them.