正如标题所说,试图通过bash连接vpn。以下脚本似乎最接近我正在寻找的答案:
#!/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
当我运行它时,vpn启动,但随后退出而没有错误且没有连接。这似乎是由-s引起的。如果我删除此参数,VPN将启动,但不会输入任何命令(即connect vpn,username,password)。从我读到的-s选项将允许传递用户名/密码。 救命啊!
答案 0 :(得分:11)
我不得不下载expect软件包(yum install expect)。这是我用来自动化vpn连接的代码
#!/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>"
真的很简单! :d
答案 1 :(得分:9)
虽然expect
可以更清洁,但并非绝对必要。假设/opt/cisco/anyconnect/bin/vpnagentd
正在运行,因为它应该是:
连接:
printf "USERNAME\nPASSWORD\ny" | /opt/cisco/anyconnect/bin/vpn -s connect HOST
替换USERNAME
,PASSWORD
和HOST
。最后的\ny
是接受登录横幅 - 这是我的主机特有的,所以你可能不需要它。
我知道这种方法存在明显的安全问题;它仅用于说明目的。
获取州:
/opt/cisco/anyconnect/bin/vpn state
断开连接:
/opt/cisco/anyconnect/bin/vpn disconnect
使用AnyConnect v3.1.05160进行了测试。
答案 2 :(得分:0)
c#solution ...在这种情况下,配置文件是组名。
//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! ...");
答案 3 :(得分:0)
基于Brayden Hancock的答案,我构建了一个从macOS钥匙串读取密码的解决方案。
第一步,我通过Keychain Access应用程序添加了一个新的密码项目,其中account
字段设置为mycompany-vpn
。脚本的第一部分从钥匙串中读取该项目,并使用ruby片段提取密码,expect
脚本部分负责其余的工作。
#!/usr/bin/env bash
get_pw () {
security 2>&1 >/dev/null find-generic-password -ga mycompany-vpn \
|ruby -e 'print $1 if STDIN.gets =~ /^password: "(.*)"$/'
}
USER=username
ADDR=vpn.company.com
PASSWORD=$(get_pw)
/usr/bin/expect -f - <<EOD
set timeout 10
spawn /opt/cisco/anyconnect/bin/vpn connect $ADDR
expect "\r\nUsername:*" {send -- "$USER\r"}
expect "Password: " {send -- "$PASSWORD\r"}
expect "Connected"
EOD
答案 4 :(得分:0)
如果您使用的是macOS,建议您将vpn密码保存在“钥匙串”中,然后从Anyconnect脚本中请求它。
例如,假设我要使用帐户foo.bar.com
和密码foo
连接到bar
。
foo
和bar
对保存在名称为fookey
的钥匙串中(不是iCloud登录)/opt/cisco/anyconnect/bin/vpn connect foo.bar.com -s << EOM
0 # foo.bar.com doesn't require two factor authorization
foo # vpn account
$(sudo security find-generic-password -ws fookey) # vpn password
EOM
使用这种方法,您不需要每次都输入vpn密码,也无需将密码写入未经加密的文件中。
如果您不熟悉bash脚本,请阅读以下内容以获取解释: