Connect CISCO Anyconnect VPN via bash

2019-02-06 17:07发布

As title says, trying to connect vpn via bash. The following script seemed closest to the answer I'm looking for:

#!/bin/bash
/opt/cisco/anyconnect/bin/vpn -s << EOF
connect https://your.cisco.vpn.hostname/vpn_name
here_goes_your_username
here_goes_your_passwordy
EOF

When I run this the vpn starts but then exits without an error and without connecting. This seems to be caused by the -s. If I remove this parameter the VPN will start but none of the commands (ie connect vpn, username, password) will be entered. From what I read the -s option will allow the username/password to be passed. Help!

标签: bash vpn cisco
3条回答
男人必须洒脱
2楼-- · 2019-02-06 17:49

c# solution ... in this case profile is the group name.

//file = @"C:\Program Files (x86)\Cisco\Cisco AnyConnect Secure Mobility Client\vpncli.exe"
var file = vpnInfo.ExecutablePath;
var host = vpnInfo.Host;
var profile = vpnInfo.ProfileName;
var user = vpnInfo.User;
var pass = vpnInfo.Password;
var confirm = "y";

var proc = new Process
{
    StartInfo = new ProcessStartInfo
    {
        FileName = file,
        Arguments = string.Format("-s"),
        UseShellExecute = false,
        RedirectStandardInput = true,
        RedirectStandardOutput = true,
        RedirectStandardError = true,
    }
};

proc.OutputDataReceived += (s, a) => stdOut.AppendLine(a.Data);
proc.ErrorDataReceived += (s, a) => stdOut.AppendLine(a.Data);

//make sure it is not running, otherwise connection will fail
var procFilter = new HashSet<string>() { "vpnui", "vpncli" };
var existingProcs = Process.GetProcesses().Where(p => procFilter.Contains(p.ProcessName));
if (existingProcs.Any())
{
    foreach (var p in existingProcs)
    {
        p.Kill();
    }
}

proc.Start();
proc.BeginOutputReadLine();

//simulate profile file
var simProfile = string.Format("{1}{0}{2}{0}{3}{0}{4}{0}{5}{0}"
    , Environment.NewLine
    , string.Format("connect {0}", host)
    , profile
    , user
    , pass
    , confirm
    );

proc.StandardInput.Write(simProfile);
proc.StandardInput.Flush();

//todo: these should be configurable values
var waitTime = 500; //in ms
var maxWait = 10;

var count = 0;
var output = stdOut.ToString();
while (!output.Contains("state: Connected"))
{
    if (count > maxWait)
        throw new Exception("Unable to connect to VPN.");

    Thread.Sleep(waitTime);
    output = stdOut.ToString();
    count++;
}
stdOut.Append("VPN connection established! ...");
查看更多
Rolldiameter
3楼-- · 2019-02-06 17:53

Although expect can be cleaner, it is not strictly necessary. 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, and so you may not need it.

I understand that there are obvious security concerns with this method; it's for illustration purposes only.

To get state:

/opt/cisco/anyconnect/bin/vpn state

To disconnect:

/opt/cisco/anyconnect/bin/vpn disconnect

This was tested with AnyConnect v3.1.05160.

查看更多
Evening l夕情丶
4楼-- · 2019-02-06 17:58

I had to download the expect packages (yum install expect). Here is the code I used to automate vpn connection

#!/usr/bin/expect

eval spawn /opt/cisco/anyconnect/bin/vpn connect vpn.domain.com

expect "Username: " { send "username\r" }
expect "Password: " { send "password\r" }

set timeout 60
expect "VPN>"

Real easy! :D

查看更多
登录 后发表回答