fangpsh's blog

一键连接VPN

公司安全的同事最近给OpenVPN加上了基于Google Authenticator的二步验证,密码是「常用密码」+「每次变化的Token」,每次在外边想做事都得打开手机查看Token,输入密码串,安全是安全了,可是不能忍!

OSX 生成Token

首先想到的是不要每次都打开手机,所以开始寻找Google Authenticator 生成工具的桌面版,果然有很多解决方案Is there a Google Authenticator desktop client?, 有Web版的、Java版的,不过最高效的当然是命令行版oathtool:

安装oath-toolkit:

brew install oath-toolkit

一个shell脚本,拷贝到 /usr/local/bin/,加上可执行权限:

#!/bin/bash
#fork from http://superuser.com/questions/462478/is-there-a-google-authenticator-desktop-client , by Peter Beckman

scriptname=`basename $0`
if [ -z $1 ]
then
echo "$scriptname: Service Name Req'd"
echo ""
echo "Usage:"
echo "   otp google"
echo ""
echo "Configuration: $HOME/.otpkeys"
echo "Format: name=key"
exit
fi
otpkey=` grep ^$1 $HOME/.otpkeys | cut -d"=" -f 2 | sed "s/ //g" `
if [ -z $otpkey ]
then
echo "$scriptname: Bad Service Name"
exit
fi
token=`/usr/local/bin/oathtool --totp -b $otpkey`
echo $token
echo $token | /usr/bin/pbcopy #自动拷贝至剪贴板

创建$HOME/.otpkeys 文件,输入Token生成码,格式:

格式:「名称」=「生成码」
例:google=UKPPIDEALLKPYTT9

好了,打开终端,执行 [脚本名] [名称] 试一试,例:

 ~  which oath
/usr/local/bin/oath
 ~  cat ~/.otpkeys
google=UKPPIDEALLKPYTT9
 ~  oath google
123456

另外按下 Command键+V 试一试,爽到不行,pbcopy真是个伟大的命令。

自动连接VPN

自动生成Token复制到剪贴板是方便了一点,不过想着每次还得自己打开客户端--「Tunnelblick」手动输入太烦。 安装OpenVPN:

brew install Caskroom/cask/tuntap #先安装这货
brew install openvpn

安装完成后拷贝OpenVPN的配置文件至 /usr/local/etc/openvpn目录(不放这个目录也行。。反正是手动指定的), 例:

#/usr/local/etc/openvpn/client.ovpn
...
remote vpn.google.com 1234
...
ca /usr/local/etc/openvpn/ca.crt
cert /usr/local/etc/openvpn/client1.crt
key /usr/local/etc/openvpn/client1.key
...

记得上面的cakeycert几个要写绝对路径,即使和openvpn的配置文件在同一目录下。
好了,执行

sudo /usr/local/sbin/openvpn  --config /usr/local/etc/openvpn/client.ovpn

试一试,输入帐号和密码,没问题的话会看到连接成功,下发的路由等等。

连接成功之后尝试把前面几步输入的操作用脚本搞定,祭出老牌神器--[expect]。

#!/usr/bin/expect

set username 「你的用户名」
set passwd [exec sh -c {echo "「你的密码」"`「上面一步生成Token你的脚本的绝对路径」 $HOME/.otpkeys中对应的条目名称」`}]
#例:set passwd [exec sh -c {echo "helloworld"`/usr/local/bin/oath google`}]
spawn sudo /usr/local/sbin/openvpn  --config /usr/local/etc/openvpn/「OpenVPN配置文件」
#例:spawn sudo /usr/local/sbin/openvpn  --config /usr/local/etc/openvpn/client.ovpn
expect  "Enter Auth Username:" {send "$username\n"}
expect "Enter Auth Password:" {send "$passwd\n"}

interact

保存上面的脚本到一个你觉得方便运行的地方,爽到不行不行的。不喜欢expect脚本的,可以用openvpn的 'auth-user-pass-verify' 选项来达到同样的目的。

openconnect

如果用的是OpenConnect的话,使用下列命令:

brew install Caskroom/cask/tuntap
brew install openconnect
echo "Password"`oath google`  |sudo openconnect --user=USERNAME --passwd-on-stdin   vpn.google.com