48

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 9

54

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 HOST

Replace 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 disconnect

This was tested with AnyConnect v3.1.05160.

4
  • 5
    In case your client does not connect due to certificate validation error Certificate is from an untrusted source, and you still want to connect then pass a y parameter in the above method so that the command to connect becomes: printf "y\nUSERNAME\nPASSWORD\ny" | /opt/cisco/anyconnect/bin/vpn -s connect HOST. Note that do this only in the case that you absolutely trust your connection; otherwise there might be a middleman sitting in and snooping onto you.
    – shivams
    Apr 22, 2015 at 11:38
  • 2
    Works beautifully (though my version needs a GROUPNAME\nUSERNAME\nPASSWORDy. If you want to keep your password separate from the command (which may be a shell script or a dotfile key binding), you can do this: cat ~/.anyconnect_credentials | /opt/cisco/anyconnect/bin/vpn -s connect HOST Nov 4, 2019 at 18:08
  • @SridharSarnobat Using a separate file for the credentials works, but it prints out your password in the log like: >> notice: Please respond to banner. MYPASSWORD Nov 19, 2019 at 20:05
  • is there a way to specify the profile from the CLI ? Nov 29, 2021 at 20:59
14

I 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.

0
4

I 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.com

Using anyconnect 3.1.05170. Tested on Debian 6, LinuxMint 17

5
  • Why is 0\n necessary? Or is it specific to your company?
    – Asclepius
    Nov 9, 2014 at 5:10
  • @A-B-B That's just saying output a zero 0, followed by a newline \n followed by username, followed by a newline \n etc... Jan 22, 2015 at 21:39
  • @MattFriedman, I know what it's saying, but I don't know why it's necessary at all.
    – Asclepius
    Jan 22, 2015 at 23:02
  • 1
    @A-B-B When running interactively and your connection uses groups, the possible groups will be enumerated. 0 then means "use the first group".
    – jmd_dk
    Mar 6, 2018 at 5:24
  • 1
    Nice one. I did not like providing pin and token via plaintext, so i altered the script as follows: echo -n "Enter PIN :"; read -s PIN; echo; echo -n "Enter RSA token: "; read -s TOKEN; echo -e "0\nusername\n$PIN$TOKEN\n" > /tmp/answers.txt. As well as rm /tmp/answers.txt at the end of the file Aug 4, 2021 at 8:10
4

You can put your connection info in a separate file, e.g.

anyconnect.txt:

connect [HOST]
[GROUP or 0 or 1]
[USER]
[PASSWORD]
y
exit

And then do:

/opt/cisco/anyconnect/bin/vpn -s < anyconnect.txt
1
  • Hi @Dan, is it also possible to parse the 2nd password? I need to give a 2nd password 'push', which directs anyconnect client a push notification on my phone. While adding 'push' next to the [PASSWORD] line made the vpn client send a push notification to my phone, the client doesn't accept it and I don't know why. Below is my log ... Username: [...] Password: [...] Second Password: >> notice: Hostscan is performing system scan >> notice: Hostscan is performing software scan >> notice: Hostscan state idle >> notice: Hostscan is waiting for the next scan >> Login failed.
    – J-min
    Jul 10, 2021 at 20:53
3

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
EOF

To Disable

/opt/cisco/anyconnect/bin/vpn disconnect

*I know this is similar to Peter S.'s answer above.

1
  • 1
    This worked for me in one command for El Capitan, printf "y\n[GROUP]\n\n[PASSWORD]\ny\n" | /opt/cisco/anyconnect/bin/vpn -s connect HOST
    – Rabea
    Nov 23, 2016 at 0:07
1

To 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
        ;;
esac

The 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.

0

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"
0

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 $1

Save 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
0

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
  • As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Apr 15 at 3:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.