我正在尝试编写一个脚本,该脚本将在计算机启动时建立 openvpn 隧道。主要问题在于输入pkcs12密码。我意识到以纯文本形式存储密码是非常糟糕的做法,但我对此并不太大惊小怪 - 计算机在所有其他方面都非常安全,因此我非常有信心除了我之外没有人可以访问它查看密码。
我添加了--management
和--management-query-passwords
选项,以便可以通过 telnet 会话输入密码。当我手动执行此操作时,效果很好,但是当我尝试使用 bash 脚本自动执行此操作时,它会失败。我的猜测是,要么我没有在密码行后正确执行回车,要么其他一些垃圾值作为输入潜入到 telnet 会话中。这是相关的代码位(xxx 表示分类的内容):
$ cat user.ovpn
#OpenVPN Server conf
tls-client
client
dev tun
proto udp
tun-mtu 1400
remote xxxxxxxxxxxxxxxxxxx 1194
pkcs12 user.p12
cipher AES-256-CBC
comp-lzo
verb 3
ns-cert-type server
tls-remote xxxxxxxxxxxxxxxxxxxxxxx
management 127.0.0.1 5558
management-query-passwords
$ cat telnet_commands.sh
#!/bin/bash
echo "open 127.0.0.1 5558"
sleep 1
echo -e "password 'Private Key' xxxxxxxxxx\r\n"
$ nohup openvpn user.ovpn &
$ ./telnet_commands.sh | telnet
$ #manually check whether this worked:
$ telnet 127.0.0.1 5558
Escape character is '^]'.
>INFO:OpenVPN Management Interface Version 1 -- type 'help' for more info
>PASSWORD:Need 'Private Key' password
显然这不起作用——openvpn telnet 管理界面仍在等待输入密码。
答案1
只是想提一下(至少在 Ubuntu 12.04 上)--askpass /你的/文件openvpn 的参数,从文件中读取私钥密码。
答案2
我的工作案例有一个小修正:
nohup openvpn /etc/init.d/ovpn/Userxxx.ovpn &
/etc/init.d/ovpn/telnet_commands.sh
答案3
我希望它所寻找的只是私钥的密码。尝试使用echo -e "xxxxxxxxx\r\n"
或echo "xxxxxxxx"
。
您可能想尝试使用expect
来响应密码请求。某些密码程序会在类型设备上查找密码tty
。程序expect 处理这个问题。
您最好寻找一个rc.d
初始化脚本来启动您的隧道。这是启动时启动的正常方法。
答案4
好的,我已经成功地自动输入了 openvpn 隧道密码,并且还成功地让隧道在启动时运行。希望这可以帮助其他正在尝试做同样事情的人 - 因为我花了 20 多个小时才弄清楚现在看起来非常基本的东西。代码:
$ cat /etc/init.d/ZZcreate_ovpn_tun.sh
#!/bin/bash
# check if the tunnel already exists before trying to create it
proc=$(ps aux | grep openvpn | grep Userxxx)
if [ "$proc" == "" ]; then
echo "ovpn tunnel does not exist yet - will create it now"
else
echo "ovpn tunnel already exists ($proc)"
exit 0
fi
# load the config file into openvpn - has options to request the pkcs12 password through
# telnet
nohup openvpn /etc/init.d/ovpn/Userxxx.ovpn
sleep 1
# enter the password though a telnet session
/etc/init.d/ovpn/telnet_commands.sh
$ cat /etc/init.d/ovpn/telnet_commands.sh
#!/usr/bin/expect
spawn telnet 127.0.0.1 5558
expect ">PASSWORD:Need 'Private Key' password"
send "password 'Private Key' xxxxxxxxxxxxx\r"
expect "SUCCESS: 'Private Key' password entered, but not yet verified"
send "quit\r"
expect eof
$ cat Userxxx.ovpn
#OpenVPN Server conf
tls-client
client
dev tun
proto udp
tun-mtu 1400
remote xxxxxxxxxxxxxxxxxxxxxxxxxxxxx.com.au 1194
pkcs12 /etc/init.d/ovpn/Userxxx.p12
cipher AES-256-CBC
comp-lzo
verb 3
ns-cert-type server
tls-remote xxxxxxxxxxxxxxxxxxxxxxxxxxx.com.au
management 127.0.0.1 5558
management-query-passwords
$ sudo update-rc.d ZZcreate_ovpn_tun.sh defaults
$ sudo shutdown -r 0
$ # wait for system to boot up again
$ ps aux | grep openvpn
root 5279 0.0 0.1 28224 3728 ? S 22:48 0:00 openvpn /etc/init.d/ovpn/Userxxx.ovpn
您可能还想将所有输出重定向到一个文件,以便在失败时您能够了解原因。我调用了文件 ZZcreate_ovpn_tun.sh 以确保它是 init.d 目录中所有脚本中最后运行的。理想情况下,我会确保它只在 6 级左右运行,但目前效果很好。