Cisco AnyConnect Secure Mobility Clientのパスワード入力が面倒臭すぎる
とあるサーバーに接続する時に、Cisco AnyConnect Secure Mobility Client を使う決まりになっているのですが、案内されているやり方はUIでいちいちパスワードを入力する方法で、非常にめんどくさい。それぐらいコマンドラインでやらせろや!と思って調べると、CLIもちゃんとCiscoインストール時に用意してあるみたいです。
というわけで、他の人のスクリプトを参考にしながら、CLIでCiscoのVPN接続をするスクリプトを書きました。
参考:このサイトが助けになりました。
(Mac)Cisco AnyConnect Secure Mobility Clientをコマンドラインから操作する
Shellスクリプト
まずciscoのコマンドがどこにあるか調べましょう。LinuxあるいはMac OS Xの場合、/opt/cisco/anyconnect/bin/vpn
にあるらしいです。たぶんあると思いますが一応チェックしといて下さい。
そしたらこんな感じのスクリプトを書きます。
#!/bin/bash
# setting
cisco_vpn=/opt/cisco/anyconnect/bin/vpn
USER='なんとか'
PASS='かんとか'
# if not exist then exit
if [ ! -e $cisco_vpn ]; then
echo "Not found cisco" >&2 ; exit 1
fi
# kill Cisco AnyConnect
killid=`pgrep 'Cisco AnyConnect Secure Mobility Client'`
if [ -n '$killid' ]; then
echo "Can I kill 'Cisco AnyConnect'? [Enter] " ; ps aux $killid ; read
sudo kill $killid
fi
# connect
printf "y\n$USER\n$PASS" | $cisco_vpn connect vpn接続先のサーバー名
内容としては
- ciscoコマンドのパス、ユーザー名とパスワードを設定。 (セキュリティの観点からはIDやパスワードを保存すべきじゃないんでしょうね。)
-
Cisco AnyConnect Secure Mobility Client
が動いているとコマンドの方でvpn接続してくれないので、Cisco AnyConnect Secure Mobility Client
をkillします。 - 本来対話形式するところの答えを用意しといて、vpn接続を実行。
これができたらあとは、~/.bashrc
とかにalias ssh_hoge='~/vpn_hoge.sh; sleep 1; ssh hoge'
という具合に書いておけば気軽に接続できます。
安全にパスワードを取得するバージョン(macOSの場合)
上の例では、パスワードをベタ書きしておりセキュリティ的によくないので、よりマシなスクリプトを加筆しておきます(2023.8.4)。こちら"Macのキーチェーンアクセスを使ってターミナルで安全にパスワードを取得する" にパスワードの取得方法をまとめました。Mac向けなのでご了承ください。またいくつかエラー処理を追加したのでそれもご参考ください。
#!/bin/bash
# if something wrong in this shell script, stop it
set -eu
# setting
cisco_vpn=/opt/cisco/anyconnect/bin/vpn
USER='なんとか'
PASS=`security find-generic-password -a account_name -s cisco_vpn_password -w`
# If command does not exist, then exit
if [ ! -e $cisco_vpn ]; then
echo "ciso not installed" >&2
exit 1
fi
# Kill running Cisco
if pgrep -f Cisco > /dev/null; then
echo -e "\nCisco process detected. Can I kill this with super-user privileges? [Enter]\n"
read
pkill -f Cisco
fi
# If already connected, no need to connect again
isconnected=`/opt/cisco/anyconnect/bin/vpn state | grep "Connected" | wc -l`
if [ $isconnected -gt 0 ]; then
echo "VPN already connected."
exit 0
fi
# Check if vpn return an error
output=$(printf "${USER}\n${PASS}" | $cisco_vpn -s connect vpn.cfca.nao.ac.jp)
nlerror=$(echo "$output" | grep -c "error")
# If error, kill running processes and try again
if [ $nlerror -gt 0 ]; then
echo "Errors occurred during the VPN connection process. Try again after killing vpn."
pkill vpn
pkill cisco
# Wait for the process to die
sleep 3 # or 5
output=$(printf "${USER}\n${PASS}" | $cisco_vpn -s connect vpn.cfca.nao.ac.jp)
exit 1
fi