公司安全的同事最近给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
...
记得上面的ca
,key
,cert
几个要写绝对路径,即使和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