I am trying to use Cisco anyconnect 3.1 from Linux command line to connect to a server. I can connect, but I have to submit one parameter at a time. I would like to connect from a script that will run in another server. Can I do that? Something like
vpn connect server_add group_name user_name passwd 0 9 Answers
Assuming /opt/cisco/anyconnect/bin/vpnagentd is running as it automatically should be:
To connect:
printf 'USERNAME\nPASSWORD\ny' | /opt/cisco/anyconnect/bin/vpn -s connect HOSTReplace USERNAME, PASSWORD, and HOST. The \ny at the end is to accept the login banner - this is specific to my host.
Note the single quotes ' instead of double quotes " - this is because double quotes tell Bash to interpret certain characters within strings, such as exclamation marks, as Bash history commands. Double quotes will make this command fail with an "event not found" error if the password contains an exclamation mark. Single-quoted strings pass exclamation marks along without interpreting them.
To disconnect:
/opt/cisco/anyconnect/bin/vpn disconnectThis was tested with AnyConnect v3.1.05160.
4I ran into the same difficulty try to use Cisco AnyConnect from Mac OS X Terminal. To get the Cisco vpn command to take its input from standard input, you have to specify the -s option, which puts the Cisco vpn command into interactive mode. Then you can provide the responses that you give in interactive mode.
The responses that you need to give depend upon how the VPN server administrator has configured the server. For me, the vpn interactive prompts are
Group:
Username:
Password:
Blah, blah, blah, ...
accept? :So the command that I run is
$ /opt/cisco/anyconnect/bin/vpn -s connect vpn.example.com <<"EOF"
0
username
password
y
exit
EOF(The quotes around EOF are to prevent command/parameter expansion/substitution in the following input.)
The exit at the end is to exit the Cisco vpn interactive mode.
0I like to simplify the command line, so I use the above approach in a shell script named gotowork. As above, I need to provide the group, my user name, and a passkey composed of a private PIN plus a RSA SecurID passcode. I don't have to answer the above "accept?" question. Everything but the RSA passcode is in the script, so the command line is
$ gotowork <RSA passcode>I have to run it as root. Assume the PIN is 1234. The script essentials:
# put the interactive answers into a text file
echo -e "0\nusername\n1234$1\n" > /tmp/answers.txt
# find the path to the anyconnect executables
ciscopath="$(dirname $(find /opt/cisco -depth -name vpnagentd))"
# make sure the anyconnect daemon is running
[ $(pidof vpnagentd) ] || $ciscopath/vpnagentd
# connect
$ciscopath/vpn -s < /tmp/answers.txt connect remote.mycompany.comUsing anyconnect 3.1.05170. Tested on Debian 6, LinuxMint 17
5You can put your connection info in a separate file, e.g.
anyconnect.txt:
connect [HOST]
[GROUP or 0 or 1]
[USER]
[PASSWORD]
y
exitAnd then do:
/opt/cisco/anyconnect/bin/vpn -s < anyconnect.txt 1 This is what worked for me on OSX El Capitan. Placeholders are surrounded by [square braces].
To Enable
/opt/cisco/anyconnect/bin/vpn -s connect [HOST_ADDRESS] <<"EOF"
[VPN_USERNAME]
[VPN_PASSWORD]
y
EOFTo Disable
/opt/cisco/anyconnect/bin/vpn disconnect*I know this is similar to Peter S.'s answer above.
1To avoid hard-coding your password in a plain-text config file or putting it on the command line, you can also integrate with a CLI password manager like pass.
#!/bin/bash
# Easily connect to Cisco AnyConnect VPN
# Get first parameter
COMMAND="$1"
case $COMMAND in connect | CONNECT | c | C) printf "2\n${username}\n$(pass show my_password_entry)\n" | \ /opt/cisco/anyconnect/bin/vpn -s connect remote_host_url ;; disconnect | DISCONNECT | d | D) /opt/cisco/anyconnect/bin/vpn disconnect ;; *) cat <<EOF
Usage: vpnctl COMMAND connect | CONNECT | c | C Connect to the VPN disconnect | DISCONNECT | d | D Disconnect from the VPN
EOF ;;
esacThe initial 2 in the printf string just selects from a menu which my organization has configured to show up before you can put in your username and password. The exact printf statement may vary for you.
Tested using Cisco AnyConnect 4.10.02086 on Manjaro 21.2.6, with kernel 5.17.9.
For this use case, I used expect script. Pasting my solution below:
`#!/usr/bin/expect
spawn sudo /opt/cisco/anyconnect/bin/vpnagentd
expect ": "
send "Sudo Password goes here \r"
expect "$ "
spawn /opt/cisco/anyconnect/bin/vpn -s connect HOST
expect "*]*"
send -- "Username goes here\r"
expect "Password: "
send -- "Password goes here\r"
expect "Answer: "
send -- "If MFA is not enabled, then this step can be skipped\r" Inspired from others answers, I've written a shell script for less key strokes:
#!/usr/bin/env bash
__quickvpn(){ local username="your_username_here" local password="your_pwd_here" local url="your_host_here" local vpn_tool="/opt/cisco/anyconnect/bin/vpn" if [[ -z $1 && -e /opt/cisco/anyconnect/bin/vpn ]];then echo "usage: on | off | state \n - on: connect\n - off: disconnect\n - state: connect status\n" elif [[ $1 == "on" ]];then print "${username}\n${password}\ny" | $vpn_tool -s connect $url > /dev/null 2>&1 elif [[ $1 == "off" ]]; then print "${username}\n${password}\ny" | $vpn_tool -s disconnect $url > /dev/null 2>&1 elif [[ $1 == "state" ]]; then $vpn_tool -s state | sed 's/>>//' | sed -n 's/\(state:.*\).*/\1/p;/state/q' else echo "cisco vpn not found" fi
}
__quickvpn $1Save above as a shell script file named as myvpn under /usr/local/bin and chmod 744 /usr/local/bin/myvpn then you could use it like:
myvpn on # connect
myvpn off # disconnect
myvpn state # connection status This is what worked on MacOS Monterey:
#connect to vpn
cvpn() { printf 'y\n[your username]\n[password]\ny' | /opt/cisco/anyconnect/bin/vpn -s connect <vpn dns/url>
}
#disconnect to vpn
dvpn() { /opt/cisco/anyconnect/bin/vpn disconnect
} 1