(Mac)Cisco AnyConnect Secure Mobility Clientをコマンドラインから操作する

どこにニーズがあるのかわかりませんが、私が必要だったので作ってみました。

Cisco AnyConnect Secure Mobility Clientは一般的にはGUIで提供されるVPNクライアントです。
起動するとこんな感じの画面が出て、予め設定しておけば決められた接続先に自動的に接続してくれるのですが、認証が必要な接続の場合は都度パスワード入力を求められます。

![スクリーンショット_2018-03-28_8_07_09.jpg](https://qiita-image-store.s3.amazonaws.com/0/110606/55e00611-39af-e944-fba5-e26291432bcd.jpeg)

これが毎回面倒でしかたなかったので、なんとかする方法がないか調べていたのですが、実は公式ヘルプにコマンドラインツールの記載があり、このクライアントをCLIから起動できることがわかりました。

<TABLE ALIGN=CENTER><TR><TD>
 <A HREF="https://www.cisco.com/c/en/us/td/docs/security/vpn_client/anyconnect/anyconnect30/administration/guide/anyconnectadmin30/ac15userguidelines.html#15928" TARGET="_blank"><STRONG>Cisco AnyConnect Secure Mobility Client 管理者ガイド リリース 4.2  <BR>
- AnyConnect クライアントとインストーラのカスタマイズとローカライズ [Cisco AnyConnect セキュア モビリティ クライアント] - Cisco  </STRONG></A>
 <A HREF="http://b.hatena.ne.jp/entry/https://www.cisco.com/c/en/us/td/docs/security/vpn_client/anyconnect/anyconnect30/administration/guide/anyconnectadmin30/ac15userguidelines.html#15928" TARGET="_blank">
 <IMG BORDER="0" SRC="http://b.hatena.ne.jp/entry/image/https://www.cisco.com/c/en/us/td/docs/security/vpn_client/anyconnect/anyconnect30/administration/guide/anyconnectadmin30/ac15userguidelines.html#15928" BORDER="0" ALT="" /></a>
 <BR>
AnyConnect CLI コマンドの使用
Cisco AnyConnect VPN Client には、グラフィカル ユーザ インターフェイスを使用せずにクライアント コマンドを入力することを希望するユーザ向けに、コマンドライン インターフェイス（CLI）があります。ここでは、CLI コマンド プロンプトの起動方法、および CLI を介して使用できるコマンドについて説明します。</TD>
 <TD WIDTH=150px>
 <IMG STYLE="float:left;margin-right:.5em;" SRC="http://capture.heartrails.com/120x120/cool?https://www.cisco.com/c/ja_jp/td/docs/sec/vpnendpointsecurclients/anyconnectsecuremobilityc/cg/004/b_AnyConnect_Administrator_Guide_4-2/b_AnyConnect_Administrator_Guide_4-2_chapter_01.html#id_27281" ALT="" WIDTH="120" HEIGHT="120" />
 </TD></TR>
</TABLE>

しかし実際にこのコマンドをターミナルから実行してみても、対話型シェルが起動するだけで結果的にアカウントとパスワードを入力する必要があるのは同じになってしまいました。

```
$ /opt/cisco/anyconnect/bin/vpn connect access.example.com/access_target
Cisco AnyConnect Secure Mobility Client (version 3.1.05178) .

Copyright (c) 2004 - 2013 Cisco Systems, Inc.  All Rights Reserved.


  >> state: Disconnected
  >> state: Disconnected
  >> notice: Ready to connect.
  >> registered with local VPN subsystem.
  >> contacting host (access.example.com/access_target) for login information...
  >> notice: Contacting access.example.com/access_target.
  >> warning: No valid certificates available for authentication.

  >> Please enter your username and password.

Username: 
Password:
```

これでは意味がないので、expectコマンドを使いシェル化してユーザー名とパスワードを入力させます。

```bash:vpnauto.sh
#!/bin/sh

# 接続先エイリアスまたはIPアドレス
CONNECTION_ALIAS=access.example.com/access_target
# ユーザー名
USER_NAME=user@example.com
# パスワード
PW=PWPWPW
# タイムアウト
TIMEOUT=5

expect -c "
    set timeout ${TIMEOUT}
    spawn /opt/cisco/anyconnect/bin/vpn connect ${CONNECTION_ALIAS}
    expect \“Username:\”
    send \"${USER_NAME}\n\"
    expect \"Password:\"
    send \"${PW}\n\"
    expect \"state: Connected\"
    exit 0
"
```

expectは、シェルの中で新たなコマンドラインプロセスを立ち上げて、そのプロセスとの入出力を制御できるコマンド。-c オプションでクォートの中に記載されたexpectの拡張コマンドを書かれた通りに実行していきます。

ここに記載されている拡張コマンドの概要を説明すると

----

**set timeout：** タイムアウト設定。
**spawn：** 指定されたコマンドを新たなプロセスで実行
**expect：** 標準出力に出力されたテキストをフェッチして一致するものがあれば続行
**send：** 標準入力にテキストを送る

----

こんな感じです。

エラーハンドリングとか何もしていないので、接続に失敗したりしてもユーザーとパスワードは送られてしまうので注意してください。

あとはこのシェルに実行権限をつけて実行するだけです。

```bash
$ chmod 755 vpnauto.sh
$ ./vpnauto.sh
spawn /opt/cisco/anyconnect/bin/vpn connect access.example.com/access_target
Cisco AnyConnect Secure Mobility Client (version 3.1.05178) .

Copyright (c) 2004 - 2013 Cisco Systems, Inc.  All Rights Reserved.
(略)
  >> Please enter your username and password.

Username: user@example.com
Password:
  >> state: Connecting
  >> notice: Establishing VPN session...
  >> notice: Checking for profile updates...
  >> notice: Checking for customization updates...
  >> notice: Performing any required updates...
  >> state: Connecting
  >> notice: Establishing VPN session...
  >> notice: Establishing VPN - Initiating connection...
  >> notice: Establishing VPN - Examining system...
  >> notice: Establishing VPN - Activating VPN adapter...
  >> notice: Establishing VPN - Configuring system...
  >> notice: Establishing VPN...
  >> state: Connected
  >> notice: Connected to access.example.com/access_target.
VPN>
$ 
```

# 注意点

AnyConnectのGUIクライアントが起動している状態でCLIを実行するとエラーになります。
この場合はGUIを落としてから実行して下さい。

```
  >> error: Connect not available. Another AnyConnect application is running
or this functionality was not requested by this application.
```


# 参考にしたサイト

<TABLE ALIGN=CENTER><TR><TD WIDTH=400px>
 <A HREF="http://kazmax.zpp.jp/cmd/e/expect.1.html" TARGET="_blank"><STRONG>expect - コマンド (プログラム) の説明 - Linux コマンド集 一覧表</STRONG></A>
 <A HREF="http://b.hatena.ne.jp/entry/http://kazmax.zpp.jp/cmd/e/expect.1.html" TARGET="_blank">
 <IMG BORDER="0" SRC="http://b.hatena.ne.jp/entry/image/http://kazmax.zpp.jp/cmd/e/expect.1.html" BORDER="0" ALT="" /></a>
 <BR>
 expect - コマンド (プログラム) の説明 - Linux コマンド集 一覧表... 
 </TD>
 <TD WIDTH=150px>
 <IMG STYLE="float:left;margin-right:.5em;" SRC="http://capture.heartrails.com/120x120/cool?http://kazmax.zpp.jp/cmd/e/expect.1.html" ALT="" WIDTH="120" HEIGHT="120" />
 </TD></TR>
</TABLE>